From linux.amoon at gmail.com  Sat Nov  1 01:09:41 2025
From: linux.amoon at gmail.com (Anand Moon)
Date: Sat, 1 Nov 2025 13:39:41 +0530
Subject: [PATCH v1 2/2] PCI: dw-rockchip: Add runtime PM support to
 Rockchip PCIe driver
In-Reply-To: <e7cttuu5525k7ryvmkh6ifspm5vloj4muazvmp3yxtkgsdtbjs@u4odsfurejxq>
References: <20251027145602.199154-1-linux.amoon@gmail.com>
 <20251027145602.199154-3-linux.amoon@gmail.com> <ukgkfetbggzon4ppndl7gpitlsz7hjhzhyx3dgxqhdo52exguy@bqksd7d27lpy>
 <CANAwSgTECOAoKeJS_=HxkkTP4OJvYu5xGQxY__Auh81v3QT=-w@mail.gmail.com> <e7cttuu5525k7ryvmkh6ifspm5vloj4muazvmp3yxtkgsdtbjs@u4odsfurejxq>
Message-ID: <CANAwSgTRFMiSN8Q-tndvVXk7NxuNJE7GmcBXq46RQ=Z6-qOLEw@mail.gmail.com>

Hi Manivannan

On Fri, 31 Oct 2025 at 20:23, Manivannan Sadhasivam <mani at kernel.org> wrote:
>
> On Fri, Oct 31, 2025 at 07:33:23PM +0530, Anand Moon wrote:
> > Hi Manivannan
> >
> > Thanks for your review comment.
> >
> > On Fri, 31 Oct 2025 at 14:09, Manivannan Sadhasivam <mani at kernel.org> wrote:
> > >
> > > On Mon, Oct 27, 2025 at 08:25:30PM +0530, Anand Moon wrote:
> > > > Add runtime power management support to the Rockchip DesignWare PCIe
> > > > controller driver by enabling devm_pm_runtime() in the probe function.
> > > > These changes allow the PCIe controller to suspend and resume dynamically,
> > > > improving power efficiency on supported platforms.
> > > >
> > >
> > > Seriously? How can this patch improve the power efficiency if it is not doing
> > > any PM operation on its own?
> > >
> > I could verify that runtime power management is active
> >
>
> This is runtime status being active, which is a different thing as it only
> allows the runtime PM hierarchy to be maintained. But the way you described the
> commit message sounds like the patch is enabling runtime PM of the controller
> and that improves efficiency (as if the controller driver is actively doing
> runtime PM operations).
>
> > [root at rockpi-5b alarm]# cat
> > /sys/devices/platform/a41000000.pcie/power/runtime_status
> > active
> > [root at rockpi-5b alarm]#  find /sys -name runtime_status
> > /sys/devices/platform/a41000000.pcie/pci0004:40/0004:40:00.0/power/runtime_status
> > /sys/devices/platform/a41000000.pcie/pci0004:40/0004:40:00.0/pci_bus/0004:41/power/runtime_status
> > /sys/devices/platform/a41000000.pcie/pci0004:40/0004:40:00.0/0004:41:00.0/power/runtime_status
> > /sys/devices/platform/a41000000.pcie/pci0004:40/0004:40:00.0/0004:41:00.0/net/enP4p65s0/power/runtime_status
> > /sys/devices/platform/a41000000.pcie/pci0004:40/0004:40:00.0/0004:41:00.0/net/enP4p65s0/enP4p65s0-3::lan/power/runtime_status
> > /sys/devices/platform/a41000000.pcie/pci0004:40/0004:40:00.0/0004:41:00.0/net/enP4p65s0/enP4p65s0-2::lan/power/runtime_status
> > /sys/devices/platform/a41000000.pcie/pci0004:40/0004:40:00.0/0004:41:00.0/net/enP4p65s0/enP4p65s0-1::lan/power/runtime_status
> > /sys/devices/platform/a41000000.pcie/pci0004:40/0004:40:00.0/0004:41:00.0/net/enP4p65s0/enP4p65s0-0::lan/power/runtime_status
> > /sys/devices/platform/a41000000.pcie/pci0004:40/0004:40:00.0/0004:41:00.0/mdio_bus/r8169-4-4100/power/runtime_status
> > /sys/devices/platform/a41000000.pcie/pci0004:40/0004:40:00.0/0004:41:00.0/mdio_bus/r8169-4-4100/r8169-4-4100:00/power/runtime_status
> > /sys/devices/platform/a41000000.pcie/pci0004:40/0004:40:00.0/0004:41:00.0/mdio_bus/r8169-4-4100/r8169-4-4100:00/hwmon/hwmon11/power/runtime_status
> >
> > Well, the powertop shows that the runtime power management is enabled
> > on Radxa Rock 5b,
> >
> > PowerTOP 2.15     Overview   Idle stats   Frequency stats   Device
> > stats   Device Freq stats   Tunables   WakeUp
> > >> Good          Wireless Power Saving for interface wlan0
> >    Good          VM writeback timeout
> >    Good          Bluetooth device interface status
> >    Good          NMI watchdog should be turned off
> >    Good          Autosuspend for unknown USB device 2-1.3 (8087:0a2b)
> >    Good          Autosuspend for USB device USB 2.0 Hub [2-1]
> >    Good          Autosuspend for USB device Generic Platform OHCI
> > controller [usb1]
> >    Good          Autosuspend for USB device xHCI Host Controller [usb8]
> >    Good          Autosuspend for USB device Generic Platform OHCI
> > controller [usb4]
> >    Good          Autosuspend for USB device EHCI Host Controller [usb2]
> >    Good          Autosuspend for USB device xHCI Host Controller [usb6]
> >    Good          Autosuspend for USB device EHCI Host Controller [usb3]
> >    Good          Autosuspend for USB device xHCI Host Controller [usb5]
> >    Good          Autosuspend for USB device xHCI Host Controller [usb7]
> >    Good          Runtime PM for PCI Device Intel Corporation Wireless
> > 8265 / 8275
> >    Good          Runtime PM for PCI Device Rockchip Electronics Co., Ltd RK3588
> >    Good          Runtime PM for PCI Device Rockchip Electronics Co., Ltd RK3588
> >    Good          Runtime PM for PCI Device Realtek Semiconductor Co.,
> > Ltd. RTL8125 2.5GbE Controller
> >    Good          Runtime PM for PCI Device Rockchip Electronics Co., Ltd RK3588
> >    Good          Runtime PM for PCI Device Samsung Electronics Co Ltd
> > NVMe SSD Controller SM981/PM981/PM983
> >
> > PowerTOP 2.15     Overview   Idle stats   Frequency stats   Device
> > stats   Device Freq stats   Tunables   WakeUp
> >               Usage     Device name
> >               1.1%        CPU use
> >             100.0%        Radio device: rfkill_gpio
> >             100.0%        runtime-rockchip-gate-link-clk.712
> >             100.0%        PCI Device: Realtek Semiconductor Co., Ltd.
> > RTL8125 2.5GbE Controller
> >             100.0%        runtime-rockchip-gate-link-clk.717
> >             100.0%        runtime-rockchip-gate-link-clk.714
> >             100.0%        runtime-rockchip-gate-link-clk.489
> >             100.0%        runtime-a40000000.pcie
> >             100.0%        runtime-a40800000.pcie
> >             100.0%        runtime-rockchip-gate-link-clk.718
> >             100.0%        runtime-rockchip-gate-link-clk.706
> >             100.0%        runtime-rockchip-gate-link-clk.708
> >             100.0%        PCI Device: Intel Corporation Wireless 8265 / 8275
> >             100.0%        Radio device: btusb
> >             100.0%        runtime-fcd00000.usb
> >             100.0%        PCI Device: Samsung Electronics Co Ltd NVMe
> > SSD Controller SM981/PM981/PM983
> >             100.0%        Radio device: rfkill_gpio
> >             100.0%        runtime-fc000000.usb
> >             100.0%        Radio device: iwlwifi
> >             100.0%        PCI Device: Rockchip Electronics Co., Ltd RK3588
> >             100.0%        PCI Device: Rockchip Electronics Co., Ltd RK3588
> >             100.0%        PCI Device: Rockchip Electronics Co., Ltd RK3588
> >             100.0%        runtime-rockchip-gate-link-clk.711
> >             100.0%        runtime-fc400000.usb
> >             100.0%        runtime-rockchip-gate-link-clk.704
> >             100.0%        runtime-rockchip-gate-link-clk.701
> >             100.0%        runtime-rockchip-gate-link-clk.716
> >             100.0%        runtime-rockchip-gate-link-clk.707
> >             100.0%        runtime-rockchip-gate-link-clk.709
> >             100.0%        runtime-rockchip-gate-link-clk.719
> >             100.0%        runtime-xhci-hcd.1.auto
> >             100.0%        runtime-feb50000.serial
> >             100.0%        runtime-rockchip-gate-link-clk.715
> >             100.0%        runtime-rockchip-gate-link-clk.710
> >
> > > Again, a pointless patch.
>
> This patch might make sense on its own, to enable runtime PM status of the
> controller so that the runtime PM could be applied to the entire PCIe hierarchy.
>
I will update this in the commit message.
> > I implemented a .remove patch to ensure proper resource cleanup,
> > which is a necessary step for successfully enabling and managing
> > runtime power for the device.
>
> How a dead code (remove callback for a always built-in driver) becomes necessary
> for runtime PM.
>
Ok, understood we don't have platform_driver_unregister in
builtin_platform_driver
I will drop the first patch.

> - Mani
>
Thanks
-Annad
> --
> ????????? ????????


From linux.amoon at gmail.com  Sat Nov  1 03:47:54 2025
From: linux.amoon at gmail.com (Anand Moon)
Date: Sat, 1 Nov 2025 16:17:54 +0530
Subject: [PATCH v1] PCI: dw-rockchip: Simplify regulator setup with devm_regulator_get_enable_optional()
In-Reply-To: <CANAwSgRjXS4V_Kpw5kaJnPA8f=18uN-MgfEQ5ErN3aFRqbJKfg@mail.gmail.com>
References: <20250905112736.6401-1-linux.amoon@gmail.com> <176085588758.11569.7678087221969106036.b4-ty@kernel.org>
 <CANAwSgRjXS4V_Kpw5kaJnPA8f=18uN-MgfEQ5ErN3aFRqbJKfg@mail.gmail.com>
Message-ID: <CANAwSgSrisWFPPRkZ=ukCjui3_xzgrmLKz5F9iXnerUFktk5UA@mail.gmail.com>

Hi Manivannan,

On Fri, 31 Oct 2025 at 12:27, Anand Moon <linux.amoon at gmail.com> wrote:
>
> Hi Manivannan,
>
> On Sun, 19 Oct 2025 at 12:08, Manivannan Sadhasivam <mani at kernel.org> wrote:
> >
> >
> > On Fri, 05 Sep 2025 16:57:25 +0530, Anand Moon wrote:
> > > Replace manual get/enable logic with devm_regulator_get_enable_optional()
> > > to reduce boilerplate and improve error handling. This devm helper ensures
> > > the regulator is enabled during probe and automatically disabled on driver
> > > removal. Dropping the vpcie3v3 struct member eliminates redundant state
> > > tracking, resulting in cleaner and more maintainable code.
> > >
> > >
> > > [...]
> >
> > Applied, thanks!
> >
> > [1/1] PCI: dw-rockchip: Simplify regulator setup with devm_regulator_get_enable_optional()
> >       commit: c930b10f17c03858cfe19b9873ba5240128b4d1b
> >
> I am looking to suspend or resume the issue. We probably need to
> toggle the regulator
> to maintain the power status on the PCIe controller.
> Therefore, dropping the patch is an option; I will add dev_err_probe
> for PHY later in the patch.
>
I found this series with the address system suspend support

[1] https://lore.kernel.org/linux-pci/20251029-rockchip-pcie-system-suspend-v4-0-ce2e1b0692d2 at collabora.com/

This patch will conflict with
[2] https://lore.kernel.org/linux-pci/20251029-rockchip-pcie-system-suspend-v4-3-ce2e1b0692d2 at collabora.com/

So please drop my patch.

Thanks
-Anand


From linux.amoon at gmail.com  Sat Nov  1 04:19:25 2025
From: linux.amoon at gmail.com (Anand Moon)
Date: Sat, 1 Nov 2025 16:49:25 +0530
Subject: [PATCH v4 0/9] PCI: dw-rockchip: add system suspend support
In-Reply-To: <20251029-rockchip-pcie-system-suspend-v4-0-ce2e1b0692d2@collabora.com>
References: <20251029-rockchip-pcie-system-suspend-v4-0-ce2e1b0692d2@collabora.com>
Message-ID: <CANAwSgTMc=FcOi4=vPCUytMMg5dZO7QU4m6D=6V8RZ9hSDxn4A@mail.gmail.com>

Hi Sebastian,

On Wed, 29 Oct 2025 at 23:27, Sebastian Reichel
<sebastian.reichel at collabora.com> wrote:
>
> I've recently been working on fixing up at least basic system suspend
> support on the Rockchip RK3576 platform. Currently the biggest open
> issue is missing support in the PCIe driver. This series is a follow-up
> for Shawn Lin's series with feedback from Niklas Cassel and Manivannan
> Sadhasivam being handled as well as some of my own changes fixing up
> things I noticed.
>
> In opposite to Shawn Lin I did not test with different peripherals as my
> main goal is getting basic suspend to ram working in the first place. I
> did notice issues with the Broadcom WLAN card on the RK3576 EVB.
> Suspending that platform without a driver being probed works, but after
> probing brcmfmac suspend is aborted because brcmf_pcie_pm_enter_D3()
> does not work. As far as I can tell the problem is unrelated to the
> Rockchip PCIe driver.
>
Well, I gave it a try on Radxa Rock 5b,
I am observing the falling warning.

PM: noirq suspend of devices failed

alarm at rockpi-5b:~$ sudo systemctl suspend
[sudo] password for alarm:
alarm at rockpi-5b:~$ [  459.301536][ T6149] wlan0: deauthenticating from
78:d2:94:85:bb:b2 by local choice (Reason: 3=DEAUTH_LEAVING)
[  459.383823][ T6056] r8169 0004:41:00.0 enP4p65s0: Link is Down
[  459.384568][ T6056] r8169 0004:41:00.0: disabling bus mastering
[  459.862229][ T6291] PM: suspend entry (deep)
[  459.935040][ T6291] Filesystems sync: 0.072 seconds
[  459.941444][ T6253] (NULL device *): loading
/lib/firmware/6.18.0-rc3-3-ARM64-GCC/intel/ibt-12-16.sfi failed with
error -20
[  459.943775][ T6253] (NULL device *): loading
/lib/firmware/6.18.0-rc3-3-ARM64-GCC/intel/ibt-12-16.ddc failed with
error -20
[  459.945047][   T59] (NULL device *): loading
/lib/firmware/6.18.0-rc3-3-ARM64-GCC/arm/mali/arch10.8/mali_csffw.bin
failed with error -20
[  459.946854][ T6253] (NULL device *): loading
/lib/firmware/6.18.0-rc3-3-ARM64-GCC/iwlwifi-8265-36.ucode failed with
error -20
[  459.953052][ T6291] Freezing user space processes
[  460.001306][ T6291] Freezing user space processes completed
(elapsed 0.047 seconds)
[  460.001993][ T6291] OOM killer disabled.
[  460.002341][ T6291] Freezing remaining freezable tasks
[  460.004202][ T6291] Freezing remaining freezable tasks completed
(elapsed 0.001 seconds)
[  460.004953][ T6291] printk: Suspending console(s) (use
no_console_suspend to debug)
[  460.070242][ T6253] nvme 0000:01:00.0: save config 0x00: 0xa808144d
[  460.070261][ T6253] nvme 0000:01:00.0: save config 0x04: 0x00100406
[  460.070272][ T6253] nvme 0000:01:00.0: save config 0x08: 0x01080200
[  460.070281][ T6253] nvme 0000:01:00.0: save config 0x0c: 0x00000000
[  460.070291][ T6253] nvme 0000:01:00.0: save config 0x10: 0xf0200004
[  460.070300][ T6253] nvme 0000:01:00.0: save config 0x14: 0x00000000
[  460.070309][ T6253] nvme 0000:01:00.0: save config 0x18: 0x00000000
[  460.070319][ T6253] nvme 0000:01:00.0: save config 0x1c: 0x00000000
[  460.070328][ T6253] nvme 0000:01:00.0: save config 0x20: 0x00000000
[  460.070337][ T6253] nvme 0000:01:00.0: save config 0x24: 0x00000000
[  460.070346][ T6253] nvme 0000:01:00.0: save config 0x28: 0x00000000
[  460.070355][ T6253] nvme 0000:01:00.0: save config 0x2c: 0xa801144d
[  460.070364][ T6253] nvme 0000:01:00.0: save config 0x30: 0x00000000
[  460.070373][ T6253] nvme 0000:01:00.0: save config 0x34: 0x00000040
[  460.070383][ T6253] nvme 0000:01:00.0: save config 0x38: 0x00000000
[  460.070392][ T6253] nvme 0000:01:00.0: save config 0x3c: 0x0000016d
[  460.274027][ T6253] iwlwifi 0002:21:00.0: save config 0x00: 0x24fd8086
[  460.274058][ T6253] iwlwifi 0002:21:00.0: save config 0x04: 0x00100406
[  460.274080][ T6253] iwlwifi 0002:21:00.0: save config 0x08: 0x02800078
[  460.274102][ T6253] iwlwifi 0002:21:00.0: save config 0x0c: 0x00000000
[  460.274124][ T6253] iwlwifi 0002:21:00.0: save config 0x10: 0xf2200004
[  460.274146][ T6253] iwlwifi 0002:21:00.0: save config 0x14: 0x00000000
[  460.274168][ T6253] iwlwifi 0002:21:00.0: save config 0x18: 0x00000000
[  460.274189][ T6253] iwlwifi 0002:21:00.0: save config 0x1c: 0x00000000
[  460.274210][ T6253] iwlwifi 0002:21:00.0: save config 0x20: 0x00000000
[  460.274232][ T6253] iwlwifi 0002:21:00.0: save config 0x24: 0x00000000
[  460.274253][ T6253] iwlwifi 0002:21:00.0: save config 0x28: 0x00000000
[  460.274275][ T6253] iwlwifi 0002:21:00.0: save config 0x2c: 0x10108086
[  460.274296][ T6253] iwlwifi 0002:21:00.0: save config 0x30: 0x00000000
[  460.274318][ T6253] iwlwifi 0002:21:00.0: save config 0x34: 0x000000c8
[  460.274340][ T6253] iwlwifi 0002:21:00.0: save config 0x38: 0x00000000
[  460.274361][ T6253] iwlwifi 0002:21:00.0: save config 0x3c: 0x00000183
[  460.274917][ T6300] r8169 0004:41:00.0: save config 0x00: 0x812510ec
[  460.274927][ T6300] r8169 0004:41:00.0: save config 0x04: 0x00100403
[  460.274937][ T6300] r8169 0004:41:00.0: save config 0x08: 0x02000005
[  460.274947][ T6300] r8169 0004:41:00.0: save config 0x0c: 0x00000010
[  460.274957][ T6300] r8169 0004:41:00.0: save config 0x10: 0xf4100001
[  460.274967][ T6300] r8169 0004:41:00.0: save config 0x14: 0x00000000
[  460.274977][ T6300] r8169 0004:41:00.0: save config 0x18: 0xf4200004
[  460.274987][ T6300] r8169 0004:41:00.0: save config 0x1c: 0x00000000
[  460.274996][ T6300] r8169 0004:41:00.0: save config 0x20: 0xf4210004
[  460.275006][ T6300] r8169 0004:41:00.0: save config 0x24: 0x00000000
[  460.275016][ T6300] r8169 0004:41:00.0: save config 0x28: 0x00000000
[  460.275026][ T6300] r8169 0004:41:00.0: save config 0x2c: 0x012310ec
[  460.275036][ T6300] r8169 0004:41:00.0: save config 0x30: 0x00000000
[  460.275045][ T6300] r8169 0004:41:00.0: save config 0x34: 0x00000040
[  460.275055][ T6300] r8169 0004:41:00.0: save config 0x38: 0x00000000
[  460.275065][ T6300] r8169 0004:41:00.0: save config 0x3c: 0x00000197
[  460.285117][ T6253] iwlwifi 0002:21:00.0: PCI PM: Suspend power state: D3hot
[  460.287498][ T6300] r8169 0004:41:00.0: PCI PM: Suspend power state: D3hot
[  460.287631][ T6296] pcieport 0004:40:00.0: save config 0x00: 0x35881d87
[  460.287644][ T6296] pcieport 0004:40:00.0: save config 0x04: 0x00100507
[  460.287651][ T6296] pcieport 0004:40:00.0: save config 0x08: 0x06040001
[  460.287658][ T6296] pcieport 0004:40:00.0: save config 0x0c: 0x00010000
[  460.287664][ T6296] pcieport 0004:40:00.0: save config 0x10: 0x00000000
[  460.287671][ T6296] pcieport 0004:40:00.0: save config 0x14: 0x00000000
[  460.287677][ T6296] pcieport 0004:40:00.0: save config 0x18: 0x00414140
[  460.287683][ T6296] pcieport 0004:40:00.0: save config 0x1c: 0x00000000
[  460.287689][ T6296] pcieport 0004:40:00.0: save config 0x20: 0xf420f420
[  460.287696][ T6296] pcieport 0004:40:00.0: save config 0x24: 0x0001fff1
[  460.287702][ T6296] pcieport 0004:40:00.0: save config 0x28: 0x00000000
[  460.287708][ T6296] pcieport 0004:40:00.0: save config 0x2c: 0x00000000
[  460.287714][ T6296] pcieport 0004:40:00.0: save config 0x30: 0x00000000
[  460.287720][ T6296] pcieport 0004:40:00.0: save config 0x34: 0x00000040
[  460.287727][ T6296] pcieport 0004:40:00.0: save config 0x38: 0x00000000
[  460.287733][ T6296] pcieport 0004:40:00.0: save config 0x3c: 0x00020197
[  460.299895][ T6296] pcieport 0004:40:00.0: PCI PM: Suspend power state: D3hot
[  460.311927][ T6291] rockchip-dw-pcie a41000000.pcie: Timeout
waiting for L2 entry! LTSSM: 0x12
[  460.311935][ T6291] rockchip-dw-pcie a41000000.pcie: PM:
dpm_run_callback(): genpd_suspend_noirq returns -110
[  460.311950][ T6291] rockchip-dw-pcie a41000000.pcie: PM: failed to
suspend noirq: error -110
[  460.328691][   T57] pcieport 0004:40:00.0: restore config 0x2c:
0x00000000 -> 0x00000000
[  460.328706][   T57] pcieport 0004:40:00.0: restore config 0x28:
0x00000000 -> 0x00000000
[  460.328714][   T57] pcieport 0004:40:00.0: restore config 0x24:
0x0001fff1 -> 0x0001fff1
[  460.329363][ T6299] iwlwifi 0002:21:00.0: restore config 0x3c:
0x00000100 -> 0x00000183
[  460.329558][ T6299] iwlwifi 0002:21:00.0: restore config 0x10:
0x00000004 -> 0xf2200004
[  460.329643][ T6299] iwlwifi 0002:21:00.0: restore config 0x04:
0x00100000 -> 0x00100406
[  460.341978][ T6291] PM: noirq suspend of devices failed
[  460.352925][ T6303] xhci-hcd xhci-hcd.7.auto: xHC error in resume,
USBSTS 0x401, Reinit
[  460.352937][ T6303] usb usb5: root hub lost power or was reset
[  460.352941][ T6303] usb usb6: root hub lost power or was reset
[  460.517043][   T56] xhci-hcd xhci-hcd.8.auto: xHC error in resume,
USBSTS 0x401, Reinit
[  460.517056][   T56] usb usb7: root hub lost power or was reset
[  460.517060][   T56] usb usb8: root hub lost power or was reset
[  460.833660][ T6291] OOM killer enabled.
[  460.834002][ T6291] Restarting tasks: Starting
[  460.835432][ T6291] Restarting tasks: Done
[  460.835846][ T6291] random: crng reseeded on system resumption
[  460.837377][ T6291] PM: suspend exit
[  460.838167][ T6291] PM: suspend entry (s2idle)
[  460.976541][ T6291] Filesystems sync: 0.138 seconds
[  460.978668][ T6291] Freezing user space processes
[  460.980928][ T6291] Freezing user space processes completed
(elapsed 0.001 seconds)
[  460.981607][ T6291] OOM killer disabled.
[  460.981954][ T6291] Freezing remaining freezable tasks
[  460.997394][ T6291] Freezing remaining freezable tasks completed
(elapsed 0.014 seconds)
[  460.998116][ T6291] printk: Suspending console(s) (use
no_console_suspend to debug)
[  461.041501][ T6299] nvme 0000:01:00.0: save config 0x00: 0xa808144d
[  461.041520][ T6299] nvme 0000:01:00.0: save config 0x04: 0x00100406
[  461.041530][ T6299] nvme 0000:01:00.0: save config 0x08: 0x01080200
[  461.041540][ T6299] nvme 0000:01:00.0: save config 0x0c: 0x00000000
[  461.041549][ T6299] nvme 0000:01:00.0: save config 0x10: 0xf0200004
[  461.041559][ T6299] nvme 0000:01:00.0: save config 0x14: 0x00000000
[  461.041568][ T6299] nvme 0000:01:00.0: save config 0x18: 0x00000000
[  461.041577][ T6299] nvme 0000:01:00.0: save config 0x1c: 0x00000000
[  461.041586][ T6299] nvme 0000:01:00.0: save config 0x20: 0x00000000
[  461.041595][ T6299] nvme 0000:01:00.0: save config 0x24: 0x00000000
[  461.041604][ T6299] nvme 0000:01:00.0: save config 0x28: 0x00000000
[  461.041613][ T6299] nvme 0000:01:00.0: save config 0x2c: 0xa801144d
[  461.041622][ T6299] nvme 0000:01:00.0: save config 0x30: 0x00000000
[  461.041632][ T6299] nvme 0000:01:00.0: save config 0x34: 0x00000040
[  461.041641][ T6299] nvme 0000:01:00.0: save config 0x38: 0x00000000
[  461.041650][ T6299] nvme 0000:01:00.0: save config 0x3c: 0x0000016d
[  461.211199][ T6307] r8169 0004:41:00.0: save config 0x00: 0x812510ec
[  461.211220][ T6307] r8169 0004:41:00.0: save config 0x04: 0x00100403
[  461.211233][ T6307] r8169 0004:41:00.0: save config 0x08: 0x02000005
[  461.211246][ T6307] r8169 0004:41:00.0: save config 0x0c: 0x00000010
[  461.211257][ T6307] r8169 0004:41:00.0: save config 0x10: 0xf4100001
[  461.211269][ T6307] r8169 0004:41:00.0: save config 0x14: 0x00000000
[  461.211294][ T6297] iwlwifi 0002:21:00.0: save config 0x00: 0x24fd8086
[  461.211298][ T6307] r8169 0004:41:00.0: save config 0x18: 0xf4200004
[  461.211311][ T6307] r8169 0004:41:00.0: save config 0x1c: 0x00000000
[  461.211327][ T6297] iwlwifi 0002:21:00.0: save config 0x04: 0x00100406
[  461.211333][ T6307] r8169 0004:41:00.0: save config 0x20: 0xf4210004
[  461.211350][ T6297] iwlwifi 0002:21:00.0: save config 0x08: 0x02800078
[  461.211355][ T6307] r8169 0004:41:00.0: save config 0x24: 0x00000000
[  461.211372][ T6297] iwlwifi 0002:21:00.0: save config 0x0c: 0x00000000
[  461.211379][ T6307] r8169 0004:41:00.0: save config 0x28: 0x00000000
[  461.211395][ T6297] iwlwifi 0002:21:00.0: save config 0x10: 0xf2200004
[  461.211401][ T6307] r8169 0004:41:00.0: save config 0x2c: 0x012310ec
[  461.211417][ T6297] iwlwifi 0002:21:00.0: save config 0x14: 0x00000000
[  461.211421][ T6307] r8169 0004:41:00.0: save config 0x30: 0x00000000
[  461.211439][ T6297] iwlwifi 0002:21:00.0: save config 0x18: 0x00000000
[  461.211445][ T6307] r8169 0004:41:00.0: save config 0x34: 0x00000040
[  461.211461][ T6297] iwlwifi 0002:21:00.0: save config 0x1c: 0x00000000
[  461.211468][ T6307] r8169 0004:41:00.0: save config 0x38: 0x00000000
[  461.211483][ T6297] iwlwifi 0002:21:00.0: save config 0x20: 0x00000000
[  461.211487][ T6307] r8169 0004:41:00.0: save config 0x3c: 0x00000197
[  461.211505][ T6297] iwlwifi 0002:21:00.0: save config 0x24: 0x00000000
[  461.211527][ T6297] iwlwifi 0002:21:00.0: save config 0x28: 0x00000000
[  461.211550][ T6297] iwlwifi 0002:21:00.0: save config 0x2c: 0x10108086
[  461.211574][ T6297] iwlwifi 0002:21:00.0: save config 0x30: 0x00000000
[  461.211596][ T6297] iwlwifi 0002:21:00.0: save config 0x34: 0x000000c8
[  461.211618][ T6297] iwlwifi 0002:21:00.0: save config 0x38: 0x00000000
[  461.211644][ T6297] iwlwifi 0002:21:00.0: save config 0x3c: 0x00000183
[  461.224517][ T6297] iwlwifi 0002:21:00.0: PCI PM: Suspend power state: D3hot
[  461.224566][ T6307] r8169 0004:41:00.0: PCI PM: Suspend power state: D3hot
[  461.224614][ T6299] pcieport 0004:40:00.0: save config 0x00: 0x35881d87
[  461.224622][ T6299] pcieport 0004:40:00.0: save config 0x04: 0x00100507
[  461.224629][ T6299] pcieport 0004:40:00.0: save config 0x08: 0x06040001
[  461.224636][ T6299] pcieport 0004:40:00.0: save config 0x0c: 0x00010000
[  461.224642][ T6299] pcieport 0004:40:00.0: save config 0x10: 0x00000000
[  461.224649][ T6299] pcieport 0004:40:00.0: save config 0x14: 0x00000000
[  461.224655][ T6299] pcieport 0004:40:00.0: save config 0x18: 0x00414140
[  461.224661][ T6299] pcieport 0004:40:00.0: save config 0x1c: 0x00000000
[  461.224667][ T6299] pcieport 0004:40:00.0: save config 0x20: 0xf420f420
[  461.224673][ T6299] pcieport 0004:40:00.0: save config 0x24: 0x0001fff1
[  461.224680][ T6299] pcieport 0004:40:00.0: save config 0x28: 0x00000000
[  461.224686][ T6299] pcieport 0004:40:00.0: save config 0x2c: 0x00000000
[  461.224692][ T6299] pcieport 0004:40:00.0: save config 0x30: 0x00000000
[  461.224698][ T6299] pcieport 0004:40:00.0: save config 0x34: 0x00000040
[  461.224705][ T6299] pcieport 0004:40:00.0: save config 0x38: 0x00000000
[  461.224711][ T6299] pcieport 0004:40:00.0: save config 0x3c: 0x00020197
[  461.236873][ T6299] pcieport 0004:40:00.0: PCI PM: Suspend power state: D3hot
[  461.247945][ T6291] rockchip-dw-pcie a41000000.pcie: Failed to
receive PME_TO_Ack
[  461.258929][ T6291] rockchip-dw-pcie a41000000.pcie: Timeout
waiting for L2 entry! LTSSM: 0x12
[  461.258937][ T6291] rockchip-dw-pcie a41000000.pcie: PM:
dpm_run_callback(): genpd_suspend_noirq returns -110
[  461.258952][ T6291] rockchip-dw-pcie a41000000.pcie: PM: failed to
suspend noirq: error -110
[  461.276608][ T6303] iwlwifi 0002:21:00.0: restore config 0x3c:
0x00000100 -> 0x00000183
[  461.276655][ T6302] pcieport 0004:40:00.0: restore config 0x2c:
0x00000000 -> 0x00000000
[  461.276683][ T6302] pcieport 0004:40:00.0: restore config 0x28:
0x00000000 -> 0x00000000
[  461.276714][ T6302] pcieport 0004:40:00.0: restore config 0x24:
0x0001fff1 -> 0x0001fff1
[  461.276805][ T6303] iwlwifi 0002:21:00.0: restore config 0x10:
0x00000004 -> 0xf2200004
[  461.276908][ T6303] iwlwifi 0002:21:00.0: restore config 0x04:
0x00100000 -> 0x00100406
[  461.289977][ T6291] PM: noirq suspend of devices failed
[  461.302571][ T6298] xhci-hcd xhci-hcd.7.auto: xHC error in resume,
USBSTS 0x401, Reinit
[  461.302581][ T6298] usb usb5: root hub lost power or was reset
[  461.302585][ T6298] usb usb6: root hub lost power or was reset
[  461.425101][ T6307] xhci-hcd xhci-hcd.8.auto: xHC error in resume,
USBSTS 0x401, Reinit
[  461.425111][ T6307] usb usb7: root hub lost power or was reset
[  461.425115][ T6307] usb usb8: root hub lost power or was reset
[  461.746324][ T6291] OOM killer enabled.
[  461.746666][ T6291] Restarting tasks: Starting
[  461.748345][ T6291] Restarting tasks: Done
[  461.748757][ T6291] random: crng reseeded on system resumption
[  461.749533][ T6291] PM: suspend exit
[  461.809104][ T6056] Realtek Internal NBASE-T PHY r8169-4-4100:00:
attached PHY driver (mii_bus:phy_addr=r8169-4-4100:00, irq=MAC)
[  461.810148][ T6056] r8169 0004:41:00.0: enabling bus mastering
[  461.989335][ T6298] r8169 0004:41:00.0 enP4p65s0: Link is Down
[  464.915207][ T6311] r8169 0004:41:00.0 enP4p65s0: Link is Up -
1Gbps/Full - flow control rx/tx
[  465.527599][ T6149] wlan0: authenticate with 78:d2:94:85:bb:b2
(local address=a4:6b:b6:06:5c:8e)
[  465.529749][ T6149] wlan0: send auth to 78:d2:94:85:bb:b2 (try 1/3)
[  465.543850][ T6298] wlan0: authenticated
[  465.545190][ T6298] wlan0: associate with 78:d2:94:85:bb:b2 (try 1/3)
[  465.555534][ T6298] wlan0: RX AssocResp from 78:d2:94:85:bb:b2
(capab=0x31 status=0 aid=1)
[  465.560431][ T6298] wlan0: associated

Thanks
-Anand

> Changes since PATCHv3:
>  * https://lore.kernel.org/linux-pci/1744940759-23823-1-git-send-email-shawn.lin at rock-chips.com/
>  * rename rockchip_pcie_get_ltssm to rockchip_pcie_get_ltssm_status_reg
>    in a separate patch (Niklas Cassel)
>  * rename rockchip_pcie_get_pure_ltssm to rockchip_pcie_get_ltssm_state
>    in a separate patch (Niklas Cassel)
>  * Move devm_phy_get out of phy_init to probe in a separate patch
>    (Manivannan Sadhasivam)
>  * Add helper function for enhanced LTSSM control mode in a separate patch
>    (Niklas Cassel)
>  * Add helper function for controller mode in a separate patch
>    (Niklas Cassel)
>  * Add helper function for DDL indicator in a separate patch
>    (Niklas Cassel)
>  * Move rockchip_pcie_pme_turn_off implementation in a separate patch
>  * Rebase to v6.18-rc3 using new FIELD_PREP_WM16()
>  * Improve readability of PME_TURN_OFF/PME_TO_ACK defines (Manivannan Sadhasivam)
>  * Fix usage of reverse Xmas (Manivannan Sadhasivam)
>  * Assert PERST# before turning off other resources (Manivannan Sadhasivam)
>  * Improve some error messages (Manivannan Sadhasivam)
>  * Rename goto labels as per their purpose (Manivannan Sadhasivam)
>  * Add extra patch for dw_pcie_resume_noirq, since I've seen errors
>    during resume on boards not having anything plugged into their PCIe
>    port
>
> Signed-off-by: Sebastian Reichel <sebastian.reichel at collabora.com>
> ---
> Sebastian Reichel (9):
>       PCI: dw-rockchip: Rename rockchip_pcie_get_ltssm function
>       PCI: dw-rockchip: Support get_ltssm operation
>       PCI: dw-rockchip: Move devm_phy_get out of phy_init
>       PCI: dw-rockchip: Add helper function for enhanced LTSSM control mode
>       PCI: dw-rockchip: Add helper function for controller mode
>       PCI: dw-rockchip: Add helper function for DDL indicator
>       PCI: dw-rockchip: Add pme_turn_off support
>       PCI: dw-rockchip: Add system PM support
>       PCI: dwc: support missing PCIe device on resume
>
>  drivers/pci/controller/dwc/pcie-designware-host.c |  13 +-
>  drivers/pci/controller/dwc/pcie-dw-rockchip.c     | 220 ++++++++++++++++++----
>  2 files changed, 198 insertions(+), 35 deletions(-)
> ---
> base-commit: dcb6fa37fd7bc9c3d2b066329b0d27dedf8becaa
> change-id: 20251028-rockchip-pcie-system-suspend-86cf08a7b229
>
> Best regards,
> --
> Sebastian Reichel <sebastian.reichel at collabora.com>
>
>


From heiko at sntech.de  Sat Nov  1 04:44:54 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Sat, 01 Nov 2025 12:44:54 +0100
Subject: [PATCH] arm64: dts: rockchip: pwm-fan overlay for NanoPC-T6
In-Reply-To: <2cfeeb0c-f7e0-b101-62c4-3b6eae40a30b@manjaro.org>
References: <d583ee43-38c4-40fb-b33b-ce3153c9723b@gmail.com>
 <CABjd4Yzfx-4xBHVB=W_r6nEdbwNJKdpHYB6bN3Xsk8dZOegJWw@mail.gmail.com>
 <2cfeeb0c-f7e0-b101-62c4-3b6eae40a30b@manjaro.org>
Message-ID: <2246326.irdbgypaU6@phil>

Am Montag, 27. Oktober 2025, 22:15:05 Mitteleurop?ische Normalzeit schrieb Dragan Simic:
> Hello Alexey,
> 
> On Monday, October 27, 2025 21:56 CET, Alexey Charkov <alchark at gmail.com> wrote:
> > On Tue, Oct 28, 2025 at 12:02?AM Dragan Simic <dsimic at manjaro.org> wrote:
> > > On Mon, Oct 27, 2025 at 7:08?PM Hugh Cole-Baker <sigmaris at gmail.com> wrote:
> > > > On 27/10/2025 09:14, Alexey Charkov wrote:
> > > >
> > > >> Is there any downside to enabling this unconditionally in the board
> > > >> .dts?
> > > >
> > > > Only that it goes against the principle that the DT should describe the
> > > > hardware; the board .dts would describe a cooling device that doesn't
> > > > actually exist on the base board.
> > >
> > > Having a separate DT overlay is perfectly fine if we want to
> > > describe a board absolutely correctly: if the fan actually isn't
> > > present, the operating system shouldn't be made to think it is
> > > there, especially if there's no fan RPM feedback, which is the
> > > case on almost all Rockchip boards that support a fan.
> > >
> > > Preventing the kernel from managing a non-existent fan might even
> > > save some CPU cycles, ending up producing a bit less heat, which
> > > can only help in passively cooled setups.
> > 
> > Sounds like an overcomplication without real benefit. It's one thing
> > with overlays for functionality that can be software-incompatible
> > depending on whether an external attachment is connected or depending
> > on the type of attachment connected. Here we are looking at a plain
> > 2-pin fan which cannot be software incompatible to anything really
> > (it's not like one could repurpose the fan connector for anything
> > meaningful if a fan is not in use, and noone gets hurt if a PWM output
> > is left running without load).
> > 
> > The CPU cycles spent parsing a slightly larger DTB at boot are likely
> > comparable to those spent activating a PWM output needlessly upon
> > hitting the active cooling trip point, and both are negligible for any
> > practical purpose.
> 
> Hmm, right, I forgot for a moment that the PWM output is generated
> by dedicated hardware, so not many CPU cycles would be wasted.
> 
> BTW, with a fan PWM signal generated by a soft-GPIO output, much
> more CPU cycles would've been saved by omitting the fan definition
> if it isn't present, but that isn't the case here.
> 
> > > However, the practice so far has been to describe the fans in the
> > > main board dts files, if the board provides fan support, regardless
> > > of the fan being present in a particular board setup or not.
> > >
> > > > I guess then in theory, an OS might allow the SoC to reach undesirably high
> > > > temperatures if it's relying on the nonexistent fan to cool it down. But I
> > > > don't think this would be an issue on Linux, at least, in practice.
> > >
> > > We're safe, a thermal runaway isn't going to happen when the fan is
> > > defined in a board DT but actually isn't present.  Thermal CPU and
> > > GPU throttling will prevent the overheating from happening.
> > >
> > > >> Overlays require more user configuration, and not all
> > > >> bootloaders support them directly (e.g. systemd-boot users would
> > > >> struggle). Compiling with overlays enabled also makes .dtb's a lot
> > > >> larger due to added symbols information.
> > > >
> > > > Nowadays (on Debian at least) using overlays is pretty easy, I'm using the
> > > > u-boot-menu package in Debian, I just copy the overlay(s) to /boot/dtbo/ and
> > > > it detects them automatically and adds them to extlinux.conf for u-boot to
> > > > apply.
> > > >
> > > > Couldn't systemd-boot users just use rk3588-nanopc-t6-(lts-)with-fan.dtb as
> > > > their single DT to load, if it doesn't support applying overlays and they
> > > > want to use the fan addon?
> > 
> > Sure, but it's a manual configuration step, where otherwise the kernel
> > would just default to the correct dtb for the board that the firmware
> > told it about. The fan is not discoverable, so the firmware won't ever
> > offer the "-with-fan" variant, meaning users would need to supply it
> > manually in every instance.
> 
> FWIW, the most user-friendly SBC family in the world, Raspberry
> Pi, :) requires manual enabling of the fan on Raspberry Pi 4.
> I haven't researched what's the background for that, perhaps the
> need to keep the GPIO expansion header completely unoccupied by
> default, because the fan attaches to the GPIO header, instead of
> to some dedicated fan connector.
> 
> > > Yes, that's an option.  However, that in general doesn't resolve
> > > the issues arising from systemd-boot users wanting to apply more
> > > than a single DT overlay.
> > >
> > > > FWIW, I haven't noticed any problems with having a larger .dtb (using mainline
> > > > U-Boot to load it) and several other RK3588 boards are also compiled with
> > > > symbols enabled already, and I haven't seen any issues reported with them.
> > >
> > > After thinking a bit about it, I'd support the extraction of fan
> > > definitions into separate DT overlays.  As I wrote above already,
> > > not managing the non-existent fan might actually help a bit with
> > > passively cooled board setups, which is a good enough reason for
> > > me to support separate DT overlays.
> > 
> > Practical benefits sound far fetched here, while forcing users to
> > manually configure something that would have otherwise just worked.
> > Let's see what Heiko thinks.

Personally, I'm more on the less complication side.

I.e. if there is an actual fan-connector on the board we should describe
it as such.

Overlays I see for things where you attach hats to generic pin headers
to create specific functionality on top of a generic interface.

But if the board itself has an actual fan header, it should be described
as such. Because that then _is_ the standard use of that.


Heiko




From heiko at sntech.de  Sat Nov  1 04:51:35 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Sat, 01 Nov 2025 12:51:35 +0100
Subject: [PATCH v2 1/2] arm64: dts: rockchip: Fix USB Type-C host mode for Radxa
 ROCK 5B+/5T
In-Reply-To: <20251029130200.987580-1-naoki@radxa.com>
References: <20251029130200.987580-1-naoki@radxa.com>
Message-ID: <3389401.44csPzL39Z@phil>

Hi,

Am Mittwoch, 29. Oktober 2025, 14:01:59 Mitteleurop?ische Normalzeit schrieb FUKAUMI Naoki:
> The Radxa ROCK 5B+/5T USB Type-C port supports Dual Role Data and
> should also act as a host. However, currently, when acting as a host,
> only self-powered devices work.
> 
> Since the ROCK 5B+ supports Dual Role Power, set the power-role
> property to "dual" and the try-power-role property to "sink". (along
> with related properties)
> 
> The ROCK 5T should only support the "source" power role, but when the
> power-role property is set to "source", when acting as a host, only
> self-powered devices work. As a workaround, set the power-role
> property to "dual" and the try-power-role property to "sink".
>
> This allows the port to act as a host, supply power to the port, and
> allow bus-powered devices to work.

So it sounds like you're working around an issue coming from the Linux
usb stack here? If the usb stack handles those power roles wrongly
shouldn't it be fixed instead of introducing wrong hacks to generic
hardware descriptions?

Like Linux isn't the only consumer of Devicetrees, so hacking them
together to walk around driver issues feels wrong.


Heiko

> Note that there is a separate known issue where USB 3.0 SuperSpeed
> devices do not work when oriented in reverse. This issue should be
> addressed separately. (USB 2.0/1.1 devices work in both orientations)
> 
> Fixes: 67b2c15d8fb3c ("arm64: dts: rockchip: add USB-C support for ROCK 5B/5B+/5T")
> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> ---
> Changes in v2:
> - Refine commit message
> - Use board-specific dts to describe (try-)power-role
> ---
>  arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi | 4 ++--
>  arch/arm64/boot/dts/rockchip/rk3588-rock-5b-plus.dts    | 5 +++++
>  arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts         | 4 ++++
>  arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts         | 5 +++++
>  4 files changed, 16 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi
> index 3bbe78810ec6f..7aac77dfc5f16 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi
> @@ -331,12 +331,12 @@ usb_con: connector {
>  			data-role = "dual";
>  			/* fusb302 supports PD Rev 2.0 Ver 1.2 */
>  			pd-revision = /bits/ 8 <0x2 0x0 0x1 0x2>;
> -			power-role = "sink";
> -			try-power-role = "sink";
>  			op-sink-microwatt = <1000000>;
>  			sink-pdos =
>  				<PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>,
>  				<PDO_VAR(5000, 20000, 5000)>;
> +			source-pdos =
> +				<PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
>  
>  			altmodes {
>  				displayport {
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-plus.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-plus.dts
> index 5e984a44120e4..07a840d9b3859 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-plus.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-plus.dts
> @@ -110,6 +110,11 @@ vcc5v0_host_en: vcc5v0-host-en {
>  	};
>  };
>  
> +&usb_con {
> +	power-role = "dual";
> +	try-power-role = "sink";
> +};
> +
>  &usbdp_phy0 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&usbc_sbu_dc>;
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
> index 8ef01010d985b..da13dafcbc823 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
> @@ -49,6 +49,10 @@ vcc5v0_host_en: vcc5v0-host-en {
>  	};
>  };
>  
> +&usb_con {
> +	power-role = "sink";
> +};
> +
>  &usbdp_phy0 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&usbc_sbu_dc>;
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts
> index c1763835f53d4..96ffffec7e05d 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts
> @@ -130,6 +130,11 @@ usbc_sbu_dc: usbc-sbu-dc {
>  	};
>  };
>  
> +&usb_con {
> +	power-role = "dual";
> +	try-power-role = "sink";
> +};
> +
>  &usbdp_phy0 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&usbc_sbu_dc>;
> 






From heiko at sntech.de  Sat Nov  1 04:54:06 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Sat, 01 Nov 2025 12:54:06 +0100
Subject: [PATCH] arm64: dts: rockchip: fix eMMC corruption on NanoPC-T6 with
 A3A444 chips
In-Reply-To: <5af928c4-4b6e-489c-ad39-26cef3dd7473@gmail.com>
References: <20251017073954.130710-1-cnsztl@gmail.com>
 <08911ae2-fef3-432d-a236-d820c9cb67ac@gmail.com>
 <5af928c4-4b6e-489c-ad39-26cef3dd7473@gmail.com>
Message-ID: <10751338.nUPlyArG6x@phil>

Am Montag, 27. Oktober 2025, 18:34:25 Mitteleurop?ische Normalzeit schrieb Tianling Shen:
> + Jianfeng
> 
> On 2025/10/20 12:44, Tianling Shen wrote:
> > Hi Shawn,
> > 
> > On 2025/10/20 9:53, Shawn Lin wrote:
> >> Hi Tianling
> >>
> >> On 2025/10/17 Friday 15:39, Tianling Shen wrote:
> >>> From: Grzegorz Sterniczuk <grzegorz at sternicz.uk>
> >>>
> >>> Some NanoPC-T6 boards with A3A444 eMMC chips experience I/O errors and
> >>> corruption when using HS400 mode. Downgrade to HS200 mode to ensure
> >>> stable operation.
> >>
> >> May I ask you to test another patch I just posted to see if it fixes
> >> your issue?
> >>
> >> https://patchwork.kernel.org/project/linux-mmc/ 
> >> patch/1760924981-52339-1- git-send-email-shawn.lin at rock-chips.com/
> > 
> > Thank you for the patch! I will ask my friend to test it but he uses 
> > this board as a home router, so it may take a few days or weeks to 
> > report the result.
> 
> Hi all, sorry for the late. My friend has tested this patch and it works 
> fine after 50 times dd operation. A big thanks to Shawn!

So I guess, we don't need the patch reducing the speed anymore, right?


Thanks
Heiko


> And hi Jianfeng, I found you made a similiar patch[1] for the ROCK 5 ITX 
> board to lower down the mmc speed, could you please check if this patch 
> also fixes your issue?
> 
> Thanks,
> Tianling.
> 
> 1. 
> https://lore.kernel.org/linux-rockchip/20250228143341.70244-1-liujianfeng1994 at gmail.com/
> 
> > 
> > Thanks,
> > Tianling.
> > 
> >>
> >>
> >>>
> >>> Signed-off-by: Grzegorz Sterniczuk <grzegorz at sternicz.uk>
> >>> Signed-off-by: Tianling Shen <cnsztl at gmail.com>
> >>> ---
> >>>   arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi | 3 +--
> >>>   1 file changed, 1 insertion(+), 2 deletions(-)
> >>>
> >>> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi b/ 
> >>> arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
> >>> index fafeabe9adf9..5f63f38f7326 100644
> >>> --- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
> >>> +++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
> >>> @@ -717,8 +717,7 @@ &sdhci {
> >>>       no-sd;
> >>>       non-removable;
> >>>       max-frequency = <200000000>;
> >>> -    mmc-hs400-1_8v;
> >>> -    mmc-hs400-enhanced-strobe;
> >>> +    mmc-hs200-1_8v;
> >>>       status = "okay";
> >>>   };
> >>
> > 
> 
> 






From amadeus at jmu.edu.cn  Sat Nov  1 05:00:08 2025
From: amadeus at jmu.edu.cn (Chukun Pan)
Date: Sat,  1 Nov 2025 20:00:08 +0800
Subject: [PATCH 4/6] arm64: dts: rockchip: fixes supply for 100ASK DshanPi A1
In-Reply-To: <20251101120010.41729-1-amadeus@jmu.edu.cn>
References: <20251101120010.41729-1-amadeus@jmu.edu.cn>
Message-ID: <20251101120010.41729-4-amadeus@jmu.edu.cn>

>From the schematic, the supply of ES8388 chip and the vmmc-supply
of SD card both originate from the VCC3V3_S0 regulator, fix it.

Fixes: d809417c5a40 ("arm64: dts: rockchip: add DTs for 100ASK DShanPi A1")
Signed-off-by: Chukun Pan <amadeus at jmu.edu.cn>
---
 arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts b/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
index 425a78db9522..7c961cb27032 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
@@ -606,9 +606,9 @@ es8388: audio-codec at 10 {
 		compatible = "everest,es8388", "everest,es8328";
 		reg = <0x10>;
 		clocks = <&cru CLK_SAI1_MCLKOUT_TO_IO>;
-		AVDD-supply = <&vcca_3v3_s0>;
+		AVDD-supply = <&vcc_3v3_s0>;
 		DVDD-supply = <&vcc_3v3_s0>;
-		HPVDD-supply = <&vcca_3v3_s0>;
+		HPVDD-supply = <&vcc_3v3_s0>;
 		PVDD-supply = <&vcc_3v3_s0>;
 		assigned-clocks = <&cru CLK_SAI1_MCLKOUT_TO_IO>;
 		assigned-clock-rates = <12288000>;
@@ -710,7 +710,7 @@ &sdmmc {
 	cap-sd-highspeed;
 	disable-wp;
 	sd-uhs-sdr104;
-	vmmc-supply = <&vcc_3v3_s3>;
+	vmmc-supply = <&vcc_3v3_s0>;
 	vqmmc-supply = <&vccio_sd_s0>;
 	status = "okay";
 };
-- 
2.25.1



From amadeus at jmu.edu.cn  Sat Nov  1 05:00:05 2025
From: amadeus at jmu.edu.cn (Chukun Pan)
Date: Sat,  1 Nov 2025 20:00:05 +0800
Subject: [PATCH 1/6] arm64: dts: rockchip: add mmc aliases for 100ASK DshanPi A1
Message-ID: <20251101120010.41729-1-amadeus@jmu.edu.cn>

Add missing MMC aliases. Remove the max-frequency property
from the MMC node, which is already defined in rk3576.dtsi.

Signed-off-by: Chukun Pan <amadeus at jmu.edu.cn>
---
 arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts b/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
index 59c172573cf8..9cbd3fae16ab 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
@@ -19,6 +19,8 @@ / {
 	aliases {
 		ethernet0 = &gmac0;
 		ethernet1 = &gmac1;
+		mmc0 = &sdhci;
+		mmc1 = &sdmmc;
 	};
 
 	chosen {
@@ -735,7 +737,6 @@ &sai6 {
 &sdhci {
 	bus-width = <8>;
 	full-pwr-cycle-in-suspend;
-	max-frequency = <200000000>;
 	mmc-hs400-1_8v;
 	mmc-hs400-enhanced-strobe;
 	no-sdio;
@@ -749,7 +750,6 @@ &sdmmc {
 	cap-mmc-highspeed;
 	cap-sd-highspeed;
 	disable-wp;
-	max-frequency = <200000000>;
 	sd-uhs-sdr104;
 	vmmc-supply = <&vcc_3v3_s3>;
 	vqmmc-supply = <&vccio_sd_s0>;
-- 
2.25.1



From amadeus at jmu.edu.cn  Sat Nov  1 05:00:07 2025
From: amadeus at jmu.edu.cn (Chukun Pan)
Date: Sat,  1 Nov 2025 20:00:07 +0800
Subject: [PATCH 3/6] arm64: dts: rockchip: fixes ethernet for 100ASK DshanPi A1
In-Reply-To: <20251101120010.41729-1-amadeus@jmu.edu.cn>
References: <20251101120010.41729-1-amadeus@jmu.edu.cn>
Message-ID: <20251101120010.41729-3-amadeus@jmu.edu.cn>

Currently, Ethernet is unusable due to an incorrect PHY address.
This commit fixes this, removes the incorrect 25M clock pinctrl,
and adds the missing PHY supply.

Fixes: d809417c5a40 ("arm64: dts: rockchip: add DTs for 100ASK DShanPi A1")
Signed-off-by: Chukun Pan <amadeus at jmu.edu.cn>
---
 .../dts/rockchip/rk3576-100ask-dshanpi-a1.dts     | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts b/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
index f8bc401e796f..425a78db9522 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
@@ -192,6 +192,7 @@ &gmac0 {
 	clock_in_out = "output";
 	phy-mode = "rgmii-id";
 	phy-handle = <&rgmii_phy0>;
+	phy-supply = <&vcc_3v3_s0>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&eth0m0_miim
 		     &eth0m0_tx_bus2
@@ -205,13 +206,13 @@ &gmac1 {
 	clock_in_out = "output";
 	phy-mode = "rgmii-id";
 	phy-handle = <&rgmii_phy1>;
+	phy-supply = <&vcc_3v3_s0>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&eth1m0_miim
 		     &eth1m0_tx_bus2
 		     &eth1m0_rx_bus2
 		     &eth1m0_rgmii_clk
-		     &eth1m0_rgmii_bus
-		     &ethm0_clk1_25m_out>;
+		     &eth1m0_rgmii_bus>;
 	status = "okay";
 };
 
@@ -618,10 +619,9 @@ es8388: audio-codec at 10 {
 };
 
 &mdio0 {
-	rgmii_phy0: phy at 1 {
+	rgmii_phy0: phy at 0 {
 		compatible = "ethernet-phy-ieee802.3-c22";
-		reg = <0x1>;
-		clocks = <&cru REFCLKO25M_GMAC0_OUT>;
+		reg = <0>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&gmac0_rst>;
 		reset-assert-us = <20000>;
@@ -631,10 +631,9 @@ rgmii_phy0: phy at 1 {
 };
 
 &mdio1 {
-	rgmii_phy1: phy at 1 {
+	rgmii_phy1: phy at 0 {
 		compatible = "ethernet-phy-ieee802.3-c22";
-		reg = <0x1>;
-		clocks = <&cru REFCLKO25M_GMAC1_OUT>;
+		reg = <0>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&gmac1_rst>;
 		reset-assert-us = <20000>;
-- 
2.25.1



From amadeus at jmu.edu.cn  Sat Nov  1 05:00:06 2025
From: amadeus at jmu.edu.cn (Chukun Pan)
Date: Sat,  1 Nov 2025 20:00:06 +0800
Subject: [PATCH 2/6] arm64: dts: rockchip: fixes regulator for 100ASK DshanPi A1
In-Reply-To: <20251101120010.41729-1-amadeus@jmu.edu.cn>
References: <20251101120010.41729-1-amadeus@jmu.edu.cn>
Message-ID: <20251101120010.41729-2-amadeus@jmu.edu.cn>

Referencing the schematic [1], correct the names of the USB
regulator, remove these non-existent RTC and UFS regulators.

[1] https://dl.100ask.net/Hardware/MPU/RK3576-DshanPi-A1/DshanPi-A1-RK3576-SCH_V1.1.pdf

Fixes: d809417c5a40 ("arm64: dts: rockchip: add DTs for 100ASK DShanPi A1")
Signed-off-by: Chukun Pan <amadeus at jmu.edu.cn>
---
 .../dts/rockchip/rk3576-100ask-dshanpi-a1.dts | 46 ++-----------------
 1 file changed, 3 insertions(+), 43 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts b/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
index 9cbd3fae16ab..f8bc401e796f 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
@@ -85,16 +85,6 @@ vcc_1v1_nldo_s3: regulator-vcc-1v1-nldo-s3 {
 		vin-supply = <&vcc_5v0_sys>;
 	};
 
-	vcc_1v2_ufs_vccq_s0: regulator-vcc-1v2-ufs-vccq-s0 {
-		compatible = "regulator-fixed";
-		regulator-name = "vcc_1v2_ufs_vccq_s0";
-		regulator-always-on;
-		regulator-boot-on;
-		regulator-min-microvolt = <1200000>;
-		regulator-max-microvolt = <1200000>;
-		vin-supply = <&vcc_5v0_sys>;
-	};
-
 	vcc_1v8_s0: regulator-vcc-1v8-s0 {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc_1v8_s0";
@@ -105,16 +95,6 @@ vcc_1v8_s0: regulator-vcc-1v8-s0 {
 		vin-supply = <&vcc_1v8_s3>;
 	};
 
-	vcc_1v8_ufs_vccq2_s0: regulator-vcc-1v8-ufs-vccq2-s0 {
-		compatible = "regulator-fixed";
-		regulator-name = "vcc_1v8_ufs_vccq2_s0";
-		regulator-always-on;
-		regulator-boot-on;
-		regulator-min-microvolt = <1800000>;
-		regulator-max-microvolt = <1800000>;
-		vin-supply = <&vcc_1v8_s3>;
-	};
-
 	vcc_2v0_pldo_s3: regulator-vcc-2v0-pldo-s3 {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc_2v0_pldo_s3";
@@ -135,16 +115,6 @@ vcc_3v3_m2: regulator-vcc-3v3-m2 {
 		vin-supply = <&vcc_5v0_sys>;
 	};
 
-	vcc_3v3_rtc_s5: regulator-vcc-3v3-rtc-s5 {
-		compatible = "regulator-fixed";
-		regulator-name = "vcc_3v3_rtc_s5";
-		regulator-always-on;
-		regulator-boot-on;
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		vin-supply = <&vcc_5v0_sys>;
-	};
-
 	vcc_3v3_s0: regulator-vcc-3v3-s0 {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc_3v3_s0";
@@ -165,27 +135,17 @@ vcc_5v0_sys: regulator-vcc-5v0-sys {
 		vin-supply = <&vcc_in>;
 	};
 
-	vcc_5v0_typec0: regulator-vcc-5v0-typec0 {
+	vbus5v0_typec: regulator-vbus5v0-typec {
 		compatible = "regulator-fixed";
 		enable-active-high;
 		gpios = <&gpio1 RK_PC1 GPIO_ACTIVE_HIGH>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&typec5v_pwren_h>;
-		regulator-name = "vcc_5v0_typec0";
+		regulator-name = "vbus5v0_typec";
 		regulator-min-microvolt = <5000000>;
 		regulator-max-microvolt = <5000000>;
 		vin-supply = <&vcc_5v0_sys>;
 	};
-
-	vcc_3v3_ufs_s0: regulator-vcc-ufs-s0 {
-		compatible = "regulator-fixed";
-		regulator-name = "vcc_3v3_ufs_s0";
-		regulator-always-on;
-		regulator-boot-on;
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		vin-supply = <&vcc_5v0_sys>;
-	};
 };
 
 &combphy0_ps {
@@ -761,7 +721,7 @@ &u2phy0 {
 };
 
 &u2phy0_otg {
-	phy-supply = <&vcc_5v0_typec0>;
+	phy-supply = <&vbus5v0_typec>;
 	status = "okay";
 };
 
-- 
2.25.1



From amadeus at jmu.edu.cn  Sat Nov  1 05:00:09 2025
From: amadeus at jmu.edu.cn (Chukun Pan)
Date: Sat,  1 Nov 2025 20:00:09 +0800
Subject: [PATCH 5/6] arm64: dts: rockchip: fixes audio for 100ASK DshanPi A1
In-Reply-To: <20251101120010.41729-1-amadeus@jmu.edu.cn>
References: <20251101120010.41729-1-amadeus@jmu.edu.cn>
Message-ID: <20251101120010.41729-5-amadeus@jmu.edu.cn>

Correct the i2c address of the ES8388 chip and the gpio of hp_det pin.
According to the schematic, the ES8388 chip is connected to the SoC's
sai2 controller instead of sai1, fix it.

Fixes: d809417c5a40 ("arm64: dts: rockchip: add DTs for 100ASK DShanPi A1")
Signed-off-by: Chukun Pan <amadeus at jmu.edu.cn>
---
 .../dts/rockchip/rk3576-100ask-dshanpi-a1.dts | 23 ++++++++-----------
 1 file changed, 9 insertions(+), 14 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts b/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
index 7c961cb27032..815f75e7cd70 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
@@ -46,7 +46,7 @@ es8388_sound: es8388-sound {
 		simple-audio-card,pin-switches = "Headphone", "Line Out";
 
 		simple-audio-card,cpu {
-			sound-dai = <&sai1>;
+			sound-dai = <&sai2>;
 		};
 
 		simple-audio-card,codec {
@@ -602,18 +602,18 @@ regulator-state-mem {
 &i2c4 {
 	status = "okay";
 
-	es8388: audio-codec at 10 {
+	es8388: audio-codec at 11 {
 		compatible = "everest,es8388", "everest,es8328";
-		reg = <0x10>;
-		clocks = <&cru CLK_SAI1_MCLKOUT_TO_IO>;
+		reg = <0x11>;
+		clocks = <&cru CLK_SAI2_MCLKOUT_TO_IO>;
+		assigned-clocks = <&cru CLK_SAI2_MCLKOUT_TO_IO>;
+		assigned-clock-rates = <12288000>;
 		AVDD-supply = <&vcc_3v3_s0>;
 		DVDD-supply = <&vcc_3v3_s0>;
 		HPVDD-supply = <&vcc_3v3_s0>;
 		PVDD-supply = <&vcc_3v3_s0>;
-		assigned-clocks = <&cru CLK_SAI1_MCLKOUT_TO_IO>;
-		assigned-clock-rates = <12288000>;
 		pinctrl-names = "default";
-		pinctrl-0 = <&sai1m0_mclk>;
+		pinctrl-0 = <&sai2m0_mclk>;
 		#sound-dai-cells = <0>;
 	};
 };
@@ -663,7 +663,7 @@ gmac1_rst: gmac1-rst {
 
 	headphone {
 		hp_det: hp-det {
-			rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
 		};
 	};
 
@@ -680,12 +680,7 @@ typec5v_pwren_h: typec5v-pwren-h {
 	};
 };
 
-&sai1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&sai1m0_lrck
-		     &sai1m0_sclk
-		     &sai1m0_sdi0
-		     &sai1m0_sdo0>;
+&sai2 {
 	status = "okay";
 };
 
-- 
2.25.1



From amadeus at jmu.edu.cn  Sat Nov  1 05:00:10 2025
From: amadeus at jmu.edu.cn (Chukun Pan)
Date: Sat,  1 Nov 2025 20:00:10 +0800
Subject: [PATCH 6/6] arm64: dts: rockchip: update 100ASK DshanPi A1 support
In-Reply-To: <20251101120010.41729-1-amadeus@jmu.edu.cn>
References: <20251101120010.41729-1-amadeus@jmu.edu.cn>
Message-ID: <20251101120010.41729-6-amadeus@jmu.edu.cn>

Enable button, RTC and USB support for the 100ASK DshanPi A1 board.

Signed-off-by: Chukun Pan <amadeus at jmu.edu.cn>
---
 .../dts/rockchip/rk3576-100ask-dshanpi-a1.dts | 94 +++++++++++++++++++
 1 file changed, 94 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts b/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
index 815f75e7cd70..f325adf348ce 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
@@ -7,6 +7,7 @@
 /dts-v1/;
 
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
 #include <dt-bindings/leds/common.h>
 #include <dt-bindings/pinctrl/rockchip.h>
 #include <dt-bindings/soc/rockchip,vop2.h>
@@ -66,6 +67,61 @@ hdmi_con_in: endpoint {
 		};
 	};
 
+	keys-0 {
+		compatible = "adc-keys";
+		io-channels = <&saradc 0>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <1800000>;
+		poll-interval = <100>;
+
+		button-maskrom {
+			label = "MASKROM";
+			linux,code = <KEY_SETUP>;
+			press-threshold-microvolt = <0>;
+		};
+	};
+
+	keys-1 {
+		compatible = "adc-keys";
+		io-channels = <&saradc 1>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <1800000>;
+		poll-interval = <100>;
+
+		button-recovery {
+			label = "RECOVERY";
+			linux,code = <KEY_VENDOR>;
+			press-threshold-microvolt = <0>;
+		};
+	};
+
+	keys-2 {
+		compatible = "adc-keys";
+		io-channels = <&saradc 4>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <1800000>;
+		poll-interval = <100>;
+
+		button-user2 {
+			label = "USER2";
+			linux,code = <BTN_2>;
+			press-threshold-microvolt = <0>;
+		};
+	};
+
+	keys-3 {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&gpio0_a0_d>;
+
+		button-user1 {
+			gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_LOW>;
+			label = "USER1";
+			linux,code = <BTN_1>;
+			wakeup-source;
+		};
+	};
+
 	vcc_in: regulator-vcc-12v0-dcin {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc_in";
@@ -599,6 +655,15 @@ regulator-state-mem {
 	};
 };
 
+&i2c2 {
+	status = "okay";
+
+	rtc at 68 {
+		compatible = "dallas,ds1338";
+		reg = <0x68>;
+	};
+};
+
 &i2c4 {
 	status = "okay";
 
@@ -618,6 +683,11 @@ es8388: audio-codec at 11 {
 	};
 };
 
+&i2c9 {
+	pinctrl-0 = <&i2c9m1_xfer>;
+	status = "okay";
+};
+
 &mdio0 {
 	rgmii_phy0: phy at 0 {
 		compatible = "ethernet-phy-ieee802.3-c22";
@@ -661,6 +731,12 @@ gmac1_rst: gmac1-rst {
 		};
 	};
 
+	gpio-keys {
+		gpio0_a0_d: gpio0-a0-d {
+			rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
 	headphone {
 		hp_det: hp-det {
 			rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
@@ -688,6 +764,11 @@ &sai6 {
 	status = "okay";
 };
 
+&saradc {
+	vref-supply = <&vcca1v8_pldo2_s0>;
+	status = "okay";
+};
+
 &sdhci {
 	bus-width = <8>;
 	full-pwr-cycle-in-suspend;
@@ -733,6 +814,19 @@ &uart0 {
 	status = "okay";
 };
 
+&usbdp_phy {
+	status = "okay";
+};
+
+&usb_drd0_dwc3 {
+	status = "okay";
+};
+
+&usb_drd1_dwc3 {
+	dr_mode = "host";
+	status = "okay";
+};
+
 &vop {
 	status = "okay";
 };
-- 
2.25.1



From cnsztl at gmail.com  Sat Nov  1 05:14:31 2025
From: cnsztl at gmail.com (Tianling Shen)
Date: Sat, 1 Nov 2025 20:14:31 +0800
Subject: [PATCH] arm64: dts: rockchip: fix eMMC corruption on NanoPC-T6
 with A3A444 chips
In-Reply-To: <10751338.nUPlyArG6x@phil>
References: <20251017073954.130710-1-cnsztl@gmail.com>
 <08911ae2-fef3-432d-a236-d820c9cb67ac@gmail.com>
 <5af928c4-4b6e-489c-ad39-26cef3dd7473@gmail.com> <10751338.nUPlyArG6x@phil>
Message-ID: <3cba9996-228e-4086-99ba-4a2a00de57ab@gmail.com>

Hi Heiko,

On 2025/11/1 19:54, Heiko Stuebner wrote:
> Am Montag, 27. Oktober 2025, 18:34:25 Mitteleurop?ische Normalzeit schrieb Tianling Shen:
>> + Jianfeng
>>
>> On 2025/10/20 12:44, Tianling Shen wrote:
>>> Hi Shawn,
>>>
>>> On 2025/10/20 9:53, Shawn Lin wrote:
>>>> Hi Tianling
>>>>
>>>> On 2025/10/17 Friday 15:39, Tianling Shen wrote:
>>>>> From: Grzegorz Sterniczuk <grzegorz at sternicz.uk>
>>>>>
>>>>> Some NanoPC-T6 boards with A3A444 eMMC chips experience I/O errors and
>>>>> corruption when using HS400 mode. Downgrade to HS200 mode to ensure
>>>>> stable operation.
>>>>
>>>> May I ask you to test another patch I just posted to see if it fixes
>>>> your issue?
>>>>
>>>> https://patchwork.kernel.org/project/linux-mmc/
>>>> patch/1760924981-52339-1- git-send-email-shawn.lin at rock-chips.com/
>>>
>>> Thank you for the patch! I will ask my friend to test it but he uses
>>> this board as a home router, so it may take a few days or weeks to
>>> report the result.
>>
>> Hi all, sorry for the late. My friend has tested this patch and it works
>> fine after 50 times dd operation. A big thanks to Shawn!
> 
> So I guess, we don't need the patch reducing the speed anymore, right?

Yes! ;)

Thanks,
Tianling.

> 
> 
> Thanks
> Heiko
> 
> 
>> And hi Jianfeng, I found you made a similiar patch[1] for the ROCK 5 ITX
>> board to lower down the mmc speed, could you please check if this patch
>> also fixes your issue?
>>
>> Thanks,
>> Tianling.
>>
>> 1.
>> https://lore.kernel.org/linux-rockchip/20250228143341.70244-1-liujianfeng1994 at gmail.com/
>>
>>>
>>> Thanks,
>>> Tianling.
>>>
>>>>
>>>>
>>>>>
>>>>> Signed-off-by: Grzegorz Sterniczuk <grzegorz at sternicz.uk>
>>>>> Signed-off-by: Tianling Shen <cnsztl at gmail.com>
>>>>> ---
>>>>>    arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi | 3 +--
>>>>>    1 file changed, 1 insertion(+), 2 deletions(-)
>>>>>
>>>>> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi b/
>>>>> arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
>>>>> index fafeabe9adf9..5f63f38f7326 100644
>>>>> --- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
>>>>> +++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
>>>>> @@ -717,8 +717,7 @@ &sdhci {
>>>>>        no-sd;
>>>>>        non-removable;
>>>>>        max-frequency = <200000000>;
>>>>> -    mmc-hs400-1_8v;
>>>>> -    mmc-hs400-enhanced-strobe;
>>>>> +    mmc-hs200-1_8v;
>>>>>        status = "okay";
>>>>>    };
>>>>
>>>
>>
>>
> 
> 
> 
> 



From dsimic at manjaro.org  Sat Nov  1 05:50:59 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Sat, 01 Nov 2025 13:50:59 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= fix eMMC corruption on NanoPC-T6 with A3A444 chips
In-Reply-To: <10751338.nUPlyArG6x@phil>
References: <20251017073954.130710-1-cnsztl@gmail.com>
 <08911ae2-fef3-432d-a236-d820c9cb67ac@gmail.com>
 <5af928c4-4b6e-489c-ad39-26cef3dd7473@gmail.com> <10751338.nUPlyArG6x@phil>
Message-ID: <e52de2b5-bf10-ce0e-66b7-66b1c46525f3@manjaro.org>

Hello Heiko,

On Saturday, November 01, 2025 12:54 CET, Heiko Stuebner <heiko at sntech.de> wrote:
> Am Montag, 27. Oktober 2025, 18:34:25 Mitteleurop?ische Normalzeit schrieb Tianling Shen:
> > On 2025/10/20 12:44, Tianling Shen wrote:
> > > On 2025/10/20 9:53, Shawn Lin wrote:
> > >> On 2025/10/17 Friday 15:39, Tianling Shen wrote:
> > >>> From: Grzegorz Sterniczuk <grzegorz at sternicz.uk>
> > >>>
> > >>> Some NanoPC-T6 boards with A3A444 eMMC chips experience I/O errors and
> > >>> corruption when using HS400 mode. Downgrade to HS200 mode to ensure
> > >>> stable operation.
> > >>
> > >> May I ask you to test another patch I just posted to see if it fixes
> > >> your issue?
> > >>
> > >> https://patchwork.kernel.org/project/linux-mmc/ 
> > >> patch/1760924981-52339-1- git-send-email-shawn.lin at rock-chips.com/
> > > 
> > > Thank you for the patch! I will ask my friend to test it but he uses 
> > > this board as a home router, so it may take a few days or weeks to 
> > > report the result.
> > 
> > Hi all, sorry for the late. My friend has tested this patch and it works 
> > fine after 50 times dd operation. A big thanks to Shawn!
> 
> So I guess, we don't need the patch reducing the speed anymore, right?

Exactly, the approach of lowering the speed of eMMC to improve
its reliability is no longer needed, thanks to Shawn correcting
the DLL_STRBIN_TAPNUM_DEFAULT value in the above-linked patch.

We just need to test does HS400 work on the ROCK 5 ITX reliably
as well, so the previous lowering to HS200 in commit b36402e4a077
("arm64: dts: rockchip: slow down emmc freq for rock 5 itx", 2025-
02-28) could be reverted as no longer needed.

> > And hi Jianfeng, I found you made a similiar patch[1] for the ROCK 5 ITX 
> > board to lower down the mmc speed, could you please check if this patch 
> > also fixes your issue?
> > 
> > [1] https://lore.kernel.org/linux-rockchip/20250228143341.70244-1-liujianfeng1994 at gmail.com/
> > 
> > >>> Signed-off-by: Grzegorz Sterniczuk <grzegorz at sternicz.uk>
> > >>> Signed-off-by: Tianling Shen <cnsztl at gmail.com>
> > >>> ---
> > >>>   arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi | 3 +--
> > >>>   1 file changed, 1 insertion(+), 2 deletions(-)
> > >>>
> > >>> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi b/ 
> > >>> arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
> > >>> index fafeabe9adf9..5f63f38f7326 100644
> > >>> --- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
> > >>> +++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
> > >>> @@ -717,8 +717,7 @@ &sdhci {
> > >>>       no-sd;
> > >>>       non-removable;
> > >>>       max-frequency = <200000000>;
> > >>> -    mmc-hs400-1_8v;
> > >>> -    mmc-hs400-enhanced-strobe;
> > >>> +    mmc-hs200-1_8v;
> > >>>       status = "okay";
> > >>>   };



From sigmaris at gmail.com  Sat Nov  1 06:14:53 2025
From: sigmaris at gmail.com (Hugh Cole-Baker)
Date: Sat, 1 Nov 2025 13:14:53 +0000
Subject: [PATCH] arm64: dts: rockchip: pwm-fan overlay for NanoPC-T6
In-Reply-To: <2246326.irdbgypaU6@phil>
References: <d583ee43-38c4-40fb-b33b-ce3153c9723b@gmail.com>
 <CABjd4Yzfx-4xBHVB=W_r6nEdbwNJKdpHYB6bN3Xsk8dZOegJWw@mail.gmail.com>
 <2cfeeb0c-f7e0-b101-62c4-3b6eae40a30b@manjaro.org> <2246326.irdbgypaU6@phil>
Message-ID: <1a66cbba-41c3-425f-b830-efe4b83280f3@gmail.com>

On 01/11/2025 11:44, Heiko Stuebner wrote:
> Am Montag, 27. Oktober 2025, 22:15:05 Mitteleurop?ische Normalzeit schrieb Dragan Simic:
>> Hello Alexey,
>>
>> On Monday, October 27, 2025 21:56 CET, Alexey Charkov <alchark at gmail.com> wrote:
>>> On Tue, Oct 28, 2025 at 12:02?AM Dragan Simic <dsimic at manjaro.org> wrote:
>>>> On Mon, Oct 27, 2025 at 7:08?PM Hugh Cole-Baker <sigmaris at gmail.com> wrote:
>>>>> On 27/10/2025 09:14, Alexey Charkov wrote:
>>>>>
>>>>>> Is there any downside to enabling this unconditionally in the board
>>>>>> .dts?
>>>>>
>>>>> Only that it goes against the principle that the DT should describe the
>>>>> hardware; the board .dts would describe a cooling device that doesn't
>>>>> actually exist on the base board.
>>>>
>>>> Having a separate DT overlay is perfectly fine if we want to
>>>> describe a board absolutely correctly: if the fan actually isn't
>>>> present, the operating system shouldn't be made to think it is
>>>> there, especially if there's no fan RPM feedback, which is the
>>>> case on almost all Rockchip boards that support a fan.
>>>>
>>>> Preventing the kernel from managing a non-existent fan might even
>>>> save some CPU cycles, ending up producing a bit less heat, which
>>>> can only help in passively cooled setups.
>>>
>>> Sounds like an overcomplication without real benefit. It's one thing
>>> with overlays for functionality that can be software-incompatible
>>> depending on whether an external attachment is connected or depending
>>> on the type of attachment connected. Here we are looking at a plain
>>> 2-pin fan which cannot be software incompatible to anything really
>>> (it's not like one could repurpose the fan connector for anything
>>> meaningful if a fan is not in use, and noone gets hurt if a PWM output
>>> is left running without load).
>>>
>>> The CPU cycles spent parsing a slightly larger DTB at boot are likely
>>> comparable to those spent activating a PWM output needlessly upon
>>> hitting the active cooling trip point, and both are negligible for any
>>> practical purpose.
>>
>> Hmm, right, I forgot for a moment that the PWM output is generated
>> by dedicated hardware, so not many CPU cycles would be wasted.
>>
>> BTW, with a fan PWM signal generated by a soft-GPIO output, much
>> more CPU cycles would've been saved by omitting the fan definition
>> if it isn't present, but that isn't the case here.
>>
>>>> However, the practice so far has been to describe the fans in the
>>>> main board dts files, if the board provides fan support, regardless
>>>> of the fan being present in a particular board setup or not.
>>>>
>>>>> I guess then in theory, an OS might allow the SoC to reach undesirably high
>>>>> temperatures if it's relying on the nonexistent fan to cool it down. But I
>>>>> don't think this would be an issue on Linux, at least, in practice.
>>>>
>>>> We're safe, a thermal runaway isn't going to happen when the fan is
>>>> defined in a board DT but actually isn't present.  Thermal CPU and
>>>> GPU throttling will prevent the overheating from happening.
>>>>
>>>>>> Overlays require more user configuration, and not all
>>>>>> bootloaders support them directly (e.g. systemd-boot users would
>>>>>> struggle). Compiling with overlays enabled also makes .dtb's a lot
>>>>>> larger due to added symbols information.
>>>>>
>>>>> Nowadays (on Debian at least) using overlays is pretty easy, I'm using the
>>>>> u-boot-menu package in Debian, I just copy the overlay(s) to /boot/dtbo/ and
>>>>> it detects them automatically and adds them to extlinux.conf for u-boot to
>>>>> apply.
>>>>>
>>>>> Couldn't systemd-boot users just use rk3588-nanopc-t6-(lts-)with-fan.dtb as
>>>>> their single DT to load, if it doesn't support applying overlays and they
>>>>> want to use the fan addon?
>>>
>>> Sure, but it's a manual configuration step, where otherwise the kernel
>>> would just default to the correct dtb for the board that the firmware
>>> told it about. The fan is not discoverable, so the firmware won't ever
>>> offer the "-with-fan" variant, meaning users would need to supply it
>>> manually in every instance.
>>
>> FWIW, the most user-friendly SBC family in the world, Raspberry
>> Pi, :) requires manual enabling of the fan on Raspberry Pi 4.
>> I haven't researched what's the background for that, perhaps the
>> need to keep the GPIO expansion header completely unoccupied by
>> default, because the fan attaches to the GPIO header, instead of
>> to some dedicated fan connector.
>>
>>>> Yes, that's an option.  However, that in general doesn't resolve
>>>> the issues arising from systemd-boot users wanting to apply more
>>>> than a single DT overlay.
>>>>
>>>>> FWIW, I haven't noticed any problems with having a larger .dtb (using mainline
>>>>> U-Boot to load it) and several other RK3588 boards are also compiled with
>>>>> symbols enabled already, and I haven't seen any issues reported with them.
>>>>
>>>> After thinking a bit about it, I'd support the extraction of fan
>>>> definitions into separate DT overlays.  As I wrote above already,
>>>> not managing the non-existent fan might actually help a bit with
>>>> passively cooled board setups, which is a good enough reason for
>>>> me to support separate DT overlays.
>>>
>>> Practical benefits sound far fetched here, while forcing users to
>>> manually configure something that would have otherwise just worked.
>>> Let's see what Heiko thinks.
> 
> Personally, I'm more on the less complication side.
> 
> I.e. if there is an actual fan-connector on the board we should describe
> it as such.
> 
> Overlays I see for things where you attach hats to generic pin headers
> to create specific functionality on top of a generic interface.
> 
> But if the board itself has an actual fan header, it should be described
> as such. Because that then _is_ the standard use of that.

The board does have a fan connector, just no fan by default. But anyway,
since it sounds like the preferred approach I'll send a v2 which puts the
fan into the base board .dts.

Dragan, you mentioned there's no need for more than 2 trip points - if
I remove the trip points between "SoC is warm, start fan at slow speed"
and "SoC is v. hot, run fan at full speed" is the OS/kernel expected to
interpolate between those 2 trip points (if you have a link to docs or
code about this it'd be interesting, I couldn't find anything in the
dt-bindings)?

Best regards, Hugh


From mani at kernel.org  Sat Nov  1 06:59:41 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Sat, 1 Nov 2025 19:29:41 +0530
Subject: [PATCH v4 0/9] PCI: dw-rockchip: add system suspend support
In-Reply-To: <20251029-rockchip-pcie-system-suspend-v4-0-ce2e1b0692d2@collabora.com>
References: <20251029-rockchip-pcie-system-suspend-v4-0-ce2e1b0692d2@collabora.com>
Message-ID: <cf6zumlp4iiltglu7bbrpdeysaznrkyvlemwl4lxwkfjkgux7a@wl37bxilsprx>

On Wed, Oct 29, 2025 at 06:56:39PM +0100, Sebastian Reichel wrote:
> I've recently been working on fixing up at least basic system suspend
> support on the Rockchip RK3576 platform. Currently the biggest open
> issue is missing support in the PCIe driver. This series is a follow-up
> for Shawn Lin's series with feedback from Niklas Cassel and Manivannan
> Sadhasivam being handled as well as some of my own changes fixing up
> things I noticed.
> 
> In opposite to Shawn Lin I did not test with different peripherals as my
> main goal is getting basic suspend to ram working in the first place.

Wouldn't it break users who have connected endpoint devices and suspend their
platform? I don't want to have an untested feature that could potentially cause
regressions, just for the sake of getting basic system PM.

But if your goal is to just add basic system PM operations for CI testing, then
I would suggest you to do something minimal in the suspend/resume path that
don't disrupt the operation of a device.

But this also should be tested with some devices for sanity.

- Mani

> I
> did notice issues with the Broadcom WLAN card on the RK3576 EVB.
> Suspending that platform without a driver being probed works, but after
> probing brcmfmac suspend is aborted because brcmf_pcie_pm_enter_D3()
> does not work. As far as I can tell the problem is unrelated to the
> Rockchip PCIe driver.
> 
> Changes since PATCHv3:
>  * https://lore.kernel.org/linux-pci/1744940759-23823-1-git-send-email-shawn.lin at rock-chips.com/
>  * rename rockchip_pcie_get_ltssm to rockchip_pcie_get_ltssm_status_reg
>    in a separate patch (Niklas Cassel)
>  * rename rockchip_pcie_get_pure_ltssm to rockchip_pcie_get_ltssm_state
>    in a separate patch (Niklas Cassel)
>  * Move devm_phy_get out of phy_init to probe in a separate patch
>    (Manivannan Sadhasivam)
>  * Add helper function for enhanced LTSSM control mode in a separate patch
>    (Niklas Cassel)
>  * Add helper function for controller mode in a separate patch
>    (Niklas Cassel)
>  * Add helper function for DDL indicator in a separate patch
>    (Niklas Cassel)
>  * Move rockchip_pcie_pme_turn_off implementation in a separate patch
>  * Rebase to v6.18-rc3 using new FIELD_PREP_WM16()
>  * Improve readability of PME_TURN_OFF/PME_TO_ACK defines (Manivannan Sadhasivam)
>  * Fix usage of reverse Xmas (Manivannan Sadhasivam)
>  * Assert PERST# before turning off other resources (Manivannan Sadhasivam)
>  * Improve some error messages (Manivannan Sadhasivam)
>  * Rename goto labels as per their purpose (Manivannan Sadhasivam)
>  * Add extra patch for dw_pcie_resume_noirq, since I've seen errors
>    during resume on boards not having anything plugged into their PCIe
>    port
> 
> Signed-off-by: Sebastian Reichel <sebastian.reichel at collabora.com>
> ---
> Sebastian Reichel (9):
>       PCI: dw-rockchip: Rename rockchip_pcie_get_ltssm function
>       PCI: dw-rockchip: Support get_ltssm operation
>       PCI: dw-rockchip: Move devm_phy_get out of phy_init
>       PCI: dw-rockchip: Add helper function for enhanced LTSSM control mode
>       PCI: dw-rockchip: Add helper function for controller mode
>       PCI: dw-rockchip: Add helper function for DDL indicator
>       PCI: dw-rockchip: Add pme_turn_off support
>       PCI: dw-rockchip: Add system PM support
>       PCI: dwc: support missing PCIe device on resume
> 
>  drivers/pci/controller/dwc/pcie-designware-host.c |  13 +-
>  drivers/pci/controller/dwc/pcie-dw-rockchip.c     | 220 ++++++++++++++++++----
>  2 files changed, 198 insertions(+), 35 deletions(-)
> ---
> base-commit: dcb6fa37fd7bc9c3d2b066329b0d27dedf8becaa
> change-id: 20251028-rockchip-pcie-system-suspend-86cf08a7b229
> 
> Best regards,
> -- 
> Sebastian Reichel <sebastian.reichel at collabora.com>
> 

-- 
????????? ????????


From amadeus at jmu.edu.cn  Sat Nov  1 07:01:01 2025
From: amadeus at jmu.edu.cn (Chukun Pan)
Date: Sat,  1 Nov 2025 22:01:01 +0800
Subject: [PATCH 1/1] arm64: dts: rockchip: drop reset from rk3576 i2c9 node
Message-ID: <20251101140101.302229-1-amadeus@jmu.edu.cn>

The reset property is not part of the binding, so drop it.
It is also not used by the driver, so it was likely copied
from some vendor-kernel node.

Fixes: 57b1ce903966 ("arm64: dts: rockchip: Add rk3576 SoC base DT")
Signed-off-by: Chukun Pan <amadeus at jmu.edu.cn>
---
 arch/arm64/boot/dts/rockchip/rk3576.dtsi | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3576.dtsi b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
index f0c3ab00a7f3..a86fc6b4e8c4 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
@@ -2549,8 +2549,6 @@ i2c9: i2c at 2ae80000 {
 			interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
 			pinctrl-names = "default";
 			pinctrl-0 = <&i2c9m0_xfer>;
-			resets = <&cru SRST_I2C9>, <&cru SRST_P_I2C9>;
-			reset-names = "i2c", "apb";
 			#address-cells = <1>;
 			#size-cells = <0>;
 			status = "disabled";
-- 
2.25.1



From mani at kernel.org  Sat Nov  1 07:20:58 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Sat, 1 Nov 2025 19:50:58 +0530
Subject: [PATCH v4 9/9] PCI: dwc: support missing PCIe device on resume
In-Reply-To: <dc230a62-bd31-450a-9acd-fa654f694b3a@oss.qualcomm.com>
References: <20251029-rockchip-pcie-system-suspend-v4-0-ce2e1b0692d2@collabora.com>
 <20251029-rockchip-pcie-system-suspend-v4-9-ce2e1b0692d2@collabora.com>
 <dc230a62-bd31-450a-9acd-fa654f694b3a@oss.qualcomm.com>
Message-ID: <qlil44i7ywwxurdfovkbqvvjff7dey53uy5hzq4zbmvg7jg54o@zdg27w4q26gr>

On Thu, Oct 30, 2025 at 11:07:19AM +0530, Krishna Chaitanya Chundru wrote:
> 
> On 10/29/2025 11:26 PM, Sebastian Reichel wrote:
> > When dw_pcie_resume_noirq() is called for a PCIe root complex for a PCIe
> > slot with no device plugged on Rockchip RK3576, dw_pcie_wait_for_link()
> > will return -ETIMEDOUT. During probe time this does not happen, since
> > the platform sets 'use_linkup_irq'.
> > 
> > This adds the same logic from dw_pcie_host_init() to the PM resume
> > function to avoid the problem.
> > 
> > Signed-off-by: Sebastian Reichel <sebastian.reichel at collabora.com>
> > ---
> >   drivers/pci/controller/dwc/pcie-designware-host.c | 13 ++++++++++---
> >   1 file changed, 10 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> > index e92513c5bda5..f25f1c136900 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > @@ -1215,9 +1215,16 @@ int dw_pcie_resume_noirq(struct dw_pcie *pci)
> >   	if (ret)
> >   		return ret;
> > -	ret = dw_pcie_wait_for_link(pci);
> > -	if (ret)
> > -		return ret;
> > +	/*
> > +	 * Note: Skip the link up delay only when a Link Up IRQ is present.
> > +	 * If there is no Link Up IRQ, we should not bypass the delay
> > +	 * because that would require users to manually rescan for devices.
> > +	 */
> 
> In the resume scenario, we should explicitly wait for the link to be up,
> there is no IRQ support at this resume phase

This could be fixed if the PM handlers are moved to non-no_irq ones.

> and secondly after controller resume pm framework will start resuming the
> bridges & endpoints. what happens
> if the link is not up by the time endpoint is resume is called. And entire
> save & restore states might also gets messed up.
> There will be no way to recover from this.
> 

This is true if there were any devices connected to the bus during suspend. If
there were no devices, then it is fine to skip waiting for the link to be up.

- Mani

-- 
????????? ????????


From jbx6244 at gmail.com  Sat Nov  1 08:35:26 2025
From: jbx6244 at gmail.com (Johan Jonker)
Date: Sat, 1 Nov 2025 16:35:26 +0100
Subject: [PATCH v1] arm64: dts: rockchip: correct assigned-clock-rates
 spelling
Message-ID: <92714b6c-6c0d-4a10-afe4-73ed313c87c0@gmail.com>

Due to some copy and paste from the manufacturer tree the property
assigned-clock-rate is missing a letter "s". Correct spelling to
reduce dtbs_check output.

Signed-off-by: Johan Jonker <jbx6244 at gmail.com>
---

https://github.com/rockchip-linux/kernel/blob/develop-4.4/arch/arm64/boot/dts/rockchip/rk3328-evb.dts#L313
---
 arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts | 2 +-
 arch/arm64/boot/dts/rockchip/rk3328-evb.dts     | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts b/arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts
index b5bf84322031..b9d4d78bff0f 100644
--- a/arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts
@@ -184,7 +184,7 @@ &emmc {

 &gmac2phy {
 	assigned-clock-parents = <&cru SCLK_MAC2PHY_SRC>;
-	assigned-clock-rate = <50000000>;
+	assigned-clock-rates = <50000000>;
 	assigned-clocks = <&cru SCLK_MAC2PHY>;
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
index 3707df6acf1f..76715de886e2 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts
@@ -101,7 +101,7 @@ &emmc {
 &gmac2phy {
 	phy-supply = <&vcc_phy>;
 	clock_in_out = "output";
-	assigned-clock-rate = <50000000>;
+	assigned-clock-rates = <50000000>;
 	assigned-clocks = <&cru SCLK_MAC2PHY>;
 	assigned-clock-parents = <&cru SCLK_MAC2PHY_SRC>;
 	status = "okay";
--
2.39.5



From jbx6244 at gmail.com  Sat Nov  1 16:18:13 2025
From: jbx6244 at gmail.com (Johan Jonker)
Date: Sun, 2 Nov 2025 00:18:13 +0100
Subject: [PATCH v1] ARM: dts: rockchip: rk3288: move edp assigned-clocks to
 edp node
Message-ID: <7d6fa223-ab90-4c44-9180-54df78467ea5@gmail.com>

The rk3288 power-controller node contains an assigned-clocks property
that conflicts with the bindings. From the git history it shows that they
wanted to assign the rk3288 EDP_24M clock input centrally before an edp
node was available. Move the edp assigned-clocks property to the edp node
to reduce dtbs_check output.

Signed-off-by: Johan Jonker <jbx6244 at gmail.com>
---

Not tested with hardware.

ARM: dts: rockchip: Assign RK3288 EDP_24M input centrally
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/arch/arm/boot/dts/rk3288.dtsi?id=df5ea015984633526874619ca1288fc5f2cf47c0

ARM: dts: rockchip: add rk3288 displayport controller node
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/arch/arm/boot/dts/rk3288.dtsi?id=6df7ec6186644a4ffb4f0c859327ef41a1145a5f

ARM: dts: rockchip: add rk3288 edp-phy node
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/arch/arm/boot/dts/rk3288.dtsi?id=f5663969d8125a5c5b7835812e1e636ecedf030b

ARM: dts: rockchip: move rk3288 edp phy under the GRF
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/arch/arm/boot/dts/rk3288.dtsi?id=4b91545072ad7ca1963d2a89c8b42fc2eb561484
---
 arch/arm/boot/dts/rockchip/rk3288.dtsi | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/rockchip/rk3288.dtsi b/arch/arm/boot/dts/rockchip/rk3288.dtsi
index 7e284b4fecdc..7477fc5da3ec 100644
--- a/arch/arm/boot/dts/rockchip/rk3288.dtsi
+++ b/arch/arm/boot/dts/rockchip/rk3288.dtsi
@@ -741,9 +741,6 @@ power: power-controller {
 			#address-cells = <1>;
 			#size-cells = <0>;

-			assigned-clocks = <&cru SCLK_EDP_24M>;
-			assigned-clock-parents = <&xin24m>;
-
 			/*
 			 * Note: Although SCLK_* are the working clocks
 			 * of device without including on the NOC, needed for
@@ -1193,6 +1190,8 @@ edp: dp at ff970000 {
 		compatible = "rockchip,rk3288-dp";
 		reg = <0x0 0xff970000 0x0 0x4000>;
 		interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+		assigned-clocks = <&cru SCLK_EDP_24M>;
+		assigned-clock-parents = <&xin24m>;
 		clocks = <&cru SCLK_EDP>, <&cru PCLK_EDP_CTRL>;
 		clock-names = "dp", "pclk";
 		phys = <&edp_phy>;
--
2.39.5



From naoki at radxa.com  Sun Nov  2 01:02:25 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Sun, 2 Nov 2025 17:02:25 +0900
Subject: [PATCH v2 1/2] arm64: dts: rockchip: Fix USB Type-C host mode for
 Radxa ROCK 5B+/5T
In-Reply-To: <3389401.44csPzL39Z@phil>
References: <20251029130200.987580-1-naoki@radxa.com>
 <3389401.44csPzL39Z@phil>
Message-ID: <0E9BD1F921A89A99+8730cb12-0d40-4c50-b423-51c47120c9f8@radxa.com>

Hi Heiko,

On 11/1/25 20:51, Heiko Stuebner wrote:
> Hi,
> 
> Am Mittwoch, 29. Oktober 2025, 14:01:59 Mitteleurop?ische Normalzeit schrieb FUKAUMI Naoki:
>> The Radxa ROCK 5B+/5T USB Type-C port supports Dual Role Data and
>> should also act as a host. However, currently, when acting as a host,
>> only self-powered devices work.
>>
>> Since the ROCK 5B+ supports Dual Role Power, set the power-role
>> property to "dual" and the try-power-role property to "sink". (along
>> with related properties)
>>
>> The ROCK 5T should only support the "source" power role, but when the
>> power-role property is set to "source", when acting as a host, only
>> self-powered devices work. As a workaround, set the power-role
>> property to "dual" and the try-power-role property to "sink".
>>
>> This allows the port to act as a host, supply power to the port, and
>> allow bus-powered devices to work.
> 
> So it sounds like you're working around an issue coming from the Linux
> usb stack here? If the usb stack handles those power roles wrongly
> shouldn't it be fixed instead of introducing wrong hacks to generic
> hardware descriptions?
> 
> Like Linux isn't the only consumer of Devicetrees, so hacking them
> together to walk around driver issues feels wrong.

You are right. I will amend the patch for the ROCK 5T to set the 
power-role to "source". This will correct the current erroneous setting 
of "sink", surface the problem in the Linux USB stack (which should be 
fixed separately), and allow us to discuss this problem.

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> Heiko
> 
>> Note that there is a separate known issue where USB 3.0 SuperSpeed
>> devices do not work when oriented in reverse. This issue should be
>> addressed separately. (USB 2.0/1.1 devices work in both orientations)
>>
>> Fixes: 67b2c15d8fb3c ("arm64: dts: rockchip: add USB-C support for ROCK 5B/5B+/5T")
>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
>> ---
>> Changes in v2:
>> - Refine commit message
>> - Use board-specific dts to describe (try-)power-role
>> ---
>>   arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi | 4 ++--
>>   arch/arm64/boot/dts/rockchip/rk3588-rock-5b-plus.dts    | 5 +++++
>>   arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts         | 4 ++++
>>   arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts         | 5 +++++
>>   4 files changed, 16 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi
>> index 3bbe78810ec6f..7aac77dfc5f16 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi
>> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi
>> @@ -331,12 +331,12 @@ usb_con: connector {
>>   			data-role = "dual";
>>   			/* fusb302 supports PD Rev 2.0 Ver 1.2 */
>>   			pd-revision = /bits/ 8 <0x2 0x0 0x1 0x2>;
>> -			power-role = "sink";
>> -			try-power-role = "sink";
>>   			op-sink-microwatt = <1000000>;
>>   			sink-pdos =
>>   				<PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>,
>>   				<PDO_VAR(5000, 20000, 5000)>;
>> +			source-pdos =
>> +				<PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
>>   
>>   			altmodes {
>>   				displayport {
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-plus.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-plus.dts
>> index 5e984a44120e4..07a840d9b3859 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-plus.dts
>> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-plus.dts
>> @@ -110,6 +110,11 @@ vcc5v0_host_en: vcc5v0-host-en {
>>   	};
>>   };
>>   
>> +&usb_con {
>> +	power-role = "dual";
>> +	try-power-role = "sink";
>> +};
>> +
>>   &usbdp_phy0 {
>>   	pinctrl-names = "default";
>>   	pinctrl-0 = <&usbc_sbu_dc>;
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
>> index 8ef01010d985b..da13dafcbc823 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
>> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
>> @@ -49,6 +49,10 @@ vcc5v0_host_en: vcc5v0-host-en {
>>   	};
>>   };
>>   
>> +&usb_con {
>> +	power-role = "sink";
>> +};
>> +
>>   &usbdp_phy0 {
>>   	pinctrl-names = "default";
>>   	pinctrl-0 = <&usbc_sbu_dc>;
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts
>> index c1763835f53d4..96ffffec7e05d 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts
>> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts
>> @@ -130,6 +130,11 @@ usbc_sbu_dc: usbc-sbu-dc {
>>   	};
>>   };
>>   
>> +&usb_con {
>> +	power-role = "dual";
>> +	try-power-role = "sink";
>> +};
>> +
>>   &usbdp_phy0 {
>>   	pinctrl-names = "default";
>>   	pinctrl-0 = <&usbc_sbu_dc>;
>>
> 
> 
> 
> 
> 



From naoki at radxa.com  Sun Nov  2 01:28:13 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Sun, 2 Nov 2025 17:28:13 +0900
Subject: [PATCH v2 2/2] arm64: dts: rockchip: Fix USB Type-C host mode for
 Radxa ROCK 5 ITX
In-Reply-To: <20251029130200.987580-2-naoki@radxa.com>
References: <20251029130200.987580-1-naoki@radxa.com>
 <20251029130200.987580-2-naoki@radxa.com>
Message-ID: <DAF1CC9361853E89+ce2c6a94-2aba-45c6-b0ca-ad2c3b7208a1@radxa.com>

Please ignore this patch.

By the way, could someone try a bus-powered USB Type-C device with the 
ROCK 5 ITX(+) and let me know the result?

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

On 10/29/25 22:02, FUKAUMI Naoki wrote:
> The Radxa ROCK 5 ITX USB Type-C port supports Dual Role Data and
> should also act as a host. However, currently, when acting as a host,
> only self-powered devices work.
> 
> As a workaround, set the power-role property to "dual" and the
> try-power-role property to "sink". (along with related properties)
> 
> This allows the port to act as a host, supply power to the port, and
> allow bus-powered devices to work.
> 
> Note that there is a separate known issue where USB 3.0 SuperSpeed
> devices do not work when oriented in reverse. This issue should be
> addressed separately. (USB 2.0/1.1 devices work in both orientations)
> 
> Fixes: 31390eb8ffbf2 ("arm64: dts: rockchip: add ROCK 5 ITX board")
> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> ---
> Changes in v2:
> - Refine commit message
> ---
>   arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts | 7 ++++++-
>   1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
> index bc8140883de47..1664f85db4aaa 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
> @@ -484,9 +484,14 @@ usb_con: connector {
>   			compatible = "usb-c-connector";
>   			data-role = "dual";
>   			label = "USB-C";
> -			power-role = "source";
> +			op-sink-microwatt = <50000>;
> +			/* fusb302 supports PD Rev 2.0 Ver 1.2 */
> +			pd-revision = /bits/ 8 <0x2 0x0 0x1 0x2>;
> +			power-role = "dual";
> +			sink-pdos = <PDO_FIXED(5000, 10, PDO_FIXED_USB_COMM)>;
>   			source-pdos =
>   				<PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
> +			try-power-role = "sink";
>   
>   			ports {
>   				#address-cells = <1>;




From dmitry.baryshkov at oss.qualcomm.com  Sun Nov  2 08:39:25 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Sun, 2 Nov 2025 18:39:25 +0200
Subject: [PATCH v6 13/25] drm/msm: Compute dumb-buffer sizes with
 drm_mode_size_dumb()
In-Reply-To: <20250821081918.79786-14-tzimmermann@suse.de>
References: <20250821081918.79786-1-tzimmermann@suse.de>
 <20250821081918.79786-14-tzimmermann@suse.de>
Message-ID: <vptw5tquup34e3jen62znnw26qe76f3pys4lpsal5g3czwev6y@2q724ibos7by>

On Thu, Aug 21, 2025 at 10:17:20AM +0200, Thomas Zimmermann wrote:
> Call drm_mode_size_dumb() to compute dumb-buffer scanline pitch
> and buffer size. Alignment is specified in bytes, but the hardware
> requires the scanline pitch to be a multiple of 32 pixels. Therefore
> compute the byte size of 32 pixels in the given color mode and align
> the pitch accordingly. This replaces the existing code in the driver's
> align_pitch() helper.
> 
> v3:
> - clarify pitch alignment in commit message (Dmitry)
> 
> Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> Cc: Rob Clark <robdclark at gmail.com>
> Cc: Abhinav Kumar <quic_abhinavk at quicinc.com>
> Cc: Dmitry Baryshkov <dmitry.baryshkov at linaro.org>
> Cc: Sean Paul <sean at poorly.run>
> Cc: Marijn Suijten <marijn.suijten at somainline.org>
> ---
>  drivers/gpu/drm/msm/msm_gem.c | 27 +++++++++++++++++++++++++--
>  1 file changed, 25 insertions(+), 2 deletions(-)
> 

This broke kms_getfb at getfb-reject-nv12 and kms_getfb at getfb2-accept-nv12
IGT tests. I'll submit a fix separately.

-- 
With best wishes
Dmitry


From chaoyi.chen at rock-chips.com  Sun Nov  2 17:11:57 2025
From: chaoyi.chen at rock-chips.com (Chaoyi Chen)
Date: Mon, 3 Nov 2025 09:11:57 +0800
Subject: [PATCH v8 01/10] usb: typec: Add notifier functions
In-Reply-To: <aQS8IatWiAUzBUxd@kuha.fi.intel.com>
References: <20251029071435.88-1-kernel@airkyi.com>
 <20251029071435.88-2-kernel@airkyi.com> <aQS8IatWiAUzBUxd@kuha.fi.intel.com>
Message-ID: <39c21e9f-4958-4007-bb09-3ef40ff30d2a@rock-chips.com>

On 10/31/2025 9:39 PM, Heikki Krogerus wrote:

> Hi,
>
>> diff --git a/include/linux/usb/typec_notify.h b/include/linux/usb/typec_notify.h
>> new file mode 100644
>> index 000000000000..f3a7b5f5b05b
>> --- /dev/null
>> +++ b/include/linux/usb/typec_notify.h
>> @@ -0,0 +1,16 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +
>> +#ifndef __USB_TYPEC_NOTIFY
>> +#define __USB_TYPEC_NOTIFY
>> +
>> +#include <linux/notifier.h>
> Replace that include with a forward declaration:
>
> struct notifier_block;
>
>> +enum usb_typec_event {
>> +	TYPEC_ALTMODE_REGISTERED,
>> +	TYPEC_ALTMODE_UNREGISTERED,
>> +};
>> +
>> +int typec_altmode_register_notify(struct notifier_block *nb);
>> +int typec_altmode_unregister_notify(struct notifier_block *nb);
>> +
>> +#endif /* __USB_TYPEC_NOTIFY */
> I don't see any need for a separate header file for this. Intoduce
> those in typec_altmode.h.

Will fix these in v9. Thank you.


>
> thanks,
>
-- 
Best,
Chaoyi



From chaoyi.chen at rock-chips.com  Sun Nov  2 17:15:55 2025
From: chaoyi.chen at rock-chips.com (Chaoyi Chen)
Date: Mon, 3 Nov 2025 09:15:55 +0800
Subject: [PATCH v8 03/10] drm/bridge: Implement generic USB Type-C DP HPD
 bridge
In-Reply-To: <aQTAdaIgjgTRSgxL@kuha.fi.intel.com>
References: <20251029071435.88-1-kernel@airkyi.com>
 <20251029071435.88-4-kernel@airkyi.com> <aQTAdaIgjgTRSgxL@kuha.fi.intel.com>
Message-ID: <48b9ae2c-7cc5-430d-94c0-e49d341a4b14@rock-chips.com>

On 10/31/2025 9:58 PM, Heikki Krogerus wrote:

> Wed, Oct 29, 2025 at 03:14:28PM +0800, Chaoyi Chen kirjoitti:
>> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
>>
>> Several USB-C controller drivers have already implemented the DP HPD
>> bridge function provided by aux-hpd-bridge.c, but there are still
>> some USB-C controller driver that have not yet implemented it.
>>
>> This patch implements a generic DP HPD bridge based on aux-hpd-bridge.c,
>> so that other USB-C controller drivers don't need to implement it again.
>>
>> Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
>> ---
>>
>> Changes in v8:
>> - Merge generic DP HPD bridge into one module.
>>
>>   drivers/gpu/drm/bridge/Kconfig                |  5 +-
>>   drivers/gpu/drm/bridge/Makefile               |  8 +++-
>>   drivers/gpu/drm/bridge/aux-hpd-bridge.c       | 23 ++++++++-
>>   drivers/gpu/drm/bridge/aux-hpd-bridge.h       | 13 +++++
>>   .../gpu/drm/bridge/aux-hpd-typec-dp-bridge.c  | 47 +++++++++++++++++++
>>   5 files changed, 93 insertions(+), 3 deletions(-)
>>   create mode 100644 drivers/gpu/drm/bridge/aux-hpd-bridge.h
>>   create mode 100644 drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
>>
>> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
>> index a250afd8d662..17257b223a28 100644
>> --- a/drivers/gpu/drm/bridge/Kconfig
>> +++ b/drivers/gpu/drm/bridge/Kconfig
>> @@ -23,13 +23,16 @@ config DRM_AUX_BRIDGE
>>   	  build bridges chain.
>>   
>>   config DRM_AUX_HPD_BRIDGE
>> -	tristate
>> +	tristate "AUX HPD bridge support"
> Don't you now need:
>
>          depends on TYPEC || !TYPEC
>
>>   	depends on DRM_BRIDGE && OF
>>   	select AUXILIARY_BUS
>>   	help
>>   	  Simple bridge that terminates the bridge chain and provides HPD
>>   	  support.
>>   
>> +	  Specifically, if you want a default Type-C DisplayPort HPD bridge for
>> +	  each port of the Type-C controller, say Y here.
>> +
>>   menu "Display Interface Bridges"
>>   	depends on DRM && DRM_BRIDGE
>>   
>> diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
>> index c7dc03182e59..2998937444bc 100644
>> --- a/drivers/gpu/drm/bridge/Makefile
>> +++ b/drivers/gpu/drm/bridge/Makefile
>> @@ -1,6 +1,12 @@
>>   # SPDX-License-Identifier: GPL-2.0
>>   obj-$(CONFIG_DRM_AUX_BRIDGE) += aux-bridge.o
>> -obj-$(CONFIG_DRM_AUX_HPD_BRIDGE) += aux-hpd-bridge.o
>> +
>> +hpd-bridge-y := aux-hpd-bridge.o
>> +ifneq ($(CONFIG_TYPEC),)
>> +hpd-bridge-y += aux-hpd-typec-dp-bridge.o
>> +endif
>> +obj-$(CONFIG_DRM_AUX_HPD_BRIDGE) += hpd-bridge.o
>> +
>>   obj-$(CONFIG_DRM_CHIPONE_ICN6211) += chipone-icn6211.o
>>   obj-$(CONFIG_DRM_CHRONTEL_CH7033) += chrontel-ch7033.o
>>   obj-$(CONFIG_DRM_CROS_EC_ANX7688) += cros-ec-anx7688.o
>> diff --git a/drivers/gpu/drm/bridge/aux-hpd-bridge.c b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
>> index 2e9c702c7087..11ad6dc776c7 100644
>> --- a/drivers/gpu/drm/bridge/aux-hpd-bridge.c
>> +++ b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
>> @@ -12,6 +12,8 @@
>>   #include <drm/drm_bridge.h>
>>   #include <drm/bridge/aux-bridge.h>
>>   
>> +#include "aux-hpd-bridge.h"
>> +
>>   static DEFINE_IDA(drm_aux_hpd_bridge_ida);
>>   
>>   struct drm_aux_hpd_bridge_data {
>> @@ -204,7 +206,26 @@ static struct auxiliary_driver drm_aux_hpd_bridge_drv = {
>>   	.id_table = drm_aux_hpd_bridge_table,
>>   	.probe = drm_aux_hpd_bridge_probe,
>>   };
>> -module_auxiliary_driver(drm_aux_hpd_bridge_drv);
>> +
>> +static int drm_aux_hpd_bridge_mod_init(void)
>> +{
>> +	int ret;
>> +
>> +	ret = auxiliary_driver_register(&drm_aux_hpd_bridge_drv);
>> +	if (ret)
>> +		return ret;
>> +
>> +	return drm_aux_hpd_typec_dp_bridge_init();
>> +}
>> +
>> +static void drm_aux_hpd_bridge_mod_exit(void)
>> +{
>> +	drm_aux_hpd_typec_dp_bridge_exit();
>> +	auxiliary_driver_unregister(&drm_aux_hpd_bridge_drv);
>> +}
>> +
>> +module_init(drm_aux_hpd_bridge_mod_init);
>> +module_exit(drm_aux_hpd_bridge_mod_exit);
>>   
>>   MODULE_AUTHOR("Dmitry Baryshkov <dmitry.baryshkov at linaro.org>");
>>   MODULE_DESCRIPTION("DRM HPD bridge");
>> diff --git a/drivers/gpu/drm/bridge/aux-hpd-bridge.h b/drivers/gpu/drm/bridge/aux-hpd-bridge.h
>> new file mode 100644
>> index 000000000000..69364731c2f1
>> --- /dev/null
>> +++ b/drivers/gpu/drm/bridge/aux-hpd-bridge.h
>> @@ -0,0 +1,13 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +#ifndef AUX_HPD_BRIDGE_H
>> +#define AUX_HPD_BRIDGE_H
>> +
>> +#if IS_REACHABLE(CONFIG_TYPEC)
>> +int drm_aux_hpd_typec_dp_bridge_init(void);
>> +void drm_aux_hpd_typec_dp_bridge_exit(void);
>> +#else
>> +static inline int drm_aux_hpd_typec_dp_bridge_init(void) { return 0; }
>> +static inline void drm_aux_hpd_typec_dp_bridge_exit(void) { }
>> +#endif /* IS_REACHABLE(CONFIG_TYPEC) */
>> +
>> +#endif /* AUX_HPD_BRIDGE_H */
>> diff --git a/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c b/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
>> new file mode 100644
>> index 000000000000..6f2a1fca0fc5
>> --- /dev/null
>> +++ b/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
>> @@ -0,0 +1,47 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +#include <linux/of.h>
>> +#include <linux/usb/typec_altmode.h>
>> +#include <linux/usb/typec_dp.h>
>> +#include <linux/usb/typec_notify.h>
>> +
>> +#include <drm/bridge/aux-bridge.h>
>> +
>> +#include "aux-hpd-bridge.h"
>> +
>> +#if IS_REACHABLE(CONFIG_TYPEC)
> You don't need that. You should not use ifdefs in .c files.
>
Oh yes, this should be handled by depend on. I will fix it in v9.

-- 
Best,
Chaoyi



From dmitry.baryshkov at oss.qualcomm.com  Sun Nov  2 20:00:57 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Mon, 3 Nov 2025 06:00:57 +0200
Subject: [PATCH v8 03/10] drm/bridge: Implement generic USB Type-C DP HPD
 bridge
In-Reply-To: <20251029071435.88-4-kernel@airkyi.com>
References: <20251029071435.88-1-kernel@airkyi.com>
 <20251029071435.88-4-kernel@airkyi.com>
Message-ID: <rzozpbqmymdczerh3iijxxtz3xnsznoku7w2mquikwv6u5osvo@7h43hwc2fpzm>

On Wed, Oct 29, 2025 at 03:14:28PM +0800, Chaoyi Chen wrote:
> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> 
> Several USB-C controller drivers have already implemented the DP HPD
> bridge function provided by aux-hpd-bridge.c, but there are still
> some USB-C controller driver that have not yet implemented it.
> 
> This patch implements a generic DP HPD bridge based on aux-hpd-bridge.c,
> so that other USB-C controller drivers don't need to implement it again.

This doesn't describe the problem that you are trying to solve.

> 
> Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> ---
> 
> Changes in v8:
> - Merge generic DP HPD bridge into one module.
> 
>  drivers/gpu/drm/bridge/Kconfig                |  5 +-
>  drivers/gpu/drm/bridge/Makefile               |  8 +++-
>  drivers/gpu/drm/bridge/aux-hpd-bridge.c       | 23 ++++++++-
>  drivers/gpu/drm/bridge/aux-hpd-bridge.h       | 13 +++++
>  .../gpu/drm/bridge/aux-hpd-typec-dp-bridge.c  | 47 +++++++++++++++++++
>  5 files changed, 93 insertions(+), 3 deletions(-)
>  create mode 100644 drivers/gpu/drm/bridge/aux-hpd-bridge.h
>  create mode 100644 drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
> 
> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
> index a250afd8d662..17257b223a28 100644
> --- a/drivers/gpu/drm/bridge/Kconfig
> +++ b/drivers/gpu/drm/bridge/Kconfig
> @@ -23,13 +23,16 @@ config DRM_AUX_BRIDGE
>  	  build bridges chain.
>  
>  config DRM_AUX_HPD_BRIDGE
> -	tristate
> +	tristate "AUX HPD bridge support"

Why? No, this is supposed to be selected by other drivers. Users don't
know an wouldn't know what is this.

>  	depends on DRM_BRIDGE && OF
>  	select AUXILIARY_BUS
>  	help
>  	  Simple bridge that terminates the bridge chain and provides HPD
>  	  support.
>  
> +	  Specifically, if you want a default Type-C DisplayPort HPD bridge for
> +	  each port of the Type-C controller, say Y here.
> +
>  menu "Display Interface Bridges"
>  	depends on DRM && DRM_BRIDGE
>  
> diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
> index c7dc03182e59..2998937444bc 100644
> --- a/drivers/gpu/drm/bridge/Makefile
> +++ b/drivers/gpu/drm/bridge/Makefile
> @@ -1,6 +1,12 @@
>  # SPDX-License-Identifier: GPL-2.0
>  obj-$(CONFIG_DRM_AUX_BRIDGE) += aux-bridge.o
> -obj-$(CONFIG_DRM_AUX_HPD_BRIDGE) += aux-hpd-bridge.o
> +
> +hpd-bridge-y := aux-hpd-bridge.o
> +ifneq ($(CONFIG_TYPEC),)
> +hpd-bridge-y += aux-hpd-typec-dp-bridge.o
> +endif
> +obj-$(CONFIG_DRM_AUX_HPD_BRIDGE) += hpd-bridge.o
> +
>  obj-$(CONFIG_DRM_CHIPONE_ICN6211) += chipone-icn6211.o
>  obj-$(CONFIG_DRM_CHRONTEL_CH7033) += chrontel-ch7033.o
>  obj-$(CONFIG_DRM_CROS_EC_ANX7688) += cros-ec-anx7688.o
> diff --git a/drivers/gpu/drm/bridge/aux-hpd-bridge.c b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
> index 2e9c702c7087..11ad6dc776c7 100644
> --- a/drivers/gpu/drm/bridge/aux-hpd-bridge.c
> +++ b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
> @@ -12,6 +12,8 @@
>  #include <drm/drm_bridge.h>
>  #include <drm/bridge/aux-bridge.h>
>  
> +#include "aux-hpd-bridge.h"
> +
>  static DEFINE_IDA(drm_aux_hpd_bridge_ida);
>  
>  struct drm_aux_hpd_bridge_data {
> @@ -204,7 +206,26 @@ static struct auxiliary_driver drm_aux_hpd_bridge_drv = {
>  	.id_table = drm_aux_hpd_bridge_table,
>  	.probe = drm_aux_hpd_bridge_probe,
>  };
> -module_auxiliary_driver(drm_aux_hpd_bridge_drv);
> +
> +static int drm_aux_hpd_bridge_mod_init(void)
> +{
> +	int ret;
> +
> +	ret = auxiliary_driver_register(&drm_aux_hpd_bridge_drv);
> +	if (ret)
> +		return ret;
> +
> +	return drm_aux_hpd_typec_dp_bridge_init();
> +}
> +
> +static void drm_aux_hpd_bridge_mod_exit(void)
> +{
> +	drm_aux_hpd_typec_dp_bridge_exit();
> +	auxiliary_driver_unregister(&drm_aux_hpd_bridge_drv);
> +}
> +
> +module_init(drm_aux_hpd_bridge_mod_init);
> +module_exit(drm_aux_hpd_bridge_mod_exit);
>  
>  MODULE_AUTHOR("Dmitry Baryshkov <dmitry.baryshkov at linaro.org>");
>  MODULE_DESCRIPTION("DRM HPD bridge");
> diff --git a/drivers/gpu/drm/bridge/aux-hpd-bridge.h b/drivers/gpu/drm/bridge/aux-hpd-bridge.h
> new file mode 100644
> index 000000000000..69364731c2f1
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/aux-hpd-bridge.h
> @@ -0,0 +1,13 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +#ifndef AUX_HPD_BRIDGE_H
> +#define AUX_HPD_BRIDGE_H
> +
> +#if IS_REACHABLE(CONFIG_TYPEC)
> +int drm_aux_hpd_typec_dp_bridge_init(void);
> +void drm_aux_hpd_typec_dp_bridge_exit(void);
> +#else
> +static inline int drm_aux_hpd_typec_dp_bridge_init(void) { return 0; }
> +static inline void drm_aux_hpd_typec_dp_bridge_exit(void) { }
> +#endif /* IS_REACHABLE(CONFIG_TYPEC) */
> +
> +#endif /* AUX_HPD_BRIDGE_H */
> diff --git a/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c b/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
> new file mode 100644
> index 000000000000..6f2a1fca0fc5
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
> @@ -0,0 +1,47 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +#include <linux/of.h>
> +#include <linux/usb/typec_altmode.h>
> +#include <linux/usb/typec_dp.h>
> +#include <linux/usb/typec_notify.h>
> +
> +#include <drm/bridge/aux-bridge.h>
> +
> +#include "aux-hpd-bridge.h"
> +
> +#if IS_REACHABLE(CONFIG_TYPEC)
> +static int drm_typec_bus_event(struct notifier_block *nb,
> +			       unsigned long action, void *data)
> +{

This feels like this should be a part of the Type-C subsystem rather
than DRM.

> +	struct typec_altmode *alt = (struct typec_altmode *)data;
> +
> +	if (action != TYPEC_ALTMODE_REGISTERED)
> +		goto done;
> +
> +	if (is_typec_partner(&alt->dev) || alt->svid != USB_TYPEC_DP_SID)
> +		goto done;
> +
> +	/*
> +	 * alt->dev.parent->parent : USB-C controller device
> +	 * alt->dev.parent         : USB-C connector device
> +	 */
> +	drm_dp_hpd_bridge_register(alt->dev.parent->parent,
> +				   to_of_node(alt->dev.parent->fwnode));
> +
> +done:
> +	return NOTIFY_OK;
> +}
> +
> +static struct notifier_block drm_typec_event_nb = {
> +	.notifier_call = drm_typec_bus_event,
> +};
> +
> +int drm_aux_hpd_typec_dp_bridge_init(void)
> +{
> +	return typec_altmode_register_notify(&drm_typec_event_nb);
> +}
> +
> +void drm_aux_hpd_typec_dp_bridge_exit(void)
> +{
> +	typec_altmode_unregister_notify(&drm_typec_event_nb);
> +}
> +#endif
> -- 
> 2.49.0
> 

-- 
With best wishes
Dmitry


From chaoyi.chen at rock-chips.com  Sun Nov  2 22:24:12 2025
From: chaoyi.chen at rock-chips.com (Chaoyi Chen)
Date: Mon, 3 Nov 2025 14:24:12 +0800
Subject: [PATCH v8 03/10] drm/bridge: Implement generic USB Type-C DP HPD
 bridge
In-Reply-To: <rzozpbqmymdczerh3iijxxtz3xnsznoku7w2mquikwv6u5osvo@7h43hwc2fpzm>
References: <20251029071435.88-1-kernel@airkyi.com>
 <20251029071435.88-4-kernel@airkyi.com>
 <rzozpbqmymdczerh3iijxxtz3xnsznoku7w2mquikwv6u5osvo@7h43hwc2fpzm>
Message-ID: <eca9d5bd-23bd-4c1d-b2f2-c0c32f14177f@rock-chips.com>

On 11/3/2025 12:00 PM, Dmitry Baryshkov wrote:

> On Wed, Oct 29, 2025 at 03:14:28PM +0800, Chaoyi Chen wrote:
>> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
>>
>> Several USB-C controller drivers have already implemented the DP HPD
>> bridge function provided by aux-hpd-bridge.c, but there are still
>> some USB-C controller driver that have not yet implemented it.
>>
>> This patch implements a generic DP HPD bridge based on aux-hpd-bridge.c,
>> so that other USB-C controller drivers don't need to implement it again.
> This doesn't describe the problem that you are trying to solve.

I'll try to describe the information more accurately. Thank you.


>
>> Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
>> ---
>>
>> Changes in v8:
>> - Merge generic DP HPD bridge into one module.
>>
>>   drivers/gpu/drm/bridge/Kconfig                |  5 +-
>>   drivers/gpu/drm/bridge/Makefile               |  8 +++-
>>   drivers/gpu/drm/bridge/aux-hpd-bridge.c       | 23 ++++++++-
>>   drivers/gpu/drm/bridge/aux-hpd-bridge.h       | 13 +++++
>>   .../gpu/drm/bridge/aux-hpd-typec-dp-bridge.c  | 47 +++++++++++++++++++
>>   5 files changed, 93 insertions(+), 3 deletions(-)
>>   create mode 100644 drivers/gpu/drm/bridge/aux-hpd-bridge.h
>>   create mode 100644 drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
>>
>> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
>> index a250afd8d662..17257b223a28 100644
>> --- a/drivers/gpu/drm/bridge/Kconfig
>> +++ b/drivers/gpu/drm/bridge/Kconfig
>> @@ -23,13 +23,16 @@ config DRM_AUX_BRIDGE
>>   	  build bridges chain.
>>   
>>   config DRM_AUX_HPD_BRIDGE
>> -	tristate
>> +	tristate "AUX HPD bridge support"
> Why? No, this is supposed to be selected by other drivers. Users don't
> know an wouldn't know what is this.

In v7, I implemented an additional module for selecting this option. But Heikki believes that it would be better to merge the two modules into one.



>
>>   	depends on DRM_BRIDGE && OF
>>   	select AUXILIARY_BUS
>>   	help
>>   	  Simple bridge that terminates the bridge chain and provides HPD
>>   	  support.
>>   
>> +	  Specifically, if you want a default Type-C DisplayPort HPD bridge for
>> +	  each port of the Type-C controller, say Y here.
>> +
>>   menu "Display Interface Bridges"
>>   	depends on DRM && DRM_BRIDGE
>>   
>> diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
>> index c7dc03182e59..2998937444bc 100644
>> --- a/drivers/gpu/drm/bridge/Makefile
>> +++ b/drivers/gpu/drm/bridge/Makefile
>> @@ -1,6 +1,12 @@
>>   # SPDX-License-Identifier: GPL-2.0
>>   obj-$(CONFIG_DRM_AUX_BRIDGE) += aux-bridge.o
>> -obj-$(CONFIG_DRM_AUX_HPD_BRIDGE) += aux-hpd-bridge.o
>> +
>> +hpd-bridge-y := aux-hpd-bridge.o
>> +ifneq ($(CONFIG_TYPEC),)
>> +hpd-bridge-y += aux-hpd-typec-dp-bridge.o
>> +endif
>> +obj-$(CONFIG_DRM_AUX_HPD_BRIDGE) += hpd-bridge.o
>> +
>>   obj-$(CONFIG_DRM_CHIPONE_ICN6211) += chipone-icn6211.o
>>   obj-$(CONFIG_DRM_CHRONTEL_CH7033) += chrontel-ch7033.o
>>   obj-$(CONFIG_DRM_CROS_EC_ANX7688) += cros-ec-anx7688.o
>> diff --git a/drivers/gpu/drm/bridge/aux-hpd-bridge.c b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
>> index 2e9c702c7087..11ad6dc776c7 100644
>> --- a/drivers/gpu/drm/bridge/aux-hpd-bridge.c
>> +++ b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
>> @@ -12,6 +12,8 @@
>>   #include <drm/drm_bridge.h>
>>   #include <drm/bridge/aux-bridge.h>
>>   
>> +#include "aux-hpd-bridge.h"
>> +
>>   static DEFINE_IDA(drm_aux_hpd_bridge_ida);
>>   
>>   struct drm_aux_hpd_bridge_data {
>> @@ -204,7 +206,26 @@ static struct auxiliary_driver drm_aux_hpd_bridge_drv = {
>>   	.id_table = drm_aux_hpd_bridge_table,
>>   	.probe = drm_aux_hpd_bridge_probe,
>>   };
>> -module_auxiliary_driver(drm_aux_hpd_bridge_drv);
>> +
>> +static int drm_aux_hpd_bridge_mod_init(void)
>> +{
>> +	int ret;
>> +
>> +	ret = auxiliary_driver_register(&drm_aux_hpd_bridge_drv);
>> +	if (ret)
>> +		return ret;
>> +
>> +	return drm_aux_hpd_typec_dp_bridge_init();
>> +}
>> +
>> +static void drm_aux_hpd_bridge_mod_exit(void)
>> +{
>> +	drm_aux_hpd_typec_dp_bridge_exit();
>> +	auxiliary_driver_unregister(&drm_aux_hpd_bridge_drv);
>> +}
>> +
>> +module_init(drm_aux_hpd_bridge_mod_init);
>> +module_exit(drm_aux_hpd_bridge_mod_exit);
>>   
>>   MODULE_AUTHOR("Dmitry Baryshkov <dmitry.baryshkov at linaro.org>");
>>   MODULE_DESCRIPTION("DRM HPD bridge");
>> diff --git a/drivers/gpu/drm/bridge/aux-hpd-bridge.h b/drivers/gpu/drm/bridge/aux-hpd-bridge.h
>> new file mode 100644
>> index 000000000000..69364731c2f1
>> --- /dev/null
>> +++ b/drivers/gpu/drm/bridge/aux-hpd-bridge.h
>> @@ -0,0 +1,13 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +#ifndef AUX_HPD_BRIDGE_H
>> +#define AUX_HPD_BRIDGE_H
>> +
>> +#if IS_REACHABLE(CONFIG_TYPEC)
>> +int drm_aux_hpd_typec_dp_bridge_init(void);
>> +void drm_aux_hpd_typec_dp_bridge_exit(void);
>> +#else
>> +static inline int drm_aux_hpd_typec_dp_bridge_init(void) { return 0; }
>> +static inline void drm_aux_hpd_typec_dp_bridge_exit(void) { }
>> +#endif /* IS_REACHABLE(CONFIG_TYPEC) */
>> +
>> +#endif /* AUX_HPD_BRIDGE_H */
>> diff --git a/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c b/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
>> new file mode 100644
>> index 000000000000..6f2a1fca0fc5
>> --- /dev/null
>> +++ b/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
>> @@ -0,0 +1,47 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +#include <linux/of.h>
>> +#include <linux/usb/typec_altmode.h>
>> +#include <linux/usb/typec_dp.h>
>> +#include <linux/usb/typec_notify.h>
>> +
>> +#include <drm/bridge/aux-bridge.h>
>> +
>> +#include "aux-hpd-bridge.h"
>> +
>> +#if IS_REACHABLE(CONFIG_TYPEC)
>> +static int drm_typec_bus_event(struct notifier_block *nb,
>> +			       unsigned long action, void *data)
>> +{
> This feels like this should be a part of the Type-C subsystem rather
> than DRM.

In v7, this used to be a part of the Type-C subsystem. I'm not sure what Heikki thinks about this.



>
>> +	struct typec_altmode *alt = (struct typec_altmode *)data;
>> +
>> +	if (action != TYPEC_ALTMODE_REGISTERED)
>> +		goto done;
>> +
>> +	if (is_typec_partner(&alt->dev) || alt->svid != USB_TYPEC_DP_SID)
>> +		goto done;
>> +
>> +	/*
>> +	 * alt->dev.parent->parent : USB-C controller device
>> +	 * alt->dev.parent         : USB-C connector device
>> +	 */
>> +	drm_dp_hpd_bridge_register(alt->dev.parent->parent,
>> +				   to_of_node(alt->dev.parent->fwnode));
>> +
>> +done:
>> +	return NOTIFY_OK;
>> +}
>> +
>> +static struct notifier_block drm_typec_event_nb = {
>> +	.notifier_call = drm_typec_bus_event,
>> +};
>> +
>> +int drm_aux_hpd_typec_dp_bridge_init(void)
>> +{
>> +	return typec_altmode_register_notify(&drm_typec_event_nb);
>> +}
>> +
>> +void drm_aux_hpd_typec_dp_bridge_exit(void)
>> +{
>> +	typec_altmode_unregister_notify(&drm_typec_event_nb);
>> +}
>> +#endif
>> -- 
>> 2.49.0
>>
-- 
Best,
Chaoyi



From geraldogabriel at gmail.com  Sun Nov  2 22:26:35 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Mon, 3 Nov 2025 03:26:35 -0300
Subject: [RFC PATCH 0/2] PCI: rockchip-host: support quirky devices
Message-ID: <cover.1762150971.git.geraldogabriel@gmail.com>

With these two changes I'm able to work with a Samsung PM981a OEM SSD
that is known to be not-working with Rockchip-IP PCIe.

Previously I attempted a contrived solution that mostly worked for my
simple purposes but was rather inelegant and impractical.

Now I have isolated the behavior to the three lines in the two commits.
Omit those three lines and you get a working set with the kernel.

I have no idea how to actually implement this in a way that makes sense
and doesn't break the PCIe spec but it is my sincere wish that
interested RK3399 parties test the change and report any regressions
with already-working devices and specifically, successes or failures of
initial link-training with these changes.

Geraldo Nascimento (2):
  arm64: dts: rockchip: drop PCIe 3v3 always-on/boot-on
  PCI: rockchip-host: drop wait on PERST# toggle

 arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi | 2 --
 drivers/pci/controller/pcie-rockchip-host.c           | 1 -
 2 files changed, 3 deletions(-)

-- 
2.49.0



From geraldogabriel at gmail.com  Sun Nov  2 22:27:05 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Mon, 3 Nov 2025 03:27:05 -0300
Subject: [RFC PATCH 1/2] arm64: dts: rockchip: drop PCIe 3v3 always-on/boot-on
In-Reply-To: <cover.1762150971.git.geraldogabriel@gmail.com>
References: <cover.1762150971.git.geraldogabriel@gmail.com>
Message-ID: <1c1cb7f94cf41142c55561ce8f2a2579021d4818.1762150971.git.geraldogabriel@gmail.com>

Example commit of needed dropping of regulator always-on/boot-on
declarations to make sure quirky devices known to not be working on
RK3399 are able to enumerate on the PCI bus.

One example only, tested on my ROCK PI N10 board, to avoid patch-bomb

Signed-off-by: Geraldo Nascimento <geraldogabriel at gmail.com>
---
 arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
index aa70776e898a..ad99a8558bf0 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
@@ -25,8 +25,6 @@ vcc3v3_pcie: regulator-vcc-pcie {
 		pinctrl-names = "default";
 		pinctrl-0 = <&pcie_pwr>;
 		regulator-name = "vcc3v3_pcie";
-		regulator-always-on;
-		regulator-boot-on;
 		vin-supply = <&vcc5v0_sys>;
 	};
 
-- 
2.49.0



From geraldogabriel at gmail.com  Sun Nov  2 22:27:25 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Mon, 3 Nov 2025 03:27:25 -0300
Subject: [RFC PATCH 2/2] PCI: rockchip-host: drop wait on PERST# toggle
In-Reply-To: <cover.1762150971.git.geraldogabriel@gmail.com>
References: <cover.1762150971.git.geraldogabriel@gmail.com>
Message-ID: <d3d0c3a387ff461e62bbd66a0bde654a9a17761e.1762150971.git.geraldogabriel@gmail.com>

With this change PCIe will complete link-training with a known quirky
device - Samsung OEM PM981a SSD. This is completely against the PCIe
spec and yet it works as long as the power regulator for 3v3 PCIe
power is not defined as always-on or boot-on.

Signed-off-by: Geraldo Nascimento <geraldogabriel at gmail.com>
---
 drivers/pci/controller/pcie-rockchip-host.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c
index ee1822ca01db..6add0faf6dc9 100644
--- a/drivers/pci/controller/pcie-rockchip-host.c
+++ b/drivers/pci/controller/pcie-rockchip-host.c
@@ -314,7 +314,6 @@ static int rockchip_pcie_host_init_port(struct rockchip_pcie *rockchip)
 	rockchip_pcie_write(rockchip, PCIE_CLIENT_LINK_TRAIN_ENABLE,
 			    PCIE_CLIENT_CONFIG);
 
-	msleep(PCIE_T_PVPERL_MS);
 	gpiod_set_value_cansleep(rockchip->perst_gpio, 1);
 
 	msleep(PCIE_RESET_CONFIG_WAIT_MS);
-- 
2.49.0



From xakep.amatop at gmail.com  Sun Nov  2 23:32:12 2025
From: xakep.amatop at gmail.com (Mykola Kvach)
Date: Mon, 3 Nov 2025 09:32:12 +0200
Subject: [PATCH] arm64: dts: rockchip: orangepi-5: fix PCIe 3.3V regulator voltage
In-Reply-To: <1499f50e-aa4f-454a-b8b5-c9a21bef7f72@collabora.com>
References: <20251024173830.49211-1-xakep.amatop@gmail.com> <1499f50e-aa4f-454a-b8b5-c9a21bef7f72@collabora.com>
Message-ID: <CAGeoDV-+HjpW9CMy5ypsMFDYgYKrV-5zMDGie0=_JyTCo7NF2Q@mail.gmail.com>

Hi Michael,

Thank you for the fast response and the review.

On Mon, Oct 27, 2025 at 2:39?PM Michael Riesch
<michael.riesch at collabora.com> wrote:
>
> Hi Mykola,
>
> Thanks for your patch.
>
> Cc: Muhammed who is the author of commit b6bc755d806e
>
> On 10/24/25 19:38, Mykola Kvach wrote:
> > The vcc3v3_pcie20 fixed regulator powers the PCIe device-side 3.3V
> > rail for pcie2x1l2 via vpcie3v3-supply. The DTS mistakenly set its
> > regulator-min/max-microvolt to 1800000. Correct both to 3300000
> > to match the rail name, the PCIe/M.2 power requirement, and the
> > actual hardware wiring on Orange Pi 5.
> >
>
> I guess a "Fixes" tag is in order here:
>
> Fixes: b6bc755d806e ("arm64: dts: rockchip: Add Orange Pi 5")

Thank you for pointing that out. I will add the Fixes tag in v2.

>
> And make sure to Cc: <stable at vger.kernel.org>

Will do.

>
> > Signed-off-by: Mykola Kvach <xakep.amatop at gmail.com>
>
> The change itself makes sense to me.
>
> Reviewed-by: Michael Riesch <michael.riesch at collabora.com>

Thanks! I will carry your Reviewed-by in v2 (diff unchanged).


Best regards,
Mykola

>
> Best regards,
> Michael
>
> > ---
> >  arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts
> > index ad6d04793b0a..83b9b6645a1e 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts
> > +++ b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts
> > @@ -14,8 +14,8 @@ vcc3v3_pcie20: regulator-vcc3v3-pcie20 {
> >               gpios = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
> >               regulator-name = "vcc3v3_pcie20";
> >               regulator-boot-on;
> > -             regulator-min-microvolt = <1800000>;
> > -             regulator-max-microvolt = <1800000>;
> > +             regulator-min-microvolt = <3300000>;
> > +             regulator-max-microvolt = <3300000>;
> >               startup-delay-us = <50000>;
> >               vin-supply = <&vcc5v0_sys>;
> >       };
>


From xakep.amatop at gmail.com  Mon Nov  3 02:08:14 2025
From: xakep.amatop at gmail.com (Mykola Kvach)
Date: Mon,  3 Nov 2025 12:08:14 +0200
Subject: [PATCH v2] arm64: dts: rockchip: orangepi-5: fix PCIe 3.3V regulator voltage
In-Reply-To: <20251024173830.49211-1-xakep.amatop@gmail.com>
References: <20251024173830.49211-1-xakep.amatop@gmail.com>
Message-ID: <9232ae8cc8e7eb4f986734c8820f44b7989b9dae.1762161839.git.xakep.amatop@gmail.com>

The vcc3v3_pcie20 fixed regulator powers the PCIe device-side 3.3V rail
for pcie2x1l2 via vpcie3v3-supply. The DTS mistakenly set its
regulator-min/max-microvolt to 1800000 (1.8 V). Correct both to 3300000
(3.3 V) to match the rail name, the PCIe/M.2 power requirement, and the
actual hardware wiring on Orange Pi 5.

Fixes: b6bc755d806e ("arm64: dts: rockchip: Add Orange Pi 5")
Signed-off-by: Mykola Kvach <xakep.amatop at gmail.com>
Reviewed-by: Michael Riesch <michael.riesch at collabora.com>
---
Changes in v2:
- add Fixes tag and Cc stable list as requested during review.
---
 arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts
index ad6d04793b0a..83b9b6645a1e 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts
@@ -14,8 +14,8 @@ vcc3v3_pcie20: regulator-vcc3v3-pcie20 {
 		gpios = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
 		regulator-name = "vcc3v3_pcie20";
 		regulator-boot-on;
-		regulator-min-microvolt = <1800000>;
-		regulator-max-microvolt = <1800000>;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
 		startup-delay-us = <50000>;
 		vin-supply = <&vcc5v0_sys>;
 	};
--
2.43.0



From xakep.amatop at gmail.com  Mon Nov  3 02:27:40 2025
From: xakep.amatop at gmail.com (Mykola Kvach)
Date: Mon,  3 Nov 2025 12:27:40 +0200
Subject: [PATCH v3] arm64: dts: rockchip: orangepi-5: fix PCIe 3.3V regulator voltage
In-Reply-To: <9232ae8cc8e7eb4f986734c8820f44b7989b9dae.1762161839.git.xakep.amatop@gmail.com>
References: <9232ae8cc8e7eb4f986734c8820f44b7989b9dae.1762161839.git.xakep.amatop@gmail.com>
Message-ID: <cf6e08dfdfbf1c540685d12388baab1326f95d2c.1762165324.git.xakep.amatop@gmail.com>

The vcc3v3_pcie20 fixed regulator powers the PCIe device-side 3.3V rail
for pcie2x1l2 via vpcie3v3-supply. The DTS mistakenly set its
regulator-min/max-microvolt to 1800000 (1.8 V). Correct both to 3300000
(3.3 V) to match the rail name, the PCIe/M.2 power requirement, and the
actual hardware wiring on Orange Pi 5.

Fixes: b6bc755d806e ("arm64: dts: rockchip: Add Orange Pi 5")
Cc: stable at vger.kernel.org
Signed-off-by: Mykola Kvach <xakep.amatop at gmail.com>
Reviewed-by: Michael Riesch <michael.riesch at collabora.com>
---
Changes in v3:
- add "Cc: stable at vger.kernel.org" to commit message.

Changes in v2:
- add Fixes tag and Cc stable list as requested during review.
---
 arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts
index ad6d04793b0a..83b9b6645a1e 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts
@@ -14,8 +14,8 @@ vcc3v3_pcie20: regulator-vcc3v3-pcie20 {
 		gpios = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
 		regulator-name = "vcc3v3_pcie20";
 		regulator-boot-on;
-		regulator-min-microvolt = <1800000>;
-		regulator-max-microvolt = <1800000>;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
 		startup-delay-us = <50000>;
 		vin-supply = <&vcc5v0_sys>;
 	};
--
2.43.0



From heikki.krogerus at linux.intel.com  Mon Nov  3 05:48:09 2025
From: heikki.krogerus at linux.intel.com (Heikki Krogerus)
Date: Mon, 3 Nov 2025 15:48:09 +0200
Subject: [PATCH v8 03/10] drm/bridge: Implement generic USB Type-C DP HPD
 bridge
In-Reply-To: <eca9d5bd-23bd-4c1d-b2f2-c0c32f14177f@rock-chips.com>
References: <20251029071435.88-1-kernel@airkyi.com>
 <20251029071435.88-4-kernel@airkyi.com>
 <rzozpbqmymdczerh3iijxxtz3xnsznoku7w2mquikwv6u5osvo@7h43hwc2fpzm>
 <eca9d5bd-23bd-4c1d-b2f2-c0c32f14177f@rock-chips.com>
Message-ID: <aQiymTFVU7UpcJ1p@kuha.fi.intel.com>

> > > diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
> > > index a250afd8d662..17257b223a28 100644
> > > --- a/drivers/gpu/drm/bridge/Kconfig
> > > +++ b/drivers/gpu/drm/bridge/Kconfig
> > > @@ -23,13 +23,16 @@ config DRM_AUX_BRIDGE
> > >   	  build bridges chain.
> > >   config DRM_AUX_HPD_BRIDGE
> > > -	tristate
> > > +	tristate "AUX HPD bridge support"
> > Why? No, this is supposed to be selected by other drivers. Users don't
> > know an wouldn't know what is this.
> 
> In v7, I implemented an additional module for selecting this option. But
> Heikki believes that it would be better to merge the two modules into one.

Like I said before, I was merely curious why not just squash the
support into that AUX_PD_HPD_BRIDGE. If that does not make sense, then
so be it - make it a "Display Interface Bridge" driver like you
originally proposed.

> > >   	depends on DRM_BRIDGE && OF
> > >   	select AUXILIARY_BUS
> > >   	help
> > >   	  Simple bridge that terminates the bridge chain and provides HPD
> > >   	  support.
> > > +	  Specifically, if you want a default Type-C DisplayPort HPD bridge for
> > > +	  each port of the Type-C controller, say Y here.
> > > +
> > >   menu "Display Interface Bridges"
> > >   	depends on DRM && DRM_BRIDGE
> > > diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
> > > index c7dc03182e59..2998937444bc 100644
> > > --- a/drivers/gpu/drm/bridge/Makefile
> > > +++ b/drivers/gpu/drm/bridge/Makefile
> > > @@ -1,6 +1,12 @@
> > >   # SPDX-License-Identifier: GPL-2.0
> > >   obj-$(CONFIG_DRM_AUX_BRIDGE) += aux-bridge.o
> > > -obj-$(CONFIG_DRM_AUX_HPD_BRIDGE) += aux-hpd-bridge.o
> > > +
> > > +hpd-bridge-y := aux-hpd-bridge.o
> > > +ifneq ($(CONFIG_TYPEC),)
> > > +hpd-bridge-y += aux-hpd-typec-dp-bridge.o
> > > +endif
> > > +obj-$(CONFIG_DRM_AUX_HPD_BRIDGE) += hpd-bridge.o
> > > +
> > >   obj-$(CONFIG_DRM_CHIPONE_ICN6211) += chipone-icn6211.o
> > >   obj-$(CONFIG_DRM_CHRONTEL_CH7033) += chrontel-ch7033.o
> > >   obj-$(CONFIG_DRM_CROS_EC_ANX7688) += cros-ec-anx7688.o
> > > diff --git a/drivers/gpu/drm/bridge/aux-hpd-bridge.c b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
> > > index 2e9c702c7087..11ad6dc776c7 100644
> > > --- a/drivers/gpu/drm/bridge/aux-hpd-bridge.c
> > > +++ b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
> > > @@ -12,6 +12,8 @@
> > >   #include <drm/drm_bridge.h>
> > >   #include <drm/bridge/aux-bridge.h>
> > > +#include "aux-hpd-bridge.h"
> > > +
> > >   static DEFINE_IDA(drm_aux_hpd_bridge_ida);
> > >   struct drm_aux_hpd_bridge_data {
> > > @@ -204,7 +206,26 @@ static struct auxiliary_driver drm_aux_hpd_bridge_drv = {
> > >   	.id_table = drm_aux_hpd_bridge_table,
> > >   	.probe = drm_aux_hpd_bridge_probe,
> > >   };
> > > -module_auxiliary_driver(drm_aux_hpd_bridge_drv);
> > > +
> > > +static int drm_aux_hpd_bridge_mod_init(void)
> > > +{
> > > +	int ret;
> > > +
> > > +	ret = auxiliary_driver_register(&drm_aux_hpd_bridge_drv);
> > > +	if (ret)
> > > +		return ret;
> > > +
> > > +	return drm_aux_hpd_typec_dp_bridge_init();
> > > +}
> > > +
> > > +static void drm_aux_hpd_bridge_mod_exit(void)
> > > +{
> > > +	drm_aux_hpd_typec_dp_bridge_exit();
> > > +	auxiliary_driver_unregister(&drm_aux_hpd_bridge_drv);
> > > +}
> > > +
> > > +module_init(drm_aux_hpd_bridge_mod_init);
> > > +module_exit(drm_aux_hpd_bridge_mod_exit);
> > >   MODULE_AUTHOR("Dmitry Baryshkov <dmitry.baryshkov at linaro.org>");
> > >   MODULE_DESCRIPTION("DRM HPD bridge");
> > > diff --git a/drivers/gpu/drm/bridge/aux-hpd-bridge.h b/drivers/gpu/drm/bridge/aux-hpd-bridge.h
> > > new file mode 100644
> > > index 000000000000..69364731c2f1
> > > --- /dev/null
> > > +++ b/drivers/gpu/drm/bridge/aux-hpd-bridge.h
> > > @@ -0,0 +1,13 @@
> > > +/* SPDX-License-Identifier: GPL-2.0-only */
> > > +#ifndef AUX_HPD_BRIDGE_H
> > > +#define AUX_HPD_BRIDGE_H
> > > +
> > > +#if IS_REACHABLE(CONFIG_TYPEC)
> > > +int drm_aux_hpd_typec_dp_bridge_init(void);
> > > +void drm_aux_hpd_typec_dp_bridge_exit(void);
> > > +#else
> > > +static inline int drm_aux_hpd_typec_dp_bridge_init(void) { return 0; }
> > > +static inline void drm_aux_hpd_typec_dp_bridge_exit(void) { }
> > > +#endif /* IS_REACHABLE(CONFIG_TYPEC) */
> > > +
> > > +#endif /* AUX_HPD_BRIDGE_H */
> > > diff --git a/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c b/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
> > > new file mode 100644
> > > index 000000000000..6f2a1fca0fc5
> > > --- /dev/null
> > > +++ b/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
> > > @@ -0,0 +1,47 @@
> > > +// SPDX-License-Identifier: GPL-2.0+
> > > +#include <linux/of.h>
> > > +#include <linux/usb/typec_altmode.h>
> > > +#include <linux/usb/typec_dp.h>
> > > +#include <linux/usb/typec_notify.h>
> > > +
> > > +#include <drm/bridge/aux-bridge.h>
> > > +
> > > +#include "aux-hpd-bridge.h"
> > > +
> > > +#if IS_REACHABLE(CONFIG_TYPEC)
> > > +static int drm_typec_bus_event(struct notifier_block *nb,
> > > +			       unsigned long action, void *data)
> > > +{
> > This feels like this should be a part of the Type-C subsystem rather
> > than DRM.
> 
> In v7, this used to be a part of the Type-C subsystem. I'm not sure what
> Heikki thinks about this.

Your original proposal of making the entire TYPEC subsystem depend on
DRM is _not_ going to happen. In general, if I've now understood this
correctly, this thing probable should be a "display interface bridge
driver", similar to what you proposed in the previous version.

Note also that you could make it selected automatically, so there is
no need for user selectable option if that's the preference. Kconfig
and Makefile gives you options on how to do that. For example, maybe
this Kconfig works (or does not, but something like it will):

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index a250afd8d662..7487024ba2ce 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -30,6 +30,15 @@ config DRM_AUX_HPD_BRIDGE
          Simple bridge that terminates the bridge chain and provides HPD
          support.
 
+if DRM_AUX_HPD_BRIDGE
+
+config DRM_AUX_HPD_TYPEC_BRIDGE
+       tristate
+       depends on TYPEC || !TYPEC
+       default TYPEC
+
+endif /* DRM_AUX_HPD_BRIDGE */
+
 menu "Display Interface Bridges"
        depends on DRM && DRM_BRIDGE
 


thanks,

-- 
heikki


From lee at kernel.org  Mon Nov  3 07:25:56 2025
From: lee at kernel.org (Lee Jones)
Date: Mon, 3 Nov 2025 15:25:56 +0000
Subject: [PATCH v3 2/5] mfd: Add Rockchip mfpwm driver
In-Reply-To: <16341fe2-7d2b-45a6-a861-93950c1bbd1f@yandex.com>
References: <20251027-rk3576-pwm-v3-0-654a5cb1e3f8@collabora.com>
 <20251027-rk3576-pwm-v3-2-654a5cb1e3f8@collabora.com>
 <16341fe2-7d2b-45a6-a861-93950c1bbd1f@yandex.com>
Message-ID: <20251103152556.GB8064@google.com>

On Tue, 28 Oct 2025, Johan Jonker wrote:

> 
> 
> On 10/27/25 18:11, Nicolas Frattaroli wrote:
> > With the Rockchip RK3576, the PWM IP used by Rockchip has changed
> > substantially. Looking at both the downstream pwm-rockchip driver as
> > well as the mainline pwm-rockchip driver made it clear that with all its
> > additional features and its differences from previous IP revisions, it
> > is best supported in a new driver.
> > 
> > This brings us to the question as to what such a new driver should be.
> > To me, it soon became clear that it should actually be several new
> > drivers, most prominently when Uwe Kleine-K?nig let me know that I
> > should not implement the pwm subsystem's capture callback, but instead
> > write a counter driver for this functionality.
> > 
> > Combined with the other as-of-yet unimplemented functionality of this
> > new IP, it became apparent that it needs to be spread across several
> > subsystems.
> > 
> > For this reason, we add a new MFD core driver, called mfpwm (short for
> > "Multi-function PWM"). This "parent" driver makes sure that only one
> > device function driver is using the device at a time, and is in charge
> > of registering the MFD cell devices for the individual device functions
> > offered by the device.
> > 
> > An acquire/release pattern is used to guarantee that device function
> > drivers don't step on each other's toes.
> > 
> > Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
> > ---
> >  MAINTAINERS                        |   2 +
> >  drivers/mfd/Kconfig                |  15 ++
> >  drivers/mfd/Makefile               |   1 +
> >  drivers/mfd/rockchip-mfpwm.c       | 340 +++++++++++++++++++++++++++
> >  include/linux/mfd/rockchip-mfpwm.h | 454 +++++++++++++++++++++++++++++++++++++
> >  5 files changed, 812 insertions(+)
> > 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index baecabab35a2..8f3235ba825e 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -22372,6 +22372,8 @@ L:	linux-rockchip at lists.infradead.org
> >  L:	linux-pwm at vger.kernel.org
> >  S:	Maintained
> 
> >  F:	Documentation/devicetree/bindings/pwm/rockchip,rk3576-pwm.yaml
> 
> A question not so much for Nicolas specific:
> The yaml documents already have a 'maintainers' entry.
> However MAINTAINERS is full yaml entries.
> Could someone explain why we still need dual registration?
> 
> maintainers:
>   - Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
> 
> > +F:	drivers/soc/rockchip/mfpwm.c
> > +F:	include/soc/rockchip/mfpwm.h
> 
> different file name and location?
> 
>   drivers/mfd/rockchip-mfpwm.c       | 340 +++++++++++++++++++++++++++
>   include/linux/mfd/rockchip-mfpwm.h | 454 +++++++++++++++++++++++++++++++++++++
> 
> 
> >  
> >  ROCKCHIP RK3568 RANDOM NUMBER GENERATOR SUPPORT
> >  M:	Daniel Golle <daniel at makrotopia.org>
> > diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> > index dbeac6825a10..8b3a3160fbdf 100644
> > --- a/drivers/mfd/Kconfig
> > +++ b/drivers/mfd/Kconfig
> > @@ -1367,6 +1367,21 @@ config MFD_RC5T583
> >  	  Additional drivers must be enabled in order to use the
> >  	  different functionality of the device.
> >  
> > +config MFD_ROCKCHIP_MFPWM
> > +	tristate "Rockchip multi-function PWM controller"
> > +	depends on OF
> > +	depends on HAS_IOMEM
> > +	depends on COMMON_CLK
> > +	select MFD_CORE
> > +	help
> > +	  Some Rockchip SoCs, such as the RK3576, use a PWM controller that has
> > +	  several different functions, such as generating PWM waveforms but also
> > +	  counting waveforms.
> > +
> > +	  This driver manages the overall device, and selects between different
> > +	  functionalities at runtime as needed. Drivers for them are implemented
> > +	  in their respective subsystems.
> > +
> >  config MFD_RK8XX
> >  	tristate
> >  	select MFD_CORE
> > diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> > index e75e8045c28a..ebadbaea9e4a 100644
> > --- a/drivers/mfd/Makefile
> > +++ b/drivers/mfd/Makefile
> > @@ -231,6 +231,7 @@ obj-$(CONFIG_MFD_PALMAS)	+= palmas.o
> >  obj-$(CONFIG_MFD_VIPERBOARD)    += viperboard.o
> >  obj-$(CONFIG_MFD_NTXEC)		+= ntxec.o
> >  obj-$(CONFIG_MFD_RC5T583)	+= rc5t583.o rc5t583-irq.o
> > +obj-$(CONFIG_MFD_ROCKCHIP_MFPWM)	+= rockchip-mfpwm.o
> >  obj-$(CONFIG_MFD_RK8XX)		+= rk8xx-core.o
> >  obj-$(CONFIG_MFD_RK8XX_I2C)	+= rk8xx-i2c.o
> >  obj-$(CONFIG_MFD_RK8XX_SPI)	+= rk8xx-spi.o
> > diff --git a/drivers/mfd/rockchip-mfpwm.c b/drivers/mfd/rockchip-mfpwm.c
> > new file mode 100644
> > index 000000000000..08c2d8da41b7
> > --- /dev/null
> > +++ b/drivers/mfd/rockchip-mfpwm.c
> > @@ -0,0 +1,340 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +/*
> > + * Copyright (c) 2025 Collabora Ltd.
> > + *
> > + * A driver to manage all the different functionalities exposed by Rockchip's
> > + * PWMv4 hardware.
> > + *
> > + * This driver is chiefly focused on guaranteeing non-concurrent operation
> > + * between the different device functions, as well as setting the clocks.
> > + * It registers the device function platform devices, e.g. PWM output or
> > + * PWM capture.
> > + *
> > + * Authors:
> > + *     Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
> > + */
> > +
> > +#include <linux/array_size.h>
> > +#include <linux/clk.h>
> > +#include <linux/clk-provider.h>
> > +#include <linux/mfd/core.h>
> > +#include <linux/mfd/rockchip-mfpwm.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/overflow.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/spinlock.h>
> > +
> > +/**
> > + * struct rockchip_mfpwm - private mfpwm driver instance state struct
> > + * @pdev: pointer to this instance's &struct platform_device
> > + * @base: pointer to the memory mapped registers of this device
> > + * @pwm_clk: pointer to the PLL clock the PWM signal may be derived from
> > + * @osc_clk: pointer to the fixed crystal the PWM signal may be derived from
> > + * @rc_clk: pointer to the RC oscillator the PWM signal may be derived from
> > + * @chosen_clk: a clk-mux of pwm_clk, osc_clk and rc_clk
> > + * @pclk: pointer to the APB bus clock needed for mmio register access
> > + * @active_func: pointer to the currently active device function, or %NULL if no
> > + *               device function is currently actively using any of the shared
> > + *               resources. May only be checked/modified with @state_lock held.
> > + * @acquire_cnt: number of times @active_func has currently mfpwm_acquire()'d
> > + *               it. Must only be checked or modified while holding @state_lock.
> > + * @state_lock: this lock is held while either the active device function, the
> > + *              enable register, or the chosen clock is being changed.
> > + * @irq: the IRQ number of this device
> > + */
> > +struct rockchip_mfpwm {
> > +	struct platform_device *pdev;
> > +	void __iomem *base;
> > +	struct clk *pwm_clk;
> > +	struct clk *osc_clk;
> > +	struct clk *rc_clk;
> > +	struct clk *chosen_clk;
> > +	struct clk *pclk;
> > +	struct rockchip_mfpwm_func *active_func;
> > +	unsigned int acquire_cnt;
> > +	spinlock_t state_lock;
> > +	int irq;
> > +};
> > +
> > +static atomic_t subdev_id = ATOMIC_INIT(0);
> > +
> > +static inline struct rockchip_mfpwm *to_rockchip_mfpwm(struct platform_device *pdev)
> > +{
> > +	return platform_get_drvdata(pdev);
> > +}
> > +
> > +static int mfpwm_check_pwmf(const struct rockchip_mfpwm_func *pwmf,
> > +			    const char *fname)
> > +{
> > +	struct device *dev = &pwmf->parent->pdev->dev;
> > +
> > +	if (IS_ERR_OR_NULL(pwmf)) {
> > +		dev_warn(dev, "called %s with an erroneous handle, no effect\n",
> > +			 fname);
> > +		return -EINVAL;
> > +	}
> > +
> > +	if (IS_ERR_OR_NULL(pwmf->parent)) {
> > +		dev_warn(dev, "called %s with an erroneous mfpwm_func parent, no effect\n",
> > +			 fname);
> > +		return -EINVAL;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +__attribute__((nonnull))
> > +static int mfpwm_do_acquire(struct rockchip_mfpwm_func *pwmf)
> > +{
> > +	struct rockchip_mfpwm *mfpwm = pwmf->parent;
> > +	unsigned int cnt;
> > +
> > +	if (mfpwm->active_func && pwmf->id != mfpwm->active_func->id)
> > +		return -EBUSY;
> > +
> > +	if (!mfpwm->active_func)
> > +		mfpwm->active_func = pwmf;
> > +
> > +	if (!check_add_overflow(mfpwm->acquire_cnt, 1, &cnt)) {
> > +		mfpwm->acquire_cnt = cnt;
> > +	} else {
> > +		dev_warn(&mfpwm->pdev->dev, "prevented acquire counter overflow in %s\n",
> > +			 __func__);
> > +		return -EOVERFLOW;
> > +	}
> > +
> > +	dev_dbg(&mfpwm->pdev->dev, "%d acquired mfpwm, acquires now at %u\n",
> > +		pwmf->id, mfpwm->acquire_cnt);
> > +
> > +	return clk_enable(mfpwm->pclk);
> > +}
> > +
> > +int mfpwm_acquire(struct rockchip_mfpwm_func *pwmf)
> > +{
> > +	struct rockchip_mfpwm *mfpwm;
> > +	unsigned long flags;
> > +	int ret = 0;
> > +
> > +	ret = mfpwm_check_pwmf(pwmf, "mfpwm_acquire");
> > +	if (ret)
> > +		return ret;
> > +
> > +	mfpwm = pwmf->parent;
> > +	dev_dbg(&mfpwm->pdev->dev, "%d is attempting to acquire\n", pwmf->id);
> > +
> > +	if (!spin_trylock_irqsave(&mfpwm->state_lock, flags))
> > +		return -EBUSY;
> > +
> > +	ret = mfpwm_do_acquire(pwmf);
> > +
> > +	spin_unlock_irqrestore(&mfpwm->state_lock, flags);
> > +
> > +	return ret;
> > +}
> > +EXPORT_SYMBOL_NS_GPL(mfpwm_acquire, "ROCKCHIP_MFPWM");
> > +
> > +__attribute__((nonnull))
> > +static void mfpwm_do_release(const struct rockchip_mfpwm_func *pwmf)
> > +{
> > +	struct rockchip_mfpwm *mfpwm = pwmf->parent;
> > +
> > +	if (!mfpwm->active_func)
> > +		return;
> > +
> > +	if (mfpwm->active_func->id != pwmf->id)
> > +		return;
> > +
> > +	/*
> > +	 * No need to check_sub_overflow here, !mfpwm->active_func above catches
> > +	 * this type of problem already.
> > +	 */
> > +	mfpwm->acquire_cnt--;
> > +
> > +	if (!mfpwm->acquire_cnt)
> > +		mfpwm->active_func = NULL;
> > +
> > +	clk_disable(mfpwm->pclk);
> > +}
> > +
> > +void mfpwm_release(const struct rockchip_mfpwm_func *pwmf)
> > +{
> > +	struct rockchip_mfpwm *mfpwm;
> > +	unsigned long flags;
> > +
> > +	if (mfpwm_check_pwmf(pwmf, "mfpwm_release"))
> > +		return;
> > +
> > +	mfpwm = pwmf->parent;
> > +
> > +	spin_lock_irqsave(&mfpwm->state_lock, flags);
> > +	mfpwm_do_release(pwmf);
> > +	dev_dbg(&mfpwm->pdev->dev, "%d released mfpwm, acquires now at %u\n",
> > +		pwmf->id, mfpwm->acquire_cnt);
> > +	spin_unlock_irqrestore(&mfpwm->state_lock, flags);
> > +}
> > +EXPORT_SYMBOL_NS_GPL(mfpwm_release, "ROCKCHIP_MFPWM");
> > +
> > +/**
> > + * mfpwm_register_subdev - register a single mfpwm_func
> > + * @mfpwm: pointer to the parent &struct rockchip_mfpwm
> > + * @name: sub-device name string
> > + *
> > + * Allocate a single &struct mfpwm_func, fill its members with appropriate data,
> > + * and register a new mfd cell.
> > + *
> > + * Returns: 0 on success, negative errno on error
> > + */
> > +static int mfpwm_register_subdev(struct rockchip_mfpwm *mfpwm,
> > +				 const char *name)
> > +{
> > +	struct rockchip_mfpwm_func *func;
> > +	struct mfd_cell cell = {};
> > +
> > +	func = devm_kzalloc(&mfpwm->pdev->dev, sizeof(*func), GFP_KERNEL);
> > +	if (IS_ERR(func))
> > +		return PTR_ERR(func);
> > +	func->irq = mfpwm->irq;
> > +	func->parent = mfpwm;
> > +	func->id = atomic_inc_return(&subdev_id);
> > +	func->base = mfpwm->base;
> > +	func->core = mfpwm->chosen_clk;
> > +	cell.name = name;
> > +	cell.platform_data = func;
> > +	cell.pdata_size = sizeof(*func);
> > +	// cell.ignore_resource_conflicts = true;
> > +	// cell.resources = mfpwm->pdev->resource;
> > +	// cell.num_resources = mfpwm->pdev->num_resources;
> > +
> > +	return devm_mfd_add_devices(&mfpwm->pdev->dev, func->id, &cell, 1, NULL,
> > +				    0, NULL);
> > +}
> > +
> > +static int mfpwm_register_subdevs(struct rockchip_mfpwm *mfpwm)
> > +{
> > +	int ret;
> > +
> 
> > +	ret = mfpwm_register_subdev(mfpwm, "pwm-rockchip-v4");
> 
> Not sure who came up with this name?
> In case we need to filter wouldn't be easier to order it just like the bindings: manufacture '-' function

Please snip your replies in the future.

-- 
Lee Jones [???]


From coiaprant at gmail.com  Mon Nov  3 09:16:59 2025
From: coiaprant at gmail.com (Coia Prant)
Date: Tue,  4 Nov 2025 01:16:59 +0800
Subject: [PATCH v5 0/3] Add devicetree for the 9Tripod X3568 v4
Message-ID: <20251103171702.1518730-1-coiaprant@gmail.com>

Change in v2:
- Add vendor 'ninetripod' to board filename
  > 'x3568_v4' => 'ninetripod_x3568_v4'

Change in v3:
- Fix Makefile

Change in v4:
- Fix overlay dtso

Change in v5:
- Rename 'ninetripod' to '9tripod'
- Add rtc0 to alias
- Fix PCIe regulators node
  > Test passed with CLK missing and CLK installed.
  > No boot issue observed.
- Replace ethernet MDIO PHY
  > mdio0: phy0 => phy3
  > mdio1: phy0 => phy2
  > All point to the same device.
  > Rockchip's phy0 appears to be a universal PHY.

Coia Prant (3):
  dt-bindings: vendor-prefixes: Add 9Tripod
  dt-bindings: arm: rockchip: Add 9Tripod X3568 series
  arm64: dts: rockchip: Add devicetree for the 9Tripod X3568 v4

 .../devicetree/bindings/arm/rockchip.yaml     |   6 +
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 arch/arm64/boot/dts/rockchip/Makefile         |  11 +
 .../rk3568-9tripod-x3568-v4-camera-demo.dtso  |  84 ++
 .../rk3568-9tripod-x3568-v4-video-demo.dtso   | 154 +++
 .../dts/rockchip/rk3568-9tripod-x3568-v4.dts  | 887 ++++++++++++++++++
 6 files changed, 1144 insertions(+)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4-camera-demo.dtso
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4-video-demo.dtso
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4.dts

-- 
2.47.3



From coiaprant at gmail.com  Mon Nov  3 09:17:00 2025
From: coiaprant at gmail.com (Coia Prant)
Date: Tue,  4 Nov 2025 01:17:00 +0800
Subject: [PATCH v5 1/3] dt-bindings: vendor-prefixes: Add 9Tripod
In-Reply-To: <20251103171702.1518730-1-coiaprant@gmail.com>
References: <20251103171702.1518730-1-coiaprant@gmail.com>
Message-ID: <20251103171702.1518730-2-coiaprant@gmail.com>

Add 9Tripod to the vendor prefixes.

Signed-off-by: Coia Prant <coiaprant at gmail.com>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index f1d188200..97b169f63 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -30,6 +30,8 @@ patternProperties:
     description: 70mai Co., Ltd.
   "^8dev,.*":
     description: 8devices, UAB
+  "^9tripod,.*":
+    description: Shenzhen 9Tripod Innovation and Development CO., LTD.
   "^abb,.*":
     description: ABB
   "^abilis,.*":
-- 
2.47.3



From coiaprant at gmail.com  Mon Nov  3 09:17:01 2025
From: coiaprant at gmail.com (Coia Prant)
Date: Tue,  4 Nov 2025 01:17:01 +0800
Subject: [PATCH v5 2/3] dt-bindings: arm: rockchip: Add 9Tripod X3568 series
In-Reply-To: <20251103171702.1518730-1-coiaprant@gmail.com>
References: <20251103171702.1518730-1-coiaprant@gmail.com>
Message-ID: <20251103171702.1518730-3-coiaprant@gmail.com>

This documents 9Tripod X3568 v4 which is a SBC based on RK3568 SoC.

Link: http://www.9tripod.com/showpro.php?id=117
Link: https://appletsapi.52solution.com/media/X3568V4%E5%BC%80%E5%8F%91%E6%9D%BF%E7%A1%AC%E4%BB%B6%E6%89%8B%E5%86%8C.pdf

Signed-off-by: Coia Prant <coiaprant at gmail.com>
---
 Documentation/devicetree/bindings/arm/rockchip.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
index 6aceaa8ac..9b9b3d2c0 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.yaml
+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
@@ -25,6 +25,12 @@ properties:
           - const: vamrs,rock960
           - const: rockchip,rk3399
 
+      - description: 9Tripod X3568 series board
+        items:
+          - enum:
+              - 9tripod,x3568-v4
+          - const: rockchip,rk3568
+
       - description: Amarula Vyasa RK3288
         items:
           - const: amarula,vyasa-rk3288
-- 
2.47.3



From coiaprant at gmail.com  Mon Nov  3 09:17:02 2025
From: coiaprant at gmail.com (Coia Prant)
Date: Tue,  4 Nov 2025 01:17:02 +0800
Subject: [PATCH v5 3/3] arm64: dts: rockchip: Add devicetree for the 9Tripod X3568 v4
In-Reply-To: <20251103171702.1518730-1-coiaprant@gmail.com>
References: <20251103171702.1518730-1-coiaprant@gmail.com>
Message-ID: <20251103171702.1518730-4-coiaprant@gmail.com>

The 9Tripod X3568 v4 is an RK3568-based SBC, just like the RK3568-EVB.
It always uses soldered connections between the X3568CV2/X3568CV3/X3568CV4 core board
and the X3568bv4 I/O board.

The differences between the core boards
- PCB size, layout
- CPU (RKK3568B2/RK3568J)
- Memory type (DDR4/LPDDR4/LPDDR4X) and size
- eMMC size
- DSI/EDP resistor values
Although the components vary, they maintain full compatibility.

The X3568 board has multiple hardware revisions, and we currently support v4 (I/O board).

Specification:
- SoC: RockChip RK3568 ARM64 (4 cores)
- eMMC: 16-128 GB
- RAM: 2-16 GB
- Power: DC 12V 2A
- Ethernet: 2x YT8521SC RGMII (10/100/1000 Mbps)
- Wireless radio: 802.11b/g/n/ac/ax dual-band
- LED:
  Power: AlwaysOn
  User: GPIO
- Button:
  VOL+: SARADC/0 <35k ?V>
  VOL-: SARADC/0 <450k ?V>
  Power/Reset: PMIC RK809
- CAN
  CAN/1: 4-pin (PH 2.0)
- PWM
  PWM/4: Backlight DSI/0 DSI/1
  PWM/7: IR Receiver [may not install]
- UART:
  UART/2: Debug TTL - 1500000 8N1 (1.25mm)
  UART/3: TTL (PH 2.0)
  UART/4: TTL (PH 2.0)
  UART/8: AP6275S Bluetooth
  UART/9: TTL (PH 2.0)
- I2C:
  I2C/0: PMIC RK809
  I2C/1: Touchscreen DSI/0 DSI/1
  I2C/4: Camera
  I2C/5: RTC at 51 PCF8563
- I2S:
  I2S/0: miniHDMI Sound
  I2S/1: RK809 Audio Codec
  I2S/3: AP6275S Bluetooth Sound
- SDMMC:
  SDMMC/0: microSD (TF) slot
  SDMMC/2: AP6275S SDIO WiFi card
- Camera: 1x CSI
- Video: miniHDMI / DSI0 (MIPI/LVDS) / DSI1 (MIPI/EDP)
- Audio: miniHDMI / MIC on-board / Speaker / SPDIF / 3.5mm Headphones / AP6275S Bluetooth
- USB:
  USB 2.0 HOST x2
  USB 2.0 HOST x3 (4-pin)
  USB 2.0 OTG x1 (shared with USB 3.0 OTG/HOST) [slot may not install]
  USB 3.0 HOST x1
  USB 3.0 OTG/HOST x1
- SATA: 1x SATA 3.0 with Power/4-pin [slot may not install]
- PCIe: 1x PCIe 3.0 x2 (x4 connecter) [power/clock/slot may not install]

Link:
- https://appletsapi.52solution.com/media/X3568V4%E5%BC%80%E5%8F%91%E6%9D%BF%E7%A1%AC%E4%BB%B6%E6%89%8B%E5%86%8C.pdf
- https://blog.gov.cooking/archives/research-ninetripod-x3568-v4-and-flash.html

Signed-off-by: Coia Prant <coiaprant at gmail.com>
---
 arch/arm64/boot/dts/rockchip/Makefile         |  11 +
 .../rk3568-9tripod-x3568-v4-camera-demo.dtso  |  84 ++
 .../rk3568-9tripod-x3568-v4-video-demo.dtso   | 154 +++
 .../dts/rockchip/rk3568-9tripod-x3568-v4.dts  | 887 ++++++++++++++++++
 4 files changed, 1136 insertions(+)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4-camera-demo.dtso
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4-video-demo.dtso
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4.dts

diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index ad684e383..959a806a2 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -130,6 +130,9 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-lubancat-1.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-nanopi-r3s.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-bigtreetech-cb2-manta.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-bigtreetech-pi2.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-9tripod-x3568-v4.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-9tripod-x3568-v4-camera-demo.dtbo
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-9tripod-x3568-v4-video-demo.dtbo
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-bpi-r2-pro.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-v10.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-fastrhino-r66s.dtb
@@ -252,6 +255,14 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-armsom-sige5-v1.2-wifibt.dtb
 rk3576-armsom-sige5-v1.2-wifibt-dtbs := rk3576-armsom-sige5.dtb \
 	rk3576-armsom-sige5-v1.2-wifibt.dtbo
 
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-9tripod-x3568-v4-camera-demo.dtb
+rk3568-9tripod-x3568-v4-camera-demo-dtbs := rk3568-9tripod-x3568-v4.dtb \
+	rk3568-9tripod-x3568-v4-camera-demo.dtbo
+
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-9tripod-x3568-v4-video-demo.dtb
+rk3568-9tripod-x3568-v4-video-demo-dtbs := rk3568-9tripod-x3568-v4.dtb \
+	rk3568-9tripod-x3568-v4-video-demo.dtbo
+
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-edgeble-neu6a-wifi.dtb
 rk3588-edgeble-neu6a-wifi-dtbs := rk3588-edgeble-neu6a-io.dtb \
 	rk3588-edgeble-neu6a-wifi.dtbo
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4-camera-demo.dtso b/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4-camera-demo.dtso
new file mode 100644
index 000000000..2b428ca71
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4-camera-demo.dtso
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+
+// This is a sample reference, due to lack of hardware can not be tested, at your own risk
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/rk3568-cru.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+
+&{/} {
+	vcc_cam: regulator-vcc-cam {
+		compatible = "regulator-fixed";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		enable-active-high;
+		gpio = <&gpio0 RK_PC1 GPIO_ACTIVE_HIGH>;
+		regulator-name = "vcc_cam";
+		vin-supply = <&vcc3v3_sys>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc_cam_en>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+};
+
+&pinctrl {
+	cam {
+		vcc_cam_en: vcc_cam_en {
+			rockchip,pins =	<0 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
+
+&csi_dphy {
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port at 0 {
+			reg = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			mipi_in_ucam: endpoint at 2 {
+				reg = <2>;
+				remote-endpoint = <&ucam_out>;
+				data-lanes = <1 2 3 4>;
+			};
+		};
+	};
+};
+
+&i2c4 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+
+	camera at 37 {
+		compatible = "ovti,ov5695";
+		reg = <0x37>;
+		clocks = <&cru CLK_CIF_OUT>;
+		clock-names = "xvclk";
+		avdd-supply = <&vcc_cam>;
+		dvdd-supply = <&vcc_cam>;
+		dovdd-supply = <&vcc_cam>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&cif_clk>;
+		reset-gpios = <&gpio3 RK_PB6 GPIO_ACTIVE_LOW>;
+		pwdn-gpios = <&gpio4 RK_PB4 GPIO_ACTIVE_LOW>;
+
+		port {
+			ucam_out: endpoint {
+				remote-endpoint = <&mipi_in_ucam>;
+				data-lanes = <1 2 3 4>;
+			};
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4-video-demo.dtso b/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4-video-demo.dtso
new file mode 100644
index 000000000..e7fa1ca48
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4-video-demo.dtso
@@ -0,0 +1,154 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+
+// This is a sample reference, due to lack of hardware can not be tested, at your own risk
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/rk3568-cru.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
+
+&{/} {	
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		brightness-levels = <20 220>;
+		default-brightness-level = <100>;
+		num-interpolated-steps = <200>;
+		power-supply = <&vcc3v3_sys>;
+		pwms = <&pwm4 0 25000 0>;
+	};
+
+	vcc3v3_lcd0_n: regulator-vcc3v3-lcd0-n {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3_lcd0_n";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		enable-active-high;
+		gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
+		vin-supply = <&vcc3v3_sys>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc3v3_lcd0_n_en>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+
+	vcc3v3_lcd1_n: regulator-vcc3v3-lcd1-n {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3_lcd1_n";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		enable-active-high;
+		gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
+		vin-supply = <&vcc3v3_sys>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc3v3_lcd1_n_en>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+};
+
+&pinctrl {
+	display {
+		vcc3v3_lcd0_n_en: vcc3v3_lcd0_n_en {
+			rockchip,pins = <0 RK_PC7 0 &pcfg_pull_none>;
+		};
+		vcc3v3_lcd1_n_en: vcc3v3_lcd1_n_en {
+			rockchip,pins = <0 RK_PC5 0 &pcfg_pull_none>;
+		};
+	};
+
+	touchscreen {
+		touch_int: touch_int {
+			rockchip,pins = <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+		touch_rst: touch_rst {
+			rockchip,pins = <0 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
+
+&dsi0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	clock-master;
+	status = "okay";
+
+	panel at 0 {
+		compatible = "wanchanglong,w552793baa", "raydium,rm67200";
+		reg = <0>;
+		backlight = <&backlight>;
+		iovcc-supply = <&vcc3v3_lcd0_n>;
+		reset-gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_LOW>;
+		vdd-supply = <&vcc3v3_lcd0_n>;
+		vsn-supply = <&vcc5v0_sys>;
+		vsp-supply = <&vcc5v0_sys>;
+
+		port {
+			panel_in_dsi: endpoint {
+				remote-endpoint = <&dsi0_out_panel>;
+			};
+		};
+	};
+};
+
+&dsi0_in {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	dsi0_in_vp1: endpoint {
+		remote-endpoint = <&vp1_out_dsi0>;
+	};
+};
+
+&dsi0_out {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	dsi0_out_panel: endpoint {
+		remote-endpoint = <&panel_in_dsi>;
+	};
+};
+
+&dsi_dphy0 {
+	status = "okay";
+};
+
+&pwm4 {
+	status = "okay";
+};
+
+&i2c1 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+
+	touchscreen0: goodix at 14 {
+		compatible = "goodix,gt1151";
+		reg = <0x14>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PB5 IRQ_TYPE_EDGE_FALLING>;
+		AVDD28-supply = <&vcc3v3_lcd0_n>;
+		irq-gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&touch_int &touch_rst>;
+		reset-gpios = <&gpio0 RK_PB6 GPIO_ACTIVE_LOW>;
+		VDDIO-supply = <&vcc3v3_lcd0_n>;
+	};
+};
+
+&vp1 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	vp1_out_dsi0: endpoint at ROCKCHIP_VOP2_EP_MIPI0 {
+		reg = <ROCKCHIP_VOP2_EP_MIPI0>;
+		remote-endpoint = <&dsi0_in_vp1>;
+	};
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4.dts b/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4.dts
new file mode 100644
index 000000000..443ed7d4b
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4.dts
@@ -0,0 +1,887 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
+#include "rk3568.dtsi"
+
+/ {
+	model = "9Tripod X3568 v4";
+	compatible = "9tripod,x3568-v4", "rockchip,rk3568";
+
+	aliases {
+		ethernet0 = &gmac0;
+		ethernet1 = &gmac1;
+		mmc0 = &sdhci;
+		mmc1 = &sdmmc0;
+		mmc2 = &sdmmc2;
+		rtc0 = &rtc0;
+	};
+
+	chosen {
+		stdout-path = "serial2:1500000n8";
+	};
+
+	adc-keys {
+		compatible = "adc-keys";
+		io-channels = <&saradc 0>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <1800000>;
+		poll-interval = <100>;
+
+		button-vol-up {
+			label = "volume up";
+			linux,code = <KEY_VOLUMEUP>;
+			press-threshold-microvolt = <50000>;
+		};
+
+		button-vol-down {
+			label = "volume down";
+			linux,code = <KEY_VOLUMEDOWN>;
+			press-threshold-microvolt = <500000>;
+		};
+	};
+
+	hdmi-con {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_work: led-0 {
+			gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>;
+			function = LED_FUNCTION_HEARTBEAT;
+			color = <LED_COLOR_ID_BLUE>;
+			linux,default-trigger = "heartbeat";
+			pinctrl-names = "default";
+			pinctrl-0 = <&led_work_en>;
+		};
+	};
+
+	rk809-sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,format = "i2s";
+		simple-audio-card,name = "Analog RK809";
+		simple-audio-card,mclk-fs = <256>;
+
+		simple-audio-card,cpu {
+			sound-dai = <&i2s1_8ch>;
+		};
+		simple-audio-card,codec {
+			sound-dai = <&rk809>;
+		};
+	};
+
+	pdm_codec: pdm-codec {
+		compatible = "dmic-codec";
+		num-channels = <2>;
+		#sound-dai-cells = <0>;
+	};
+
+	pdm_sound: pdm-sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "microphone";
+
+		simple-audio-card,cpu {
+			sound-dai = <&pdm>;
+		};
+
+		simple-audio-card,codec {
+			sound-dai = <&pdm_codec>;
+		};
+	};
+
+	spdif_dit: spdif-dit {
+		compatible = "linux,spdif-dit";
+		#sound-dai-cells = <0>;
+	};
+
+	spdif_sound: spdif-sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "SPDIF";
+
+		simple-audio-card,cpu {
+			sound-dai = <&spdif>;
+		};
+		simple-audio-card,codec {
+			sound-dai = <&spdif_dit>;
+		};
+	};
+
+	sdio_pwrseq: sdio-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		clocks = <&rk809 1>;
+		clock-names = "ext_clock";
+		pinctrl-names = "default";
+		pinctrl-0 = <&wifi_enable>;
+		post-power-on-delay-ms = <100>;
+		power-off-delay-us = <300>;
+		reset-gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_LOW>;
+	};
+
+	dc_12v: regulator-dc-12v {
+		compatible = "regulator-fixed";
+		regulator-name = "dc_12v";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+	};
+
+	pcie30_avdd0v9: regulator-pcie30-avdd0v9 {
+		compatible = "regulator-fixed";
+		regulator-name = "pcie30_avdd0v9";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <900000>;
+		regulator-max-microvolt = <900000>;
+		vin-supply = <&vcc3v3_sys>;
+	};
+
+	pcie30_avdd1v8: regulator-pcie30-avdd1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "pcie30_avdd1v8";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&vcc3v3_sys>;
+	};
+
+	vcc3v3_sys: regulator-vcc3v3-sys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&dc_12v>;
+	};
+
+	vcc3v3_pcie: regulator-vcc3v3-pcie {
+		compatible = "regulator-gpio";
+		regulator-name = "vcc3v3_pcie";
+		regulator-min-microvolt = <100000>;
+		regulator-max-microvolt = <3300000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc3v3_pcie_en_pin>;
+		gpios = <&gpio3 RK_PC3 GPIO_ACTIVE_HIGH>;
+		gpios-states = <1>;
+		states = <100000 0>, <3300000 1>;
+		startup-delay-us = <5000>;
+	};
+
+	vcc5v0_sys: regulator-vcc5v0-sys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&dc_12v>;
+	};
+
+	vcc5v0_usb: regulator-vcc5v0-usb {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_usb";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&dc_12v>;
+	};
+
+	vcc5v0_usb_host: regulator-vcc5v0-usb-host {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc5v0_usb_host_en>;
+		regulator-name = "vcc5v0_usb_host";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc5v0_usb>;
+	};
+
+	vcc5v0_usb_otg: regulator-vcc5v0-usb-otg {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc5v0_usb_otg_en>;
+		regulator-name = "vcc5v0_usb_otg";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc5v0_usb>;
+	};
+};
+
+&can1 {
+	assigned-clocks = <&cru CLK_CAN1>;
+	assigned-clock-rates = <150000000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&can1m1_pins>;
+	status = "okay";
+};
+
+/* used for usb_host0_xhci */
+&combphy0 {
+	status = "okay";
+};
+
+/* used for usb_host1_xhci */
+&combphy1 {
+	status = "okay";
+};
+
+/* connected to sata2 */
+&combphy2 {
+	status = "okay";
+};
+
+&cpu0 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu1 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu2 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu3 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&gmac0 {
+	assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>;
+	assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>;
+	assigned-clock-rates = <0>, <125000000>;
+	clock_in_out = "output";
+	pinctrl-names = "default";
+	pinctrl-0 = <&gmac0_miim
+			&gmac0_tx_bus2
+			&gmac0_rx_bus2
+			&gmac0_rgmii_clk
+			&gmac0_rgmii_bus
+			&gmac0_clkinout>;
+	phy-handle = <&rgmii_phy0>;
+	phy-mode = "rgmii-id";
+	status = "okay";
+};
+
+&gmac1 {
+	assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
+	assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>;
+	assigned-clock-rates = <0>, <125000000>;
+	clock_in_out = "output";
+	pinctrl-names = "default";
+	pinctrl-0 = <&gmac1m1_miim
+			&gmac1m1_tx_bus2
+			&gmac1m1_rx_bus2
+			&gmac1m1_rgmii_clk
+			&gmac1m1_rgmii_bus
+			&gmac1m1_clkinout>;
+	phy-handle = <&rgmii_phy1>;
+	phy-mode = "rgmii-id";
+	status = "okay";
+};
+
+&gpu {
+	mali-supply = <&vdd_gpu>;
+	status = "okay";
+};
+
+&hdmi {
+	avdd-0v9-supply = <&vdda0v9_image>;
+	avdd-1v8-supply = <&vcca1v8_image>;
+	status = "okay";
+};
+
+&hdmi_in {
+	hdmi_in_vp0: endpoint {
+		remote-endpoint = <&vp0_out_hdmi>;
+	};
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
+&hdmi_sound {
+	status = "okay";
+};
+
+&i2c0 {
+	status = "okay";
+
+	vdd_cpu: regulator at 1c {
+		compatible = "tcs,tcs4525";
+		reg = <0x1c>;
+		fcs,suspend-voltage-selector = <1>;
+		regulator-name = "vdd_cpu";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <800000>;
+		regulator-max-microvolt = <1150000>;
+		regulator-ramp-delay = <2300>;
+		vin-supply = <&vcc5v0_sys>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+
+	rk809: pmic at 20 {
+		compatible = "rockchip,rk809";
+		reg = <0x20>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
+		assigned-clocks = <&cru I2S1_MCLKOUT_TX>;
+		assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>;
+		#clock-cells = <1>;
+		clock-names = "mclk";
+		clocks = <&cru I2S1_MCLKOUT_TX>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_int>, <&i2s1m0_mclk>;
+		system-power-controller;
+		#sound-dai-cells = <0>;
+		vcc1-supply = <&vcc3v3_sys>;
+		vcc2-supply = <&vcc3v3_sys>;
+		vcc3-supply = <&vcc3v3_sys>;
+		vcc4-supply = <&vcc3v3_sys>;
+		vcc5-supply = <&vcc3v3_sys>;
+		vcc6-supply = <&vcc3v3_sys>;
+		vcc7-supply = <&vcc3v3_sys>;
+		vcc8-supply = <&vcc3v3_sys>;
+		vcc9-supply = <&vcc3v3_sys>;
+		wakeup-source;
+
+		regulators {
+			vdd_logic: DCDC_REG1 {
+				regulator-name = "vdd_logic";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-initial-mode = <0x2>;
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_gpu: DCDC_REG2 {
+				regulator-name = "vdd_gpu";
+				regulator-always-on;
+				regulator-initial-mode = <0x2>;
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_ddr: DCDC_REG3 {
+				regulator-name = "vcc_ddr";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-initial-mode = <0x2>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			vdd_npu: DCDC_REG4 {
+				regulator-name = "vdd_npu";
+				regulator-initial-mode = <0x2>;
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_1v8: DCDC_REG5 {
+				regulator-name = "vcc_1v8";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda0v9_image: LDO_REG1 {
+				regulator-name = "vdda0v9_image";
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda_0v9: LDO_REG2 {
+				regulator-name = "vdda_0v9";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda0v9_pmu: LDO_REG3 {
+				regulator-name = "vdda0v9_pmu";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <900000>;
+				};
+			};
+
+			vccio_acodec: LDO_REG4 {
+				regulator-name = "vccio_acodec";
+				regulator-always-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vccio_sd: LDO_REG5 {
+				regulator-name = "vccio_sd";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc3v3_pmu: LDO_REG6 {
+				regulator-name = "vcc3v3_pmu";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vcca_1v8: LDO_REG7 {
+				regulator-name = "vcca_1v8";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcca1v8_pmu: LDO_REG8 {
+				regulator-name = "vcca1v8_pmu";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vcca1v8_image: LDO_REG9 {
+				regulator-name = "vcca1v8_image";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_3v3: SWITCH_REG1 {
+				regulator-name = "vcc_3v3";
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc3v3_sd: SWITCH_REG2 {
+				regulator-name = "vcc3v3_sd";
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+		};
+
+		codec {
+			rockchip,mic-in-differential;
+		};
+	};
+};
+
+&i2c5 {
+	status = "okay";
+
+	rtc0: rtc at 51 {
+		compatible = "nxp,pcf8563";
+		reg = <0x51>;
+		#clock-cells = <0>;
+	};
+};
+
+&i2s0_8ch {
+	status = "okay";
+};
+
+&i2s1_8ch {
+	pinctrl-0 = <&i2s1m0_sclktx &i2s1m0_lrcktx &i2s1m0_sdi0 &i2s1m0_sdo0>;
+	rockchip,trcm-sync-tx-only;
+	status = "okay";
+};
+
+/* used for AP6275S Bluetooth Sound */
+&i2s3_2ch {
+	status = "okay";
+};
+
+&mdio0 {
+	rgmii_phy0: ethernet-phy at 3 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <3>;
+		reset-assert-us = <20000>;
+		reset-deassert-us = <100000>;
+		reset-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_LOW>;
+
+		leds {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			led at 1 {
+				reg = <1>;
+				color = <LED_COLOR_ID_GREEN>;
+				function = LED_FUNCTION_LAN;
+				default-state = "keep";
+			};
+
+			/* Note: The LED polarity is inverted */
+			led at 2 {
+				reg = <2>;
+				color = <LED_COLOR_ID_AMBER>;
+				function = LED_FUNCTION_LAN;
+				default-state = "keep";
+			};
+		};
+	};
+};
+
+&mdio1 {
+	rgmii_phy1: ethernet-phy at 2 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <2>;
+		reset-assert-us = <20000>;
+		reset-deassert-us = <100000>;
+		reset-gpios = <&gpio2 RK_PD1 GPIO_ACTIVE_LOW>;
+
+		leds {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			led at 1 {
+				reg = <1>;
+				color = <LED_COLOR_ID_GREEN>;
+				function = LED_FUNCTION_LAN;
+				default-state = "keep";
+			};
+
+			/* Note: The LED polarity is inverted */
+			led at 2 {
+				reg = <2>;
+				color = <LED_COLOR_ID_AMBER>;
+				function = LED_FUNCTION_LAN;
+				default-state = "keep";
+			};
+		};
+	};
+};
+
+&pcie30phy {
+	status = "okay";
+};
+
+&pcie3x2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie_reset_pin>;
+	reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_HIGH>;
+	vpcie3v3-supply = <&vcc3v3_pcie>;
+	status = "okay";
+};
+
+&pdm {
+	status = "okay";
+};
+
+&pinctrl {
+	leds {
+		led_work_en: led_work_en {
+			rockchip,pins = <0 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	pmic {
+		pmic_int: pmic_int {
+			rockchip,pins =
+				<0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	sdio-pwrseq {
+		wifi_enable: wifi-enable {
+			rockchip,pins = <3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	usb {
+		vcc5v0_usb_host_en: vcc5v0_usb_host_en {
+			rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+		vcc5v0_usb_otg_en: vcc5v0_usb_otg_en {
+			rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	pcie {
+		pcie_reset_pin: pcie-reset-pin {
+			rockchip,pins = <2 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+		vcc3v3_pcie_en_pin: vcc3v3-pcie-en-pin {
+			rockchip,pins = <3 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
+
+&pmu_io_domains {
+	pmuio1-supply = <&vcc3v3_pmu>;
+	pmuio2-supply = <&vcc3v3_pmu>;
+	vccio1-supply = <&vccio_acodec>;
+	vccio2-supply = <&vcc_1v8>;
+	vccio3-supply = <&vccio_sd>;
+	vccio4-supply = <&vcc_1v8>;
+	vccio5-supply = <&vcc_3v3>;
+	vccio6-supply = <&vcc_1v8>;
+	vccio7-supply = <&vcc_3v3>;
+	status = "okay";
+};
+
+&pwm4 {
+	status = "okay";
+};
+
+/* Required remotectl for IR receiver */
+&pwm7 {
+	status = "disabled";
+};
+
+&saradc {
+	vref-supply = <&vcca_1v8>;
+	status = "okay";
+};
+
+&sata2 {
+	status = "okay";
+};
+
+/* used for eMMC */
+&sdhci {
+	bus-width = <8>;
+	max-frequency = <200000000>;
+	mmc-hs200-1_8v;
+	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
+	status = "okay";
+};
+
+/* used for microSD (TF) Slot */
+&sdmmc0 {
+	bus-width = <4>;
+	cap-sd-highspeed;
+	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
+	disable-wp;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
+	sd-uhs-sdr104;
+	vmmc-supply = <&vcc3v3_sd>;
+	vqmmc-supply = <&vccio_sd>;
+	status = "okay";
+};
+
+/* used for AP6275S WiFi */
+&sdmmc2 {
+	bus-width = <4>;
+	disable-wp;
+	cap-sd-highspeed;
+	cap-sdio-irq;
+	keep-power-in-suspend;
+	mmc-pwrseq = <&sdio_pwrseq>;
+	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc2m0_bus4 &sdmmc2m0_cmd &sdmmc2m0_clk>;
+	sd-uhs-sdr12;
+	sd-uhs-sdr25;
+	sd-uhs-sdr50;
+	sd-uhs-sdr104;
+	vmmc-supply = <&vcc3v3_sys>;
+	vqmmc-supply = <&vcc_1v8>;
+	status = "okay";
+};
+
+&spdif {
+	status = "okay";
+};
+
+&tsadc {
+	rockchip,hw-tshut-mode = <1>;
+	rockchip,hw-tshut-polarity = <0>;
+	status = "okay";
+};
+
+/* used for Debug */
+&uart2 {
+	status = "okay";
+};
+
+&uart3 {
+	pinctrl-0 = <&uart3m1_xfer>;
+	status = "okay";
+};
+
+&uart4 {
+	pinctrl-0 = <&uart4m1_xfer>;
+	status = "okay";
+};
+
+/* used for WiFi/BT AP6275S */
+&uart8 {
+	pinctrl-0 = <&uart8m0_xfer &uart8m0_ctsn>;
+	status = "okay";
+};
+
+&uart9 {
+	pinctrl-0 = <&uart9m1_xfer>;
+	status = "okay";
+};
+
+&usb_host0_ehci {
+	status = "okay";
+};
+
+&usb_host0_ohci {
+	status = "okay";
+};
+
+&usb_host0_xhci {
+	extcon = <&usb2phy0>;
+	status = "okay";
+};
+
+&usb_host1_ehci {
+	status = "okay";
+};
+
+&usb_host1_ohci {
+	status = "okay";
+};
+
+&usb_host1_xhci {
+	status = "okay";
+};
+
+&usb2phy0 {
+	status = "okay";
+};
+
+&usb2phy0_host {
+	phy-supply = <&vcc5v0_usb_host>;
+	status = "okay";
+};
+
+&usb2phy0_otg {
+	phy-supply = <&vcc5v0_usb_otg>;
+	status = "okay";
+};
+
+&usb2phy1 {
+	status = "okay";
+};
+
+&usb2phy1_host {
+	phy-supply = <&vcc5v0_usb_host>;
+	status = "okay";
+};
+
+&usb2phy1_otg {
+	phy-supply = <&vcc5v0_usb_host>;
+	status = "okay";
+};
+
+&vop {
+	assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>;
+	assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>;
+	status = "okay";
+};
+
+&vop_mmu {
+	status = "okay";
+};
+
+&vp0 {
+	vp0_out_hdmi: endpoint at ROCKCHIP_VOP2_EP_HDMI0 {
+		reg = <ROCKCHIP_VOP2_EP_HDMI0>;
+		remote-endpoint = <&hdmi_in_vp0>;
+	};
+};
-- 
2.47.3



From helgaas at kernel.org  Mon Nov  3 10:10:38 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Mon, 3 Nov 2025 12:10:38 -0600
Subject: [RFC PATCH 2/2] PCI: rockchip-host: drop wait on PERST# toggle
In-Reply-To: <d3d0c3a387ff461e62bbd66a0bde654a9a17761e.1762150971.git.geraldogabriel@gmail.com>
Message-ID: <20251103181038.GA1814635@bhelgaas>

On Mon, Nov 03, 2025 at 03:27:25AM -0300, Geraldo Nascimento wrote:
> With this change PCIe will complete link-training with a known quirky
> device - Samsung OEM PM981a SSD. This is completely against the PCIe
> spec and yet it works as long as the power regulator for 3v3 PCIe
> power is not defined as always-on or boot-on.

What is against the spec?  In what way is this SSD "known quirky"?  Is
there a published erratum for it?

Removing this delay might make this SSD work, but if this delay is
required per PCIe spec, how can we be confident that other devices
will still work?

Reports of devices that still work is not really enough to move this
from the "hack that makes one device work" column to the "safe and
effective for all devices" column.

It's easy to see how *lack* of a delay can break something, but much
harder to imagine how *removing* a delay can make something work.
Devices must be able to tolerate pretty much arbitrary delays.

> Signed-off-by: Geraldo Nascimento <geraldogabriel at gmail.com>
> ---
>  drivers/pci/controller/pcie-rockchip-host.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c
> index ee1822ca01db..6add0faf6dc9 100644
> --- a/drivers/pci/controller/pcie-rockchip-host.c
> +++ b/drivers/pci/controller/pcie-rockchip-host.c
> @@ -314,7 +314,6 @@ static int rockchip_pcie_host_init_port(struct rockchip_pcie *rockchip)
>  	rockchip_pcie_write(rockchip, PCIE_CLIENT_LINK_TRAIN_ENABLE,
>  			    PCIE_CLIENT_CONFIG);
>  
> -	msleep(PCIE_T_PVPERL_MS);
>  	gpiod_set_value_cansleep(rockchip->perst_gpio, 1);
>  
>  	msleep(PCIE_RESET_CONFIG_WAIT_MS);
> -- 
> 2.49.0
> 
> 
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip


From jgg at nvidia.com  Mon Nov  3 10:54:00 2025
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Mon, 3 Nov 2025 14:54:00 -0400
Subject: [PATCH v1 02/20] iommu: Introduce a test_dev domain op and an
 internal helper
In-Reply-To: <aQO//+6/B/WbdK2h@Asurada-Nvidia>
References: <cover.1760312725.git.nicolinc@nvidia.com>
 <32ce256a2ece5d63e99d5858f953586859818ffc.1760312725.git.nicolinc@nvidia.com>
 <BN9PR11MB5276D10BD480FE66881870B08CFBA@BN9PR11MB5276.namprd11.prod.outlook.com>
 <aQO//+6/B/WbdK2h@Asurada-Nvidia>
Message-ID: <20251103185400.GA1537560@nvidia.com>

On Thu, Oct 30, 2025 at 12:43:59PM -0700, Nicolin Chen wrote:

> FWIW, I am thinking of another design based on Jason's remarks:
> https://lore.kernel.org/linux-iommu/aQBopHFub8wyQh5C at Asurada-Nvidia/
> 
> So, instead of core initiating the round trip between the blocking
> domain and group->domain, it forwards dev_reset_prepare/done to the
> driver where it does a low-level attachment that wouldn't fail:
>   For SMMUv3, it's an STE update.
>   For intel_iommu, it seems to be the context table update?

Kevin, how bad do you think the UAPI issue is if we ignore it?

Jason


From sebastian.reichel at collabora.com  Mon Nov  3 10:58:15 2025
From: sebastian.reichel at collabora.com (Sebastian Reichel)
Date: Mon, 3 Nov 2025 19:58:15 +0100
Subject: [PATCH v4 0/9] PCI: dw-rockchip: add system suspend support
In-Reply-To: <cf6zumlp4iiltglu7bbrpdeysaznrkyvlemwl4lxwkfjkgux7a@wl37bxilsprx>
References: <20251029-rockchip-pcie-system-suspend-v4-0-ce2e1b0692d2@collabora.com>
 <cf6zumlp4iiltglu7bbrpdeysaznrkyvlemwl4lxwkfjkgux7a@wl37bxilsprx>
Message-ID: <cbvcjgcd7saxj42ifgqn3l6mwpgenlhbr4zuf5ibqbtj6rmzqh@yuc7flbwyi2y>

Hi,

On Sat, Nov 01, 2025 at 07:29:41PM +0530, Manivannan Sadhasivam wrote:
> On Wed, Oct 29, 2025 at 06:56:39PM +0100, Sebastian Reichel wrote:
> > I've recently been working on fixing up at least basic system suspend
> > support on the Rockchip RK3576 platform. Currently the biggest open
> > issue is missing support in the PCIe driver. This series is a follow-up
> > for Shawn Lin's series with feedback from Niklas Cassel and Manivannan
> > Sadhasivam being handled as well as some of my own changes fixing up
> > things I noticed.
> > 
> > In opposite to Shawn Lin I did not test with different peripherals as my
> > main goal is getting basic suspend to ram working in the first place.
> 
> Wouldn't it break users who have connected endpoint devices and suspend their
> platform? I don't want to have an untested feature that could potentially cause
> regressions, just for the sake of getting basic system PM.
>
> But if your goal is to just add basic system PM operations for CI
> testing, then I would suggest you to do something minimal in the
> suspend/resume path that don't disrupt the operation of a device.
>
> But this also should be tested with some devices for sanity.

My goal is proper system PM support, but I would like to go step by
step. Right now system suspend on the Rockchip RK3576 EVB just hangs
the board and it has to be power cycled afterwards. In parallel to
this series I've send a bunch of fixes to get it working. It surely
isn't perfect, but I fear things regressing again in other areas while
the complex PCIe system sleep is being worked on - simply blocking system
suspend is not very helpful, since it effectively hides suspend problems.

Greetings,

-- Sebastian


> - Mani
> 
> > I did notice issues with the Broadcom WLAN card on the RK3576 EVB.
> > Suspending that platform without a driver being probed works, but after
> > probing brcmfmac suspend is aborted because brcmf_pcie_pm_enter_D3()
> > does not work. As far as I can tell the problem is unrelated to the
> > Rockchip PCIe driver.
> > 
> > Changes since PATCHv3:
> >  * https://lore.kernel.org/linux-pci/1744940759-23823-1-git-send-email-shawn.lin at rock-chips.com/
> >  * rename rockchip_pcie_get_ltssm to rockchip_pcie_get_ltssm_status_reg
> >    in a separate patch (Niklas Cassel)
> >  * rename rockchip_pcie_get_pure_ltssm to rockchip_pcie_get_ltssm_state
> >    in a separate patch (Niklas Cassel)
> >  * Move devm_phy_get out of phy_init to probe in a separate patch
> >    (Manivannan Sadhasivam)
> >  * Add helper function for enhanced LTSSM control mode in a separate patch
> >    (Niklas Cassel)
> >  * Add helper function for controller mode in a separate patch
> >    (Niklas Cassel)
> >  * Add helper function for DDL indicator in a separate patch
> >    (Niklas Cassel)
> >  * Move rockchip_pcie_pme_turn_off implementation in a separate patch
> >  * Rebase to v6.18-rc3 using new FIELD_PREP_WM16()
> >  * Improve readability of PME_TURN_OFF/PME_TO_ACK defines (Manivannan Sadhasivam)
> >  * Fix usage of reverse Xmas (Manivannan Sadhasivam)
> >  * Assert PERST# before turning off other resources (Manivannan Sadhasivam)
> >  * Improve some error messages (Manivannan Sadhasivam)
> >  * Rename goto labels as per their purpose (Manivannan Sadhasivam)
> >  * Add extra patch for dw_pcie_resume_noirq, since I've seen errors
> >    during resume on boards not having anything plugged into their PCIe
> >    port
> > 
> > Signed-off-by: Sebastian Reichel <sebastian.reichel at collabora.com>
> > ---
> > Sebastian Reichel (9):
> >       PCI: dw-rockchip: Rename rockchip_pcie_get_ltssm function
> >       PCI: dw-rockchip: Support get_ltssm operation
> >       PCI: dw-rockchip: Move devm_phy_get out of phy_init
> >       PCI: dw-rockchip: Add helper function for enhanced LTSSM control mode
> >       PCI: dw-rockchip: Add helper function for controller mode
> >       PCI: dw-rockchip: Add helper function for DDL indicator
> >       PCI: dw-rockchip: Add pme_turn_off support
> >       PCI: dw-rockchip: Add system PM support
> >       PCI: dwc: support missing PCIe device on resume
> > 
> >  drivers/pci/controller/dwc/pcie-designware-host.c |  13 +-
> >  drivers/pci/controller/dwc/pcie-dw-rockchip.c     | 220 ++++++++++++++++++----
> >  2 files changed, 198 insertions(+), 35 deletions(-)
> > ---
> > base-commit: dcb6fa37fd7bc9c3d2b066329b0d27dedf8becaa
> > change-id: 20251028-rockchip-pcie-system-suspend-86cf08a7b229
> > 
> > Best regards,
> > -- 
> > Sebastian Reichel <sebastian.reichel at collabora.com>
> > 
> 
> -- 
> ????????? ????????
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251103/89802e79/attachment-0001.sig>

From sebastian.reichel at collabora.com  Mon Nov  3 11:00:45 2025
From: sebastian.reichel at collabora.com (Sebastian Reichel)
Date: Mon, 3 Nov 2025 20:00:45 +0100
Subject: [PATCH v4 9/9] PCI: dwc: support missing PCIe device on resume
In-Reply-To: <qlil44i7ywwxurdfovkbqvvjff7dey53uy5hzq4zbmvg7jg54o@zdg27w4q26gr>
References: <20251029-rockchip-pcie-system-suspend-v4-0-ce2e1b0692d2@collabora.com>
 <20251029-rockchip-pcie-system-suspend-v4-9-ce2e1b0692d2@collabora.com>
 <dc230a62-bd31-450a-9acd-fa654f694b3a@oss.qualcomm.com>
 <qlil44i7ywwxurdfovkbqvvjff7dey53uy5hzq4zbmvg7jg54o@zdg27w4q26gr>
Message-ID: <s67opnadijrebativ27oiofub5cgr3lbclhxnmwnqrkltweqqj@j4douhswobsv>

Hi,

On Sat, Nov 01, 2025 at 07:50:58PM +0530, Manivannan Sadhasivam wrote:
> On Thu, Oct 30, 2025 at 11:07:19AM +0530, Krishna Chaitanya Chundru wrote:
> > 
> > On 10/29/2025 11:26 PM, Sebastian Reichel wrote:
> > > When dw_pcie_resume_noirq() is called for a PCIe root complex for a PCIe
> > > slot with no device plugged on Rockchip RK3576, dw_pcie_wait_for_link()
> > > will return -ETIMEDOUT. During probe time this does not happen, since
> > > the platform sets 'use_linkup_irq'.
> > > 
> > > This adds the same logic from dw_pcie_host_init() to the PM resume
> > > function to avoid the problem.
> > > 
> > > Signed-off-by: Sebastian Reichel <sebastian.reichel at collabora.com>
> > > ---
> > >   drivers/pci/controller/dwc/pcie-designware-host.c | 13 ++++++++++---
> > >   1 file changed, 10 insertions(+), 3 deletions(-)
> > > 
> > > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> > > index e92513c5bda5..f25f1c136900 100644
> > > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > > @@ -1215,9 +1215,16 @@ int dw_pcie_resume_noirq(struct dw_pcie *pci)
> > >   	if (ret)
> > >   		return ret;
> > > -	ret = dw_pcie_wait_for_link(pci);
> > > -	if (ret)
> > > -		return ret;
> > > +	/*
> > > +	 * Note: Skip the link up delay only when a Link Up IRQ is present.
> > > +	 * If there is no Link Up IRQ, we should not bypass the delay
> > > +	 * because that would require users to manually rescan for devices.
> > > +	 */
> > 
> > In the resume scenario, we should explicitly wait for the link to be up,
> > there is no IRQ support at this resume phase
> 
> This could be fixed if the PM handlers are moved to non-no_irq ones.
> 
> > and secondly after controller resume pm framework will start resuming the
> > bridges & endpoints. what happens
> > if the link is not up by the time endpoint is resume is called. And entire
> > save & restore states might also gets messed up.
> > There will be no way to recover from this.
> > 
> 
> This is true if there were any devices connected to the bus during suspend. If
> there were no devices, then it is fine to skip waiting for the link to be up.

I thought about setting a flag in the suspend routine, that a device
is expected to be there at resume time. But I suppose it might also
have been removed during the system suspend?

Greetings,

-- Sebastian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251103/39f1e97d/attachment.sig>

From geraldogabriel at gmail.com  Mon Nov  3 12:55:38 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Mon, 3 Nov 2025 17:55:38 -0300
Subject: [RFC PATCH 2/2] PCI: rockchip-host: drop wait on PERST# toggle
In-Reply-To: <20251103181038.GA1814635@bhelgaas>
References: <d3d0c3a387ff461e62bbd66a0bde654a9a17761e.1762150971.git.geraldogabriel@gmail.com>
 <20251103181038.GA1814635@bhelgaas>
Message-ID: <aQkWysK2XA01lkB8@geday>

On Mon, Nov 03, 2025 at 12:10:38PM -0600, Bjorn Helgaas wrote:
> On Mon, Nov 03, 2025 at 03:27:25AM -0300, Geraldo Nascimento wrote:
> > With this change PCIe will complete link-training with a known quirky
> > device - Samsung OEM PM981a SSD. This is completely against the PCIe
> > spec and yet it works as long as the power regulator for 3v3 PCIe
> > power is not defined as always-on or boot-on.
> 
> What is against the spec?  In what way is this SSD "known quirky"?  Is
> there a published erratum for it?

Hi Bjorn!

My proposed change itself is against the spec.

This SSD is known to simply not complete initial link-training with
Rockchip-IP PCIe. This is not officialy documented but based on
reports across boards (like the Armbian one).

I think it's the other way around though, it's the Rockchip-IP PCIe
controller that is quirky somehow and doesn't play nice with
many, many devices.

> 
> Removing this delay might make this SSD work, but if this delay is
> required per PCIe spec, how can we be confident that other devices
> will still work?

We really can't be sure there will be no side-effects to other devices.

> 
> Reports of devices that still work is not really enough to move this
> from the "hack that makes one device work" column to the "safe and
> effective for all devices" column.

I agree, and I knew from the start I would not get encouragements from
the community relative to this change. Still, it seemed selfish not to
share the workaround.

> 
> It's easy to see how *lack* of a delay can break something, but much
> harder to imagine how *removing* a delay can make something work.
> Devices must be able to tolerate pretty much arbitrary delays.

That said, the problem of quirky Rockchip-IP PCIe remains. The fact
that removing the delay makes it work with devices that previously
did not complete initial link training must at least point to a
resolution somehow, even if the present change is unacceptable.

I'll continue to hack around this, see if I can pinpoint exactly why
that delay screws up my initial link training.

Thanks,
Geraldo Nascimento


From helgaas at kernel.org  Mon Nov  3 13:32:06 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Mon, 3 Nov 2025 15:32:06 -0600
Subject: [PATCH v3] PCI: dw-rockchip: Prevent advertising L1 Substates
 support
In-Reply-To: <20251028190218.GA1525614@bhelgaas>
Message-ID: <20251103213206.GA1818418@bhelgaas>

On Tue, Oct 28, 2025 at 02:02:18PM -0500, Bjorn Helgaas wrote:
> On Fri, Oct 17, 2025 at 06:32:53PM +0200, Niklas Cassel wrote:
> > The L1 substates support requires additional steps to work, namely:
> > -Proper handling of the CLKREQ# sideband signal. (It is mostly handled by
> >  hardware, but software still needs to set the clkreq fields in the
> >  PCIE_CLIENT_POWER_CON register to match the hardware implementation.)
> > -Program the frequency of the aux clock into the
> >  DSP_PCIE_PL_AUX_CLK_FREQ_OFF register. (During L1 substates the core_clk
> >  is turned off and the aux_clk is used instead.)
> ...

> > +static void rockchip_pcie_disable_l1sub(struct dw_pcie *pci)
> > +{
> > +	u32 cap, l1subcap;
> > +
> > +	cap = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_L1SS);
> > +	if (cap) {
> > +		l1subcap = dw_pcie_readl_dbi(pci, cap + PCI_L1SS_CAP);
> > +		l1subcap &= ~(PCI_L1SS_CAP_L1_PM_SS | PCI_L1SS_CAP_ASPM_L1_1 |
> > +			      PCI_L1SS_CAP_ASPM_L1_2 | PCI_L1SS_CAP_PCIPM_L1_1 |
> > +			      PCI_L1SS_CAP_PCIPM_L1_2);
> > +		dw_pcie_writel_dbi(pci, cap + PCI_L1SS_CAP, l1subcap);
> > +	}
> > +}
> 
> I like this.  But why should we do it just for dw-rockchip?  Is there
> something special about dw-rockchip that makes this a problem?  Maybe
> we should consider doing this in the dwc, cadence, mobiveil, and plda
> cores instead of trying to do it for every driver individually?
> 
> Advertising L1SS support via PCI_EXT_CAP_ID_L1SS means users can
> enable L1SS via CONFIG_PCIEASPM_POWER_SUPERSAVE=y or sysfs, and that
> seems likely to cause problems unless CLKREQ# is supported.

Any thoughts on this?  There's nothing rockchip-specific in this
patch.  What I'm proposing is something like this:

    PCI: dwc: Prevent advertising L1 PM Substates
    
    L1 PM Substates require the CLKREF# signal and driver-specific support.  If
    CLKREF# is not supported or the driver support is lacking, enabling L1.1 or
    L1.2 may cause errors when accessing devices, e.g.,
    
      nvme nvme0: controller is down; will reset: CSTS=0xffffffff, PCI_STATUS=0x10
    
    If both ends of a link advertise support for L1 PM Substates, and the
    kernel is built with CONFIG_PCIEASPM_POWER_SUPERSAVE=y or users enable L1.x
    via sysfs, Linux tries to enable them.
    
    To prevent errors when L1.x may not work, disable advertising the L1 PM
    Substates.  Drivers can enable advertising them if they know CLKREF# is
    present and the Root Port is configured correctly.
    
    Based on Niklas's patch from
    https://patch.msgid.link/20251017163252.598812-2-cassel at kernel.org

diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index 20c9333bcb1c..83b5330c9e45 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -950,6 +950,27 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
 	return 0;
 }
 
+static void dw_pcie_clear_l1ss_advert(struct dw_pcie_rp *pp)
+{
+	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+	u16 l1ss;
+	u32 l1ss_cap;
+
+	l1ss = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_L1SS);
+	if (!l1ss)
+		return;
+
+	/*
+	 * By default, don't advertise L1 PM Substates because they require
+	 * CLKREF# and other driver-specific support.
+	 */
+	l1ss_cap = dw_pcie_readl_dbi(pci, l1ss + PCI_L1SS_CAP);
+	l1ss_cap &= ~(PCI_L1SS_CAP_PCIPM_L1_1 | PCI_L1SS_CAP_ASPM_L1_1 |
+		      PCI_L1SS_CAP_PCIPM_L1_2 | PCI_L1SS_CAP_ASPM_L1_2 |
+		      PCI_L1SS_CAP_L1_PM_SS);
+	dw_pcie_writel_dbi(pci, l1ss + PCI_L1SS_CAP, l1ss_cap);
+}
+
 static void dw_pcie_program_presets(struct dw_pcie_rp *pp, enum pci_bus_speed speed)
 {
 	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
@@ -1060,6 +1081,7 @@ int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
 		PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
 	dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
 
+	dw_pcie_clear_l1ss_advert(pp);
 	dw_pcie_config_presets(pp);
 	/*
 	 * If the platform provides its own child bus config accesses, it means


From heiko at sntech.de  Mon Nov  3 15:40:30 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue,  4 Nov 2025 00:40:30 +0100
Subject: [PATCH 0/2] Drop RK3568's variant of the CLK_NR_CLKS constant
Message-ID: <20251103234032.413563-1-heiko@sntech.de>

This drops the use of the CLK_NR_CLKS constant from the rk3568 clock
driver and after that, drops the constant from the binding that should
not have been part of it in the first place.

Heiko Stuebner (2):
  clk: rockchip: rk3568: Drop CLK_NR_CLKS usage
  dt-bindings: clock: rk3568: Drop CLK_NR_CLKS define

 drivers/clk/rockchip/clk-rk3568.c      | 5 ++++-
 include/dt-bindings/clock/rk3568-cru.h | 2 --
 2 files changed, 4 insertions(+), 3 deletions(-)

-- 
2.47.2



From heiko at sntech.de  Mon Nov  3 15:40:31 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue,  4 Nov 2025 00:40:31 +0100
Subject: [PATCH 1/2] clk: rockchip: rk3568: Drop CLK_NR_CLKS usage
In-Reply-To: <20251103234032.413563-1-heiko@sntech.de>
References: <20251103234032.413563-1-heiko@sntech.de>
Message-ID: <20251103234032.413563-2-heiko@sntech.de>

In order to get rid of CLK_NR_CLKS and be able to drop it from the
bindings, use rockchip_clk_find_max_clk_id helper to find the highest
clock id.

Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
 drivers/clk/rockchip/clk-rk3568.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/rockchip/clk-rk3568.c b/drivers/clk/rockchip/clk-rk3568.c
index 97d279399ae8..74eabf9b2ae2 100644
--- a/drivers/clk/rockchip/clk-rk3568.c
+++ b/drivers/clk/rockchip/clk-rk3568.c
@@ -1652,6 +1652,7 @@ CLK_OF_DECLARE(rk3568_cru_pmu, "rockchip,rk3568-pmucru", rk3568_pmu_clk_init);
 static void __init rk3568_clk_init(struct device_node *np)
 {
 	struct rockchip_clk_provider *ctx;
+	unsigned long clk_nr_clks;
 	void __iomem *reg_base;
 
 	reg_base = of_iomap(np, 0);
@@ -1660,7 +1661,9 @@ static void __init rk3568_clk_init(struct device_node *np)
 		return;
 	}
 
-	ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
+	clk_nr_clks = rockchip_clk_find_max_clk_id(rk3568_clk_branches,
+						   ARRAY_SIZE(rk3568_clk_branches)) + 1;
+	ctx = rockchip_clk_init(np, reg_base, clk_nr_clks);
 	if (IS_ERR(ctx)) {
 		pr_err("%s: rockchip clk init failed\n", __func__);
 		iounmap(reg_base);
-- 
2.47.2



From heiko at sntech.de  Mon Nov  3 15:40:32 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue,  4 Nov 2025 00:40:32 +0100
Subject: [PATCH 2/2] dt-bindings: clock: rk3568: Drop CLK_NR_CLKS define
In-Reply-To: <20251103234032.413563-1-heiko@sntech.de>
References: <20251103234032.413563-1-heiko@sntech.de>
Message-ID: <20251103234032.413563-3-heiko@sntech.de>

CLK_NR_CLKS has always only be used on the driver side to calculate array
sizes should never have been part of the clock-binding.

Let's drop it, since the kernel code no longer uses it either and nothing
else has ever used it.

Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
 include/dt-bindings/clock/rk3568-cru.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/include/dt-bindings/clock/rk3568-cru.h b/include/dt-bindings/clock/rk3568-cru.h
index 5263085c5b23..f01f0e9ce8f1 100644
--- a/include/dt-bindings/clock/rk3568-cru.h
+++ b/include/dt-bindings/clock/rk3568-cru.h
@@ -483,8 +483,6 @@
 
 #define PCLK_CORE_PVTM		450
 
-#define CLK_NR_CLKS		(PCLK_CORE_PVTM + 1)
-
 /* pmu soft-reset indices */
 /* pmucru_softrst_con0 */
 #define SRST_P_PDPMU_NIU	0
-- 
2.47.2



From heiko at sntech.de  Mon Nov  3 15:49:23 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue,  4 Nov 2025 00:49:23 +0100
Subject: [PATCH 0/3] SCMI clocks on RK356x
Message-ID: <20251103234926.416137-1-heiko@sntech.de>

This cleans up the existing use of SCMI clocks on the RK356x SoCs.


Heiko Stuebner (3):
  dt-bindings: clock: rk3568: Add SCMI clock ids
  arm64: dts: rockchip: use SCMI clock id for cpu clock on rk356x
  arm64: dts: rockchip: add missing clocks for cpu cores on rk356

 arch/arm64/boot/dts/rockchip/rk356x-base.dtsi | 5 ++++-
 include/dt-bindings/clock/rk3568-cru.h        | 6 ++++++
 2 files changed, 10 insertions(+), 1 deletion(-)

-- 
2.47.2



From heiko at sntech.de  Mon Nov  3 15:49:24 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue,  4 Nov 2025 00:49:24 +0100
Subject: [PATCH 1/3] dt-bindings: clock: rk3568: Add SCMI clock ids
In-Reply-To: <20251103234926.416137-1-heiko@sntech.de>
References: <20251103234926.416137-1-heiko@sntech.de>
Message-ID: <20251103234926.416137-2-heiko@sntech.de>

The Trusted Firmware on RK3568 exposes 3 clocks via the SCMI clock
interface. Add descriptive IDs for them.

The clock ids are used in both the older vendor-binary TF-A, as well
as the recently merged upstream SCMI clock implementation.

Link: https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/31265
Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
 include/dt-bindings/clock/rk3568-cru.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/include/dt-bindings/clock/rk3568-cru.h b/include/dt-bindings/clock/rk3568-cru.h
index f01f0e9ce8f1..1e0aef8a645d 100644
--- a/include/dt-bindings/clock/rk3568-cru.h
+++ b/include/dt-bindings/clock/rk3568-cru.h
@@ -483,6 +483,12 @@
 
 #define PCLK_CORE_PVTM		450
 
+/* scmi-clocks indices */
+
+#define SCMI_CLK_CPU		0
+#define SCMI_CLK_GPU		1
+#define SCMI_CLK_NPU		2
+
 /* pmu soft-reset indices */
 /* pmucru_softrst_con0 */
 #define SRST_P_PDPMU_NIU	0
-- 
2.47.2



From heiko at sntech.de  Mon Nov  3 15:49:25 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue,  4 Nov 2025 00:49:25 +0100
Subject: [PATCH 2/3] arm64: dts: rockchip: use SCMI clock id for cpu clock on rk356x
In-Reply-To: <20251103234926.416137-1-heiko@sntech.de>
References: <20251103234926.416137-1-heiko@sntech.de>
Message-ID: <20251103234926.416137-3-heiko@sntech.de>

Instead of hard-coding 0, use the more descriptive ID from the binding
to reference the SCMI clock for the cpu on rk356x.

Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
 arch/arm64/boot/dts/rockchip/rk356x-base.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
index a3361527d4fe..d0c76401b45e 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
@@ -53,7 +53,7 @@ cpu0: cpu at 0 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a55";
 			reg = <0x0 0x0>;
-			clocks = <&scmi_clk 0>;
+			clocks = <&scmi_clk SCMI_CLK_CPU>;
 			#cooling-cells = <2>;
 			enable-method = "psci";
 			i-cache-size = <0x8000>;
-- 
2.47.2



From heiko at sntech.de  Mon Nov  3 15:49:26 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue,  4 Nov 2025 00:49:26 +0100
Subject: [PATCH 3/3] arm64: dts: rockchip: add missing clocks for cpu cores on rk356x
In-Reply-To: <20251103234926.416137-1-heiko@sntech.de>
References: <20251103234926.416137-1-heiko@sntech.de>
Message-ID: <20251103234926.416137-4-heiko@sntech.de>

All cpu cores are supplied by the same clock, but all except the first
core are missing that clocks reference - add the missing ones.

Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
 arch/arm64/boot/dts/rockchip/rk356x-base.dtsi | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
index d0c76401b45e..a1815f8a96e1 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
@@ -69,6 +69,7 @@ cpu1: cpu at 100 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a55";
 			reg = <0x0 0x100>;
+			clocks = <&scmi_clk SCMI_CLK_CPU>;
 			#cooling-cells = <2>;
 			enable-method = "psci";
 			i-cache-size = <0x8000>;
@@ -84,6 +85,7 @@ cpu2: cpu at 200 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a55";
 			reg = <0x0 0x200>;
+			clocks = <&scmi_clk SCMI_CLK_CPU>;
 			#cooling-cells = <2>;
 			enable-method = "psci";
 			i-cache-size = <0x8000>;
@@ -99,6 +101,7 @@ cpu3: cpu at 300 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a55";
 			reg = <0x0 0x300>;
+			clocks = <&scmi_clk SCMI_CLK_CPU>;
 			#cooling-cells = <2>;
 			enable-method = "psci";
 			i-cache-size = <0x8000>;
-- 
2.47.2



From shawn.lin at rock-chips.com  Mon Nov  3 16:58:02 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Tue, 4 Nov 2025 08:58:02 +0800
Subject: [PATCH v3] PCI: dw-rockchip: Prevent advertising L1 Substates
 support
In-Reply-To: <20251103213206.GA1818418@bhelgaas>
References: <20251103213206.GA1818418@bhelgaas>
Message-ID: <0e32766b-b951-4ab4-ae3d-c802cf649edf@rock-chips.com>

Hi Bjorn,

? 2025/11/04 ??? 5:32, Bjorn Helgaas ??:
> On Tue, Oct 28, 2025 at 02:02:18PM -0500, Bjorn Helgaas wrote:
>> On Fri, Oct 17, 2025 at 06:32:53PM +0200, Niklas Cassel wrote:
>>> The L1 substates support requires additional steps to work, namely:
>>> -Proper handling of the CLKREQ# sideband signal. (It is mostly handled by
>>>   hardware, but software still needs to set the clkreq fields in the
>>>   PCIE_CLIENT_POWER_CON register to match the hardware implementation.)
>>> -Program the frequency of the aux clock into the
>>>   DSP_PCIE_PL_AUX_CLK_FREQ_OFF register. (During L1 substates the core_clk
>>>   is turned off and the aux_clk is used instead.)
>> ...
> 
>>> +static void rockchip_pcie_disable_l1sub(struct dw_pcie *pci)
>>> +{
>>> +	u32 cap, l1subcap;
>>> +
>>> +	cap = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_L1SS);
>>> +	if (cap) {
>>> +		l1subcap = dw_pcie_readl_dbi(pci, cap + PCI_L1SS_CAP);
>>> +		l1subcap &= ~(PCI_L1SS_CAP_L1_PM_SS | PCI_L1SS_CAP_ASPM_L1_1 |
>>> +			      PCI_L1SS_CAP_ASPM_L1_2 | PCI_L1SS_CAP_PCIPM_L1_1 |
>>> +			      PCI_L1SS_CAP_PCIPM_L1_2);
>>> +		dw_pcie_writel_dbi(pci, cap + PCI_L1SS_CAP, l1subcap);
>>> +	}
>>> +}
>>
>> I like this.  But why should we do it just for dw-rockchip?  Is there
>> something special about dw-rockchip that makes this a problem?  Maybe
>> we should consider doing this in the dwc, cadence, mobiveil, and plda
>> cores instead of trying to do it for every driver individually?
>>
>> Advertising L1SS support via PCI_EXT_CAP_ID_L1SS means users can
>> enable L1SS via CONFIG_PCIEASPM_POWER_SUPERSAVE=y or sysfs, and that
>> seems likely to cause problems unless CLKREQ# is supported.
> 
> Any thoughts on this?  There's nothing rockchip-specific in this
> patch.  What I'm proposing is something like this:

I like your idea, though. But could it be another form of regression
that we may breaks the platform which have already support L1SS
properly? It's even harder to detect because a functional break is 
easier to notice than increased power consumption. Or maybe we could
just export dw_pcie_clear_l1ss_advert() in dwc for host drivers to
call it?

> 
>      PCI: dwc: Prevent advertising L1 PM Substates
>      
>      L1 PM Substates require the CLKREF# signal and driver-specific support.  If
>      CLKREF# is not supported or the driver support is lacking, enabling L1.1 or
>      L1.2 may cause errors when accessing devices, e.g.,
>      
>        nvme nvme0: controller is down; will reset: CSTS=0xffffffff, PCI_STATUS=0x10
>      
>      If both ends of a link advertise support for L1 PM Substates, and the
>      kernel is built with CONFIG_PCIEASPM_POWER_SUPERSAVE=y or users enable L1.x
>      via sysfs, Linux tries to enable them.
>      
>      To prevent errors when L1.x may not work, disable advertising the L1 PM
>      Substates.  Drivers can enable advertising them if they know CLKREF# is
>      present and the Root Port is configured correctly.
>      
>      Based on Niklas's patch from
>      https://patch.msgid.link/20251017163252.598812-2-cassel at kernel.org
> 
> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> index 20c9333bcb1c..83b5330c9e45 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -950,6 +950,27 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
>   	return 0;
>   }
>   
> +static void dw_pcie_clear_l1ss_advert(struct dw_pcie_rp *pp)
> +{
> +	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> +	u16 l1ss;
> +	u32 l1ss_cap;
> +
> +	l1ss = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_L1SS);
> +	if (!l1ss)
> +		return;
> +
> +	/*
> +	 * By default, don't advertise L1 PM Substates because they require
> +	 * CLKREF# and other driver-specific support.
> +	 */
> +	l1ss_cap = dw_pcie_readl_dbi(pci, l1ss + PCI_L1SS_CAP);
> +	l1ss_cap &= ~(PCI_L1SS_CAP_PCIPM_L1_1 | PCI_L1SS_CAP_ASPM_L1_1 |
> +		      PCI_L1SS_CAP_PCIPM_L1_2 | PCI_L1SS_CAP_ASPM_L1_2 |
> +		      PCI_L1SS_CAP_L1_PM_SS);
> +	dw_pcie_writel_dbi(pci, l1ss + PCI_L1SS_CAP, l1ss_cap);
> +}
> +
>   static void dw_pcie_program_presets(struct dw_pcie_rp *pp, enum pci_bus_speed speed)
>   {
>   	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> @@ -1060,6 +1081,7 @@ int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
>   		PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
>   	dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
>   
> +	dw_pcie_clear_l1ss_advert(pp);
>   	dw_pcie_config_presets(pp);
>   	/*
>   	 * If the platform provides its own child bus config accesses, it means
> 



From chaoyi.chen at rock-chips.com  Mon Nov  3 17:18:33 2025
From: chaoyi.chen at rock-chips.com (Chaoyi Chen)
Date: Tue, 4 Nov 2025 09:18:33 +0800
Subject: [PATCH v8 03/10] drm/bridge: Implement generic USB Type-C DP HPD
 bridge
In-Reply-To: <aQiymTFVU7UpcJ1p@kuha.fi.intel.com>
References: <20251029071435.88-1-kernel@airkyi.com>
 <20251029071435.88-4-kernel@airkyi.com>
 <rzozpbqmymdczerh3iijxxtz3xnsznoku7w2mquikwv6u5osvo@7h43hwc2fpzm>
 <eca9d5bd-23bd-4c1d-b2f2-c0c32f14177f@rock-chips.com>
 <aQiymTFVU7UpcJ1p@kuha.fi.intel.com>
Message-ID: <7fb7e578-b97d-4ea5-a8af-33199563d834@rock-chips.com>

On 11/3/2025 9:48 PM, Heikki Krogerus wrote:

>>>> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
>>>> index a250afd8d662..17257b223a28 100644
>>>> --- a/drivers/gpu/drm/bridge/Kconfig
>>>> +++ b/drivers/gpu/drm/bridge/Kconfig
>>>> @@ -23,13 +23,16 @@ config DRM_AUX_BRIDGE
>>>>    	  build bridges chain.
>>>>    config DRM_AUX_HPD_BRIDGE
>>>> -	tristate
>>>> +	tristate "AUX HPD bridge support"
>>> Why? No, this is supposed to be selected by other drivers. Users don't
>>> know an wouldn't know what is this.
>> In v7, I implemented an additional module for selecting this option. But
>> Heikki believes that it would be better to merge the two modules into one.
> Like I said before, I was merely curious why not just squash the
> support into that AUX_PD_HPD_BRIDGE. If that does not make sense, then
> so be it - make it a "Display Interface Bridge" driver like you
> originally proposed.

Yes, it is.


>>>>    	depends on DRM_BRIDGE && OF
>>>>    	select AUXILIARY_BUS
>>>>    	help
>>>>    	  Simple bridge that terminates the bridge chain and provides HPD
>>>>    	  support.
>>>> +	  Specifically, if you want a default Type-C DisplayPort HPD bridge for
>>>> +	  each port of the Type-C controller, say Y here.
>>>> +
>>>>    menu "Display Interface Bridges"
>>>>    	depends on DRM && DRM_BRIDGE
>>>> diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
>>>> index c7dc03182e59..2998937444bc 100644
>>>> --- a/drivers/gpu/drm/bridge/Makefile
>>>> +++ b/drivers/gpu/drm/bridge/Makefile
>>>> @@ -1,6 +1,12 @@
>>>>    # SPDX-License-Identifier: GPL-2.0
>>>>    obj-$(CONFIG_DRM_AUX_BRIDGE) += aux-bridge.o
>>>> -obj-$(CONFIG_DRM_AUX_HPD_BRIDGE) += aux-hpd-bridge.o
>>>> +
>>>> +hpd-bridge-y := aux-hpd-bridge.o
>>>> +ifneq ($(CONFIG_TYPEC),)
>>>> +hpd-bridge-y += aux-hpd-typec-dp-bridge.o
>>>> +endif
>>>> +obj-$(CONFIG_DRM_AUX_HPD_BRIDGE) += hpd-bridge.o
>>>> +
>>>>    obj-$(CONFIG_DRM_CHIPONE_ICN6211) += chipone-icn6211.o
>>>>    obj-$(CONFIG_DRM_CHRONTEL_CH7033) += chrontel-ch7033.o
>>>>    obj-$(CONFIG_DRM_CROS_EC_ANX7688) += cros-ec-anx7688.o
>>>> diff --git a/drivers/gpu/drm/bridge/aux-hpd-bridge.c b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
>>>> index 2e9c702c7087..11ad6dc776c7 100644
>>>> --- a/drivers/gpu/drm/bridge/aux-hpd-bridge.c
>>>> +++ b/drivers/gpu/drm/bridge/aux-hpd-bridge.c
>>>> @@ -12,6 +12,8 @@
>>>>    #include <drm/drm_bridge.h>
>>>>    #include <drm/bridge/aux-bridge.h>
>>>> +#include "aux-hpd-bridge.h"
>>>> +
>>>>    static DEFINE_IDA(drm_aux_hpd_bridge_ida);
>>>>    struct drm_aux_hpd_bridge_data {
>>>> @@ -204,7 +206,26 @@ static struct auxiliary_driver drm_aux_hpd_bridge_drv = {
>>>>    	.id_table = drm_aux_hpd_bridge_table,
>>>>    	.probe = drm_aux_hpd_bridge_probe,
>>>>    };
>>>> -module_auxiliary_driver(drm_aux_hpd_bridge_drv);
>>>> +
>>>> +static int drm_aux_hpd_bridge_mod_init(void)
>>>> +{
>>>> +	int ret;
>>>> +
>>>> +	ret = auxiliary_driver_register(&drm_aux_hpd_bridge_drv);
>>>> +	if (ret)
>>>> +		return ret;
>>>> +
>>>> +	return drm_aux_hpd_typec_dp_bridge_init();
>>>> +}
>>>> +
>>>> +static void drm_aux_hpd_bridge_mod_exit(void)
>>>> +{
>>>> +	drm_aux_hpd_typec_dp_bridge_exit();
>>>> +	auxiliary_driver_unregister(&drm_aux_hpd_bridge_drv);
>>>> +}
>>>> +
>>>> +module_init(drm_aux_hpd_bridge_mod_init);
>>>> +module_exit(drm_aux_hpd_bridge_mod_exit);
>>>>    MODULE_AUTHOR("Dmitry Baryshkov <dmitry.baryshkov at linaro.org>");
>>>>    MODULE_DESCRIPTION("DRM HPD bridge");
>>>> diff --git a/drivers/gpu/drm/bridge/aux-hpd-bridge.h b/drivers/gpu/drm/bridge/aux-hpd-bridge.h
>>>> new file mode 100644
>>>> index 000000000000..69364731c2f1
>>>> --- /dev/null
>>>> +++ b/drivers/gpu/drm/bridge/aux-hpd-bridge.h
>>>> @@ -0,0 +1,13 @@
>>>> +/* SPDX-License-Identifier: GPL-2.0-only */
>>>> +#ifndef AUX_HPD_BRIDGE_H
>>>> +#define AUX_HPD_BRIDGE_H
>>>> +
>>>> +#if IS_REACHABLE(CONFIG_TYPEC)
>>>> +int drm_aux_hpd_typec_dp_bridge_init(void);
>>>> +void drm_aux_hpd_typec_dp_bridge_exit(void);
>>>> +#else
>>>> +static inline int drm_aux_hpd_typec_dp_bridge_init(void) { return 0; }
>>>> +static inline void drm_aux_hpd_typec_dp_bridge_exit(void) { }
>>>> +#endif /* IS_REACHABLE(CONFIG_TYPEC) */
>>>> +
>>>> +#endif /* AUX_HPD_BRIDGE_H */
>>>> diff --git a/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c b/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
>>>> new file mode 100644
>>>> index 000000000000..6f2a1fca0fc5
>>>> --- /dev/null
>>>> +++ b/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
>>>> @@ -0,0 +1,47 @@
>>>> +// SPDX-License-Identifier: GPL-2.0+
>>>> +#include <linux/of.h>
>>>> +#include <linux/usb/typec_altmode.h>
>>>> +#include <linux/usb/typec_dp.h>
>>>> +#include <linux/usb/typec_notify.h>
>>>> +
>>>> +#include <drm/bridge/aux-bridge.h>
>>>> +
>>>> +#include "aux-hpd-bridge.h"
>>>> +
>>>> +#if IS_REACHABLE(CONFIG_TYPEC)
>>>> +static int drm_typec_bus_event(struct notifier_block *nb,
>>>> +			       unsigned long action, void *data)
>>>> +{
>>> This feels like this should be a part of the Type-C subsystem rather
>>> than DRM.
>> In v7, this used to be a part of the Type-C subsystem. I'm not sure what
>> Heikki thinks about this.
> Your original proposal of making the entire TYPEC subsystem depend on
> DRM is _not_ going to happen. In general, if I've now understood this
> correctly, this thing probable should be a "display interface bridge
> driver", similar to what you proposed in the previous version.
>
> Note also that you could make it selected automatically, so there is
> no need for user selectable option if that's the preference. Kconfig
> and Makefile gives you options on how to do that. For example, maybe
> this Kconfig works (or does not, but something like it will):
>
> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
> index a250afd8d662..7487024ba2ce 100644
> --- a/drivers/gpu/drm/bridge/Kconfig
> +++ b/drivers/gpu/drm/bridge/Kconfig
> @@ -30,6 +30,15 @@ config DRM_AUX_HPD_BRIDGE
>            Simple bridge that terminates the bridge chain and provides HPD
>            support.
>   
> +if DRM_AUX_HPD_BRIDGE
> +
> +config DRM_AUX_HPD_TYPEC_BRIDGE
> +       tristate
> +       depends on TYPEC || !TYPEC
> +       default TYPEC
> +
> +endif /* DRM_AUX_HPD_BRIDGE */
> +
>   menu "Display Interface Bridges"
>          depends on DRM && DRM_BRIDGE

Thank you for your code. I think both of your points make sense. So choosing the approach you mentioned now (similar to v7) might be a reasonable compromise.



>   
>
>
> thanks,
>
-- 
Best,
Chaoyi



From ye.zhang at rock-chips.com  Mon Nov  3 18:12:21 2025
From: ye.zhang at rock-chips.com (Ye Zhang)
Date: Tue,  4 Nov 2025 10:12:21 +0800
Subject: [PATCH v1 1/3] dt-bindings: pinctrl: Add rk3506 pinctrl support
In-Reply-To: <20251104021223.2375116-1-ye.zhang@rock-chips.com>
References: <20251104021223.2375116-1-ye.zhang@rock-chips.com>
Message-ID: <20251104021223.2375116-2-ye.zhang@rock-chips.com>

Add the compatible string for the rk3506 SoC.

Signed-off-by: Ye Zhang <ye.zhang at rock-chips.com>
---
 Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.yaml
index 125af766b992..76e607281716 100644
--- a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.yaml
@@ -44,6 +44,7 @@ properties:
       - rockchip,rk3328-pinctrl
       - rockchip,rk3368-pinctrl
       - rockchip,rk3399-pinctrl
+      - rockchip,rk3506-pinctrl
       - rockchip,rk3528-pinctrl
       - rockchip,rk3562-pinctrl
       - rockchip,rk3568-pinctrl
-- 
2.34.1



From ye.zhang at rock-chips.com  Mon Nov  3 18:12:20 2025
From: ye.zhang at rock-chips.com (Ye Zhang)
Date: Tue,  4 Nov 2025 10:12:20 +0800
Subject: [PATCH v1 0/3] pinctrl: rockchip: Add RK3506 pinctrl support
Message-ID: <20251104021223.2375116-1-ye.zhang@rock-chips.com>

This series adds pinctrl support for the Rockchip RK3506 SoC.

The series includes:
- RK3506 pinctrl driver implementation
- RMIO (Rockchip Matrix I/O) support for RK3506

Ye Zhang (3):
  dt-bindings: pinctrl: Add rk3506 pinctrl support
  pinctrl: rockchip: Add rk3506 pinctrl support
  pinctrl: rockchip: add rk3506 rmio support

 .../bindings/pinctrl/rockchip,pinctrl.yaml    |   1 +
 drivers/pinctrl/pinctrl-rockchip.c            | 517 +++++++++++++++++-
 drivers/pinctrl/pinctrl-rockchip.h            |   5 +
 3 files changed, 515 insertions(+), 8 deletions(-)

-- 
2.34.1



From ye.zhang at rock-chips.com  Mon Nov  3 18:12:23 2025
From: ye.zhang at rock-chips.com (Ye Zhang)
Date: Tue,  4 Nov 2025 10:12:23 +0800
Subject: [PATCH v1 3/3] pinctrl: rockchip: add rk3506 rmio support
In-Reply-To: <20251104021223.2375116-1-ye.zhang@rock-chips.com>
References: <20251104021223.2375116-1-ye.zhang@rock-chips.com>
Message-ID: <20251104021223.2375116-4-ye.zhang@rock-chips.com>

Support rockchip matrix io

Signed-off-by: Ye Zhang <ye.zhang at rock-chips.com>
---
 drivers/pinctrl/pinctrl-rockchip.c | 75 ++++++++++++++++++++++++++++++
 drivers/pinctrl/pinctrl-rockchip.h |  1 +
 2 files changed, 76 insertions(+)

diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index e44ef262beec..89ff8d8c7fcc 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -1258,6 +1258,74 @@ static int rockchip_verify_mux(struct rockchip_pin_bank *bank,
 	return 0;
 }
 
+static int rockchip_set_rmio(struct rockchip_pin_bank *bank, int pin, int *mux)
+{
+	struct rockchip_pinctrl *info = bank->drvdata;
+	struct rockchip_pin_ctrl *ctrl = info->ctrl;
+	struct regmap *regmap;
+	int reg, function;
+	u32 data, rmask;
+	int ret = 0;
+	int iomux_num = (pin / 8);
+	u32 iomux_max, mux_type;
+
+	mux_type = bank->iomux[iomux_num].type;
+	if (mux_type & IOMUX_WIDTH_4BIT)
+		iomux_max = (1 << 4) - 1;
+	else if (mux_type & IOMUX_WIDTH_3BIT)
+		iomux_max = (1 << 3) - 1;
+	else
+		iomux_max = (1 << 2) - 1;
+
+	if (*mux > iomux_max)
+		function = *mux - iomux_max;
+	else
+		return 0;
+
+	switch (ctrl->type) {
+	case RK3506:
+		regmap = info->regmap_rmio;
+		if (bank->bank_num == 0) {
+			if (pin < 24)
+				reg = 0x80 + 0x4 * pin;
+			else
+				ret = -EINVAL;
+		} else if (bank->bank_num == 1) {
+			if (pin >= 9 && pin <= 11)
+				reg = 0xbc + 0x4 * pin;
+			else if (pin >= 18 && pin <= 19)
+				reg = 0xa4 + 0x4 * pin;
+			else if (pin >= 25 && pin <= 27)
+				reg = 0x90 + 0x4 * pin;
+			else
+				ret = -EINVAL;
+		} else {
+			ret = -EINVAL;
+		}
+
+		if (ret) {
+			dev_err(info->dev,
+				"rmio unsupported bank_num %d function %d\n",
+				bank->bank_num, function);
+
+			return -EINVAL;
+		}
+
+		rmask = 0x7f007f;
+		data = 0x7f0000 | function;
+		*mux = 7;
+		ret = regmap_update_bits(regmap, reg, rmask, data);
+		if (ret)
+			return ret;
+		break;
+
+	default:
+		break;
+	}
+
+	return 0;
+}
+
 /*
  * Set a new mux function for a pin.
  *
@@ -1291,6 +1359,10 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
 
 	dev_dbg(dev, "setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux);
 
+	ret = rockchip_set_rmio(bank, pin, &mux);
+	if (ret)
+		return ret;
+
 	if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
 		regmap = info->regmap_pmu;
 	else if (bank->iomux[iomux_num].type & IOMUX_L_SOURCE_PMU)
@@ -4247,6 +4319,9 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
 	/* try to find the optional reference to the ioc1 syscon */
 	info->regmap_ioc1 = syscon_regmap_lookup_by_phandle_optional(np, "rockchip,ioc1");
 
+	/* try to find the optional reference to the rmio syscon */
+	info->regmap_rmio = syscon_regmap_lookup_by_phandle_optional(np, "rockchip,rmio");
+
 	ret = rockchip_pinctrl_register(pdev, info);
 	if (ret)
 		return ret;
diff --git a/drivers/pinctrl/pinctrl-rockchip.h b/drivers/pinctrl/pinctrl-rockchip.h
index 4f4aff42a80a..6d79ccf73b71 100644
--- a/drivers/pinctrl/pinctrl-rockchip.h
+++ b/drivers/pinctrl/pinctrl-rockchip.h
@@ -462,6 +462,7 @@ struct rockchip_pinctrl {
 	struct regmap			*regmap_pull;
 	struct regmap			*regmap_pmu;
 	struct regmap			*regmap_ioc1;
+	struct regmap			*regmap_rmio;
 	struct device			*dev;
 	struct rockchip_pin_ctrl	*ctrl;
 	struct pinctrl_desc		pctl;
-- 
2.34.1



From ye.zhang at rock-chips.com  Mon Nov  3 18:12:22 2025
From: ye.zhang at rock-chips.com (Ye Zhang)
Date: Tue,  4 Nov 2025 10:12:22 +0800
Subject: [PATCH v1 2/3] pinctrl: rockchip: Add rk3506 pinctrl support
In-Reply-To: <20251104021223.2375116-1-ye.zhang@rock-chips.com>
References: <20251104021223.2375116-1-ye.zhang@rock-chips.com>
Message-ID: <20251104021223.2375116-3-ye.zhang@rock-chips.com>

Add support for the 5 rk3506 GPIO banks.

Signed-off-by: Ye Zhang <ye.zhang at rock-chips.com>
---
 drivers/pinctrl/pinctrl-rockchip.c | 442 ++++++++++++++++++++++++++++-
 drivers/pinctrl/pinctrl-rockchip.h |   4 +
 2 files changed, 438 insertions(+), 8 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index 7a68a6237649..e44ef262beec 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -105,6 +105,29 @@
 		.pull_type[3] = pull3,					\
 	}
 
+#define PIN_BANK_IOMUX_FLAGS_OFFSET_DRV_FLAGS(id, pins, label, iom0,	\
+					       iom1, iom2, iom3,	\
+					       offset0, offset1,	\
+					       offset2, offset3, drv0,	\
+					       drv1, drv2, drv3)	\
+	{								\
+		.bank_num	= id,					\
+		.nr_pins	= pins,					\
+		.name		= label,				\
+		.iomux		= {					\
+			{ .type = iom0, .offset = offset0 },		\
+			{ .type = iom1, .offset = offset1 },		\
+			{ .type = iom2, .offset = offset2 },		\
+			{ .type = iom3, .offset = offset3 },		\
+		},							\
+		.drv		= {					\
+			{ .drv_type = drv0, .offset = -1 },		\
+			{ .drv_type = drv1, .offset = -1 },		\
+			{ .drv_type = drv2, .offset = -1 },		\
+			{ .drv_type = drv3, .offset = -1 },		\
+		},							\
+	}
+
 #define PIN_BANK_DRV_FLAGS(id, pins, label, type0, type1, type2, type3) \
 	{								\
 		.bank_num	= id,					\
@@ -233,6 +256,35 @@
 		.pull_type[3] = pull3,					\
 	}
 
+#define PIN_BANK_IOMUX_FLAGS_OFFSET_DRV_FLAGS_PULL_FLAGS(id, pins,	\
+						label, iom0, iom1,	\
+						iom2, iom3, offset0,	\
+						offset1, offset2,	\
+						offset3, drv0, drv1,	\
+						drv2, drv3, pull0,	\
+						pull1, pull2, pull3)	\
+	{								\
+		.bank_num	= id,					\
+		.nr_pins	= pins,					\
+		.name		= label,				\
+		.iomux		= {					\
+			{ .type = iom0, .offset = offset0 },		\
+			{ .type = iom1, .offset = offset1 },		\
+			{ .type = iom2, .offset = offset2 },		\
+			{ .type = iom3, .offset = offset3 },		\
+		},							\
+		.drv		= {					\
+			{ .drv_type = drv0, .offset = -1 },		\
+			{ .drv_type = drv1, .offset = -1 },		\
+			{ .drv_type = drv2, .offset = -1 },		\
+			{ .drv_type = drv3, .offset = -1 },		\
+		},							\
+		.pull_type[0] = pull0,					\
+		.pull_type[1] = pull1,					\
+		.pull_type[2] = pull2,					\
+		.pull_type[3] = pull3,					\
+	}
+
 #define PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, FLAG)		\
 	{								\
 		.bank_num	= ID,					\
@@ -1120,6 +1172,13 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
 	else
 		regmap = info->regmap_base;
 
+	if (ctrl->type == RK3506) {
+		if (bank->bank_num == 1)
+			regmap = info->regmap_ioc1;
+		else if (bank->bank_num == 4)
+			return 0;
+	}
+
 	/* get basic quadrupel of mux registers and the correct reg inside */
 	mux_type = bank->iomux[iomux_num].type;
 	reg = bank->iomux[iomux_num].offset;
@@ -1239,6 +1298,13 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
 	else
 		regmap = info->regmap_base;
 
+	if (ctrl->type == RK3506) {
+		if (bank->bank_num == 1)
+			regmap = info->regmap_ioc1;
+		else if (bank->bank_num == 4)
+			return 0;
+	}
+
 	/* get basic quadrupel of mux registers and the correct reg inside */
 	mux_type = bank->iomux[iomux_num].type;
 	reg = bank->iomux[iomux_num].offset;
@@ -2003,6 +2069,262 @@ static int rk3399_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
 	return 0;
 }
 
+#define RK3506_DRV_BITS_PER_PIN		8
+#define RK3506_DRV_PINS_PER_REG		2
+#define RK3506_DRV_GPIO0_A_OFFSET	0x100
+#define RK3506_DRV_GPIO0_D_OFFSET	0x830
+#define RK3506_DRV_GPIO1_OFFSET		0x140
+#define RK3506_DRV_GPIO2_OFFSET		0x180
+#define RK3506_DRV_GPIO3_OFFSET		0x1c0
+#define RK3506_DRV_GPIO4_OFFSET		0x840
+
+static int rk3506_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
+					int pin_num, struct regmap **regmap,
+					int *reg, u8 *bit)
+{
+	struct rockchip_pinctrl *info = bank->drvdata;
+	int ret = 0;
+
+	switch (bank->bank_num) {
+	case 0:
+		*regmap = info->regmap_pmu;
+		if (pin_num > 24) {
+			ret = -EINVAL;
+		} else if (pin_num < 24) {
+			*reg = RK3506_DRV_GPIO0_A_OFFSET;
+		} else {
+			*reg = RK3506_DRV_GPIO0_D_OFFSET;
+			*bit = 3;
+
+			return 0;
+		}
+		break;
+
+	case 1:
+		*regmap = info->regmap_ioc1;
+		if (pin_num < 28)
+			*reg = RK3506_DRV_GPIO1_OFFSET;
+		else
+			ret = -EINVAL;
+		break;
+
+	case 2:
+		*regmap = info->regmap_base;
+		if (pin_num < 17)
+			*reg = RK3506_DRV_GPIO2_OFFSET;
+		else
+			ret = -EINVAL;
+		break;
+
+	case 3:
+		*regmap = info->regmap_base;
+		if (pin_num < 15)
+			*reg = RK3506_DRV_GPIO3_OFFSET;
+		else
+			ret = -EINVAL;
+		break;
+
+	case 4:
+		*regmap = info->regmap_base;
+		if (pin_num < 8 || pin_num > 11) {
+			ret = -EINVAL;
+		} else {
+			*reg = RK3506_DRV_GPIO4_OFFSET;
+			*bit = 10;
+
+			return 0;
+		}
+		break;
+
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	if (ret) {
+		dev_err(info->dev, "unsupported bank_num %d pin_num %d\n", bank->bank_num, pin_num);
+
+		return ret;
+	}
+
+	*reg += ((pin_num / RK3506_DRV_PINS_PER_REG) * 4);
+	*bit = pin_num % RK3506_DRV_PINS_PER_REG;
+	*bit *= RK3506_DRV_BITS_PER_PIN;
+
+	return 0;
+}
+
+#define RK3506_PULL_BITS_PER_PIN	2
+#define RK3506_PULL_PINS_PER_REG	8
+#define RK3506_PULL_GPIO0_A_OFFSET	0x200
+#define RK3506_PULL_GPIO0_D_OFFSET	0x830
+#define RK3506_PULL_GPIO1_OFFSET	0x210
+#define RK3506_PULL_GPIO2_OFFSET	0x220
+#define RK3506_PULL_GPIO3_OFFSET	0x230
+#define RK3506_PULL_GPIO4_OFFSET	0x840
+
+static int rk3506_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+					 int pin_num, struct regmap **regmap,
+					 int *reg, u8 *bit)
+{
+	struct rockchip_pinctrl *info = bank->drvdata;
+	int ret = 0;
+
+	switch (bank->bank_num) {
+	case 0:
+		*regmap = info->regmap_pmu;
+		if (pin_num > 24) {
+			ret = -EINVAL;
+		} else if (pin_num < 24) {
+			*reg = RK3506_PULL_GPIO0_A_OFFSET;
+		} else {
+			*reg = RK3506_PULL_GPIO0_D_OFFSET;
+			*bit = 5;
+
+			return 0;
+		}
+		break;
+
+	case 1:
+		*regmap = info->regmap_ioc1;
+		if (pin_num < 28)
+			*reg = RK3506_PULL_GPIO1_OFFSET;
+		else
+			ret = -EINVAL;
+		break;
+
+	case 2:
+		*regmap = info->regmap_base;
+		if (pin_num < 17)
+			*reg = RK3506_PULL_GPIO2_OFFSET;
+		else
+			ret = -EINVAL;
+		break;
+
+	case 3:
+		*regmap = info->regmap_base;
+		if (pin_num < 15)
+			*reg = RK3506_PULL_GPIO3_OFFSET;
+		else
+			ret = -EINVAL;
+		break;
+
+	case 4:
+		*regmap = info->regmap_base;
+		if (pin_num < 8 || pin_num > 11) {
+			ret = -EINVAL;
+		} else {
+			*reg = RK3506_PULL_GPIO4_OFFSET;
+			*bit = 13;
+
+			return 0;
+		}
+		break;
+
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	if (ret) {
+		dev_err(info->dev, "unsupported bank_num %d pin_num %d\n", bank->bank_num, pin_num);
+
+		return ret;
+	}
+
+	*reg += ((pin_num / RK3506_PULL_PINS_PER_REG) * 4);
+	*bit = pin_num % RK3506_PULL_PINS_PER_REG;
+	*bit *= RK3506_PULL_BITS_PER_PIN;
+
+	return 0;
+}
+
+#define RK3506_SMT_BITS_PER_PIN		1
+#define RK3506_SMT_PINS_PER_REG		8
+#define RK3506_SMT_GPIO0_A_OFFSET	0x400
+#define RK3506_SMT_GPIO0_D_OFFSET	0x830
+#define RK3506_SMT_GPIO1_OFFSET		0x410
+#define RK3506_SMT_GPIO2_OFFSET		0x420
+#define RK3506_SMT_GPIO3_OFFSET		0x430
+#define RK3506_SMT_GPIO4_OFFSET		0x840
+
+static int rk3506_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
+					   int pin_num,
+					   struct regmap **regmap,
+					   int *reg, u8 *bit)
+{
+	struct rockchip_pinctrl *info = bank->drvdata;
+	int ret = 0;
+
+	switch (bank->bank_num) {
+	case 0:
+		*regmap = info->regmap_pmu;
+		if (pin_num > 24) {
+			ret = -EINVAL;
+		} else if (pin_num < 24) {
+			*reg = RK3506_SMT_GPIO0_A_OFFSET;
+		} else {
+			*reg = RK3506_SMT_GPIO0_D_OFFSET;
+			*bit = 9;
+
+			return 0;
+		}
+		break;
+
+	case 1:
+		*regmap = info->regmap_ioc1;
+		if (pin_num < 28)
+			*reg = RK3506_SMT_GPIO1_OFFSET;
+		else
+			ret = -EINVAL;
+		break;
+
+	case 2:
+		*regmap = info->regmap_base;
+		if (pin_num < 17)
+			*reg = RK3506_SMT_GPIO2_OFFSET;
+		else
+			ret = -EINVAL;
+		break;
+
+	case 3:
+		*regmap = info->regmap_base;
+		if (pin_num < 15)
+			*reg = RK3506_SMT_GPIO3_OFFSET;
+		else
+			ret = -EINVAL;
+		break;
+
+	case 4:
+		*regmap = info->regmap_base;
+		if (pin_num < 8 || pin_num > 11) {
+			ret = -EINVAL;
+		} else {
+			*reg = RK3506_SMT_GPIO4_OFFSET;
+			*bit = 8;
+
+			return 0;
+		}
+		break;
+
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	if (ret) {
+		dev_err(info->dev, "unsupported bank_num %d pin_num %d\n", bank->bank_num, pin_num);
+
+		return ret;
+	}
+
+	*reg += ((pin_num / RK3506_SMT_PINS_PER_REG) * 4);
+	*bit = pin_num % RK3506_SMT_PINS_PER_REG;
+	*bit *= RK3506_SMT_BITS_PER_PIN;
+
+	return 0;
+}
+
 #define RK3528_DRV_BITS_PER_PIN		8
 #define RK3528_DRV_PINS_PER_REG		2
 #define RK3528_DRV_GPIO0_OFFSET		0x100
@@ -2749,7 +3071,8 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
 		rmask_bits = RK3588_DRV_BITS_PER_PIN;
 		ret = strength;
 		goto config;
-	} else if (ctrl->type == RK3528 ||
+	} else if (ctrl->type == RK3506 ||
+		   ctrl->type == RK3528 ||
 		   ctrl->type == RK3562 ||
 		   ctrl->type == RK3568) {
 		rmask_bits = RK3568_DRV_BITS_PER_PIN;
@@ -2828,12 +3151,37 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
 	case DRV_TYPE_IO_1V8_ONLY:
 		rmask_bits = RK3288_DRV_BITS_PER_PIN;
 		break;
+	case DRV_TYPE_IO_LEVEL_2_BIT:
+		ret = regmap_read(regmap, reg, &data);
+		if (ret)
+			return ret;
+		data >>= bit;
+
+		return data & 0x3;
+	case DRV_TYPE_IO_LEVEL_8_BIT:
+		ret = regmap_read(regmap, reg, &data);
+		if (ret)
+			return ret;
+		data >>= bit;
+		data &= (1 << 8) - 1;
+
+		ret = hweight8(data);
+		if (ret > 0)
+			return ret - 1;
+		else
+			return -EINVAL;
 	default:
 		dev_err(dev, "unsupported pinctrl drive type: %d\n", drv_type);
 		return -EINVAL;
 	}
 
 config:
+	if (ctrl->type == RK3506) {
+		if ((bank->bank_num == 0 && pin_num == 24) || bank->bank_num == 4) {
+			rmask_bits = 2;
+			ret = strength;
+		}
+	}
 	/* enable the write to the equivalent lower bits */
 	data = ((1 << rmask_bits) - 1) << (bit + 16);
 	rmask = data | (data >> 16);
@@ -2957,6 +3305,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
 	case RK3328:
 	case RK3368:
 	case RK3399:
+	case RK3506:
 	case RK3528:
 	case RK3562:
 	case RK3568:
@@ -3077,6 +3426,10 @@ static int rockchip_get_schmitt(struct rockchip_pin_bank *bank, int pin_num)
 		break;
 	}
 
+	if (ctrl->type == RK3506)
+		if ((bank->bank_num == 0 && pin_num == 24) ||  bank->bank_num == 4)
+			return data & 0x3;
+
 	return data & 0x1;
 }
 
@@ -3112,6 +3465,14 @@ static int rockchip_set_schmitt(struct rockchip_pin_bank *bank,
 		break;
 	}
 
+	if (ctrl->type == RK3506) {
+		if ((bank->bank_num == 0 && pin_num == 24) || bank->bank_num == 4) {
+			data = 0x3 << (bit + 16);
+			rmask = data | (data >> 16);
+			data |= ((enable ? 0x3 : 0) << bit);
+		}
+	}
+
 	return regmap_update_bits(regmap, reg, rmask, data);
 }
 
@@ -3227,6 +3588,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl,
 	case RK3328:
 	case RK3368:
 	case RK3399:
+	case RK3506:
 	case RK3528:
 	case RK3562:
 	case RK3568:
@@ -3880,13 +4242,10 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
 	}
 
 	/* try to find the optional reference to the pmu syscon */
-	node = of_parse_phandle(np, "rockchip,pmu", 0);
-	if (node) {
-		info->regmap_pmu = syscon_node_to_regmap(node);
-		of_node_put(node);
-		if (IS_ERR(info->regmap_pmu))
-			return PTR_ERR(info->regmap_pmu);
-	}
+	info->regmap_pmu = syscon_regmap_lookup_by_phandle_optional(np, "rockchip,pmu");
+
+	/* try to find the optional reference to the ioc1 syscon */
+	info->regmap_ioc1 = syscon_regmap_lookup_by_phandle_optional(np, "rockchip,ioc1");
 
 	ret = rockchip_pinctrl_register(pdev, info);
 	if (ret)
@@ -4350,6 +4709,71 @@ static struct rockchip_pin_ctrl rk3399_pin_ctrl = {
 		.drv_calc_reg		= rk3399_calc_drv_reg_and_bit,
 };
 
+static struct rockchip_pin_bank rk3506_pin_banks[] = {
+	PIN_BANK_IOMUX_FLAGS_OFFSET_DRV_FLAGS_PULL_FLAGS(0, 32, "gpio0",
+				    IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU,
+				    IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU,
+				    IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU,
+				    IOMUX_WIDTH_2BIT | IOMUX_SOURCE_PMU,
+				    0x0, 0x8, 0x10, 0x830,
+				    DRV_TYPE_IO_LEVEL_8_BIT,
+				    DRV_TYPE_IO_LEVEL_8_BIT,
+				    DRV_TYPE_IO_LEVEL_8_BIT,
+				    DRV_TYPE_IO_LEVEL_2_BIT,
+				    0, 0, 0, 1),
+	PIN_BANK_IOMUX_FLAGS_OFFSET_DRV_FLAGS(1, 32, "gpio1",
+				    IOMUX_WIDTH_4BIT,
+				    IOMUX_WIDTH_4BIT,
+				    IOMUX_WIDTH_4BIT,
+				    IOMUX_WIDTH_4BIT,
+				    0x20, 0x28, 0x30, 0x38,
+				    DRV_TYPE_IO_LEVEL_8_BIT,
+				    DRV_TYPE_IO_LEVEL_8_BIT,
+				    DRV_TYPE_IO_LEVEL_8_BIT,
+				    DRV_TYPE_IO_LEVEL_8_BIT),
+	PIN_BANK_IOMUX_FLAGS_OFFSET_DRV_FLAGS(2, 32, "gpio2",
+				    IOMUX_WIDTH_4BIT,
+				    IOMUX_WIDTH_4BIT,
+				    IOMUX_WIDTH_4BIT,
+				    IOMUX_WIDTH_4BIT,
+				    0x40, 0x48, 0x50, 0x58,
+				    DRV_TYPE_IO_LEVEL_8_BIT,
+				    DRV_TYPE_IO_LEVEL_8_BIT,
+				    DRV_TYPE_IO_LEVEL_8_BIT,
+				    DRV_TYPE_IO_LEVEL_8_BIT),
+	PIN_BANK_IOMUX_FLAGS_OFFSET_DRV_FLAGS(3, 32, "gpio3",
+				    IOMUX_WIDTH_4BIT,
+				    IOMUX_WIDTH_4BIT,
+				    IOMUX_WIDTH_4BIT,
+				    IOMUX_WIDTH_4BIT,
+				    0x60, 0x68, 0x70, 0x78,
+				    DRV_TYPE_IO_LEVEL_8_BIT,
+				    DRV_TYPE_IO_LEVEL_8_BIT,
+				    DRV_TYPE_IO_LEVEL_8_BIT,
+				    DRV_TYPE_IO_LEVEL_8_BIT),
+	PIN_BANK_IOMUX_FLAGS_OFFSET_DRV_FLAGS_PULL_FLAGS(4, 32, "gpio4",
+				    IOMUX_WIDTH_4BIT,
+				    IOMUX_WIDTH_4BIT,
+				    IOMUX_WIDTH_4BIT,
+				    IOMUX_WIDTH_4BIT,
+				    0x80, 0x88, 0x90, 0x98,
+				    DRV_TYPE_IO_LEVEL_2_BIT,
+				    DRV_TYPE_IO_LEVEL_2_BIT,
+				    DRV_TYPE_IO_LEVEL_2_BIT,
+				    DRV_TYPE_IO_LEVEL_2_BIT,
+				    1, 1, 1, 1),
+};
+
+static struct rockchip_pin_ctrl rk3506_pin_ctrl __maybe_unused = {
+	.pin_banks		= rk3506_pin_banks,
+	.nr_banks		= ARRAY_SIZE(rk3506_pin_banks),
+	.label			= "RK3506-GPIO",
+	.type			= RK3506,
+	.pull_calc_reg		= rk3506_calc_pull_reg_and_bit,
+	.drv_calc_reg		= rk3506_calc_drv_reg_and_bit,
+	.schmitt_calc_reg	= rk3506_calc_schmitt_reg_and_bit,
+};
+
 static struct rockchip_pin_bank rk3528_pin_banks[] = {
 	PIN_BANK_IOMUX_FLAGS_OFFSET(0, 32, "gpio0",
 				    IOMUX_WIDTH_4BIT,
@@ -4560,6 +4984,8 @@ static const struct of_device_id rockchip_pinctrl_dt_match[] = {
 		.data = &rk3368_pin_ctrl },
 	{ .compatible = "rockchip,rk3399-pinctrl",
 		.data = &rk3399_pin_ctrl },
+	{ .compatible = "rockchip,rk3506-pinctrl",
+		.data = &rk3506_pin_ctrl },
 	{ .compatible = "rockchip,rk3528-pinctrl",
 		.data = &rk3528_pin_ctrl },
 	{ .compatible = "rockchip,rk3562-pinctrl",
diff --git a/drivers/pinctrl/pinctrl-rockchip.h b/drivers/pinctrl/pinctrl-rockchip.h
index 35cd38079d1e..4f4aff42a80a 100644
--- a/drivers/pinctrl/pinctrl-rockchip.h
+++ b/drivers/pinctrl/pinctrl-rockchip.h
@@ -196,6 +196,7 @@ enum rockchip_pinctrl_type {
 	RK3328,
 	RK3368,
 	RK3399,
+	RK3506,
 	RK3528,
 	RK3562,
 	RK3568,
@@ -260,6 +261,8 @@ enum rockchip_pin_drv_type {
 	DRV_TYPE_IO_1V8_ONLY,
 	DRV_TYPE_IO_1V8_3V0_AUTO,
 	DRV_TYPE_IO_3V3_ONLY,
+	DRV_TYPE_IO_LEVEL_2_BIT,
+	DRV_TYPE_IO_LEVEL_8_BIT,
 	DRV_TYPE_MAX
 };
 
@@ -458,6 +461,7 @@ struct rockchip_pinctrl {
 	int				reg_size;
 	struct regmap			*regmap_pull;
 	struct regmap			*regmap_pmu;
+	struct regmap			*regmap_ioc1;
 	struct device			*dev;
 	struct rockchip_pin_ctrl	*ctrl;
 	struct pinctrl_desc		pctl;
-- 
2.34.1



From zhangqing at rock-chips.com  Mon Nov  3 19:06:28 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Tue,  4 Nov 2025 11:06:28 +0800
Subject: [PATCH v6 0/5] clk: rockchip: Add clock controller for the RV1126B and RK3506
Message-ID: <20251104030633.2721038-1-zhangqing@rock-chips.com>

Add yaml and dt-bindings for the RV1126B and RK3506.
RK3506 depend on patches 1/5, so it is merged and submitted.

Change in V6:
Drop pvtpll, others no change.
There are many questions about pvtpll and have some dependency issues.
They will be submitted separately later.

Change in V5:
[PATCH v5 1/7]: No change
[PATCH v5 2/7]: No change
[PATCH v5 3/7]: Drop RV1126B_GRF_SOC_STATUS0
[PATCH v5 4/7]: Drop syscon
[PATCH v5 5/7]: No change
[PATCH v5 6/7]: Add clocks and clock-names, fix id define
[PATCH v5 7/7]: Drop RK3506_GRF_SOC_STATUS

Change in V4:
[PATCH v4 1/7]: No change
[PATCH v4 2/7]: remove label
[PATCH v4 3/7]: No change
[PATCH v4 4/7]: remove label,fix order
[PATCH v4 5/7]: No change
[PATCH v4 6/7]: Add yaml and dt-bindings for the RK3506
[PATCH v4 7/7]: Add clock controller for the RK3506

Change in V3:
[PATCH v3 1/5]: No change
[PATCH v3 2/5]: Fix define error
[PATCH v3 3/5]: update driver,fix errir
[PATCH v3 4/5]: fix error
[PATCH v3 5/5]: No change

Change in V2:
[PATCH v2 1/5]: update commit message, rename v2 to multi_pll
[PATCH v2 2/5]: Modify DT binding headers license
[PATCH v2 3/5]: update driver
[PATCH v2 4/5]: fix error
[PATCH v2 5/5]: update commit message

Elaine Zhang (4):
  clk: rockchip: Implement rockchip_clk_register_armclk_multi_pll()
  dt-bindings: clock, reset: Add support for rv1126b
  clk: rockchip: Add clock controller for the RV1126B
  clk: rockchip: Add clock and reset driver for RK3506

Finley Xiao (1):
  dt-bindings: clock: rockchip: Add RK3506 clock and reset unit

 .../bindings/clock/rockchip,rk3506-cru.yaml   |   51 +
 .../bindings/clock/rockchip,rv1126b-cru.yaml  |   52 +
 drivers/clk/rockchip/Kconfig                  |   14 +
 drivers/clk/rockchip/Makefile                 |    2 +
 drivers/clk/rockchip/clk-cpu.c                |  165 +++
 drivers/clk/rockchip/clk-rk3506.c             |  869 +++++++++++++
 drivers/clk/rockchip/clk-rv1126b.c            | 1103 +++++++++++++++++
 drivers/clk/rockchip/clk.c                    |   24 +
 drivers/clk/rockchip/clk.h                    |   96 ++
 drivers/clk/rockchip/rst-rk3506.c             |  226 ++++
 drivers/clk/rockchip/rst-rv1126b.c            |  444 +++++++
 .../dt-bindings/clock/rockchip,rk3506-cru.h   |  285 +++++
 .../dt-bindings/clock/rockchip,rv1126b-cru.h  |  392 ++++++
 .../dt-bindings/reset/rockchip,rk3506-cru.h   |  211 ++++
 .../dt-bindings/reset/rockchip,rv1126b-cru.h  |  405 ++++++
 15 files changed, 4339 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rv1126b-cru.yaml
 create mode 100644 drivers/clk/rockchip/clk-rk3506.c
 create mode 100644 drivers/clk/rockchip/clk-rv1126b.c
 create mode 100644 drivers/clk/rockchip/rst-rk3506.c
 create mode 100644 drivers/clk/rockchip/rst-rv1126b.c
 create mode 100644 include/dt-bindings/clock/rockchip,rk3506-cru.h
 create mode 100644 include/dt-bindings/clock/rockchip,rv1126b-cru.h
 create mode 100644 include/dt-bindings/reset/rockchip,rk3506-cru.h
 create mode 100644 include/dt-bindings/reset/rockchip,rv1126b-cru.h


base-commit: 9893549e592ad22d0a18de97acfb30204109290a
-- 
2.34.1



From zhangqing at rock-chips.com  Mon Nov  3 19:06:29 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Tue,  4 Nov 2025 11:06:29 +0800
Subject: [PATCH v6 1/5] clk: rockchip: Implement rockchip_clk_register_armclk_multi_pll()
In-Reply-To: <20251104030633.2721038-1-zhangqing@rock-chips.com>
References: <20251104030633.2721038-1-zhangqing@rock-chips.com>
Message-ID: <20251104030633.2721038-2-zhangqing@rock-chips.com>

The current path will have an independent PLL(LPLL\BPLL)
exclusively for the CPU to use.
As follows:

            |-\
    --lpll--|  \
            |mux|--[gate]--[div]--clk_core--
    --gpll--|  /
            |-/

The new chip does not have a dedicated PLL for the cpu;
it is distributed nearby from the common PLL.
If there are special frequency requirements that require the
use of pvtpll, explanations will be submitted later.

The clock path of new soc CPU simplified as follows:

    --gpll--|--\
            |   \
            |    \
            |     \
   --v0pll--| mux |--[gate]--[div]--clk_core--
            |     /
            |    /
   --v1pll--|   /
            |--/

Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
---
 drivers/clk/rockchip/clk-cpu.c | 165 +++++++++++++++++++++++++++++++++
 drivers/clk/rockchip/clk.c     |  24 +++++
 drivers/clk/rockchip/clk.h     |  15 +++
 3 files changed, 204 insertions(+)

diff --git a/drivers/clk/rockchip/clk-cpu.c b/drivers/clk/rockchip/clk-cpu.c
index dcc9dcb597ae..6e91a3041a03 100644
--- a/drivers/clk/rockchip/clk-cpu.c
+++ b/drivers/clk/rockchip/clk-cpu.c
@@ -396,3 +396,168 @@ struct clk *rockchip_clk_register_cpuclk(const char *name,
 	kfree(cpuclk);
 	return ERR_PTR(ret);
 }
+
+static int rockchip_cpuclk_multi_pll_pre_rate_change(struct rockchip_cpuclk *cpuclk,
+						     struct clk_notifier_data *ndata)
+{
+	unsigned long new_rate = roundup(ndata->new_rate, 1000);
+	const struct rockchip_cpuclk_rate_table *rate;
+	unsigned long flags;
+
+	rate = rockchip_get_cpuclk_settings(cpuclk, new_rate);
+	if (!rate) {
+		pr_err("%s: Invalid rate : %lu for cpuclk\n",
+		       __func__, new_rate);
+		return -EINVAL;
+	}
+
+	if (new_rate > ndata->old_rate) {
+		spin_lock_irqsave(cpuclk->lock, flags);
+		rockchip_cpuclk_set_dividers(cpuclk, rate);
+		spin_unlock_irqrestore(cpuclk->lock, flags);
+	}
+
+	return 0;
+}
+
+static int rockchip_cpuclk_multi_pll_post_rate_change(struct rockchip_cpuclk *cpuclk,
+						      struct clk_notifier_data *ndata)
+{
+	unsigned long new_rate = roundup(ndata->new_rate, 1000);
+	const struct rockchip_cpuclk_rate_table *rate;
+	unsigned long flags;
+
+	rate = rockchip_get_cpuclk_settings(cpuclk, new_rate);
+	if (!rate) {
+		pr_err("%s: Invalid rate : %lu for cpuclk\n",
+		       __func__, new_rate);
+		return -EINVAL;
+	}
+
+	if (new_rate < ndata->old_rate) {
+		spin_lock_irqsave(cpuclk->lock, flags);
+		rockchip_cpuclk_set_dividers(cpuclk, rate);
+		spin_unlock_irqrestore(cpuclk->lock, flags);
+	}
+
+	return 0;
+}
+
+static int rockchip_cpuclk_multi_pll_notifier_cb(struct notifier_block *nb,
+						 unsigned long event, void *data)
+{
+	struct clk_notifier_data *ndata = data;
+	struct rockchip_cpuclk *cpuclk = to_rockchip_cpuclk_nb(nb);
+	int ret = 0;
+
+	pr_debug("%s: event %lu, old_rate %lu, new_rate: %lu\n",
+		 __func__, event, ndata->old_rate, ndata->new_rate);
+	if (event == PRE_RATE_CHANGE)
+		ret = rockchip_cpuclk_multi_pll_pre_rate_change(cpuclk, ndata);
+	else if (event == POST_RATE_CHANGE)
+		ret = rockchip_cpuclk_multi_pll_post_rate_change(cpuclk, ndata);
+
+	return notifier_from_errno(ret);
+}
+
+struct clk *rockchip_clk_register_cpuclk_multi_pll(const char *name,
+						   const char *const *parent_names,
+						   u8 num_parents, void __iomem *base,
+						   int muxdiv_offset, u8 mux_shift,
+						   u8 mux_width, u8 mux_flags,
+						   int div_offset, u8 div_shift,
+						   u8 div_width, u8 div_flags,
+						   unsigned long flags, spinlock_t *lock,
+						   const struct rockchip_cpuclk_rate_table *rates,
+						   int nrates)
+{
+	struct rockchip_cpuclk *cpuclk;
+	struct clk_hw *hw;
+	struct clk_mux *mux = NULL;
+	struct clk_divider *div = NULL;
+	const struct clk_ops *mux_ops = NULL, *div_ops = NULL;
+	int ret;
+
+	if (num_parents > 1) {
+		mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+		if (!mux)
+			return ERR_PTR(-ENOMEM);
+
+		mux->reg = base + muxdiv_offset;
+		mux->shift = mux_shift;
+		mux->mask = BIT(mux_width) - 1;
+		mux->flags = mux_flags;
+		mux->lock = lock;
+		mux_ops = (mux_flags & CLK_MUX_READ_ONLY) ? &clk_mux_ro_ops
+							: &clk_mux_ops;
+	}
+
+	if (div_width > 0) {
+		div = kzalloc(sizeof(*div), GFP_KERNEL);
+		if (!div) {
+			ret = -ENOMEM;
+			goto free_mux;
+		}
+
+		div->flags = div_flags;
+		if (div_offset)
+			div->reg = base + div_offset;
+		else
+			div->reg = base + muxdiv_offset;
+		div->shift = div_shift;
+		div->width = div_width;
+		div->lock = lock;
+		div_ops = (div_flags & CLK_DIVIDER_READ_ONLY)
+						? &clk_divider_ro_ops
+						: &clk_divider_ops;
+	}
+
+	hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
+				       mux ? &mux->hw : NULL, mux_ops,
+				       div ? &div->hw : NULL, div_ops,
+				       NULL, NULL, flags);
+	if (IS_ERR(hw)) {
+		ret = PTR_ERR(hw);
+		goto free_div;
+	}
+
+	cpuclk = kzalloc(sizeof(*cpuclk), GFP_KERNEL);
+	if (!cpuclk) {
+		ret = -ENOMEM;
+		goto unregister_clk;
+	}
+
+	cpuclk->reg_base = base;
+	cpuclk->lock = lock;
+	cpuclk->clk_nb.notifier_call = rockchip_cpuclk_multi_pll_notifier_cb;
+	ret = clk_notifier_register(hw->clk, &cpuclk->clk_nb);
+	if (ret) {
+		pr_err("%s: failed to register clock notifier for %s\n",
+		       __func__, name);
+		goto free_cpuclk;
+	}
+
+	if (nrates > 0) {
+		cpuclk->rate_count = nrates;
+		cpuclk->rate_table = kmemdup(rates,
+					     sizeof(*rates) * nrates,
+					     GFP_KERNEL);
+		if (!cpuclk->rate_table) {
+			ret = -ENOMEM;
+			goto free_cpuclk;
+		}
+	}
+
+	return hw->clk;
+
+free_cpuclk:
+	kfree(cpuclk);
+unregister_clk:
+	clk_hw_unregister_composite(hw);
+free_div:
+	kfree(div);
+free_mux:
+	kfree(mux);
+
+	return ERR_PTR(ret);
+}
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
index 19caf26c991b..2601df3b1066 100644
--- a/drivers/clk/rockchip/clk.c
+++ b/drivers/clk/rockchip/clk.c
@@ -722,6 +722,30 @@ void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
 }
 EXPORT_SYMBOL_GPL(rockchip_clk_register_armclk);
 
+void rockchip_clk_register_armclk_multi_pll(struct rockchip_clk_provider *ctx,
+					    struct rockchip_clk_branch *list,
+					    const struct rockchip_cpuclk_rate_table *rates,
+					    int nrates)
+{
+	struct clk *clk;
+
+	clk = rockchip_clk_register_cpuclk_multi_pll(list->name, list->parent_names,
+						     list->num_parents, ctx->reg_base,
+						     list->muxdiv_offset, list->mux_shift,
+						     list->mux_width, list->mux_flags,
+						     list->div_offset, list->div_shift,
+						     list->div_width, list->div_flags,
+						     list->flags, &ctx->lock, rates, nrates);
+	if (IS_ERR(clk)) {
+		pr_err("%s: failed to register clock %s: %ld\n",
+		       __func__, list->name, PTR_ERR(clk));
+		return;
+	}
+
+	rockchip_clk_set_lookup(ctx, clk, list->id);
+}
+EXPORT_SYMBOL_GPL(rockchip_clk_register_armclk_multi_pll);
+
 void rockchip_clk_protect_critical(const char *const clocks[],
 				   int nclocks)
 {
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index 7c5e74c7a2e2..23653a942403 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -622,6 +622,17 @@ struct clk *rockchip_clk_register_cpuclk(const char *name,
 			const struct rockchip_cpuclk_rate_table *rates,
 			int nrates, void __iomem *reg_base, spinlock_t *lock);
 
+struct clk *rockchip_clk_register_cpuclk_multi_pll(const char *name,
+						   const char *const *parent_names,
+						   u8 num_parents, void __iomem *base,
+						   int muxdiv_offset, u8 mux_shift,
+						   u8 mux_width, u8 mux_flags,
+						   int div_offset, u8 div_shift,
+						   u8 div_width, u8 div_flags,
+						   unsigned long flags, spinlock_t *lock,
+						   const struct rockchip_cpuclk_rate_table *rates,
+						   int nrates);
+
 struct clk *rockchip_clk_register_mmc(const char *name,
 				const char *const *parent_names, u8 num_parents,
 				void __iomem *reg,
@@ -1208,6 +1219,10 @@ void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
 			const struct rockchip_cpuclk_reg_data *reg_data,
 			const struct rockchip_cpuclk_rate_table *rates,
 			int nrates);
+void rockchip_clk_register_armclk_multi_pll(struct rockchip_clk_provider *ctx,
+					    struct rockchip_clk_branch *list,
+					    const struct rockchip_cpuclk_rate_table *rates,
+					    int nrates);
 void rockchip_clk_protect_critical(const char *const clocks[], int nclocks);
 void rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx,
 					unsigned int reg, void (*cb)(void));
-- 
2.34.1



From zhangqing at rock-chips.com  Mon Nov  3 19:06:30 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Tue,  4 Nov 2025 11:06:30 +0800
Subject: [PATCH v6 2/5] dt-bindings: clock, reset: Add support for rv1126b
In-Reply-To: <20251104030633.2721038-1-zhangqing@rock-chips.com>
References: <20251104030633.2721038-1-zhangqing@rock-chips.com>
Message-ID: <20251104030633.2721038-3-zhangqing@rock-chips.com>

Add clock and reset ID defines for rv1126b.
Also add documentation for the rv1126b CRU core.

Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
Acked-by: Conor Dooley <conor.dooley at microchip.com>
---
 .../bindings/clock/rockchip,rv1126b-cru.yaml  |  52 +++
 .../dt-bindings/clock/rockchip,rv1126b-cru.h  | 392 +++++++++++++++++
 .../dt-bindings/reset/rockchip,rv1126b-cru.h  | 405 ++++++++++++++++++
 3 files changed, 849 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rv1126b-cru.yaml
 create mode 100644 include/dt-bindings/clock/rockchip,rv1126b-cru.h
 create mode 100644 include/dt-bindings/reset/rockchip,rv1126b-cru.h

diff --git a/Documentation/devicetree/bindings/clock/rockchip,rv1126b-cru.yaml b/Documentation/devicetree/bindings/clock/rockchip,rv1126b-cru.yaml
new file mode 100644
index 000000000000..04b0a5c51e4e
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/rockchip,rv1126b-cru.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/rockchip,rv1126b-cru.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip RV1126B Clock and Reset Unit
+
+maintainers:
+  - Elaine Zhang <zhangqing at rock-chips.com>
+  - Heiko Stuebner <heiko at sntech.de>
+
+description:
+  The rv1126b clock controller generates the clock and also implements a
+  reset controller for SoC peripherals.
+
+properties:
+  compatible:
+    enum:
+      - rockchip,rv1126b-cru
+
+  reg:
+    maxItems: 1
+
+  "#clock-cells":
+    const: 1
+
+  "#reset-cells":
+    const: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    const: xin24m
+
+required:
+  - compatible
+  - reg
+  - "#clock-cells"
+  - "#reset-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller at 20000000 {
+      compatible = "rockchip,rv1126b-cru";
+      reg = <0x20000000 0xc0000>;
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+    };
diff --git a/include/dt-bindings/clock/rockchip,rv1126b-cru.h b/include/dt-bindings/clock/rockchip,rv1126b-cru.h
new file mode 100644
index 000000000000..d6040058c21f
--- /dev/null
+++ b/include/dt-bindings/clock/rockchip,rv1126b-cru.h
@@ -0,0 +1,392 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/*
+ * Copyright (c) 2025 Rockchip Electronics Co., Ltd.
+ * Author: Elaine Zhang <zhangqing at rock-chips.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RV1126B_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_RV1126B_H
+
+/* pll clocks */
+#define PLL_GPLL				1
+#define PLL_CPLL				2
+#define PLL_AUPLL				3
+#define ARMCLK					4
+#define SCLK_DDR				5
+
+/* clk (clocks) */
+#define CLK_CPLL_DIV20				8
+#define CLK_CPLL_DIV10				9
+#define CLK_CPLL_DIV8				10
+#define CLK_GPLL_DIV8				11
+#define CLK_GPLL_DIV6				12
+#define CLK_GPLL_DIV4				13
+#define CLK_CPLL_DIV3				14
+#define CLK_GPLL_DIV3				15
+#define CLK_CPLL_DIV2				16
+#define CLK_GPLL_DIV2				17
+#define CLK_CM_FRAC0				18
+#define CLK_CM_FRAC1				19
+#define CLK_CM_FRAC2				20
+#define CLK_UART_FRAC0				21
+#define CLK_UART_FRAC1				22
+#define CLK_AUDIO_FRAC0				23
+#define CLK_AUDIO_FRAC1				24
+#define CLK_AUDIO_INT0				25
+#define CLK_AUDIO_INT1				26
+#define SCLK_UART0_SRC				27
+#define SCLK_UART1				28
+#define SCLK_UART2				29
+#define SCLK_UART3				30
+#define SCLK_UART4				31
+#define SCLK_UART5				32
+#define SCLK_UART6				33
+#define SCLK_UART7				34
+#define MCLK_SAI0				35
+#define MCLK_SAI1				36
+#define MCLK_SAI2				37
+#define MCLK_PDM				38
+#define CLKOUT_PDM				39
+#define MCLK_ASRC0				40
+#define MCLK_ASRC1				41
+#define MCLK_ASRC2				42
+#define MCLK_ASRC3				43
+#define CLK_ASRC0				44
+#define CLK_ASRC1				45
+#define CLK_CORE_PLL				46
+#define CLK_NPU_PLL				47
+#define CLK_VEPU_PLL				48
+#define CLK_ISP_PLL				49
+#define CLK_AISP_PLL				50
+#define CLK_SARADC0_SRC				51
+#define CLK_SARADC1_SRC				52
+#define CLK_SARADC2_SRC				53
+#define HCLK_NPU_ROOT				54
+#define PCLK_NPU_ROOT				55
+#define ACLK_VEPU_ROOT				56
+#define HCLK_VEPU_ROOT				57
+#define PCLK_VEPU_ROOT				58
+#define CLK_CORE_RGA_SRC			59
+#define ACLK_GMAC_ROOT				60
+#define ACLK_VI_ROOT				61
+#define HCLK_VI_ROOT				62
+#define PCLK_VI_ROOT				63
+#define DCLK_VICAP_ROOT				64
+#define CLK_SYS_DSMC_ROOT			65
+#define ACLK_VDO_ROOT				66
+#define ACLK_RKVDEC_ROOT			67
+#define HCLK_VDO_ROOT				68
+#define PCLK_VDO_ROOT				69
+#define DCLK_OOC_SRC				70
+#define DCLK_VOP				71
+#define DCLK_DECOM_SRC				72
+#define PCLK_DDR_ROOT				73
+#define ACLK_SYSMEM_SRC				74
+#define ACLK_TOP_ROOT				75
+#define ACLK_BUS_ROOT				76
+#define HCLK_BUS_ROOT				77
+#define PCLK_BUS_ROOT				78
+#define CCLK_SDMMC0				79
+#define CCLK_SDMMC1				80
+#define CCLK_EMMC				81
+#define SCLK_2X_FSPI0				82
+#define CLK_GMAC_PTP_REF_SRC			83
+#define CLK_GMAC_125M				84
+#define CLK_TIMER_ROOT				85
+#define TCLK_WDT_NS_SRC				86
+#define TCLK_WDT_S_SRC				87
+#define TCLK_WDT_HPMCU				88
+#define CLK_CAN0				89
+#define CLK_CAN1				90
+#define PCLK_PERI_ROOT				91
+#define ACLK_PERI_ROOT				92
+#define CLK_I2C_BUS_SRC				93
+#define CLK_SPI0				94
+#define CLK_SPI1				95
+#define BUSCLK_PMU_SRC				96
+#define CLK_PWM0				97
+#define CLK_PWM2				98
+#define CLK_PWM3				99
+#define CLK_PKA_RKCE_SRC			100
+#define ACLK_RKCE_SRC				101
+#define ACLK_VCP_ROOT				102
+#define HCLK_VCP_ROOT				103
+#define PCLK_VCP_ROOT				104
+#define CLK_CORE_FEC_SRC			105
+#define CLK_CORE_AVSP_SRC			106
+#define CLK_50M_GMAC_IOBUF_VI			107
+#define PCLK_TOP_ROOT				108
+#define CLK_MIPI0_OUT2IO			109
+#define CLK_MIPI1_OUT2IO			110
+#define CLK_MIPI2_OUT2IO			111
+#define CLK_MIPI3_OUT2IO			112
+#define CLK_CIF_OUT2IO				113
+#define CLK_MAC_OUT2IO				114
+#define MCLK_SAI0_OUT2IO			115
+#define MCLK_SAI1_OUT2IO			116
+#define MCLK_SAI2_OUT2IO			117
+#define CLK_CM_FRAC0_SRC			118
+#define CLK_CM_FRAC1_SRC			119
+#define CLK_CM_FRAC2_SRC			120
+#define CLK_UART_FRAC0_SRC			121
+#define CLK_UART_FRAC1_SRC			122
+#define CLK_AUDIO_FRAC0_SRC			123
+#define CLK_AUDIO_FRAC1_SRC			124
+#define ACLK_NPU_ROOT				125
+#define HCLK_RKNN				126
+#define ACLK_RKNN				127
+#define PCLK_GPIO3				128
+#define DBCLK_GPIO3				129
+#define PCLK_IOC_VCCIO3				130
+#define PCLK_SARADC0				131
+#define CLK_SARADC0				132
+#define HCLK_SDMMC1				133
+#define HCLK_VEPU				134
+#define ACLK_VEPU				135
+#define CLK_CORE_VEPU				136
+#define HCLK_FEC				137
+#define ACLK_FEC				138
+#define CLK_CORE_FEC				139
+#define HCLK_AVSP				140
+#define ACLK_AVSP				141
+#define BUSCLK_PMU1_ROOT			142
+#define HCLK_AISP				143
+#define ACLK_AISP				144
+#define CLK_CORE_AISP				145
+#define CLK_CORE_ISP_ROOT			146
+#define PCLK_DSMC				147
+#define ACLK_DSMC				148
+#define HCLK_CAN0				149
+#define HCLK_CAN1				150
+#define PCLK_GPIO2				151
+#define DBCLK_GPIO2				152
+#define PCLK_GPIO4				153
+#define DBCLK_GPIO4				154
+#define PCLK_GPIO5				155
+#define DBCLK_GPIO5				156
+#define PCLK_GPIO6				157
+#define DBCLK_GPIO6				158
+#define PCLK_GPIO7				159
+#define DBCLK_GPIO7				160
+#define PCLK_IOC_VCCIO2				161
+#define PCLK_IOC_VCCIO4				162
+#define PCLK_IOC_VCCIO5				163
+#define PCLK_IOC_VCCIO6				164
+#define PCLK_IOC_VCCIO7				165
+#define HCLK_ISP				166
+#define ACLK_ISP				167
+#define CLK_CORE_ISP				168
+#define HCLK_VICAP				169
+#define ACLK_VICAP				170
+#define DCLK_VICAP				171
+#define ISP0CLK_VICAP				172
+#define HCLK_VPSS				173
+#define ACLK_VPSS				174
+#define CLK_CORE_VPSS				175
+#define PCLK_CSI2HOST0				176
+#define DCLK_CSI2HOST0				177
+#define PCLK_CSI2HOST1				178
+#define DCLK_CSI2HOST1				179
+#define PCLK_CSI2HOST2				180
+#define DCLK_CSI2HOST2				181
+#define PCLK_CSI2HOST3				182
+#define DCLK_CSI2HOST3				183
+#define HCLK_SDMMC0				184
+#define ACLK_GMAC				185
+#define PCLK_GMAC				186
+#define CLK_GMAC_PTP_REF			187
+#define PCLK_CSIPHY0				188
+#define PCLK_CSIPHY1				189
+#define PCLK_MACPHY				190
+#define PCLK_SARADC1				191
+#define CLK_SARADC1				192
+#define PCLK_SARADC2				193
+#define CLK_SARADC2				194
+#define ACLK_RKVDEC				195
+#define HCLK_RKVDEC				196
+#define CLK_HEVC_CA_RKVDEC			197
+#define ACLK_VOP				198
+#define HCLK_VOP				199
+#define HCLK_RKJPEG				200
+#define ACLK_RKJPEG				201
+#define ACLK_RKMMU_DECOM			202
+#define HCLK_RKMMU_DECOM			203
+#define DCLK_DECOM				204
+#define ACLK_DECOM				205
+#define PCLK_DECOM				206
+#define PCLK_MIPI_DSI				207
+#define PCLK_DSIPHY				208
+#define ACLK_OOC				209
+#define ACLK_SYSMEM				210
+#define PCLK_DDRC				211
+#define PCLK_DDRMON				212
+#define CLK_TIMER_DDRMON			213
+#define PCLK_DFICTRL				214
+#define PCLK_DDRPHY				215
+#define PCLK_DMA2DDR				216
+#define CLK_RCOSC_SRC				217
+#define BUSCLK_PMU_MUX				218
+#define BUSCLK_PMU_ROOT				219
+#define PCLK_PMU				220
+#define CLK_XIN_RC_DIV				221
+#define CLK_32K					222
+#define PCLK_PMU_GPIO0				223
+#define DBCLK_PMU_GPIO0				224
+#define PCLK_PMU_HP_TIMER			225
+#define CLK_PMU_HP_TIMER			226
+#define CLK_PMU_32K_HP_TIMER			227
+#define PCLK_PWM1				228
+#define CLK_PWM1				229
+#define CLK_OSC_PWM1				230
+#define CLK_RC_PWM1				231
+#define CLK_FREQ_PWM1				232
+#define CLK_COUNTER_PWM1			233
+#define PCLK_I2C2				234
+#define CLK_I2C2				235
+#define PCLK_UART0				236
+#define SCLK_UART0				237
+#define PCLK_RCOSC_CTRL				238
+#define CLK_OSC_RCOSC_CTRL			239
+#define CLK_REF_RCOSC_CTRL			240
+#define PCLK_IOC_PMUIO0				241
+#define CLK_REFOUT				242
+#define CLK_PREROLL				243
+#define CLK_PREROLL_32K				244
+#define HCLK_PMU_SRAM				245
+#define PCLK_WDT_LPMCU				246
+#define TCLK_WDT_LPMCU				247
+#define CLK_LPMCU				248
+#define CLK_LPMCU_RTC				249
+#define PCLK_LPMCU_MAILBOX			250
+#define HCLK_OOC				251
+#define PCLK_SPI2AHB				252
+#define HCLK_SPI2AHB				253
+#define HCLK_FSPI1				254
+#define HCLK_XIP_FSPI1				255
+#define SCLK_1X_FSPI1				256
+#define PCLK_IOC_PMUIO1				257
+#define PCLK_AUDIO_ADC_PMU			258
+#define MCLK_AUDIO_ADC_PMU			259
+#define MCLK_AUDIO_ADC_DIV4_PMU			260
+#define MCLK_LPSAI				261
+#define ACLK_GIC400				262
+#define PCLK_WDT_NS				263
+#define TCLK_WDT_NS				264
+#define PCLK_WDT_HPMCU				265
+#define HCLK_CACHE				266
+#define PCLK_HPMCU_MAILBOX			267
+#define PCLK_HPMCU_INTMUX			268
+#define CLK_HPMCU				269
+#define CLK_HPMCU_RTC				270
+#define PCLK_RKDMA				271
+#define ACLK_RKDMA				272
+#define PCLK_DCF				273
+#define ACLK_DCF				274
+#define HCLK_RGA				275
+#define ACLK_RGA				276
+#define CLK_CORE_RGA				277
+#define PCLK_TIMER				278
+#define CLK_TIMER0				279
+#define CLK_TIMER1				280
+#define CLK_TIMER2				281
+#define CLK_TIMER3				282
+#define CLK_TIMER4				283
+#define CLK_TIMER5				284
+#define PCLK_I2C0				285
+#define CLK_I2C0				286
+#define PCLK_I2C1				287
+#define CLK_I2C1				288
+#define PCLK_I2C3				289
+#define CLK_I2C3				290
+#define PCLK_I2C4				291
+#define CLK_I2C4				292
+#define PCLK_I2C5				293
+#define CLK_I2C5				294
+#define PCLK_SPI0				295
+#define PCLK_SPI1				296
+#define PCLK_PWM0				297
+#define CLK_OSC_PWM0				298
+#define CLK_RC_PWM0				299
+#define PCLK_PWM2				300
+#define CLK_OSC_PWM2				301
+#define CLK_RC_PWM2				302
+#define PCLK_PWM3				303
+#define CLK_OSC_PWM3				304
+#define CLK_RC_PWM3				305
+#define PCLK_UART1				306
+#define PCLK_UART2				307
+#define PCLK_UART3				308
+#define PCLK_UART4				309
+#define PCLK_UART5				310
+#define PCLK_UART6				311
+#define PCLK_UART7				312
+#define PCLK_TSADC				313
+#define CLK_TSADC				314
+#define HCLK_SAI0				315
+#define HCLK_SAI1				316
+#define HCLK_SAI2				317
+#define HCLK_RKDSM				318
+#define MCLK_RKDSM				319
+#define HCLK_PDM				320
+#define HCLK_ASRC0				321
+#define HCLK_ASRC1				322
+#define PCLK_AUDIO_ADC_BUS			323
+#define MCLK_AUDIO_ADC_BUS			324
+#define MCLK_AUDIO_ADC_DIV4_BUS			325
+#define PCLK_RKCE				326
+#define HCLK_NS_RKCE				327
+#define PCLK_OTPC_NS				328
+#define CLK_SBPI_OTPC_NS			329
+#define CLK_USER_OTPC_NS			330
+#define CLK_OTPC_ARB				331
+#define PCLK_OTP_MASK				332
+#define CLK_TSADC_PHYCTRL			333
+#define LRCK_SRC_ASRC0				334
+#define LRCK_DST_ASRC0				335
+#define LRCK_SRC_ASRC1				336
+#define LRCK_DST_ASRC1				337
+#define PCLK_KEY_READER				338
+#define ACLK_NSRKCE				339
+#define CLK_PKA_NSRKCE				340
+#define PCLK_RTC_ROOT				341
+#define PCLK_GPIO1				342
+#define DBCLK_GPIO1				343
+#define PCLK_IOC_VCCIO1				344
+#define ACLK_USB3OTG				345
+#define CLK_REF_USB3OTG				346
+#define CLK_SUSPEND_USB3OTG			347
+#define HCLK_USB2HOST				348
+#define HCLK_ARB_USB2HOST			349
+#define PCLK_RTC_TEST				350
+#define HCLK_EMMC				351
+#define HCLK_FSPI0				352
+#define HCLK_XIP_FSPI0				353
+#define PCLK_PIPEPHY				354
+#define PCLK_USB2PHY				355
+#define CLK_REF_PIPEPHY_CPLL_SRC		356
+#define CLK_REF_PIPEPHY				357
+#define HCLK_VPSL				358
+#define ACLK_VPSL				359
+#define CLK_CORE_VPSL				360
+#define CLK_MACPHY				361
+#define HCLK_RKRNG_NS				362
+#define HCLK_RKRNG_S_NS				363
+#define CLK_AISP_PLL_SRC			364
+
+/* secure clks */
+#define CLK_USER_OTPC_S				400
+#define CLK_SBPI_OTPC_S				401
+#define PCLK_OTPC_S				402
+#define PCLK_KEY_READER_S			403
+#define HCLK_KL_RKCE_S				404
+#define HCLK_RKCE_S				405
+#define PCLK_WDT_S				406
+#define TCLK_WDT_S				407
+#define CLK_STIMER0				408
+#define CLK_STIMER1				409
+#define PLK_STIMER				410
+#define HCLK_RKRNG_S				411
+#define CLK_PKA_RKCE_S				412
+#define ACLK_RKCE_S				413
+
+#endif
diff --git a/include/dt-bindings/reset/rockchip,rv1126b-cru.h b/include/dt-bindings/reset/rockchip,rv1126b-cru.h
new file mode 100644
index 000000000000..19d6de2c054f
--- /dev/null
+++ b/include/dt-bindings/reset/rockchip,rv1126b-cru.h
@@ -0,0 +1,405 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/*
+ * Copyright (c) 2025 Rockchip Electronics Co., Ltd.
+ * Author: Elaine Zhang <zhangqing at rock-chips.com>
+ */
+
+#ifndef _DT_BINDINGS_RESET_ROCKCHIP_RV1126B_H
+#define _DT_BINDINGS_RESET_ROCKCHIP_RV1126B_H
+
+/* ==========================list all of reset fields id=========================== */
+/* TOPCRU-->SOFTRST_CON00 */
+
+/* TOPCRU-->SOFTRST_CON15 */
+#define SRST_PRESETN_CRU				0
+#define SRST_PRESETN_CRU_BIU				1
+
+/* BUSCRU-->SOFTRST_CON00 */
+#define SRST_ARESETN_TOP_BIU				2
+#define SRST_ARESETN_RKCE_BIU				3
+#define SRST_ARESETN_BUS_BIU				4
+#define SRST_HRESETN_BUS_BIU				5
+#define SRST_PRESETN_BUS_BIU				6
+#define SRST_PRESETN_CRU_BUS				7
+#define SRST_PRESETN_SYS_GRF				8
+#define SRST_HRESETN_BOOTROM				9
+#define SRST_ARESETN_GIC400				10
+#define SRST_ARESETN_SPINLOCK				11
+#define SRST_PRESETN_WDT_NS				12
+#define SRST_TRESETN_WDT_NS				13
+
+/* BUSCRU-->SOFTRST_CON01 */
+#define SRST_PRESETN_WDT_HPMCU				14
+#define SRST_TRESETN_WDT_HPMCU				15
+#define SRST_HRESETN_CACHE				16
+#define SRST_PRESETN_HPMCU_MAILBOX			17
+#define SRST_PRESETN_HPMCU_INTMUX			18
+#define SRST_RESETN_HPMCU_FULL_CLUSTER			19
+#define SRST_RESETN_HPMCU_PWUP				20
+#define SRST_RESETN_HPMCU_ONLY_CORE			21
+#define SRST_TRESETN_HPMCU_JTAG				22
+#define SRST_PRESETN_RKDMA				23
+#define SRST_ARESETN_RKDMA				24
+
+/* BUSCRU-->SOFTRST_CON02 */
+#define SRST_PRESETN_DCF				25
+#define SRST_ARESETN_DCF				26
+#define SRST_HRESETN_RGA				27
+#define SRST_ARESETN_RGA				28
+#define SRST_RESETN_CORE_RGA				29
+#define SRST_PRESETN_TIMER				30
+#define SRST_RESETN_TIMER0				31
+#define SRST_RESETN_TIMER1				32
+#define SRST_RESETN_TIMER2				33
+#define SRST_RESETN_TIMER3				34
+#define SRST_RESETN_TIMER4				35
+#define SRST_RESETN_TIMER5				36
+#define SRST_ARESETN_RKCE				37
+#define SRST_RESETN_PKA_RKCE				38
+#define SRST_HRESETN_RKRNG_S				39
+#define SRST_HRESETN_RKRNG_NS				40
+
+/* BUSCRU-->SOFTRST_CON03 */
+#define SRST_PRESETN_I2C0				41
+#define SRST_RESETN_I2C0				42
+#define SRST_PRESETN_I2C1				43
+#define SRST_RESETN_I2C1				44
+#define SRST_PRESETN_I2C3				45
+#define SRST_RESETN_I2C3				46
+#define SRST_PRESETN_I2C4				47
+#define SRST_RESETN_I2C4				48
+#define SRST_PRESETN_I2C5				49
+#define SRST_RESETN_I2C5				50
+#define SRST_PRESETN_SPI0				51
+#define SRST_RESETN_SPI0				52
+#define SRST_PRESETN_SPI1				53
+#define SRST_RESETN_SPI1				54
+
+/* BUSCRU-->SOFTRST_CON04 */
+#define SRST_PRESETN_PWM0				55
+#define SRST_RESETN_PWM0				56
+#define SRST_PRESETN_PWM2				57
+#define SRST_RESETN_PWM2				58
+#define SRST_PRESETN_PWM3				59
+#define SRST_RESETN_PWM3				60
+
+/* BUSCRU-->SOFTRST_CON05 */
+#define SRST_PRESETN_UART1				61
+#define SRST_SRESETN_UART1				62
+#define SRST_PRESETN_UART2				63
+#define SRST_SRESETN_UART2				64
+#define SRST_PRESETN_UART3				65
+#define SRST_SRESETN_UART3				66
+#define SRST_PRESETN_UART4				67
+#define SRST_SRESETN_UART4				68
+#define SRST_PRESETN_UART5				69
+#define SRST_SRESETN_UART5				70
+#define SRST_PRESETN_UART6				71
+#define SRST_SRESETN_UART6				72
+#define SRST_PRESETN_UART7				73
+#define SRST_SRESETN_UART7				74
+
+/* BUSCRU-->SOFTRST_CON06 */
+#define SRST_PRESETN_TSADC				75
+#define SRST_RESETN_TSADC				76
+#define SRST_HRESETN_SAI0				77
+#define SRST_MRESETN_SAI0				78
+#define SRST_HRESETN_SAI1				79
+#define SRST_MRESETN_SAI1				80
+#define SRST_HRESETN_SAI2				81
+#define SRST_MRESETN_SAI2				82
+#define SRST_HRESETN_RKDSM				83
+#define SRST_MRESETN_RKDSM				84
+#define SRST_HRESETN_PDM				85
+#define SRST_MRESETN_PDM				86
+#define SRST_RESETN_PDM					87
+
+/* BUSCRU-->SOFTRST_CON07 */
+#define SRST_HRESETN_ASRC0				88
+#define SRST_RESETN_ASRC0				89
+#define SRST_HRESETN_ASRC1				90
+#define SRST_RESETN_ASRC1				91
+#define SRST_PRESETN_AUDIO_ADC_BUS			92
+#define SRST_MRESETN_AUDIO_ADC_BUS			93
+#define SRST_PRESETN_RKCE				94
+#define SRST_HRESETN_NS_RKCE				95
+#define SRST_PRESETN_OTPC_NS				96
+#define SRST_RESETN_SBPI_OTPC_NS			97
+#define SRST_RESETN_USER_OTPC_NS			98
+#define SRST_RESETN_OTPC_ARB				99
+#define SRST_PRESETN_OTP_MASK				100
+
+/* PERICRU-->SOFTRST_CON00 */
+#define SRST_ARESETN_PERI_BIU				101
+#define SRST_PRESETN_PERI_BIU				102
+#define SRST_PRESETN_RTC_BIU				103
+#define SRST_PRESETN_CRU_PERI				104
+#define SRST_PRESETN_PERI_GRF				105
+#define SRST_PRESETN_GPIO1				106
+#define SRST_DBRESETN_GPIO1				107
+#define SRST_PRESETN_IOC_VCCIO1				108
+#define SRST_ARESETN_USB3OTG				109
+#define SRST_HRESETN_USB2HOST				110
+#define SRST_HRESETN_ARB_USB2HOST			111
+#define SRST_PRESETN_RTC_TEST				112
+
+/* PERICRU-->SOFTRST_CON01 */
+#define SRST_HRESETN_EMMC				113
+#define SRST_HRESETN_FSPI0				114
+#define SRST_HRESETN_XIP_FSPI0				115
+#define SRST_SRESETN_2X_FSPI0				116
+#define SRST_RESETN_UTMI_USB2HOST			117
+#define SRST_RESETN_REF_PIPEPHY				118
+#define SRST_PRESETN_PIPEPHY				119
+#define SRST_PRESETN_PIPEPHY_GRF			120
+#define SRST_PRESETN_USB2PHY				121
+#define SRST_RESETN_POR_USB2PHY				122
+#define SRST_RESETN_OTG_USB2PHY				123
+#define SRST_RESETN_HOST_USB2PHY			124
+
+/* CORECRU-->SOFTRST_CON00 */
+#define SRST_RESETN_REF_PVTPLL_CORE			125
+#define SRST_NCOREPORESET0				126
+#define SRST_NCORESET0					127
+#define SRST_NCOREPORESET1				128
+#define SRST_NCORESET1					129
+#define SRST_NCOREPORESET2				130
+#define SRST_NCORESET2					131
+#define SRST_NCOREPORESET3				132
+#define SRST_NCORESET3					133
+#define SRST_NDBGRESET					134
+#define SRST_NL2RESET					135
+
+/* CORECRU-->SOFTRST_CON01 */
+#define SRST_ARESETN_CORE_BIU				136
+#define SRST_PRESETN_CORE_BIU				137
+#define SRST_HRESETN_CORE_BIU				138
+#define SRST_PRESETN_DBG				139
+#define SRST_POTRESETN_DBG				140
+#define SRST_NTRESETN_DBG				141
+#define SRST_PRESETN_CORE_PVTPLL			142
+#define SRST_PRESETN_CRU_CORE				143
+#define SRST_PRESETN_CORE_GRF				144
+#define SRST_PRESETN_DFT2APB				145
+
+/* PMUCRU-->SOFTRST_CON00 */
+#define SRST_HRESETN_PMU_BIU				146
+#define SRST_PRESETN_PMU_GPIO0				147
+#define SRST_DBRESETN_PMU_GPIO0				148
+#define SRST_PRESETN_PMU_HP_TIMER			149
+#define SRST_RESETN_PMU_HP_TIMER			150
+#define SRST_RESETN_PMU_32K_HP_TIMER			151
+
+/* PMUCRU-->SOFTRST_CON01 */
+#define SRST_PRESETN_PWM1				152
+#define SRST_RESETN_PWM1				153
+#define SRST_PRESETN_I2C2				154
+#define SRST_RESETN_I2C2				155
+#define SRST_PRESETN_UART0				156
+#define SRST_SRESETN_UART0				157
+
+/* PMUCRU-->SOFTRST_CON02 */
+#define SRST_PRESETN_RCOSC_CTRL				158
+#define SRST_RESETN_REF_RCOSC_CTRL			159
+#define SRST_PRESETN_IOC_PMUIO0				160
+#define SRST_PRESETN_CRU_PMU				161
+#define SRST_PRESETN_PMU_GRF				162
+#define SRST_RESETN_PREROLL				163
+#define SRST_RESETN_PREROLL_32K				164
+#define SRST_HRESETN_PMU_SRAM				165
+
+/* PMUCRU-->SOFTRST_CON03 */
+#define SRST_PRESETN_WDT_LPMCU				166
+#define SRST_TRESETN_WDT_LPMCU				167
+#define SRST_RESETN_LPMCU_FULL_CLUSTER			168
+#define SRST_RESETN_LPMCU_PWUP				169
+#define SRST_RESETN_LPMCU_ONLY_CORE			170
+#define SRST_TRESETN_LPMCU_JTAG				171
+#define SRST_PRESETN_LPMCU_MAILBOX			172
+
+/* PMU1CRU-->SOFTRST_CON00 */
+#define SRST_PRESETN_SPI2AHB				173
+#define SRST_HRESETN_SPI2AHB				174
+#define SRST_HRESETN_FSPI1				175
+#define SRST_HRESETN_XIP_FSPI1				176
+#define SRST_SRESETN_1X_FSPI1				177
+#define SRST_PRESETN_IOC_PMUIO1				178
+#define SRST_PRESETN_CRU_PMU1				179
+#define SRST_PRESETN_AUDIO_ADC_PMU			180
+#define SRST_MRESETN_AUDIO_ADC_PMU			181
+#define SRST_HRESETN_PMU1_BIU				182
+
+/* PMU1CRU-->SOFTRST_CON01 */
+#define SRST_PRESETN_LPDMA				183
+#define SRST_ARESETN_LPDMA				184
+#define SRST_HRESETN_LPSAI				185
+#define SRST_MRESETN_LPSAI				186
+#define SRST_PRESETN_AOA_TDD				187
+#define SRST_PRESETN_AOA_FE				188
+#define SRST_PRESETN_AOA_AAD				189
+#define SRST_PRESETN_AOA_APB				190
+#define SRST_PRESETN_AOA_SRAM				191
+
+/* DDRCRU-->SOFTRST_CON00 */
+#define SRST_PRESETN_DDR_BIU				192
+#define SRST_PRESETN_DDRC				193
+#define SRST_PRESETN_DDRMON				194
+#define SRST_RESETN_TIMER_DDRMON			195
+#define SRST_PRESETN_DFICTRL				196
+#define SRST_PRESETN_DDR_GRF				197
+#define SRST_PRESETN_CRU_DDR				198
+#define SRST_PRESETN_DDRPHY				199
+#define SRST_PRESETN_DMA2DDR				200
+
+/* SUBDDRCRU-->SOFTRST_CON00 */
+#define SRST_ARESETN_SYSMEM_BIU				201
+#define SRST_ARESETN_SYSMEM				202
+#define SRST_ARESETN_DDR_BIU				203
+#define SRST_ARESETN_DDRSCH0_CPU			204
+#define SRST_ARESETN_DDRSCH1_NPU			205
+#define SRST_ARESETN_DDRSCH2_POE			206
+#define SRST_ARESETN_DDRSCH3_VI				207
+#define SRST_RESETN_CORE_DDRC				208
+#define SRST_RESETN_DDRMON				209
+#define SRST_RESETN_DFICTRL				210
+#define SRST_RESETN_RS					211
+#define SRST_ARESETN_DMA2DDR				212
+#define SRST_RESETN_DDRPHY				213
+
+/* VICRU-->SOFTRST_CON00 */
+#define SRST_RESETN_REF_PVTPLL_ISP			214
+#define SRST_ARESETN_GMAC_BIU				215
+#define SRST_ARESETN_VI_BIU				216
+#define SRST_HRESETN_VI_BIU				217
+#define SRST_PRESETN_VI_BIU				218
+#define SRST_PRESETN_CRU_VI				219
+#define SRST_PRESETN_VI_GRF				220
+#define SRST_PRESETN_VI_PVTPLL				221
+#define SRST_PRESETN_DSMC				222
+#define SRST_ARESETN_DSMC				223
+#define SRST_HRESETN_CAN0				224
+#define SRST_RESETN_CAN0				225
+#define SRST_HRESETN_CAN1				226
+#define SRST_RESETN_CAN1				227
+
+/* VICRU-->SOFTRST_CON01 */
+#define SRST_PRESETN_GPIO2				228
+#define SRST_DBRESETN_GPIO2				229
+#define SRST_PRESETN_GPIO4				230
+#define SRST_DBRESETN_GPIO4				231
+#define SRST_PRESETN_GPIO5				232
+#define SRST_DBRESETN_GPIO5				233
+#define SRST_PRESETN_GPIO6				234
+#define SRST_DBRESETN_GPIO6				235
+#define SRST_PRESETN_GPIO7				236
+#define SRST_DBRESETN_GPIO7				237
+#define SRST_PRESETN_IOC_VCCIO2				238
+#define SRST_PRESETN_IOC_VCCIO4				239
+#define SRST_PRESETN_IOC_VCCIO5				240
+#define SRST_PRESETN_IOC_VCCIO6				241
+#define SRST_PRESETN_IOC_VCCIO7				242
+
+/* VICRU-->SOFTRST_CON02 */
+#define SRST_RESETN_CORE_ISP				243
+#define SRST_HRESETN_VICAP				244
+#define SRST_ARESETN_VICAP				245
+#define SRST_DRESETN_VICAP				246
+#define SRST_ISP0RESETN_VICAP				247
+#define SRST_RESETN_CORE_VPSS				248
+#define SRST_RESETN_CORE_VPSL				249
+#define SRST_PRESETN_CSI2HOST0				250
+#define SRST_PRESETN_CSI2HOST1				251
+#define SRST_PRESETN_CSI2HOST2				252
+#define SRST_PRESETN_CSI2HOST3				253
+#define SRST_HRESETN_SDMMC0				254
+#define SRST_ARESETN_GMAC				255
+#define SRST_PRESETN_CSIPHY0				256
+#define SRST_PRESETN_CSIPHY1				257
+
+/* VICRU-->SOFTRST_CON03 */
+#define SRST_PRESETN_MACPHY				258
+#define SRST_RESETN_MACPHY				259
+#define SRST_PRESETN_SARADC1				260
+#define SRST_RESETN_SARADC1				261
+#define SRST_PRESETN_SARADC2				262
+#define SRST_RESETN_SARADC2				263
+
+/* VEPUCRU-->SOFTRST_CON00 */
+#define SRST_RESETN_REF_PVTPLL_VEPU			264
+#define SRST_ARESETN_VEPU_BIU				265
+#define SRST_HRESETN_VEPU_BIU				266
+#define SRST_PRESETN_VEPU_BIU				267
+#define SRST_PRESETN_CRU_VEPU				268
+#define SRST_PRESETN_VEPU_GRF				269
+#define SRST_PRESETN_GPIO3				270
+#define SRST_DBRESETN_GPIO3				271
+#define SRST_PRESETN_IOC_VCCIO3				272
+#define SRST_PRESETN_SARADC0				273
+#define SRST_RESETN_SARADC0				274
+#define SRST_HRESETN_SDMMC1				275
+
+/* VEPUCRU-->SOFTRST_CON01 */
+#define SRST_PRESETN_VEPU_PVTPLL			276
+#define SRST_HRESETN_VEPU				277
+#define SRST_ARESETN_VEPU				278
+#define SRST_RESETN_CORE_VEPU				279
+
+/* NPUCRU-->SOFTRST_CON00 */
+#define SRST_RESETN_REF_PVTPLL_NPU			280
+#define SRST_ARESETN_NPU_BIU				281
+#define SRST_HRESETN_NPU_BIU				282
+#define SRST_PRESETN_NPU_BIU				283
+#define SRST_PRESETN_CRU_NPU				284
+#define SRST_PRESETN_NPU_GRF				285
+#define SRST_PRESETN_NPU_PVTPLL				286
+#define SRST_HRESETN_RKNN				287
+#define SRST_ARESETN_RKNN				288
+
+/* VDOCRU-->SOFTRST_CON00 */
+#define SRST_ARESETN_RKVDEC_BIU				289
+#define SRST_ARESETN_VDO_BIU				290
+#define SRST_HRESETN_VDO_BIU				291
+#define SRST_PRESETN_VDO_BIU				292
+#define SRST_PRESETN_CRU_VDO				293
+#define SRST_PRESETN_VDO_GRF				294
+#define SRST_ARESETN_RKVDEC				295
+#define SRST_HRESETN_RKVDEC				296
+#define SRST_RESETN_HEVC_CA_RKVDEC			297
+#define SRST_ARESETN_VOP				298
+#define SRST_HRESETN_VOP				299
+#define SRST_DRESETN_VOP				300
+#define SRST_ARESETN_OOC				301
+#define SRST_HRESETN_OOC				302
+#define SRST_DRESETN_OOC				303
+
+/* VDOCRU-->SOFTRST_CON01 */
+#define SRST_HRESETN_RKJPEG				304
+#define SRST_ARESETN_RKJPEG				305
+#define SRST_ARESETN_RKMMU_DECOM			306
+#define SRST_HRESETN_RKMMU_DECOM			307
+#define SRST_DRESETN_DECOM				308
+#define SRST_ARESETN_DECOM				309
+#define SRST_PRESETN_DECOM				310
+#define SRST_PRESETN_MIPI_DSI				311
+#define SRST_PRESETN_DSIPHY				312
+
+/* VCPCRU-->SOFTRST_CON00 */
+#define SRST_RESETN_REF_PVTPLL_VCP			313
+#define SRST_ARESETN_VCP_BIU				314
+#define SRST_HRESETN_VCP_BIU				315
+#define SRST_PRESETN_VCP_BIU				316
+#define SRST_PRESETN_CRU_VCP				317
+#define SRST_PRESETN_VCP_GRF				318
+#define SRST_PRESETN_VCP_PVTPLL				319
+#define SRST_ARESETN_AISP_BIU				320
+#define SRST_HRESETN_AISP_BIU				321
+#define SRST_RESETN_CORE_AISP				322
+
+/* VCPCRU-->SOFTRST_CON01 */
+#define SRST_HRESETN_FEC				323
+#define SRST_ARESETN_FEC				324
+#define SRST_RESETN_CORE_FEC				325
+#define SRST_HRESETN_AVSP				326
+#define SRST_ARESETN_AVSP				327
+
+#endif
-- 
2.34.1



From zhangqing at rock-chips.com  Mon Nov  3 19:06:31 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Tue,  4 Nov 2025 11:06:31 +0800
Subject: [PATCH v6 3/5] clk: rockchip: Add clock controller for the RV1126B
In-Reply-To: <20251104030633.2721038-1-zhangqing@rock-chips.com>
References: <20251104030633.2721038-1-zhangqing@rock-chips.com>
Message-ID: <20251104030633.2721038-4-zhangqing@rock-chips.com>

Add the clock and reset tree definitions for the new
rv1126b SoC.

Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
---
 drivers/clk/rockchip/Kconfig       |    7 +
 drivers/clk/rockchip/Makefile      |    1 +
 drivers/clk/rockchip/clk-rv1126b.c | 1103 ++++++++++++++++++++++++++++
 drivers/clk/rockchip/clk.h         |   68 ++
 drivers/clk/rockchip/rst-rv1126b.c |  444 +++++++++++
 5 files changed, 1623 insertions(+)
 create mode 100644 drivers/clk/rockchip/clk-rv1126b.c
 create mode 100644 drivers/clk/rockchip/rst-rv1126b.c

diff --git a/drivers/clk/rockchip/Kconfig b/drivers/clk/rockchip/Kconfig
index febb7944f34b..e1ea0a098ca9 100644
--- a/drivers/clk/rockchip/Kconfig
+++ b/drivers/clk/rockchip/Kconfig
@@ -30,6 +30,13 @@ config CLK_RV1126
 	help
 	  Build the driver for RV1126 Clock Driver.
 
+config CLK_RV1126B
+	bool "Rockchip RV1126B clock controller support"
+	depends on ARM64 || COMPILE_TEST
+	default y
+	help
+	  Build the driver for RV1126B Clock Driver.
+
 config CLK_RK3036
 	bool "Rockchip RK3036 clock controller support"
 	depends on ARM || COMPILE_TEST
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index c281a9738d9f..82b4b29ad036 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -20,6 +20,7 @@ clk-rockchip-$(CONFIG_RESET_CONTROLLER) += softrst.o
 obj-$(CONFIG_CLK_PX30)          += clk-px30.o
 obj-$(CONFIG_CLK_RV110X)        += clk-rv1108.o
 obj-$(CONFIG_CLK_RV1126)        += clk-rv1126.o
+obj-$(CONFIG_CLK_RV1126B)	+= clk-rv1126b.o rst-rv1126b.o
 obj-$(CONFIG_CLK_RK3036)        += clk-rk3036.o
 obj-$(CONFIG_CLK_RK312X)        += clk-rk3128.o
 obj-$(CONFIG_CLK_RK3188)        += clk-rk3188.o
diff --git a/drivers/clk/rockchip/clk-rv1126b.c b/drivers/clk/rockchip/clk-rv1126b.c
new file mode 100644
index 000000000000..2e7ea28649fc
--- /dev/null
+++ b/drivers/clk/rockchip/clk-rv1126b.c
@@ -0,0 +1,1103 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2024 Rockchip Electronics Co., Ltd.
+ * Author: Elaine Zhang <zhangqing at rock-chips.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/syscore_ops.h>
+#include <dt-bindings/clock/rockchip,rv1126b-cru.h>
+#include "clk.h"
+
+#define RV1126B_FRAC_MAX_PRATE		1200000000
+
+#define PVTPLL_SRC_SEL_PVTPLL		(BIT(0) | BIT(16))
+
+enum rv1126b_plls {
+	gpll, cpll, aupll, dpll
+};
+
+static struct rockchip_pll_rate_table rv1126b_pll_rates[] = {
+	/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
+	RK3036_PLL_RATE(1200000000, 1, 100, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1179648000, 1, 49, 1, 1, 0, 2550137),
+	RK3036_PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0),
+	RK3036_PLL_RATE(993484800, 1, 41, 1, 1, 0, 6630355),
+	RK3036_PLL_RATE(983040000, 1, 40, 1, 1, 0, 16106127),
+	RK3036_PLL_RATE(903168000, 1, 75, 2, 1, 0, 4429185),
+	{ /* sentinel */ },
+};
+
+#define RV1126B_DIV_ACLK_CORE_MASK	0x1f
+#define RV1126B_DIV_ACLK_CORE_SHIFT	0
+#define RV1126B_DIV_PCLK_CORE_MASK	0x1f
+#define RV1126B_DIV_PCLK_CORE_SHIFT	8
+#define RV1126B_CORE_SEL_MASK		0x1
+#define RV1126B_CORE_SEL_SHIFT		1
+
+#define RV1126B_CLKSEL0(_aclk_core)						\
+{										\
+	.reg = RV1126B_CORECLKSEL_CON(2),					\
+	.val = HIWORD_UPDATE(_aclk_core - 1, RV1126B_DIV_ACLK_CORE_MASK,	\
+			     RV1126B_DIV_ACLK_CORE_SHIFT),			\
+}
+
+#define RV1126B_CLKSEL1(_pclk_dbg)						\
+{										\
+	.reg = RV1126B_CORECLKSEL_CON(2),					\
+	.val = HIWORD_UPDATE(_pclk_dbg - 1, RV1126B_DIV_PCLK_CORE_MASK,		\
+			     RV1126B_DIV_PCLK_CORE_SHIFT),			\
+}
+
+#define RV1126B_CPUCLK_RATE(_prate, _aclk_core, _pclk_dbg)			\
+{										\
+	.prate = _prate,							\
+	.divs = {								\
+		RV1126B_CLKSEL0(_aclk_core),					\
+		RV1126B_CLKSEL1(_pclk_dbg),					\
+	},									\
+}
+
+static struct rockchip_cpuclk_rate_table rv1126b_cpuclk_rates[] __initdata = {
+	RV1126B_CPUCLK_RATE(1608000000, 4, 10),
+	RV1126B_CPUCLK_RATE(1512000000, 4, 10),
+	RV1126B_CPUCLK_RATE(1416000000, 4, 10),
+	RV1126B_CPUCLK_RATE(1296000000, 3, 10),
+	RV1126B_CPUCLK_RATE(1200000000, 3, 10),
+	RV1126B_CPUCLK_RATE(1188000000, 3, 8),
+	RV1126B_CPUCLK_RATE(1104000000, 2, 8),
+	RV1126B_CPUCLK_RATE(1008000000, 2, 8),
+	RV1126B_CPUCLK_RATE(816000000, 2, 6),
+	RV1126B_CPUCLK_RATE(600000000, 2, 4),
+	RV1126B_CPUCLK_RATE(594000000, 2, 4),
+	RV1126B_CPUCLK_RATE(408000000, 1, 3),
+	RV1126B_CPUCLK_RATE(396000000, 1, 3),
+};
+
+PNAME(mux_pll_p)			= { "xin24m" };
+PNAME(mux_gpll_cpll_p)			= { "gpll", "cpll" };
+PNAME(mux_gpll_aupll_p)			= { "gpll", "aupll" };
+PNAME(mux_gpll_aupll_cpll_p)		= { "gpll", "aupll", "cpll" };
+PNAME(mux_gpll_cpll_24m_p)		= { "gpll", "cpll", "xin24m" };
+PNAME(mux_cpll_24m_p)			= { "cpll", "xin24m" };
+PNAME(mux_24m_gpll_aupll_cpll_p)	= { "xin24m", "gpll", "aupll", "cpll" };
+PNAME(mux_24m_gpll_cpll_p)		= { "xin24m", "gpll", "cpll" };
+PNAME(mux_24m_gpll_aupll_p)		= { "xin24m", "gpll", "aupll" };
+PNAME(mux_sclk_uart_src_p)		= { "xin24m", "clk_cm_frac0", "clk_cm_frac1", "clk_cm_frac2",
+					    "clk_uart_frac0", "clk_uart_frac1" };
+PNAME(mclk_sai0_src_p)			= { "xin24m", "clk_cm_frac0", "clk_cm_frac1", "clk_cm_frac2",
+					    "clk_audio_frac0", "clk_audio_frac1", "clk_audio_int0", "clk_audio_int1", "mclk_sai0_from_io" };
+PNAME(mclk_sai1_src_p)			= { "xin24m", "clk_cm_frac0", "clk_cm_frac1", "clk_cm_frac2", "clk_audio_frac0",
+					    "clk_audio_frac1", "clk_audio_int0", "clk_audio_int1", "mclk_sai1_from_io" };
+PNAME(mclk_sai2_src_p)			= { "xin24m", "clk_cm_frac0", "clk_cm_frac1", "clk_cm_frac2", "clk_audio_frac0",
+					    "clk_audio_frac1", "clk_audio_int0", "clk_audio_int1", "mclk_sai2_from_io" };
+PNAME(mux_sai_src_p)			= { "xin24m", "clk_cm_frac0", "clk_cm_frac1", "clk_cm_frac2", "clk_audio_frac0",
+					    "clk_audio_frac1", "clk_audio_int0", "clk_audio_int1", "mclk_sai0_from_io",
+					    "mclk_sai1_from_io", "mclk_sai2_from_io"};
+PNAME(mux_100m_24m_p)			= { "clk_cpll_div10", "xin24m" };
+PNAME(mux_200m_24m_p)			= { "clk_gpll_div6", "xin24m" };
+PNAME(mux_500m_400m_200m_p)		= { "clk_cpll_div2", "clk_gpll_div3", "clk_gpll_div6" };
+PNAME(mux_300m_200m_p)			= { "clk_gpll_div4", "clk_gpll_div6" };
+PNAME(mux_500m_400m_300m_p)		= { "clk_cpll_div2", "clk_gpll_div3", "clk_gpll_div4" };
+PNAME(mux_333m_200m_p)			= { "clk_cpll_div3", "clk_gpll_div6" };
+PNAME(mux_600m_400m_200m_p)		= { "clk_gpll_div2", "clk_gpll_div3", "clk_gpll_div6" };
+PNAME(mux_400m_300m_200m_p)		= { "clk_gpll_div3", "clk_gpll_div4", "clk_gpll_div6" };
+PNAME(mux_200m_100m_p)			= { "clk_gpll_div6", "clk_cpll_div10" };
+PNAME(mux_200m_100m_50m_24m_p)		= { "clk_gpll_div6", "clk_cpll_div10", "clk_cpll_div20", "xin24m" };
+PNAME(mux_600m_24m_p)			= { "clk_gpll_div2", "xin24m" };
+PNAME(mux_armclk_p)			= { "clk_core_pll", "clk_core_pvtpll" };
+PNAME(aclk_npu_root_p)			= { "clk_npu_pll", "clk_npu_pvtpll" };
+PNAME(clk_saradc0_p)			= { "clk_saradc0_src", "clk_saradc0_rcosc_io" };
+PNAME(clk_core_vepu_p)			= { "clk_vepu_pll", "clk_vepu_pvtpll" };
+PNAME(clk_core_fec_p)			= { "clk_core_fec_src", "clk_vcp_pvtpll" };
+PNAME(clk_core_aisp_p)			= { "clk_aisp_pll", "clk_vcp_pvtpll" };
+PNAME(clk_core_isp_root_p)		= { "clk_isp_pll", "clk_isp_pvtpll" };
+PNAME(clk_gmac_ptp_ref_p)		= { "clk_gmac_ptp_ref_src", "clk_gmac_ptp_from_io" };
+PNAME(clk_saradc1_p)			= { "clk_saradc1_src", "clk_saradc1_rcosc_io" };
+PNAME(clk_saradc2_p)			= { "clk_saradc2_src", "clk_saradc2_rcosc_io" };
+PNAME(clk_rcosc_src_p)			= { "xin24m", "clk_rcosc", "clk_rcosc_div2", "clk_rcosc_div3", "clk_rcosc_div4" };
+PNAME(busclk_pmu_mux_p)			= { "clk_cpll_div10", "clk_rcosc_src" };
+PNAME(clk_xin_rc_div_p)			= { "xin24m", "clk_rcosc_src" };
+PNAME(clk_32k_p)			= { "clk_xin_rc_div", "clk_32k_rtc", "clk_32k_io" };
+PNAME(mux_24m_32k_p)			= { "xin24m", "clk_32k" };
+PNAME(mux_24m_rcosc_buspmu_p)		= { "xin24m", "clk_rcosc_src", "busclk_pmu_src" };
+PNAME(mux_24m_rcosc_buspmu_32k_p)	= { "xin24m", "clk_rcosc_src", "busclk_pmu_src", "clk_32k" };
+PNAME(sclk_uart0_p)			= { "sclk_uart0_src", "xin24m", "clk_rcosc_src" };
+PNAME(clk_osc_rcosc_ctrl_p)		= { "clk_rcosc_src", "clk_testout_out" };
+PNAME(lrck_src_asrc_p)			= { "mclk_asrc0", "mclk_asrc1", "mclk_asrc2", "mclk_asrc3",
+					    "fs_inter_from_sai0", "fs_inter_from_sai1", "fs_inter_from_sai2", "clkout_pdm"};
+PNAME(clk_ref_pipephy_p)		= { "clk_ref_pipephy_cpll_src", "xin24m" };
+PNAME(clk_timer0_parents_p)		= { "clk_timer_root", "mclk_sai0_from_io", "sclk_sai0_from_io" };
+PNAME(clk_timer1_parents_p)		= { "clk_timer_root", "mclk_sai1_from_io", "sclk_sai1_from_io" };
+PNAME(clk_timer2_parents_p)		= { "clk_timer_root", "mclk_sai2_from_io", "sclk_sai2_from_io" };
+PNAME(clk_timer3_parents_p)		= { "clk_timer_root", "mclk_asrc0", "mclk_asrc1" };
+PNAME(clk_timer4_parents_p)		= { "clk_timer_root", "mclk_asrc2", "mclk_asrc3" };
+PNAME(clk_macphy_p)			= { "xin24m", "clk_cpll_div20" };
+PNAME(clk_cpll_div10_p)			= { "gpll", "clk_aisp_pll_src" };
+
+static struct rockchip_pll_clock rv1126b_pll_clks[] __initdata = {
+	[gpll] = PLL(pll_rk3328, PLL_GPLL, "gpll", mux_pll_p,
+		     CLK_IS_CRITICAL, RV1126B_PLL_CON(8),
+		     RV1126B_MODE_CON, 2, 10, 0, rv1126b_pll_rates),
+	[aupll] = PLL(pll_rk3328, PLL_AUPLL, "aupll", mux_pll_p,
+		     CLK_IS_CRITICAL, RV1126B_PLL_CON(0),
+		     RV1126B_MODE_CON, 0, 10, 0, rv1126b_pll_rates),
+	[cpll] = PLL(pll_rk3328, PLL_CPLL, "cpll", mux_pll_p,
+		     CLK_IS_CRITICAL, RV1126B_PERIPLL_CON(0),
+		     RV1126B_MODE_CON, 4, 10, 0, rv1126b_pll_rates),
+	[dpll] = PLL(pll_rk3328, 0, "dpll", mux_pll_p,
+		     CLK_IS_CRITICAL, RV1126B_SUBDDRPLL_CON(0),
+		     RV1126B_MODE_CON, 2, 10, 0, rv1126b_pll_rates),
+};
+
+#define MFLAGS CLK_MUX_HIWORD_MASK
+#define DFLAGS CLK_DIVIDER_HIWORD_MASK
+#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
+
+static struct rockchip_clk_branch rv1126b_rcdiv_pmu_fracmux __initdata =
+	MUX(CLK_32K, "clk_32k", clk_32k_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
+			RV1126B_PMUCLKSEL_CON(2), 1, 2, MFLAGS);
+
+static struct rockchip_clk_branch rv1126b_clk_branches[] __initdata = {
+
+	FACTOR(0, "clk_rcosc_div2", "clk_rcosc", 0, 1, 2),
+	FACTOR(0, "clk_rcosc_div3", "clk_rcosc", 0, 1, 3),
+	FACTOR(0, "clk_rcosc_div4", "clk_rcosc", 0, 1, 4),
+
+	/*       Clock Definition       */
+	COMPOSITE_NODIV(CLK_AISP_PLL_SRC, "clk_aisp_pll_src", mux_gpll_aupll_cpll_p, 0,
+			RV1126B_CLKSEL_CON(62), 4, 2, MFLAGS,
+			RV1126B_CLKGATE_CON(5), 4, GFLAGS),
+	DIV(CLK_AISP_PLL, "clk_aisp_pll", "clk_aisp_pll_src", 0,
+			RV1126B_CLKSEL_CON(62), 0, 3, DFLAGS),
+
+	COMPOSITE(CLK_CPLL_DIV10, "clk_cpll_div10", clk_cpll_div10_p, 0,
+			RV1126B_CLKSEL_CON(1), 15, 1, MFLAGS, 5, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(0), 1, GFLAGS),
+	COMPOSITE_NOMUX(CLK_CPLL_DIV20, "clk_cpll_div20", "cpll", 0,
+			RV1126B_CLKSEL_CON(1), 0, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(0), 0, GFLAGS),
+	COMPOSITE_NOMUX(CLK_CPLL_DIV8, "clk_cpll_div8", "cpll", 0,
+			RV1126B_CLKSEL_CON(1), 10, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(0), 2, GFLAGS),
+	COMPOSITE_NOMUX(CLK_GPLL_DIV8, "clk_gpll_div8", "gpll", 0,
+			RV1126B_CLKSEL_CON(2), 0, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(0), 3, GFLAGS),
+	COMPOSITE_NOMUX(CLK_GPLL_DIV6, "clk_gpll_div6", "gpll", 0,
+			RV1126B_CLKSEL_CON(2), 5, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(0), 4, GFLAGS),
+	COMPOSITE_NOMUX(CLK_GPLL_DIV4, "clk_gpll_div4", "gpll", 0,
+			RV1126B_CLKSEL_CON(2), 10, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(0), 5, GFLAGS),
+	COMPOSITE_NOMUX(CLK_CPLL_DIV3, "clk_cpll_div3", "cpll", 0,
+			RV1126B_CLKSEL_CON(3), 0, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(0), 6, GFLAGS),
+	COMPOSITE_NOMUX(CLK_GPLL_DIV3, "clk_gpll_div3", "gpll", 0,
+			RV1126B_CLKSEL_CON(3), 5, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(0), 7, GFLAGS),
+	COMPOSITE_NOMUX(CLK_CPLL_DIV2, "clk_cpll_div2", "cpll", 0,
+			RV1126B_CLKSEL_CON(3), 10, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(0), 8, GFLAGS),
+	COMPOSITE_NOMUX(CLK_GPLL_DIV2, "clk_gpll_div2", "gpll", 0,
+			RV1126B_CLKSEL_CON(4), 0, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(0), 9, GFLAGS),
+	MUX(CLK_CM_FRAC0_SRC, "clk_cm_frac0_src", mux_24m_gpll_aupll_cpll_p, 0,
+			RV1126B_CLKSEL_CON(10), 0, 2, MFLAGS),
+	COMPOSITE_FRAC(CLK_CM_FRAC0, "clk_cm_frac0", "clk_cm_frac0_src", 0,
+			RV1126B_CLKSEL_CON(25), 0,
+			RV1126B_CLKGATE_CON(1), 0, GFLAGS),
+	MUX(CLK_CM_FRAC1_SRC, "clk_cm_frac1_src", mux_24m_gpll_aupll_cpll_p, 0,
+			RV1126B_CLKSEL_CON(10), 2, 2, MFLAGS),
+	COMPOSITE_FRAC(CLK_CM_FRAC1, "clk_cm_frac1", "clk_cm_frac1_src", 0,
+			RV1126B_CLKSEL_CON(26), 0,
+			RV1126B_CLKGATE_CON(1), 1, GFLAGS),
+	MUX(CLK_CM_FRAC2_SRC, "clk_cm_frac2_src", mux_24m_gpll_aupll_cpll_p, 0,
+			RV1126B_CLKSEL_CON(10), 4, 2, MFLAGS),
+	COMPOSITE_FRAC(CLK_CM_FRAC2, "clk_cm_frac2", "clk_cm_frac2_src", 0,
+			RV1126B_CLKSEL_CON(27), 0,
+			RV1126B_CLKGATE_CON(1), 2, GFLAGS),
+	MUX(CLK_UART_FRAC0_SRC, "clk_uart_frac0_src", mux_24m_gpll_cpll_p, 0,
+			RV1126B_CLKSEL_CON(10), 6, 2, MFLAGS),
+	COMPOSITE_FRAC(CLK_UART_FRAC0, "clk_uart_frac0", "clk_uart_frac0_src", 0,
+			RV1126B_CLKSEL_CON(28), 0,
+			RV1126B_CLKGATE_CON(1), 3, GFLAGS),
+	MUX(CLK_UART_FRAC1_SRC, "clk_uart_frac1_src", mux_24m_gpll_cpll_p, 0,
+			RV1126B_CLKSEL_CON(10), 8, 2, MFLAGS),
+	COMPOSITE_FRAC(CLK_UART_FRAC1, "clk_uart_frac1", "clk_uart_frac1_src", 0,
+			RV1126B_CLKSEL_CON(29), 0,
+			RV1126B_CLKGATE_CON(1), 4, GFLAGS),
+	MUX(CLK_AUDIO_FRAC0_SRC, "clk_audio_frac0_src", mux_24m_gpll_aupll_p, 0,
+			RV1126B_CLKSEL_CON(10), 10, 2, MFLAGS),
+	COMPOSITE_FRAC(CLK_AUDIO_FRAC0, "clk_audio_frac0", "clk_audio_frac0_src", 0,
+			RV1126B_CLKSEL_CON(30), 0,
+			RV1126B_CLKGATE_CON(1), 5, GFLAGS),
+	MUX(CLK_AUDIO_FRAC1_SRC, "clk_audio_frac1_src", mux_24m_gpll_aupll_p, 0,
+			RV1126B_CLKSEL_CON(10), 12, 2, MFLAGS),
+	COMPOSITE_FRAC(CLK_AUDIO_FRAC1, "clk_audio_frac1", "clk_audio_frac1_src", 0,
+			RV1126B_CLKSEL_CON(31), 0,
+			RV1126B_CLKGATE_CON(1), 6, GFLAGS),
+	COMPOSITE(CLK_AUDIO_INT0, "clk_audio_int0", mux_24m_gpll_aupll_p, 0,
+			RV1126B_CLKSEL_CON(11), 6, 2, MFLAGS, 0, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(1), 7, GFLAGS),
+	COMPOSITE(CLK_AUDIO_INT1, "clk_audio_int1", mux_24m_gpll_aupll_p, 0,
+			RV1126B_CLKSEL_CON(11), 14, 2, MFLAGS, 8, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(1), 8, GFLAGS),
+	COMPOSITE(SCLK_UART0_SRC, "sclk_uart0_src", mux_sclk_uart_src_p, 0,
+			RV1126B_CLKSEL_CON(12), 5, 3, MFLAGS, 0, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(1), 9, GFLAGS),
+	COMPOSITE(SCLK_UART1, "sclk_uart1", mux_sclk_uart_src_p, 0,
+			RV1126B_CLKSEL_CON(12), 13, 3, MFLAGS, 8, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(1), 10, GFLAGS),
+	COMPOSITE(SCLK_UART2, "sclk_uart2", mux_sclk_uart_src_p, 0,
+			RV1126B_CLKSEL_CON(13), 5, 3, MFLAGS, 0, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(1), 11, GFLAGS),
+	COMPOSITE(SCLK_UART3, "sclk_uart3", mux_sclk_uart_src_p, 0,
+			RV1126B_CLKSEL_CON(13), 13, 3, MFLAGS, 8, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(1), 12, GFLAGS),
+	COMPOSITE(SCLK_UART4, "sclk_uart4", mux_sclk_uart_src_p, 0,
+			RV1126B_CLKSEL_CON(14), 5, 3, MFLAGS, 0, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(1), 13, GFLAGS),
+	COMPOSITE(SCLK_UART5, "sclk_uart5", mux_sclk_uart_src_p, 0,
+			RV1126B_CLKSEL_CON(14), 13, 3, MFLAGS, 8, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(1), 14, GFLAGS),
+	COMPOSITE(SCLK_UART6, "sclk_uart6", mux_sclk_uart_src_p, 0,
+			RV1126B_CLKSEL_CON(15), 5, 3, MFLAGS, 0, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(2), 0, GFLAGS),
+	COMPOSITE(SCLK_UART7, "sclk_uart7", mux_sclk_uart_src_p, 0,
+			RV1126B_CLKSEL_CON(15), 13, 3, MFLAGS, 8, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(2), 1, GFLAGS),
+	COMPOSITE(MCLK_SAI0, "mclk_sai0", mclk_sai0_src_p, 0,
+			RV1126B_CLKSEL_CON(16), 8, 4, MFLAGS, 0, 8, DFLAGS,
+			RV1126B_CLKGATE_CON(2), 2, GFLAGS),
+	COMPOSITE(MCLK_SAI1, "mclk_sai1", mclk_sai1_src_p, 0,
+			RV1126B_CLKSEL_CON(17), 8, 4, MFLAGS, 0, 8, DFLAGS,
+			RV1126B_CLKGATE_CON(2), 3, GFLAGS),
+	COMPOSITE(MCLK_SAI2, "mclk_sai2", mclk_sai2_src_p, 0,
+			RV1126B_CLKSEL_CON(18), 8, 4, MFLAGS, 0, 8, DFLAGS,
+			RV1126B_CLKGATE_CON(2), 4, GFLAGS),
+	COMPOSITE(MCLK_PDM, "mclk_pdm", mux_sai_src_p, 0,
+			RV1126B_CLKSEL_CON(19), 6, 4, MFLAGS, 0, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(2), 5, GFLAGS),
+	COMPOSITE_NOGATE(0, "clkout_pdm_src", mux_sai_src_p, 0,
+			RV1126B_CLKSEL_CON(20), 8, 4, MFLAGS, 0, 8, DFLAGS),
+	GATE(CLKOUT_PDM, "clkout_pdm", "clkout_pdm_src", 0,
+			RV1126B_CLKGATE_CON(2), 6, GFLAGS),
+	COMPOSITE_NODIV(MCLK_ASRC0, "mclk_asrc0", mux_sai_src_p, 0,
+			RV1126B_CLKSEL_CON(16), 12, 4, MFLAGS,
+			RV1126B_CLKGATE_CON(2), 7, GFLAGS),
+	COMPOSITE_NODIV(MCLK_ASRC1, "mclk_asrc1", mux_sai_src_p, 0,
+			RV1126B_CLKSEL_CON(17), 12, 4, MFLAGS,
+			RV1126B_CLKGATE_CON(2), 8, GFLAGS),
+	COMPOSITE_NODIV(MCLK_ASRC2, "mclk_asrc2", mux_sai_src_p, 0,
+			RV1126B_CLKSEL_CON(18), 12, 4, MFLAGS,
+			RV1126B_CLKGATE_CON(2), 9, GFLAGS),
+	COMPOSITE_NODIV(MCLK_ASRC3, "mclk_asrc3", mux_sai_src_p, 0,
+			RV1126B_CLKSEL_CON(19), 12, 4, MFLAGS,
+			RV1126B_CLKGATE_CON(2), 10, GFLAGS),
+	COMPOSITE(CLK_ASRC0, "clk_asrc0", mux_gpll_aupll_p, 0,
+			RV1126B_CLKSEL_CON(21), 6, 1, MFLAGS, 0, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(2), 11, GFLAGS),
+	COMPOSITE(CLK_ASRC1, "clk_asrc1", mux_gpll_aupll_p, 0,
+			RV1126B_CLKSEL_CON(21), 14, 1, MFLAGS, 8, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(2), 12, GFLAGS),
+	COMPOSITE_NOMUX(CLK_CORE_PLL, "clk_core_pll", "gpll", CLK_IS_CRITICAL,
+			RV1126B_CLKSEL_CON(60), 0, 3, DFLAGS,
+			RV1126B_CLKGATE_CON(5), 0, GFLAGS),
+	COMPOSITE_NOMUX(CLK_NPU_PLL, "clk_npu_pll", "gpll", CLK_IS_CRITICAL,
+			RV1126B_CLKSEL_CON(60), 6, 3, DFLAGS,
+			RV1126B_CLKGATE_CON(5), 1, GFLAGS),
+	COMPOSITE(CLK_VEPU_PLL, "clk_vepu_pll", mux_gpll_aupll_cpll_p, 0,
+			RV1126B_CLKSEL_CON(61), 4, 2, MFLAGS, 0, 3, DFLAGS,
+			RV1126B_CLKGATE_CON(5), 2, GFLAGS),
+	COMPOSITE(CLK_ISP_PLL, "clk_isp_pll", mux_gpll_aupll_cpll_p, 0,
+			RV1126B_CLKSEL_CON(61), 10, 2, MFLAGS, 6, 4, DFLAGS,
+			RV1126B_CLKGATE_CON(5), 3, GFLAGS),
+	COMPOSITE(CLK_SARADC0_SRC, "clk_saradc0_src", mux_200m_24m_p, 0,
+			RV1126B_CLKSEL_CON(63), 12, 1, MFLAGS, 0, 3, DFLAGS,
+			RV1126B_CLKGATE_CON(5), 6, GFLAGS),
+	COMPOSITE(CLK_SARADC1_SRC, "clk_saradc1_src", mux_200m_24m_p, 0,
+			RV1126B_CLKSEL_CON(63), 13, 1, MFLAGS, 4, 3, DFLAGS,
+			RV1126B_CLKGATE_CON(5), 7, GFLAGS),
+	COMPOSITE(CLK_SARADC2_SRC, "clk_saradc2_src", mux_200m_24m_p, 0,
+			RV1126B_CLKSEL_CON(63), 14, 1, MFLAGS, 8, 3, DFLAGS,
+			RV1126B_CLKGATE_CON(5), 8, GFLAGS),
+	GATE(HCLK_RKNN, "hclk_rknn", "clk_gpll_div8", CLK_IS_CRITICAL,
+			RV1126B_CLKGATE_CON(5), 10, GFLAGS),
+	GATE(PCLK_NPU_ROOT, "pclk_npu_root", "clk_cpll_div10", CLK_IS_CRITICAL,
+			RV1126B_CLKGATE_CON(5), 11, GFLAGS),
+	COMPOSITE_NODIV(ACLK_VEPU_ROOT, "aclk_vepu_root", mux_500m_400m_200m_p, CLK_IS_CRITICAL,
+			RV1126B_CLKSEL_CON(40), 0, 2, MFLAGS,
+			RV1126B_CLKGATE_CON(5), 12, GFLAGS),
+	GATE(HCLK_VEPU_ROOT, "hclk_vepu_root", "clk_gpll_div8", CLK_IS_CRITICAL,
+			RV1126B_CLKGATE_CON(5), 13, GFLAGS),
+	GATE(PCLK_VEPU_ROOT, "pclk_vepu_root", "clk_cpll_div10", 0,
+			RV1126B_CLKGATE_CON(5), 14, GFLAGS),
+	COMPOSITE(CLK_CORE_RGA_SRC, "clk_core_rga_src", mux_gpll_cpll_p, 0,
+			RV1126B_CLKSEL_CON(40), 5, 1, MFLAGS, 2, 3, DFLAGS,
+			RV1126B_CLKGATE_CON(6), 0, GFLAGS),
+	COMPOSITE_NODIV(ACLK_GMAC_ROOT, "aclk_gmac_root", mux_300m_200m_p, 0,
+			RV1126B_CLKSEL_CON(40), 6, 1, MFLAGS,
+			RV1126B_CLKGATE_CON(6), 1, GFLAGS),
+	COMPOSITE_NODIV(ACLK_VI_ROOT, "aclk_vi_root", mux_500m_400m_300m_p, CLK_IS_CRITICAL,
+			RV1126B_CLKSEL_CON(40), 7, 2, MFLAGS,
+			RV1126B_CLKGATE_CON(6), 2, GFLAGS),
+	GATE(HCLK_VI_ROOT, "hclk_vi_root", "clk_gpll_div8", CLK_IS_CRITICAL,
+			RV1126B_CLKGATE_CON(6), 3, GFLAGS),
+	GATE(PCLK_VI_ROOT, "pclk_vi_root", "clk_cpll_div10", CLK_IS_CRITICAL,
+			RV1126B_CLKGATE_CON(6), 4, GFLAGS),
+	COMPOSITE_NODIV(DCLK_VICAP_ROOT, "dclk_vicap_root", mux_333m_200m_p, 0,
+			RV1126B_CLKSEL_CON(42), 5, 1, MFLAGS,
+			RV1126B_CLKGATE_CON(6), 5, GFLAGS),
+	COMPOSITE(CLK_SYS_DSMC_ROOT, "clk_sys_dsmc_root", mux_24m_gpll_cpll_p, 0,
+			RV1126B_CLKSEL_CON(40), 14, 2, MFLAGS, 9, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(6), 6, GFLAGS),
+	COMPOSITE(ACLK_VDO_ROOT, "aclk_vdo_root", mux_gpll_cpll_p, CLK_IS_CRITICAL,
+			RV1126B_CLKSEL_CON(42), 4, 1, MFLAGS, 0, 4, DFLAGS,
+			RV1126B_CLKGATE_CON(6), 7, GFLAGS),
+	COMPOSITE(ACLK_RKVDEC_ROOT, "aclk_rkvdec_root", mux_gpll_cpll_p, 0,
+			RV1126B_CLKSEL_CON(42), 10, 1, MFLAGS, 6, 4, DFLAGS,
+			RV1126B_CLKGATE_CON(6), 8, GFLAGS),
+	GATE(HCLK_VDO_ROOT, "hclk_vdo_root", "clk_gpll_div8", CLK_IS_CRITICAL,
+			RV1126B_CLKGATE_CON(6), 9, GFLAGS),
+	GATE(PCLK_VDO_ROOT, "pclk_vdo_root", "clk_cpll_div10", CLK_IS_CRITICAL,
+			RV1126B_CLKGATE_CON(6), 10, GFLAGS),
+	COMPOSITE(DCLK_VOP, "dclk_vop", mux_gpll_cpll_p, 0,
+			RV1126B_CLKSEL_CON(43), 8, 1, MFLAGS, 0, 8, DFLAGS,
+			RV1126B_CLKGATE_CON(6), 12, GFLAGS),
+	COMPOSITE(DCLK_OOC_SRC, "dclk_ooc_src", mux_gpll_cpll_p, 0,
+			RV1126B_CLKSEL_CON(62), 7, 1, MFLAGS, 8, 8, DFLAGS,
+			RV1126B_CLKGATE_CON(6), 13, GFLAGS),
+	GATE(DCLK_DECOM_SRC, "dclk_decom_src", "clk_gpll_div3", 0,
+			RV1126B_CLKGATE_CON(6), 14, GFLAGS),
+	GATE(PCLK_DDR_ROOT, "pclk_ddr_root", "clk_cpll_div10", 0,
+			RV1126B_CLKGATE_CON(7), 0, GFLAGS),
+	COMPOSITE(ACLK_SYSMEM, "aclk_sysmem", mux_gpll_cpll_p, CLK_IS_CRITICAL,
+			RV1126B_CLKSEL_CON(44), 3, 1, MFLAGS, 0, 3, DFLAGS,
+			RV1126B_CLKGATE_CON(7), 1, GFLAGS),
+	COMPOSITE_NODIV(ACLK_TOP_ROOT, "aclk_top_root", mux_600m_400m_200m_p, CLK_IS_CRITICAL,
+			RV1126B_CLKSEL_CON(44), 6, 2, MFLAGS,
+			RV1126B_CLKGATE_CON(7), 3, GFLAGS),
+	COMPOSITE_NODIV(ACLK_BUS_ROOT, "aclk_bus_root", mux_400m_300m_200m_p, CLK_IS_CRITICAL,
+			RV1126B_CLKSEL_CON(44), 8, 2, MFLAGS,
+			RV1126B_CLKGATE_CON(7), 4, GFLAGS),
+	COMPOSITE_NODIV(HCLK_BUS_ROOT, "hclk_bus_root", mux_200m_100m_p, CLK_IS_CRITICAL,
+			RV1126B_CLKSEL_CON(44), 10, 1, MFLAGS,
+			RV1126B_CLKGATE_CON(7), 5, GFLAGS),
+	GATE(PCLK_BUS_ROOT, "pclk_bus_root", "clk_cpll_div10", CLK_IS_CRITICAL,
+			RV1126B_CLKGATE_CON(7), 6, GFLAGS),
+	COMPOSITE(CCLK_SDMMC0, "cclk_sdmmc0", mux_gpll_cpll_24m_p, 0,
+			RV1126B_CLKSEL_CON(45), 8, 2, MFLAGS, 0, 8, DFLAGS,
+			RV1126B_CLKGATE_CON(7), 7, GFLAGS),
+	COMPOSITE(CCLK_SDMMC1, "cclk_sdmmc1", mux_gpll_cpll_24m_p, 0,
+			RV1126B_CLKSEL_CON(46), 8, 2, MFLAGS, 0, 8, DFLAGS,
+			RV1126B_CLKGATE_CON(7), 8, GFLAGS),
+	COMPOSITE(CCLK_EMMC, "cclk_emmc", mux_gpll_cpll_24m_p, 0,
+			RV1126B_CLKSEL_CON(47), 8, 2, MFLAGS, 0, 8, DFLAGS,
+			RV1126B_CLKGATE_CON(7), 9, GFLAGS),
+	COMPOSITE(SCLK_2X_FSPI0, "sclk_2x_fspi0", mux_gpll_cpll_24m_p, 0,
+			RV1126B_CLKSEL_CON(48), 8, 2, MFLAGS, 0, 8, DFLAGS,
+			RV1126B_CLKGATE_CON(7), 10, GFLAGS),
+	COMPOSITE(CLK_GMAC_PTP_REF_SRC, "clk_gmac_ptp_ref_src", mux_cpll_24m_p, 0,
+			RV1126B_CLKSEL_CON(45), 10, 1, MFLAGS, 11, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(7), 11, GFLAGS),
+	GATE(CLK_GMAC_125M, "clk_gmac_125m", "clk_cpll_div8", 0,
+			RV1126B_CLKGATE_CON(7), 12, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER_ROOT, "clk_timer_root", mux_100m_24m_p, 0,
+			RV1126B_CLKSEL_CON(46), 11, 1, MFLAGS,
+			RV1126B_CLKGATE_CON(7), 13, GFLAGS),
+	COMPOSITE_NODIV(TCLK_WDT_NS_SRC, "tclk_wdt_ns_src", mux_100m_24m_p, 0,
+			RV1126B_CLKSEL_CON(46), 12, 1, MFLAGS,
+			RV1126B_CLKGATE_CON(8), 0, GFLAGS),
+	COMPOSITE_NODIV(TCLK_WDT_S_SRC, "tclk_wdt_s_src", mux_100m_24m_p, 0,
+			RV1126B_CLKSEL_CON(46), 13, 1, MFLAGS,
+			RV1126B_CLKGATE_CON(8), 1, GFLAGS),
+	COMPOSITE_NODIV(TCLK_WDT_HPMCU, "tclk_wdt_hpmcu", mux_100m_24m_p, 0,
+			RV1126B_CLKSEL_CON(46), 14, 1, MFLAGS,
+			RV1126B_CLKGATE_CON(8), 2, GFLAGS),
+	COMPOSITE(CLK_CAN0, "clk_can0", mux_gpll_cpll_24m_p, 0,
+			RV1126B_CLKSEL_CON(49), 6, 2, MFLAGS, 0, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(8), 4, GFLAGS),
+	COMPOSITE(CLK_CAN1, "clk_can1", mux_gpll_cpll_24m_p, 0,
+			RV1126B_CLKSEL_CON(49), 14, 2, MFLAGS, 8, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(8), 5, GFLAGS),
+	COMPOSITE_NODIV(PCLK_PERI_ROOT, "pclk_peri_root", mux_100m_24m_p, CLK_IS_CRITICAL,
+			RV1126B_CLKSEL_CON(47), 12, 1, MFLAGS,
+			RV1126B_CLKGATE_CON(8), 6, GFLAGS),
+	COMPOSITE_NODIV(ACLK_PERI_ROOT, "aclk_peri_root", mux_200m_24m_p, CLK_IS_CRITICAL,
+			RV1126B_CLKSEL_CON(47), 13, 1, MFLAGS,
+			RV1126B_CLKGATE_CON(8), 7, GFLAGS),
+	COMPOSITE_NODIV(CLK_I2C_BUS_SRC, "clk_i2c_bus_src", mux_200m_24m_p, 0,
+			RV1126B_CLKSEL_CON(50), 1, 1, MFLAGS,
+			RV1126B_CLKGATE_CON(8), 9, GFLAGS),
+	COMPOSITE_NODIV(CLK_SPI0, "clk_spi0", mux_200m_100m_50m_24m_p, 0,
+			RV1126B_CLKSEL_CON(50), 2, 2, MFLAGS,
+			RV1126B_CLKGATE_CON(8), 10, GFLAGS),
+	COMPOSITE_NODIV(CLK_SPI1, "clk_spi1", mux_200m_100m_50m_24m_p, 0,
+			RV1126B_CLKSEL_CON(50), 4, 2, MFLAGS,
+			RV1126B_CLKGATE_CON(8), 11, GFLAGS),
+	GATE(BUSCLK_PMU_SRC, "busclk_pmu_src", "clk_cpll_div10", CLK_IS_CRITICAL,
+			RV1126B_CLKGATE_CON(8), 12, GFLAGS),
+	COMPOSITE_NODIV(CLK_PWM0, "clk_pwm0", mux_100m_24m_p, 0,
+			RV1126B_CLKSEL_CON(50), 8, 1, MFLAGS,
+			RV1126B_CLKGATE_CON(9), 0, GFLAGS),
+	COMPOSITE_NODIV(CLK_PWM2, "clk_pwm2", mux_100m_24m_p, 0,
+			RV1126B_CLKSEL_CON(50), 10, 1, MFLAGS,
+			RV1126B_CLKGATE_CON(9), 2, GFLAGS),
+	COMPOSITE_NODIV(CLK_PWM3, "clk_pwm3", mux_100m_24m_p, 0,
+			RV1126B_CLKSEL_CON(50), 11, 1, MFLAGS,
+			RV1126B_CLKGATE_CON(9), 3, GFLAGS),
+	COMPOSITE_NODIV(CLK_PKA_RKCE_SRC, "clk_pka_rkce_src", mux_300m_200m_p, CLK_IS_CRITICAL,
+			RV1126B_CLKSEL_CON(50), 12, 1, MFLAGS,
+			RV1126B_CLKGATE_CON(9), 4, GFLAGS),
+	COMPOSITE_NODIV(ACLK_RKCE_SRC, "aclk_rkce_src", mux_200m_24m_p, CLK_IS_CRITICAL,
+			RV1126B_CLKSEL_CON(50), 13, 1, MFLAGS,
+			RV1126B_CLKGATE_CON(9), 5, GFLAGS),
+	COMPOSITE_NODIV(ACLK_VCP_ROOT, "aclk_vcp_root", mux_500m_400m_200m_p, CLK_IS_CRITICAL,
+			RV1126B_CLKSEL_CON(48), 12, 2, MFLAGS,
+			RV1126B_CLKGATE_CON(9), 6, GFLAGS),
+	GATE(HCLK_VCP_ROOT, "hclk_vcp_root", "clk_gpll_div8", CLK_IS_CRITICAL,
+			RV1126B_CLKGATE_CON(9), 7, GFLAGS),
+	GATE(PCLK_VCP_ROOT, "pclk_vcp_root", "clk_cpll_div10", CLK_IS_CRITICAL,
+			RV1126B_CLKGATE_CON(9), 8, GFLAGS),
+	COMPOSITE(CLK_CORE_FEC_SRC, "clk_core_fec_src", mux_gpll_cpll_p, 0,
+			RV1126B_CLKSEL_CON(51), 3, 1, MFLAGS, 0, 3, DFLAGS,
+			RV1126B_CLKGATE_CON(9), 9, GFLAGS),
+	GATE(CLK_50M_GMAC_IOBUF_VI, "clk_50m_gmac_iobuf_vi", "clk_cpll_div20", 0,
+			RV1126B_CLKGATE_CON(9), 11, GFLAGS),
+	GATE(PCLK_TOP_ROOT, "pclk_top_root", "clk_cpll_div10", CLK_IS_CRITICAL,
+			RV1126B_CLKGATE_CON(15), 0, GFLAGS),
+	COMPOSITE(CLK_MIPI0_OUT2IO, "clk_mipi0_out2io", mux_600m_24m_p, 0,
+			RV1126B_CLKSEL_CON(67), 11, 1, MFLAGS, 0, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(15), 3, GFLAGS),
+	COMPOSITE(CLK_MIPI1_OUT2IO, "clk_mipi1_out2io", mux_600m_24m_p, 0,
+			RV1126B_CLKSEL_CON(67), 12, 1, MFLAGS, 6, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(15), 4, GFLAGS),
+	COMPOSITE(CLK_MIPI2_OUT2IO, "clk_mipi2_out2io", mux_600m_24m_p, 0,
+			RV1126B_CLKSEL_CON(68), 11, 1, MFLAGS, 0, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(15), 5, GFLAGS),
+	COMPOSITE(CLK_MIPI3_OUT2IO, "clk_mipi3_out2io", mux_600m_24m_p, 0,
+			RV1126B_CLKSEL_CON(68), 12, 1, MFLAGS, 6, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(15), 6, GFLAGS),
+	COMPOSITE(CLK_CIF_OUT2IO, "clk_cif_out2io", mux_600m_24m_p, 0,
+			RV1126B_CLKSEL_CON(69), 5, 1, MFLAGS, 0, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(15), 7, GFLAGS),
+	COMPOSITE(CLK_MAC_OUT2IO, "clk_mac_out2io", mux_gpll_cpll_24m_p, 0,
+			RV1126B_CLKSEL_CON(69), 6, 2, MFLAGS, 8, 7, DFLAGS,
+			RV1126B_CLKGATE_CON(15), 8, GFLAGS),
+	COMPOSITE_NOMUX(MCLK_SAI0_OUT2IO, "mclk_sai0_out2io", "mclk_sai0", CLK_SET_RATE_PARENT,
+			RV1126B_CLKSEL_CON(70), 0, 4, DFLAGS,
+			RV1126B_CLKGATE_CON(15), 9, GFLAGS),
+	COMPOSITE_NOMUX(MCLK_SAI1_OUT2IO, "mclk_sai1_out2io", "mclk_sai1", CLK_SET_RATE_PARENT,
+			RV1126B_CLKSEL_CON(70), 5, 4, DFLAGS,
+			RV1126B_CLKGATE_CON(15), 10, GFLAGS),
+	COMPOSITE_NOMUX(MCLK_SAI2_OUT2IO, "mclk_sai2_out2io", "mclk_sai2", CLK_SET_RATE_PARENT,
+			RV1126B_CLKSEL_CON(70), 10, 4, DFLAGS,
+			RV1126B_CLKGATE_CON(15), 11, GFLAGS),
+
+	/* pd _npu */
+	MUX(ACLK_RKNN, "aclk_rknn", aclk_npu_root_p, CLK_SET_RATE_PARENT,
+			RV1126B_NPUCLKSEL_CON(0), 1, 1, MFLAGS),
+
+	/* pd_vepu */
+	GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_vepu_root", 0,
+			RV1126B_VEPUCLKGATE_CON(0), 7, GFLAGS),
+	GATE(DBCLK_GPIO3, "dbclk_gpio3", "xin24m", 0,
+			RV1126B_VEPUCLKGATE_CON(0), 8, GFLAGS),
+	GATE(PCLK_IOC_VCCIO3, "pclk_ioc_vccio3", "pclk_vepu_root", CLK_IS_CRITICAL,
+			RV1126B_VEPUCLKGATE_CON(0), 9, GFLAGS),
+	GATE(PCLK_SARADC0, "pclk_saradc0", "pclk_vepu_root", 0,
+			RV1126B_VEPUCLKGATE_CON(0), 10, GFLAGS),
+	MUX(CLK_SARADC0, "clk_saradc0", clk_saradc0_p, CLK_SET_RATE_PARENT,
+			RV1126B_VEPUCLKSEL_CON(0), 2, 1, MFLAGS),
+	GATE(HCLK_SDMMC1, "hclk_sdmmc1", "hclk_vepu_root", 0,
+			RV1126B_VEPUCLKGATE_CON(0), 12, GFLAGS),
+	GATE(HCLK_VEPU, "hclk_vepu", "hclk_vepu_root", 0,
+			RV1126B_VEPUCLKGATE_CON(1), 1, GFLAGS),
+	GATE(ACLK_VEPU, "aclk_vepu", "aclk_vepu_root", 0,
+			RV1126B_VEPUCLKGATE_CON(1), 2, GFLAGS),
+	COMPOSITE_NODIV(CLK_CORE_VEPU, "clk_core_vepu", clk_core_vepu_p, CLK_SET_RATE_PARENT,
+			RV1126B_VEPUCLKSEL_CON(0), 1, 1, MFLAGS,
+			RV1126B_VEPUCLKGATE_CON(1), 3, GFLAGS),
+
+	/* pd_vcp */
+	GATE(HCLK_FEC, "hclk_fec", "hclk_vcp_root", 0,
+			RV1126B_VCPCLKGATE_CON(1), 0, GFLAGS),
+	GATE(ACLK_FEC, "aclk_fec", "aclk_vcp_root", 0,
+			RV1126B_VCPCLKGATE_CON(1), 1, GFLAGS),
+	COMPOSITE_NODIV(CLK_CORE_FEC, "clk_core_fec", clk_core_fec_p, CLK_SET_RATE_PARENT,
+			RV1126B_VCPCLKSEL_CON(0), 13, 1, MFLAGS,
+			RV1126B_VCPCLKGATE_CON(1), 2, GFLAGS),
+	GATE(HCLK_AVSP, "hclk_avsp", "hclk_vcp_root", 0,
+			RV1126B_VCPCLKGATE_CON(1), 3, GFLAGS),
+	GATE(ACLK_AVSP, "aclk_avsp", "aclk_vcp_root", 0,
+			RV1126B_VCPCLKGATE_CON(1), 4, GFLAGS),
+	GATE(HCLK_AISP, "hclk_aisp", "hclk_vcp_root", 0,
+			RV1126B_VCPCLKGATE_CON(0), 11, GFLAGS),
+	GATE(ACLK_AISP, "aclk_aisp", "aclk_vcp_root", 0,
+			RV1126B_VCPCLKGATE_CON(0), 12, GFLAGS),
+	COMPOSITE_NODIV(CLK_CORE_AISP, "clk_core_aisp", clk_core_aisp_p, CLK_SET_RATE_PARENT,
+			RV1126B_VCPCLKSEL_CON(0), 15, 1, MFLAGS,
+			RV1126B_VCPCLKGATE_CON(0), 13, GFLAGS),
+
+	/* pd_vi */
+	MUX(CLK_CORE_ISP_ROOT, "clk_core_isp_root", clk_core_isp_root_p, CLK_SET_RATE_PARENT,
+			RV1126B_VICLKSEL_CON(0), 1, 1, MFLAGS),
+	GATE(PCLK_DSMC, "pclk_dsmc", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(0), 8, GFLAGS),
+	GATE(ACLK_DSMC, "aclk_dsmc", "hclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(0), 9, GFLAGS),
+	GATE(HCLK_CAN0, "hclk_can0", "hclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(0), 10, GFLAGS),
+	GATE(HCLK_CAN1, "hclk_can1", "hclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(0), 11, GFLAGS),
+	GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(1), 0, GFLAGS),
+	GATE(DBCLK_GPIO2, "dbclk_gpio2", "xin24m", 0,
+			RV1126B_VICLKGATE_CON(1), 1, GFLAGS),
+	GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(1), 2, GFLAGS),
+	GATE(DBCLK_GPIO4, "dbclk_gpio4", "xin24m", 0,
+			RV1126B_VICLKGATE_CON(1), 3, GFLAGS),
+	GATE(PCLK_GPIO5, "pclk_gpio5", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(1), 4, GFLAGS),
+	GATE(DBCLK_GPIO5, "dbclk_gpio5", "xin24m", 0,
+			RV1126B_VICLKGATE_CON(1), 5, GFLAGS),
+	GATE(PCLK_GPIO6, "pclk_gpio6", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(1), 6, GFLAGS),
+	GATE(DBCLK_GPIO6, "dbclk_gpio6", "xin24m", 0,
+			RV1126B_VICLKGATE_CON(1), 7, GFLAGS),
+	GATE(PCLK_GPIO7, "pclk_gpio7", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(1), 8, GFLAGS),
+	GATE(DBCLK_GPIO7, "dbclk_gpio7", "xin24m", 0,
+			RV1126B_VICLKGATE_CON(1), 9, GFLAGS),
+	GATE(PCLK_IOC_VCCIO2, "pclk_ioc_vccio2", "pclk_vi_root", CLK_IS_CRITICAL,
+			RV1126B_VICLKGATE_CON(1), 10, GFLAGS),
+	GATE(PCLK_IOC_VCCIO4, "pclk_ioc_vccio4", "pclk_vi_root", CLK_IS_CRITICAL,
+			RV1126B_VICLKGATE_CON(1), 11, GFLAGS),
+	GATE(PCLK_IOC_VCCIO5, "pclk_ioc_vccio5", "pclk_vi_root", CLK_IS_CRITICAL,
+			RV1126B_VICLKGATE_CON(1), 12, GFLAGS),
+	GATE(PCLK_IOC_VCCIO6, "pclk_ioc_vccio6", "pclk_vi_root", CLK_IS_CRITICAL,
+			RV1126B_VICLKGATE_CON(1), 13, GFLAGS),
+	GATE(PCLK_IOC_VCCIO7, "pclk_ioc_vccio7", "pclk_vi_root", CLK_IS_CRITICAL,
+			RV1126B_VICLKGATE_CON(1), 14, GFLAGS),
+	GATE(HCLK_ISP, "hclk_isp", "hclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(2), 0, GFLAGS),
+	GATE(ACLK_ISP, "aclk_isp", "aclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(2), 1, GFLAGS),
+	GATE(CLK_CORE_ISP, "clk_core_isp", "clk_core_isp_root", 0,
+			RV1126B_VICLKGATE_CON(2), 2, GFLAGS),
+	GATE(HCLK_VICAP, "hclk_vicap", "hclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(2), 3, GFLAGS),
+	GATE(ACLK_VICAP, "aclk_vicap", "aclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(2), 4, GFLAGS),
+	GATE(DCLK_VICAP, "dclk_vicap", "dclk_vicap_root", 0,
+			RV1126B_VICLKGATE_CON(2), 5, GFLAGS),
+	GATE(ISP0CLK_VICAP, "isp0clk_vicap", "clk_core_isp_root", 0,
+			RV1126B_VICLKGATE_CON(2), 6, GFLAGS),
+	GATE(HCLK_VPSS, "hclk_vpss", "hclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(2), 7, GFLAGS),
+	GATE(ACLK_VPSS, "aclk_vpss", "aclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(2), 8, GFLAGS),
+	GATE(CLK_CORE_VPSS, "clk_core_vpss", "clk_core_isp_root", 0,
+			RV1126B_VICLKGATE_CON(2), 9, GFLAGS),
+	GATE(HCLK_VPSL, "hclk_vpsl", "hclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(2), 10, GFLAGS),
+	GATE(ACLK_VPSL, "aclk_vpsl", "aclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(2), 11, GFLAGS),
+	GATE(CLK_CORE_VPSL, "clk_core_vpsl", "clk_core_isp_root", 0,
+			RV1126B_VICLKGATE_CON(2), 12, GFLAGS),
+	GATE(PCLK_CSI2HOST0, "pclk_csi2host0", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(3), 0, GFLAGS),
+	GATE(DCLK_CSI2HOST0, "dclk_csi2host0", "dclk_vicap_root", 0,
+			RV1126B_VICLKGATE_CON(3), 1, GFLAGS),
+	GATE(PCLK_CSI2HOST1, "pclk_csi2host1", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(3), 2, GFLAGS),
+	GATE(DCLK_CSI2HOST1, "dclk_csi2host1", "dclk_vicap_root", 0,
+			RV1126B_VICLKGATE_CON(3), 3, GFLAGS),
+	GATE(PCLK_CSI2HOST2, "pclk_csi2host2", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(3), 4, GFLAGS),
+	GATE(DCLK_CSI2HOST2, "dclk_csi2host2", "dclk_vicap_root", 0,
+			RV1126B_VICLKGATE_CON(3), 5, GFLAGS),
+	GATE(PCLK_CSI2HOST3, "pclk_csi2host3", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(3), 6, GFLAGS),
+	GATE(DCLK_CSI2HOST3, "dclk_csi2host3", "dclk_vicap_root", 0,
+			RV1126B_VICLKGATE_CON(3), 7, GFLAGS),
+	GATE(HCLK_SDMMC0, "hclk_sdmmc0", "hclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(3), 8, GFLAGS),
+	GATE(ACLK_GMAC, "aclk_gmac", "aclk_gmac_root", 0,
+			RV1126B_VICLKGATE_CON(3), 9, GFLAGS),
+	GATE(PCLK_GMAC, "pclk_gmac", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(3), 10, GFLAGS),
+	MUX(CLK_GMAC_PTP_REF, "clk_gmac_ptp_ref", clk_gmac_ptp_ref_p, CLK_SET_RATE_PARENT,
+			RV1126B_VICLKSEL_CON(0), 14, 1, MFLAGS),
+	GATE(PCLK_CSIPHY0, "pclk_csiphy0", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(3), 11, GFLAGS),
+	GATE(PCLK_CSIPHY1, "pclk_csiphy1", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(3), 12, GFLAGS),
+	GATE(PCLK_MACPHY, "pclk_macphy", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(3), 13, GFLAGS),
+	GATE(PCLK_SARADC1, "pclk_saradc1", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(4), 0, GFLAGS),
+	MUX(CLK_SARADC1, "clk_saradc1", clk_saradc1_p, CLK_SET_RATE_PARENT,
+			RV1126B_VICLKSEL_CON(0), 2, 1, MFLAGS),
+	GATE(PCLK_SARADC2, "pclk_saradc2", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(4), 2, GFLAGS),
+	MUX(CLK_SARADC2, "clk_saradc2", clk_saradc2_p, CLK_SET_RATE_PARENT,
+			RV1126B_VICLKSEL_CON(0), 3, 1, MFLAGS),
+	COMPOSITE_NODIV(CLK_MACPHY, "clk_macphy", clk_macphy_p, 0,
+			RV1126B_VICLKSEL_CON(1), 1, 1, MFLAGS,
+			RV1126B_VICLKGATE_CON(0), 12, GFLAGS),
+
+	/* pd_vdo */
+	GATE(ACLK_RKVDEC, "aclk_rkvdec", "aclk_rkvdec_root", 0,
+			RV1126B_VDOCLKGATE_CON(0), 7, GFLAGS),
+	GATE(HCLK_RKVDEC, "hclk_rkvdec", "hclk_vdo_root", 0,
+			RV1126B_VDOCLKGATE_CON(0), 8, GFLAGS),
+	GATE(CLK_HEVC_CA_RKVDEC, "clk_hevc_ca_rkvdec", "aclk_rkvdec_root", 0,
+			RV1126B_VDOCLKGATE_CON(0), 9, GFLAGS),
+	GATE(ACLK_VOP, "aclk_vop", "aclk_vdo_root", 0,
+			RV1126B_VDOCLKGATE_CON(0), 10, GFLAGS),
+	GATE(HCLK_VOP, "hclk_vop", "hclk_vdo_root", 0,
+			RV1126B_VDOCLKGATE_CON(0), 11, GFLAGS),
+	GATE(ACLK_OOC, "aclk_ooc", "aclk_vdo_root", 0,
+			RV1126B_VDOCLKGATE_CON(0), 13, GFLAGS),
+	GATE(HCLK_OOC, "hclk_ooc", "hclk_vdo_root", 0,
+			RV1126B_VDOCLKGATE_CON(0), 14, GFLAGS),
+	GATE(HCLK_RKJPEG, "hclk_rkjpeg", "hclk_vdo_root", 0,
+			RV1126B_VDOCLKGATE_CON(1), 3, GFLAGS),
+	GATE(ACLK_RKJPEG, "aclk_rkjpeg", "aclk_vdo_root", 0,
+			RV1126B_VDOCLKGATE_CON(1), 4, GFLAGS),
+	GATE(ACLK_RKMMU_DECOM, "aclk_rkmmu_decom", "aclk_vdo_root", 0,
+			RV1126B_VDOCLKGATE_CON(1), 5, GFLAGS),
+	GATE(HCLK_RKMMU_DECOM, "hclk_rkmmu_decom", "hclk_vdo_root", 0,
+			RV1126B_VDOCLKGATE_CON(1), 6, GFLAGS),
+	GATE(DCLK_DECOM, "dclk_decom", "dclk_decom_src", 0,
+			RV1126B_VDOCLKGATE_CON(1), 8, GFLAGS),
+	GATE(ACLK_DECOM, "aclk_decom", "aclk_vdo_root", 0,
+			RV1126B_VDOCLKGATE_CON(1), 9, GFLAGS),
+	GATE(PCLK_DECOM, "pclk_decom", "pclk_vdo_root", 0,
+			RV1126B_VDOCLKGATE_CON(1), 10, GFLAGS),
+	GATE(PCLK_MIPI_DSI, "pclk_mipi_dsi", "pclk_vdo_root", 0,
+			RV1126B_VDOCLKGATE_CON(1), 12, GFLAGS),
+	GATE(PCLK_DSIPHY, "pclk_dsiphy", "pclk_vdo_root", 0,
+			RV1126B_VDOCLKGATE_CON(1), 13, GFLAGS),
+
+	/* pd_ddr */
+	GATE(PCLK_DDRC, "pclk_ddrc", "pclk_ddr_root", CLK_IS_CRITICAL,
+			RV1126B_DDRCLKGATE_CON(0), 2, GFLAGS),
+	GATE(PCLK_DDRMON, "pclk_ddrmon", "pclk_ddr_root", CLK_IS_CRITICAL,
+			RV1126B_DDRCLKGATE_CON(0), 3, GFLAGS),
+	GATE(CLK_TIMER_DDRMON, "clk_timer_ddrmon", "xin24m", 0,
+			RV1126B_DDRCLKGATE_CON(0), 4, GFLAGS),
+	GATE(PCLK_DFICTRL, "pclk_dfictrl", "pclk_ddr_root", CLK_IS_CRITICAL,
+			RV1126B_DDRCLKGATE_CON(0), 5, GFLAGS),
+	GATE(PCLK_DDRPHY, "pclk_ddrphy", "pclk_ddr_root", CLK_IS_CRITICAL,
+			RV1126B_DDRCLKGATE_CON(0), 8, GFLAGS),
+	GATE(PCLK_DMA2DDR, "pclk_dma2ddr", "pclk_ddr_root", CLK_IS_CRITICAL,
+			RV1126B_DDRCLKGATE_CON(0), 9, GFLAGS),
+
+	/* pd_pmu*/
+	COMPOSITE_NODIV(CLK_RCOSC_SRC, "clk_rcosc_src", clk_rcosc_src_p, 0,
+			RV1126B_PMUCLKSEL_CON(1), 0, 3, MFLAGS,
+			RV1126B_PMUCLKGATE_CON(0), 0, GFLAGS),
+	COMPOSITE_NOGATE(BUSCLK_PMU_MUX, "busclk_pmu_mux", busclk_pmu_mux_p, 0,
+			RV1126B_PMUCLKSEL_CON(1), 3, 1, MFLAGS, 4, 2, DFLAGS),
+	GATE(BUSCLK_PMU_ROOT, "busclk_pmu_root", "busclk_pmu_mux", 0,
+			RV1126B_PMUCLKGATE_CON(0), 1, GFLAGS),
+	GATE(BUSCLK_PMU1_ROOT, "busclk_pmu1_root", "busclk_pmu_mux", CLK_IS_CRITICAL,
+			RV1126B_PMUCLKGATE_CON(3), 11, GFLAGS),
+	GATE(PCLK_PMU, "pclk_pmu", "busclk_pmu_root", CLK_IS_CRITICAL,
+			RV1126B_PMUCLKGATE_CON(0), 6, GFLAGS),
+	MUX(0, "xin_rc_src", clk_xin_rc_div_p, 0,
+			RV1126B_PMUCLKSEL_CON(2), 0, 1, MFLAGS),
+	COMPOSITE_FRACMUX_NOGATE(CLK_XIN_RC_DIV, "clk_xin_rc_div", "xin_rc_src", CLK_SET_RATE_PARENT,
+			RV1126B_PMUCLKSEL_CON(8), 0,
+			&rv1126b_rcdiv_pmu_fracmux),
+	GATE(PCLK_PMU_GPIO0, "pclk_pmu_gpio0", "busclk_pmu_root", 0,
+			RV1126B_PMUCLKGATE_CON(0), 7, GFLAGS),
+	COMPOSITE_NODIV(DBCLK_PMU_GPIO0, "dbclk_pmu_gpio0", mux_24m_32k_p, 0,
+			RV1126B_PMUCLKSEL_CON(2), 4, 1, MFLAGS,
+			RV1126B_PMUCLKGATE_CON(0), 8, GFLAGS),
+	GATE(PCLK_PMU_HP_TIMER, "pclk_pmu_hp_timer", "busclk_pmu_root", CLK_IS_CRITICAL,
+			RV1126B_PMUCLKGATE_CON(0), 10, GFLAGS),
+	COMPOSITE(CLK_PMU_HP_TIMER, "clk_pmu_hp_timer", mux_cpll_24m_p, CLK_IS_CRITICAL,
+			RV1126B_PMUCLKSEL_CON(1), 13, 1, MFLAGS, 8, 5, DFLAGS,
+			RV1126B_PMUCLKGATE_CON(0), 11, GFLAGS),
+	GATE(CLK_PMU_32K_HP_TIMER, "clk_pmu_32k_hp_timer", "clk_32k", CLK_IS_CRITICAL,
+			RV1126B_PMUCLKGATE_CON(0), 13, GFLAGS),
+	GATE(PCLK_PWM1, "pclk_pwm1", "busclk_pmu_root", 0,
+			RV1126B_PMUCLKGATE_CON(1), 0, GFLAGS),
+	COMPOSITE(CLK_PWM1, "clk_pwm1", mux_24m_rcosc_buspmu_p, 0,
+			RV1126B_PMUCLKSEL_CON(2), 8, 2, MFLAGS, 6, 2, DFLAGS,
+			RV1126B_PMUCLKGATE_CON(1), 1, GFLAGS),
+	GATE(CLK_OSC_PWM1, "clk_osc_pwm1", "xin24m", 0,
+			RV1126B_PMUCLKGATE_CON(1), 2, GFLAGS),
+	GATE(CLK_RC_PWM1, "clk_rc_pwm1", "clk_32k", 0,
+			RV1126B_PMUCLKGATE_CON(1), 3, GFLAGS),
+	GATE(PCLK_I2C2, "pclk_i2c2", "busclk_pmu_root", 0,
+			RV1126B_PMUCLKGATE_CON(1), 6, GFLAGS),
+	COMPOSITE(CLK_I2C2, "clk_i2c2", mux_24m_rcosc_buspmu_p, 0,
+			RV1126B_PMUCLKSEL_CON(2), 14, 2, MFLAGS, 12, 2, DFLAGS,
+			RV1126B_PMUCLKGATE_CON(1), 7, GFLAGS),
+	GATE(PCLK_UART0, "pclk_uart0", "busclk_pmu_root", 0,
+			RV1126B_PMUCLKGATE_CON(1), 8, GFLAGS),
+	COMPOSITE_NODIV(SCLK_UART0, "sclk_uart0", sclk_uart0_p, CLK_SET_RATE_PARENT,
+			RV1126B_PMUCLKSEL_CON(3), 0, 2, MFLAGS,
+			RV1126B_PMUCLKGATE_CON(1), 11, GFLAGS),
+	GATE(PCLK_RCOSC_CTRL, "pclk_rcosc_ctrl", "busclk_pmu_root", CLK_IS_CRITICAL,
+			RV1126B_PMUCLKGATE_CON(2), 0, GFLAGS),
+	COMPOSITE_NODIV(CLK_OSC_RCOSC_CTRL, "clk_osc_rcosc_ctrl", clk_osc_rcosc_ctrl_p, CLK_IS_CRITICAL,
+			RV1126B_PMUCLKSEL_CON(3), 2, 1, MFLAGS,
+			RV1126B_PMUCLKGATE_CON(2), 1, GFLAGS),
+	GATE(CLK_REF_RCOSC_CTRL, "clk_ref_rcosc_ctrl", "xin24m", CLK_IS_CRITICAL,
+			RV1126B_PMUCLKGATE_CON(2), 2, GFLAGS),
+	GATE(PCLK_IOC_PMUIO0, "pclk_ioc_pmuio0", "busclk_pmu_root", CLK_IS_CRITICAL,
+			RV1126B_PMUCLKGATE_CON(2), 3, GFLAGS),
+	GATE(CLK_REFOUT, "clk_refout", "xin24m", 0,
+			RV1126B_PMUCLKGATE_CON(2), 6, GFLAGS),
+	GATE(CLK_PREROLL, "clk_preroll", "busclk_pmu_root", 0,
+			RV1126B_PMUCLKGATE_CON(2), 7, GFLAGS),
+	GATE(CLK_PREROLL_32K, "clk_preroll_32k", "clk_32k", 0,
+			RV1126B_PMUCLKGATE_CON(2), 8, GFLAGS),
+	GATE(HCLK_PMU_SRAM, "hclk_pmu_sram", "busclk_pmu_root", CLK_IS_CRITICAL,
+			RV1126B_PMUCLKGATE_CON(2), 9, GFLAGS),
+	GATE(PCLK_WDT_LPMCU, "pclk_wdt_lpmcu", "busclk_pmu_root", 0,
+			RV1126B_PMUCLKGATE_CON(3), 0, GFLAGS),
+	COMPOSITE_NODIV(TCLK_WDT_LPMCU, "tclk_wdt_lpmcu", mux_24m_rcosc_buspmu_32k_p, 0,
+			RV1126B_PMUCLKSEL_CON(3), 6, 2, MFLAGS,
+			RV1126B_PMUCLKGATE_CON(3), 1, GFLAGS),
+	GATE(CLK_LPMCU, "clk_lpmcu", "busclk_pmu_root", 0,
+			RV1126B_PMUCLKGATE_CON(3), 2, GFLAGS),
+	GATE(CLK_LPMCU_RTC, "clk_lpmcu_rtc", "xin24m", 0,
+			RV1126B_PMUCLKGATE_CON(3), 3, GFLAGS),
+	GATE(PCLK_LPMCU_MAILBOX, "pclk_lpmcu_mailbox", "busclk_pmu_root", 0,
+			RV1126B_PMUCLKGATE_CON(3), 4, GFLAGS),
+
+	/* pd_pmu1 */
+	GATE(PCLK_SPI2AHB, "pclk_spi2ahb", "busclk_pmu_root", 0,
+			RV1126B_PMU1CLKGATE_CON(0), 0, GFLAGS),
+	GATE(HCLK_SPI2AHB, "hclk_spi2ahb", "busclk_pmu_root", 0,
+			RV1126B_PMU1CLKGATE_CON(0), 1, GFLAGS),
+	GATE(HCLK_FSPI1, "hclk_fspi1", "busclk_pmu_root", 0,
+			RV1126B_PMU1CLKGATE_CON(0), 2, GFLAGS),
+	GATE(HCLK_XIP_FSPI1, "hclk_xip_fspi1", "busclk_pmu_root", 0,
+			RV1126B_PMU1CLKGATE_CON(0), 3, GFLAGS),
+	COMPOSITE(SCLK_1X_FSPI1, "sclk_1x_fspi1", mux_24m_rcosc_buspmu_p, 0,
+			RV1126B_PMU1CLKSEL_CON(0), 0, 2, MFLAGS, 2, 3, DFLAGS,
+			RV1126B_PMU1CLKGATE_CON(0), 4, GFLAGS),
+	GATE(PCLK_IOC_PMUIO1, "pclk_ioc_pmuio1", "busclk_pmu_root", CLK_IS_CRITICAL,
+			RV1126B_PMU1CLKGATE_CON(0), 5, GFLAGS),
+	GATE(PCLK_AUDIO_ADC_PMU, "pclk_audio_adc_pmu", "busclk_pmu_root", 0,
+			RV1126B_PMU1CLKGATE_CON(0), 8, GFLAGS),
+
+	COMPOSITE(MCLK_LPSAI, "mclk_lpsai", mux_24m_rcosc_buspmu_p, 0,
+			RV1126B_PMU1CLKSEL_CON(0), 6, 2, MFLAGS, 8, 5, DFLAGS,
+			RV1126B_PMU1CLKGATE_CON(1), 3, GFLAGS),
+	GATE(MCLK_AUDIO_ADC_PMU, "mclk_audio_adc_pmu", "mclk_lpsai", CLK_IS_CRITICAL,
+			RV1126B_PMU1CLKGATE_CON(0), 9, GFLAGS),
+	FACTOR(MCLK_AUDIO_ADC_DIV4_PMU, "mclk_audio_adc_div4_pmu", "mclk_audio_adc_pmu", 0, 1, 4),
+
+	/* pd_bus */
+	GATE(ACLK_GIC400, "aclk_gic400", "hclk_bus_root", CLK_IS_CRITICAL,
+			RV1126B_BUSCLKGATE_CON(0), 8, GFLAGS),
+	GATE(PCLK_WDT_NS, "pclk_wdt_ns", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(0), 10, GFLAGS),
+	GATE(TCLK_WDT_NS, "tclk_wdt_ns", "tclk_wdt_ns_src", 0,
+			RV1126B_BUSCLKGATE_CON(0), 11, GFLAGS),
+	GATE(PCLK_WDT_HPMCU, "pclk_wdt_hpmcu", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(1), 0, GFLAGS),
+	GATE(HCLK_CACHE, "hclk_cache", "aclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(1), 2, GFLAGS),
+	GATE(PCLK_HPMCU_MAILBOX, "pclk_hpmcu_mailbox", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(1), 3, GFLAGS),
+	GATE(PCLK_HPMCU_INTMUX, "pclk_hpmcu_intmux", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(1), 4, GFLAGS),
+	GATE(CLK_HPMCU, "clk_hpmcu", "aclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(1), 5, GFLAGS),
+	GATE(CLK_HPMCU_RTC, "clk_hpmcu_rtc", "xin24m", 0,
+			RV1126B_BUSCLKGATE_CON(1), 10, GFLAGS),
+	GATE(PCLK_RKDMA, "pclk_rkdma", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(1), 11, GFLAGS),
+	GATE(ACLK_RKDMA, "aclk_rkdma", "aclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(1), 12, GFLAGS),
+	GATE(PCLK_DCF, "pclk_dcf", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(2), 0, GFLAGS),
+	GATE(ACLK_DCF, "aclk_dcf", "aclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(2), 1, GFLAGS),
+	GATE(HCLK_RGA, "hclk_rga", "hclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(2), 2, GFLAGS),
+	GATE(ACLK_RGA, "aclk_rga", "aclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(2), 3, GFLAGS),
+	GATE(CLK_CORE_RGA, "clk_core_rga", "clk_core_rga_src", 0,
+			RV1126B_BUSCLKGATE_CON(2), 4, GFLAGS),
+	GATE(PCLK_TIMER, "pclk_timer", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(2), 5, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0, "clk_timer0", clk_timer0_parents_p, 0,
+			RV1126B_BUSCLKSEL_CON(2), 0, 2, MFLAGS,
+			RV1126B_BUSCLKGATE_CON(2), 6, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER1, "clk_timer1", clk_timer1_parents_p, 0,
+			RV1126B_BUSCLKSEL_CON(2), 2, 2, MFLAGS,
+			RV1126B_BUSCLKGATE_CON(2), 7, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER2, "clk_timer2", clk_timer2_parents_p, 0,
+			RV1126B_BUSCLKSEL_CON(2), 4, 2, MFLAGS,
+			RV1126B_BUSCLKGATE_CON(2), 8, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER3, "clk_timer3", clk_timer3_parents_p, 0,
+			RV1126B_BUSCLKSEL_CON(2), 6, 2, MFLAGS,
+			RV1126B_BUSCLKGATE_CON(2), 9, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER4, "clk_timer4", clk_timer4_parents_p, 0,
+			RV1126B_BUSCLKSEL_CON(2), 8, 2, MFLAGS,
+			RV1126B_BUSCLKGATE_CON(2), 10, GFLAGS),
+	GATE(HCLK_RKRNG_S_NS, "hclk_rkrng_s_ns", "hclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(2), 14, GFLAGS),
+	GATE(HCLK_RKRNG_NS, "hclk_rkrng_ns", "hclk_rkrng_s_ns", 0,
+			RV1126B_BUSCLKGATE_CON(2), 15, GFLAGS),
+	GATE(CLK_TIMER5, "clk_timer5", "clk_timer_root", CLK_IS_CRITICAL,
+			RV1126B_BUSCLKGATE_CON(2), 11, GFLAGS),
+	GATE(PCLK_I2C0, "pclk_i2c0", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(3), 0, GFLAGS),
+	GATE(CLK_I2C0, "clk_i2c0", "clk_i2c_bus_src", 0,
+			RV1126B_BUSCLKGATE_CON(3), 1, GFLAGS),
+	GATE(PCLK_I2C1, "pclk_i2c1", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(3), 2, GFLAGS),
+	GATE(CLK_I2C1, "clk_i2c1", "clk_i2c_bus_src", 0,
+			RV1126B_BUSCLKGATE_CON(3), 3, GFLAGS),
+	GATE(PCLK_I2C3, "pclk_i2c3", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(3), 4, GFLAGS),
+	GATE(CLK_I2C3, "clk_i2c3", "clk_i2c_bus_src", 0,
+			RV1126B_BUSCLKGATE_CON(3), 5, GFLAGS),
+	GATE(PCLK_I2C4, "pclk_i2c4", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(3), 6, GFLAGS),
+	GATE(CLK_I2C4, "clk_i2c4", "clk_i2c_bus_src", 0,
+			RV1126B_BUSCLKGATE_CON(3), 7, GFLAGS),
+	GATE(PCLK_I2C5, "pclk_i2c5", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(3), 8, GFLAGS),
+	GATE(CLK_I2C5, "clk_i2c5", "clk_i2c_bus_src", 0,
+			RV1126B_BUSCLKGATE_CON(3), 9, GFLAGS),
+	GATE(PCLK_SPI0, "pclk_spi0", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(3), 10, GFLAGS),
+	GATE(PCLK_SPI1, "pclk_spi1", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(3), 12, GFLAGS),
+	GATE(PCLK_PWM0, "pclk_pwm0", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(4), 0, GFLAGS),
+	GATE(CLK_OSC_PWM0, "clk_osc_pwm0", "xin24m", 0,
+			RV1126B_BUSCLKGATE_CON(4), 1, GFLAGS),
+	GATE(CLK_RC_PWM0, "clk_rc_pwm0", "xin24m", 0,
+			RV1126B_BUSCLKGATE_CON(4), 2, GFLAGS),
+	GATE(PCLK_PWM2, "pclk_pwm2", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(4), 3, GFLAGS),
+	GATE(CLK_OSC_PWM2, "clk_osc_pwm2", "xin24m", 0,
+			RV1126B_BUSCLKGATE_CON(4), 4, GFLAGS),
+	GATE(CLK_RC_PWM2, "clk_rc_pwm2", "xin24m", 0,
+			RV1126B_BUSCLKGATE_CON(4), 5, GFLAGS),
+	GATE(PCLK_PWM3, "pclk_pwm3", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(4), 6, GFLAGS),
+	GATE(CLK_OSC_PWM3, "clk_osc_pwm3", "xin24m", 0,
+			RV1126B_BUSCLKGATE_CON(4), 7, GFLAGS),
+	GATE(CLK_RC_PWM3, "clk_rc_pwm3", "xin24m", 0,
+			RV1126B_BUSCLKGATE_CON(4), 8, GFLAGS),
+	GATE(PCLK_UART1, "pclk_uart1", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(4), 9, GFLAGS),
+	GATE(PCLK_UART2, "pclk_uart2", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(4), 10, GFLAGS),
+	GATE(PCLK_UART3, "pclk_uart3", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(4), 11, GFLAGS),
+	GATE(PCLK_UART4, "pclk_uart4", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(4), 12, GFLAGS),
+	GATE(PCLK_UART5, "pclk_uart5", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(4), 13, GFLAGS),
+	GATE(PCLK_UART6, "pclk_uart6", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(4), 14, GFLAGS),
+	GATE(PCLK_UART7, "pclk_uart7", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(4), 15, GFLAGS),
+	GATE(PCLK_TSADC, "pclk_tsadc", "pclk_bus_root", CLK_IS_CRITICAL,
+			RV1126B_BUSCLKGATE_CON(5), 0, GFLAGS),
+	GATE(CLK_TSADC, "clk_tsadc", "xin24m", CLK_IS_CRITICAL,
+			RV1126B_BUSCLKGATE_CON(5), 1, GFLAGS),
+	GATE(HCLK_SAI0, "hclk_sai0", "hclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(5), 2, GFLAGS),
+	GATE(HCLK_SAI1, "hclk_sai1", "hclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(5), 4, GFLAGS),
+	GATE(HCLK_SAI2, "hclk_sai2", "hclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(5), 6, GFLAGS),
+	GATE(HCLK_RKDSM, "hclk_rkdsm", "hclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(5), 8, GFLAGS),
+	GATE(MCLK_RKDSM, "mclk_rkdsm", "mclk_sai2", 0,
+			RV1126B_BUSCLKGATE_CON(5), 9, GFLAGS),
+	GATE(HCLK_PDM, "hclk_pdm", "hclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(5), 10, GFLAGS),
+	GATE(HCLK_ASRC0, "hclk_asrc0", "hclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(5), 11, GFLAGS),
+	GATE(HCLK_ASRC1, "hclk_asrc1", "hclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(5), 12, GFLAGS),
+	GATE(PCLK_AUDIO_ADC_BUS, "pclk_audio_adc_bus", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(5), 13, GFLAGS),
+	GATE(MCLK_AUDIO_ADC_BUS, "mclk_audio_adc_bus", "mclk_sai2", 0,
+			RV1126B_BUSCLKGATE_CON(5), 14, GFLAGS),
+	FACTOR(MCLK_AUDIO_ADC_DIV4_BUS, "mclk_audio_adc_div4_bus", "mclk_audio_adc_bus", 0, 1, 4),
+	GATE(PCLK_RKCE, "pclk_rkce", "pclk_bus_root", CLK_IS_CRITICAL,
+			RV1126B_BUSCLKGATE_CON(6), 0, GFLAGS),
+	GATE(HCLK_NS_RKCE, "hclk_ns_rkce", "hclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(6), 1, GFLAGS),
+	GATE(PCLK_OTPC_NS, "pclk_otpc_ns", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(6), 2, GFLAGS),
+	GATE(CLK_SBPI_OTPC_NS, "clk_sbpi_otpc_ns", "xin24m", 0,
+			RV1126B_BUSCLKGATE_CON(6), 3, GFLAGS),
+	COMPOSITE_NOMUX(CLK_USER_OTPC_NS, "clk_user_otpc_ns", "xin24m", 0,
+			RV1126B_BUSCLKSEL_CON(2), 12, 3, DFLAGS,
+			RV1126B_BUSCLKGATE_CON(6), 4, GFLAGS),
+	GATE(PCLK_OTP_MASK, "pclk_otp_mask", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(6), 6, GFLAGS),
+	GATE(CLK_TSADC_PHYCTRL, "clk_tsadc_phyctrl", "xin24m", CLK_IS_CRITICAL,
+			RV1126B_BUSCLKGATE_CON(6), 8, GFLAGS),
+	MUX(LRCK_SRC_ASRC0, "lrck_src_asrc0", lrck_src_asrc_p, 0,
+			RV1126B_BUSCLKSEL_CON(3), 0, 3, MFLAGS),
+	MUX(LRCK_DST_ASRC0, "lrck_dst_asrc0", lrck_src_asrc_p, 0,
+			RV1126B_BUSCLKSEL_CON(3), 4, 3, MFLAGS),
+	MUX(LRCK_SRC_ASRC1, "lrck_src_asrc1", lrck_src_asrc_p, 0,
+			RV1126B_BUSCLKSEL_CON(3), 8, 3, MFLAGS),
+	MUX(LRCK_DST_ASRC1, "lrck_dst_asrc1", lrck_src_asrc_p, 0,
+			RV1126B_BUSCLKSEL_CON(3), 12, 3, MFLAGS),
+	GATE(ACLK_NSRKCE, "aclk_nsrkce", "aclk_rkce_src", 0,
+			RV1126B_BUSCLKGATE_CON(2), 12, GFLAGS),
+	GATE(CLK_PKA_NSRKCE, "clk_pka_nsrkce", "clk_pka_rkce_src", 0,
+			RV1126B_BUSCLKGATE_CON(2), 13, GFLAGS),
+
+	/* pd_peri */
+	DIV(PCLK_RTC_ROOT, "pclk_rtc_root", "pclk_peri_root", 0,
+			RV1126B_PERICLKSEL_CON(0), 0, 2, DFLAGS),
+	GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_peri_root", 0,
+			RV1126B_PERICLKGATE_CON(0), 5, GFLAGS),
+	GATE(DBCLK_GPIO1, "dbclk_gpio1", "xin24m", 0,
+			RV1126B_PERICLKGATE_CON(0), 6, GFLAGS),
+	GATE(PCLK_IOC_VCCIO1, "pclk_ioc_vccio1", "pclk_peri_root", CLK_IS_CRITICAL,
+			RV1126B_PERICLKGATE_CON(0), 7, GFLAGS),
+	GATE(ACLK_USB3OTG, "aclk_usb3otg", "aclk_peri_root", 0,
+			RV1126B_PERICLKGATE_CON(0), 8, GFLAGS),
+	GATE(CLK_REF_USB3OTG, "clk_ref_usb3otg", "xin24m", 0,
+			RV1126B_PERICLKGATE_CON(0), 9, GFLAGS),
+	GATE(CLK_SUSPEND_USB3OTG, "clk_suspend_usb3otg", "xin24m", 0,
+			RV1126B_PERICLKGATE_CON(0), 10, GFLAGS),
+	GATE(HCLK_USB2HOST, "hclk_usb2host", "aclk_peri_root", 0,
+			RV1126B_PERICLKGATE_CON(0), 11, GFLAGS),
+	GATE(HCLK_ARB_USB2HOST, "hclk_arb_usb2host", "aclk_peri_root", 0,
+			RV1126B_PERICLKGATE_CON(0), 12, GFLAGS),
+	GATE(PCLK_RTC_TEST, "pclk_rtc_test", "pclk_rtc_root", 0,
+			RV1126B_PERICLKGATE_CON(0), 13, GFLAGS),
+	GATE(HCLK_EMMC, "hclk_emmc", "aclk_peri_root", 0,
+			RV1126B_PERICLKGATE_CON(1), 0, GFLAGS),
+	GATE(HCLK_FSPI0, "hclk_fspi0", "aclk_peri_root", 0,
+			RV1126B_PERICLKGATE_CON(1), 1, GFLAGS),
+	GATE(HCLK_XIP_FSPI0, "hclk_xip_fspi0", "aclk_peri_root", 0,
+			RV1126B_PERICLKGATE_CON(1), 2, GFLAGS),
+	GATE(PCLK_PIPEPHY, "pclk_pipephy", "pclk_peri_root", 0,
+			RV1126B_PERICLKGATE_CON(1), 8, GFLAGS),
+	GATE(PCLK_USB2PHY, "pclk_usb2phy", "pclk_peri_root", 0,
+			RV1126B_PERICLKGATE_CON(1), 10, GFLAGS),
+	COMPOSITE_NOMUX(CLK_REF_PIPEPHY_CPLL_SRC, "clk_ref_pipephy_cpll_src", "cpll", 0,
+			RV1126B_PERICLKSEL_CON(1), 0, 6, DFLAGS,
+			RV1126B_PERICLKGATE_CON(1), 14, GFLAGS),
+	MUX(CLK_REF_PIPEPHY, "clk_ref_pipephy", clk_ref_pipephy_p, 0,
+			RV1126B_PERICLKSEL_CON(1), 12, 1, MFLAGS),
+};
+
+static struct rockchip_clk_branch rv1126b_armclk __initdata =
+	MUX(ARMCLK, "armclk", mux_armclk_p, CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
+			RV1126B_CORECLKSEL_CON(0), 1, 1, MFLAGS);
+
+static void __init rv1126b_clk_init(struct device_node *np)
+{
+	struct rockchip_clk_provider *ctx;
+	void __iomem *reg_base;
+	unsigned long clk_nr_clks;
+
+	clk_nr_clks = rockchip_clk_find_max_clk_id(rv1126b_clk_branches,
+						   ARRAY_SIZE(rv1126b_clk_branches)) + 1;
+
+	reg_base = of_iomap(np, 0);
+	if (!reg_base) {
+		pr_err("%s: could not map cru region\n", __func__);
+		return;
+	}
+
+	ctx = rockchip_clk_init(np, reg_base, clk_nr_clks);
+	if (IS_ERR(ctx)) {
+		pr_err("%s: rockchip clk init failed\n", __func__);
+		iounmap(reg_base);
+		return;
+	}
+
+	rockchip_clk_register_plls(ctx, rv1126b_pll_clks,
+				   ARRAY_SIZE(rv1126b_pll_clks),
+				   0);
+
+	rockchip_clk_register_branches(ctx, rv1126b_clk_branches,
+				       ARRAY_SIZE(rv1126b_clk_branches));
+
+	rockchip_clk_register_armclk_multi_pll(ctx, &rv1126b_armclk,
+					       rv1126b_cpuclk_rates,
+					       ARRAY_SIZE(rv1126b_cpuclk_rates));
+
+	rv1126b_rst_init(np, reg_base);
+
+	rockchip_register_restart_notifier(ctx, RV1126B_GLB_SRST_FST, NULL);
+
+	rockchip_clk_of_add_provider(np, ctx);
+
+	/* pvtpll src init */
+	writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RV1126B_CORECLKSEL_CON(0));
+	writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RV1126B_NPUCLKSEL_CON(0));
+	writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RV1126B_VICLKSEL_CON(0));
+	writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RV1126B_VEPUCLKSEL_CON(0));
+	writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RV1126B_VCPCLKSEL_CON(0));
+}
+
+CLK_OF_DECLARE(rv1126b_cru, "rockchip,rv1126b-cru", rv1126b_clk_init);
+
+struct clk_rv1126b_inits {
+	void (*inits)(struct device_node *np);
+};
+
+static const struct clk_rv1126b_inits clk_rv1126b_init = {
+	.inits = rv1126b_clk_init,
+};
+
+static const struct of_device_id clk_rv1126b_match_table[] = {
+	{
+		.compatible = "rockchip,rv1126b-cru",
+		.data = &clk_rv1126b_init,
+	},
+	{ }
+};
+
+static int clk_rv1126b_probe(struct platform_device *pdev)
+{
+	const struct clk_rv1126b_inits *init_data;
+	struct device *dev = &pdev->dev;
+
+	init_data = device_get_match_data(dev);
+	if (!init_data)
+		return -EINVAL;
+
+	if (init_data->inits)
+		init_data->inits(dev->of_node);
+
+	return 0;
+}
+
+static struct platform_driver clk_rv1126b_driver = {
+	.probe		= clk_rv1126b_probe,
+	.driver		= {
+		.name	= "clk-rv1126b",
+		.of_match_table = clk_rv1126b_match_table,
+		.suppress_bind_attrs = true,
+	},
+};
+builtin_platform_driver_probe(clk_rv1126b_driver, clk_rv1126b_probe);
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index 23653a942403..87f09320b942 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -99,6 +99,73 @@ struct clk;
 #define RV1126_EMMC_CON0		0x450
 #define RV1126_EMMC_CON1		0x454
 
+#define RV1126B_TOPCRU_BASE		0x0
+#define RV1126B_BUSCRU_BASE		0x10000
+#define RV1126B_PERICRU_BASE		0x20000
+#define RV1126B_CORECRU_BASE		0x30000
+#define RV1126B_PMUCRU_BASE		0x40000
+#define RV1126B_PMU1CRU_BASE		0x50000
+#define RV1126B_DDRCRU_BASE		0x60000
+#define RV1126B_SUBDDRCRU_BASE		0x68000
+#define RV1126B_VICRU_BASE		0x70000
+#define RV1126B_VEPUCRU_BASE		0x80000
+#define RV1126B_NPUCRU_BASE		0x90000
+#define RV1126B_VDOCRU_BASE		0xA0000
+#define RV1126B_VCPCRU_BASE		0xB0000
+
+#define RV1126B_PLL_CON(x)		((x) * 0x4 + RV1126B_TOPCRU_BASE)
+#define RV1126B_MODE_CON		(0x280 + RV1126B_TOPCRU_BASE)
+#define RV1126B_CLKSEL_CON(x)		((x) * 0x4 + 0x300 + RV1126B_TOPCRU_BASE)
+#define RV1126B_CLKGATE_CON(x)		((x) * 0x4 + 0x800 + RV1126B_TOPCRU_BASE)
+#define RV1126B_SOFTRST_CON(x)		((x) * 0x4 + 0xa00 + RV1126B_TOPCRU_BASE)
+#define RV1126B_GLB_SRST_FST		(0xc08 + RV1126B_TOPCRU_BASE)
+#define RV1126B_GLB_SRST_SND		(0xc0c + RV1126B_TOPCRU_BASE)
+#define RV1126B_CLK_CM_FRAC0_DIV_H	(0xcc0 + RV1126B_TOPCRU_BASE)
+#define RV1126B_CLK_CM_FRAC1_DIV_H	(0xcc4 + RV1126B_TOPCRU_BASE)
+#define RV1126B_CLK_CM_FRAC2_DIV_H	(0xcc8 + RV1126B_TOPCRU_BASE)
+#define RV1126B_CLK_UART_FRAC0_DIV_H	(0xccc + RV1126B_TOPCRU_BASE)
+#define RV1126B_CLK_UART_FRAC1_DIV_H	(0xcd0 + RV1126B_TOPCRU_BASE)
+#define RV1126B_CLK_AUDIO_FRAC0_DIV_H	(0xcd4 + RV1126B_TOPCRU_BASE)
+#define RV1126B_CLK_AUDIO_FRAC1_DIV_H	(0xcd8 + RV1126B_TOPCRU_BASE)
+#define RV1126B_BUSCLKSEL_CON(x)	((x) * 0x4 + 0x300 + RV1126B_BUSCRU_BASE)
+#define RV1126B_BUSCLKGATE_CON(x)	((x) * 0x4 + 0x800 + RV1126B_BUSCRU_BASE)
+#define RV1126B_BUSSOFTRST_CON(x)	((x) * 0x4 + 0xa00 + RV1126B_BUSCRU_BASE)
+#define RV1126B_PERIPLL_CON(x)		((x) * 0x4 + RV1126B_PERICRU_BASE)
+#define RV1126B_PERICLKSEL_CON(x)	((x) * 0x4 + 0x300 + RV1126B_PERICRU_BASE)
+#define RV1126B_PERICLKGATE_CON(x)	((x) * 0x4 + 0x800 + RV1126B_PERICRU_BASE)
+#define RV1126B_PERISOFTRST_CON(x)	((x) * 0x4 + 0xa00 + RV1126B_PERICRU_BASE)
+#define RV1126B_CORECLKSEL_CON(x)	((x) * 0x4 + 0x300 + RV1126B_CORECRU_BASE)
+#define RV1126B_CORECLKGATE_CON(x)	((x) * 0x4 + 0x800 + RV1126B_CORECRU_BASE)
+#define RV1126B_CORESOFTRST_CON(x)	((x) * 0x4 + 0xa00 + RV1126B_CORECRU_BASE)
+#define RV1126B_PMUCLKSEL_CON(x)	((x) * 0x4 + 0x300 + RV1126B_PMUCRU_BASE)
+#define RV1126B_PMUCLKGATE_CON(x)	((x) * 0x4 + 0x800 + RV1126B_PMUCRU_BASE)
+#define RV1126B_PMUSOFTRST_CON(x)	((x) * 0x4 + 0xa00 + RV1126B_PMUCRU_BASE)
+#define RV1126B_PMU1CLKSEL_CON(x)	((x) * 0x4 + 0x300 + RV1126B_PMU1CRU_BASE)
+#define RV1126B_PMU1CLKGATE_CON(x)	((x) * 0x4 + 0x800 + RV1126B_PMU1CRU_BASE)
+#define RV1126B_PMU1SOFTRST_CON(x)	((x) * 0x4 + 0xa00 + RV1126B_PMU1CRU_BASE)
+#define RV1126B_DDRCLKSEL_CON(x)	((x) * 0x4 + 0x300 + RV1126B_DDRCRU_BASE)
+#define RV1126B_DDRCLKGATE_CON(x)	((x) * 0x4 + 0x800 + RV1126B_DDRCRU_BASE)
+#define RV1126B_DDRSOFTRST_CON(x)	((x) * 0x4 + 0xa00 + RV1126B_DDRCRU_BASE)
+#define RV1126B_SUBDDRPLL_CON(x)	((x) * 0x4 + RV1126B_SUBDDRCRU_BASE)
+#define RV1126B_SUBDDRCLKSEL_CON(x)	((x) * 0x4 + 0x300 + RV1126B_SUBDDRCRU_BASE)
+#define RV1126B_SUBDDRCLKGATE_CON(x)	((x) * 0x4 + 0x800 + RV1126B_SUBDDRCRU_BASE)
+#define RV1126B_SUBDDRSOFTRST_CON(x)	((x) * 0x4 + 0xa00 + RV1126B_SUBDDRCRU_BASE)
+#define RV1126B_VICLKSEL_CON(x)		((x) * 0x4 + 0x300 + RV1126B_VICRU_BASE)
+#define RV1126B_VICLKGATE_CON(x)	((x) * 0x4 + 0x800 + RV1126B_VICRU_BASE)
+#define RV1126B_VISOFTRST_CON(x)	((x) * 0x4 + 0xa00 + RV1126B_VICRU_BASE)
+#define RV1126B_VEPUCLKSEL_CON(x)	((x) * 0x4 + 0x300 + RV1126B_VEPUCRU_BASE)
+#define RV1126B_VEPUCLKGATE_CON(x)	((x) * 0x4 + 0x800 + RV1126B_VEPUCRU_BASE)
+#define RV1126B_VEPUSOFTRST_CON(x)	((x) * 0x4 + 0xa00 + RV1126B_VEPUCRU_BASE)
+#define RV1126B_NPUCLKSEL_CON(x)	((x) * 0x4 + 0x300 + RV1126B_NPUCRU_BASE)
+#define RV1126B_NPUCLKGATE_CON(x)	((x) * 0x4 + 0x800 + RV1126B_NPUCRU_BASE)
+#define RV1126B_NPUSOFTRST_CON(x)	((x) * 0x4 + 0xa00 + RV1126B_NPUCRU_BASE)
+#define RV1126B_VDOCLKSEL_CON(x)	((x) * 0x4 + 0x300 + RV1126B_VDOCRU_BASE)
+#define RV1126B_VDOCLKGATE_CON(x)	((x) * 0x4 + 0x800 + RV1126B_VDOCRU_BASE)
+#define RV1126B_VDOSOFTRST_CON(x)	((x) * 0x4 + 0xa00 + RV1126B_VDOCRU_BASE)
+#define RV1126B_VCPCLKSEL_CON(x)	((x) * 0x4 + 0x300 + RV1126B_VCPCRU_BASE)
+#define RV1126B_VCPCLKGATE_CON(x)	((x) * 0x4 + 0x800 + RV1126B_VCPCRU_BASE)
+#define RV1126B_VCPSOFTRST_CON(x)	((x) * 0x4 + 0xa00 + RV1126B_VCPCRU_BASE)
+
 #define RK2928_PLL_CON(x)		((x) * 0x4)
 #define RK2928_MODE_CON		0x40
 #define RK2928_CLKSEL_CON(x)	((x) * 0x4 + 0x44)
@@ -1261,6 +1328,7 @@ static inline void rockchip_register_softrst(struct device_node *np,
 	return rockchip_register_softrst_lut(np, NULL, num_regs, base, flags);
 }
 
+void rv1126b_rst_init(struct device_node *np, void __iomem *reg_base);
 void rk3528_rst_init(struct device_node *np, void __iomem *reg_base);
 void rk3562_rst_init(struct device_node *np, void __iomem *reg_base);
 void rk3576_rst_init(struct device_node *np, void __iomem *reg_base);
diff --git a/drivers/clk/rockchip/rst-rv1126b.c b/drivers/clk/rockchip/rst-rv1126b.c
new file mode 100644
index 000000000000..251b1875bd0b
--- /dev/null
+++ b/drivers/clk/rockchip/rst-rv1126b.c
@@ -0,0 +1,444 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2025 Rockchip Electronics Co., Ltd.
+ * Author: Elaine Zhang <zhangqing at rock-chips.com>
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <dt-bindings/reset/rockchip,rv1126b-cru.h>
+#include "clk.h"
+
+/* 0x20000000 + 0x0A00 */
+#define TOPCRU_RESET_OFFSET(id, reg, bit) [id] = (0x0 * 4 + reg * 16 + bit)
+/* 0x20010000 + 0x0A00 */
+#define BUSCRU_RESET_OFFSET(id, reg, bit) [id] = (0x10000 * 4 + reg * 16 + bit)
+/* 0x20020000 + 0x0A00 */
+#define PERICRU_RESET_OFFSET(id, reg, bit) [id] = (0x20000 * 4 + reg * 16 + bit)
+/* 0x20030000 + 0x0A00 */
+#define CORECRU_RESET_OFFSET(id, reg, bit) [id] = (0x30000 * 4 + reg * 16 + bit)
+/* 0x20040000 + 0x0A00 */
+#define PMUCRU_RESET_OFFSET(id, reg, bit) [id] = (0x40000 * 4 + reg * 16 + bit)
+/* 0x20050000 + 0x0A00 */
+#define PMU1CRU_RESET_OFFSET(id, reg, bit) [id] = (0x50000 * 4 + reg * 16 + bit)
+/* 0x20060000 + 0x0A00 */
+#define DDRCRU_RESET_OFFSET(id, reg, bit) [id] = (0x60000 * 4 + reg * 16 + bit)
+/* 0x20068000 + 0x0A00 */
+#define SUBDDRCRU_RESET_OFFSET(id, reg, bit) [id] = (0x68000 * 4 + reg * 16 + bit)
+/* 0x20070000 + 0x0A00 */
+#define VICRU_RESET_OFFSET(id, reg, bit) [id] = (0x70000 * 4 + reg * 16 + bit)
+/* 0x20080000 + 0x0A00 */
+#define VEPUCRU_RESET_OFFSET(id, reg, bit) [id] = (0x80000 * 4 + reg * 16 + bit)
+/* 0x20090000 + 0x0A00 */
+#define NPUCRU_RESET_OFFSET(id, reg, bit) [id] = (0x90000 * 4 + reg * 16 + bit)
+/* 0x200A0000 + 0x0A00 */
+#define VDOCRU_RESET_OFFSET(id, reg, bit) [id] = (0xA0000 * 4 + reg * 16 + bit)
+/* 0x200B0000 + 0x0A00 */
+#define VCPCRU_RESET_OFFSET(id, reg, bit) [id] = (0xB0000 * 4 + reg * 16 + bit)
+
+/* =================mapping table for reset ID to register offset================== */
+static const int rv1126b_register_offset[] = {
+	/* TOPCRU-->SOFTRST_CON00 */
+
+	/* TOPCRU-->SOFTRST_CON15 */
+	TOPCRU_RESET_OFFSET(SRST_PRESETN_CRU, 15, 1),
+	TOPCRU_RESET_OFFSET(SRST_PRESETN_CRU_BIU, 15, 2),
+
+	/* BUSCRU-->SOFTRST_CON00 */
+	BUSCRU_RESET_OFFSET(SRST_ARESETN_TOP_BIU, 0, 0),
+	BUSCRU_RESET_OFFSET(SRST_ARESETN_RKCE_BIU, 0, 1),
+	BUSCRU_RESET_OFFSET(SRST_ARESETN_BUS_BIU, 0, 2),
+	BUSCRU_RESET_OFFSET(SRST_HRESETN_BUS_BIU, 0, 3),
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_BUS_BIU, 0, 4),
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_CRU_BUS, 0, 5),
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_SYS_GRF, 0, 6),
+	BUSCRU_RESET_OFFSET(SRST_HRESETN_BOOTROM, 0, 7),
+	BUSCRU_RESET_OFFSET(SRST_ARESETN_GIC400, 0, 8),
+	BUSCRU_RESET_OFFSET(SRST_ARESETN_SPINLOCK, 0, 9),
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_WDT_NS, 0, 10),
+	BUSCRU_RESET_OFFSET(SRST_TRESETN_WDT_NS, 0, 11),
+
+	/* BUSCRU-->SOFTRST_CON01 */
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_WDT_HPMCU, 1, 0),
+	BUSCRU_RESET_OFFSET(SRST_TRESETN_WDT_HPMCU, 1, 1),
+	BUSCRU_RESET_OFFSET(SRST_HRESETN_CACHE, 1, 2),
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_HPMCU_MAILBOX, 1, 3),
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_HPMCU_INTMUX, 1, 4),
+	BUSCRU_RESET_OFFSET(SRST_RESETN_HPMCU_FULL_CLUSTER, 1, 5),
+	BUSCRU_RESET_OFFSET(SRST_RESETN_HPMCU_PWUP, 1, 6),
+	BUSCRU_RESET_OFFSET(SRST_RESETN_HPMCU_ONLY_CORE, 1, 7),
+	BUSCRU_RESET_OFFSET(SRST_TRESETN_HPMCU_JTAG, 1, 8),
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_RKDMA, 1, 11),
+	BUSCRU_RESET_OFFSET(SRST_ARESETN_RKDMA, 1, 12),
+
+	/* BUSCRU-->SOFTRST_CON02 */
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_DCF, 2, 0),
+	BUSCRU_RESET_OFFSET(SRST_ARESETN_DCF, 2, 1),
+	BUSCRU_RESET_OFFSET(SRST_HRESETN_RGA, 2, 2),
+	BUSCRU_RESET_OFFSET(SRST_ARESETN_RGA, 2, 3),
+	BUSCRU_RESET_OFFSET(SRST_RESETN_CORE_RGA, 2, 4),
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_TIMER, 2, 5),
+	BUSCRU_RESET_OFFSET(SRST_RESETN_TIMER0, 2, 6),
+	BUSCRU_RESET_OFFSET(SRST_RESETN_TIMER1, 2, 7),
+	BUSCRU_RESET_OFFSET(SRST_RESETN_TIMER2, 2, 8),
+	BUSCRU_RESET_OFFSET(SRST_RESETN_TIMER3, 2, 9),
+	BUSCRU_RESET_OFFSET(SRST_RESETN_TIMER4, 2, 10),
+	BUSCRU_RESET_OFFSET(SRST_RESETN_TIMER5, 2, 11),
+	BUSCRU_RESET_OFFSET(SRST_ARESETN_RKCE, 2, 12),
+	BUSCRU_RESET_OFFSET(SRST_RESETN_PKA_RKCE, 2, 13),
+	BUSCRU_RESET_OFFSET(SRST_HRESETN_RKRNG_S, 2, 14),
+	BUSCRU_RESET_OFFSET(SRST_HRESETN_RKRNG_NS, 2, 15),
+
+	/* BUSCRU-->SOFTRST_CON03 */
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_I2C0, 3, 0),
+	BUSCRU_RESET_OFFSET(SRST_RESETN_I2C0, 3, 1),
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_I2C1, 3, 2),
+	BUSCRU_RESET_OFFSET(SRST_RESETN_I2C1, 3, 3),
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_I2C3, 3, 4),
+	BUSCRU_RESET_OFFSET(SRST_RESETN_I2C3, 3, 5),
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_I2C4, 3, 6),
+	BUSCRU_RESET_OFFSET(SRST_RESETN_I2C4, 3, 7),
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_I2C5, 3, 8),
+	BUSCRU_RESET_OFFSET(SRST_RESETN_I2C5, 3, 9),
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_SPI0, 3, 10),
+	BUSCRU_RESET_OFFSET(SRST_RESETN_SPI0, 3, 11),
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_SPI1, 3, 12),
+	BUSCRU_RESET_OFFSET(SRST_RESETN_SPI1, 3, 13),
+
+	/* BUSCRU-->SOFTRST_CON04 */
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_PWM0, 4, 0),
+	BUSCRU_RESET_OFFSET(SRST_RESETN_PWM0, 4, 1),
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_PWM2, 4, 4),
+	BUSCRU_RESET_OFFSET(SRST_RESETN_PWM2, 4, 5),
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_PWM3, 4, 8),
+	BUSCRU_RESET_OFFSET(SRST_RESETN_PWM3, 4, 9),
+
+	/* BUSCRU-->SOFTRST_CON05 */
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_UART1, 5, 0),
+	BUSCRU_RESET_OFFSET(SRST_SRESETN_UART1, 5, 1),
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_UART2, 5, 2),
+	BUSCRU_RESET_OFFSET(SRST_SRESETN_UART2, 5, 3),
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_UART3, 5, 4),
+	BUSCRU_RESET_OFFSET(SRST_SRESETN_UART3, 5, 5),
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_UART4, 5, 6),
+	BUSCRU_RESET_OFFSET(SRST_SRESETN_UART4, 5, 7),
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_UART5, 5, 8),
+	BUSCRU_RESET_OFFSET(SRST_SRESETN_UART5, 5, 9),
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_UART6, 5, 10),
+	BUSCRU_RESET_OFFSET(SRST_SRESETN_UART6, 5, 11),
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_UART7, 5, 12),
+	BUSCRU_RESET_OFFSET(SRST_SRESETN_UART7, 5, 13),
+
+	/* BUSCRU-->SOFTRST_CON06 */
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_TSADC, 6, 0),
+	BUSCRU_RESET_OFFSET(SRST_RESETN_TSADC, 6, 1),
+	BUSCRU_RESET_OFFSET(SRST_HRESETN_SAI0, 6, 2),
+	BUSCRU_RESET_OFFSET(SRST_MRESETN_SAI0, 6, 3),
+	BUSCRU_RESET_OFFSET(SRST_HRESETN_SAI1, 6, 4),
+	BUSCRU_RESET_OFFSET(SRST_MRESETN_SAI1, 6, 5),
+	BUSCRU_RESET_OFFSET(SRST_HRESETN_SAI2, 6, 6),
+	BUSCRU_RESET_OFFSET(SRST_MRESETN_SAI2, 6, 7),
+	BUSCRU_RESET_OFFSET(SRST_HRESETN_RKDSM, 6, 8),
+	BUSCRU_RESET_OFFSET(SRST_MRESETN_RKDSM, 6, 9),
+	BUSCRU_RESET_OFFSET(SRST_HRESETN_PDM, 6, 10),
+	BUSCRU_RESET_OFFSET(SRST_MRESETN_PDM, 6, 11),
+	BUSCRU_RESET_OFFSET(SRST_RESETN_PDM, 6, 12),
+
+	/* BUSCRU-->SOFTRST_CON07 */
+	BUSCRU_RESET_OFFSET(SRST_HRESETN_ASRC0, 7, 0),
+	BUSCRU_RESET_OFFSET(SRST_RESETN_ASRC0, 7, 1),
+	BUSCRU_RESET_OFFSET(SRST_HRESETN_ASRC1, 7, 2),
+	BUSCRU_RESET_OFFSET(SRST_RESETN_ASRC1, 7, 3),
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_AUDIO_ADC_BUS, 7, 4),
+	BUSCRU_RESET_OFFSET(SRST_MRESETN_AUDIO_ADC_BUS, 7, 5),
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_RKCE, 7, 6),
+	BUSCRU_RESET_OFFSET(SRST_HRESETN_NS_RKCE, 7, 7),
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_OTPC_NS, 7, 8),
+	BUSCRU_RESET_OFFSET(SRST_RESETN_SBPI_OTPC_NS, 7, 9),
+	BUSCRU_RESET_OFFSET(SRST_RESETN_USER_OTPC_NS, 7, 10),
+	BUSCRU_RESET_OFFSET(SRST_RESETN_OTPC_ARB, 7, 11),
+	BUSCRU_RESET_OFFSET(SRST_PRESETN_OTP_MASK, 7, 12),
+
+	/* PERICRU-->SOFTRST_CON00 */
+	PERICRU_RESET_OFFSET(SRST_ARESETN_PERI_BIU, 0, 0),
+	PERICRU_RESET_OFFSET(SRST_PRESETN_PERI_BIU, 0, 1),
+	PERICRU_RESET_OFFSET(SRST_PRESETN_RTC_BIU, 0, 2),
+	PERICRU_RESET_OFFSET(SRST_PRESETN_CRU_PERI, 0, 3),
+	PERICRU_RESET_OFFSET(SRST_PRESETN_PERI_GRF, 0, 4),
+	PERICRU_RESET_OFFSET(SRST_PRESETN_GPIO1, 0, 5),
+	PERICRU_RESET_OFFSET(SRST_DBRESETN_GPIO1, 0, 6),
+	PERICRU_RESET_OFFSET(SRST_PRESETN_IOC_VCCIO1, 0, 7),
+	PERICRU_RESET_OFFSET(SRST_ARESETN_USB3OTG, 0, 8),
+	PERICRU_RESET_OFFSET(SRST_HRESETN_USB2HOST, 0, 11),
+	PERICRU_RESET_OFFSET(SRST_HRESETN_ARB_USB2HOST, 0, 12),
+	PERICRU_RESET_OFFSET(SRST_PRESETN_RTC_TEST, 0, 13),
+
+	/* PERICRU-->SOFTRST_CON01 */
+	PERICRU_RESET_OFFSET(SRST_HRESETN_EMMC, 1, 0),
+	PERICRU_RESET_OFFSET(SRST_HRESETN_FSPI0, 1, 1),
+	PERICRU_RESET_OFFSET(SRST_HRESETN_XIP_FSPI0, 1, 2),
+	PERICRU_RESET_OFFSET(SRST_SRESETN_2X_FSPI0, 1, 3),
+	PERICRU_RESET_OFFSET(SRST_RESETN_UTMI_USB2HOST, 1, 5),
+	PERICRU_RESET_OFFSET(SRST_RESETN_REF_PIPEPHY, 1, 7),
+	PERICRU_RESET_OFFSET(SRST_PRESETN_PIPEPHY, 1, 8),
+	PERICRU_RESET_OFFSET(SRST_PRESETN_PIPEPHY_GRF, 1, 9),
+	PERICRU_RESET_OFFSET(SRST_PRESETN_USB2PHY, 1, 10),
+	PERICRU_RESET_OFFSET(SRST_RESETN_POR_USB2PHY, 1, 11),
+	PERICRU_RESET_OFFSET(SRST_RESETN_OTG_USB2PHY, 1, 12),
+	PERICRU_RESET_OFFSET(SRST_RESETN_HOST_USB2PHY, 1, 13),
+
+	/* CORECRU-->SOFTRST_CON00 */
+	CORECRU_RESET_OFFSET(SRST_RESETN_REF_PVTPLL_CORE, 0, 0),
+	CORECRU_RESET_OFFSET(SRST_NCOREPORESET0, 0, 1),
+	CORECRU_RESET_OFFSET(SRST_NCORESET0, 0, 2),
+	CORECRU_RESET_OFFSET(SRST_NCOREPORESET1, 0, 3),
+	CORECRU_RESET_OFFSET(SRST_NCORESET1, 0, 4),
+	CORECRU_RESET_OFFSET(SRST_NCOREPORESET2, 0, 5),
+	CORECRU_RESET_OFFSET(SRST_NCORESET2, 0, 6),
+	CORECRU_RESET_OFFSET(SRST_NCOREPORESET3, 0, 7),
+	CORECRU_RESET_OFFSET(SRST_NCORESET3, 0, 8),
+	CORECRU_RESET_OFFSET(SRST_NDBGRESET, 0, 9),
+	CORECRU_RESET_OFFSET(SRST_NL2RESET, 0, 10),
+
+	/* CORECRU-->SOFTRST_CON01 */
+	CORECRU_RESET_OFFSET(SRST_ARESETN_CORE_BIU, 1, 0),
+	CORECRU_RESET_OFFSET(SRST_PRESETN_CORE_BIU, 1, 1),
+	CORECRU_RESET_OFFSET(SRST_HRESETN_CORE_BIU, 1, 2),
+	CORECRU_RESET_OFFSET(SRST_PRESETN_DBG, 1, 3),
+	CORECRU_RESET_OFFSET(SRST_POTRESETN_DBG, 1, 4),
+	CORECRU_RESET_OFFSET(SRST_NTRESETN_DBG, 1, 5),
+	CORECRU_RESET_OFFSET(SRST_PRESETN_CORE_PVTPLL, 1, 6),
+	CORECRU_RESET_OFFSET(SRST_PRESETN_CRU_CORE, 1, 7),
+	CORECRU_RESET_OFFSET(SRST_PRESETN_CORE_GRF, 1, 8),
+	CORECRU_RESET_OFFSET(SRST_PRESETN_DFT2APB, 1, 10),
+
+	/* PMUCRU-->SOFTRST_CON00 */
+	PMUCRU_RESET_OFFSET(SRST_HRESETN_PMU_BIU, 0, 0),
+	PMUCRU_RESET_OFFSET(SRST_PRESETN_PMU_GPIO0, 0, 7),
+	PMUCRU_RESET_OFFSET(SRST_DBRESETN_PMU_GPIO0, 0, 8),
+	PMUCRU_RESET_OFFSET(SRST_PRESETN_PMU_HP_TIMER, 0, 10),
+	PMUCRU_RESET_OFFSET(SRST_RESETN_PMU_HP_TIMER, 0, 11),
+	PMUCRU_RESET_OFFSET(SRST_RESETN_PMU_32K_HP_TIMER, 0, 12),
+
+	/* PMUCRU-->SOFTRST_CON01 */
+	PMUCRU_RESET_OFFSET(SRST_PRESETN_PWM1, 1, 0),
+	PMUCRU_RESET_OFFSET(SRST_RESETN_PWM1, 1, 1),
+	PMUCRU_RESET_OFFSET(SRST_PRESETN_I2C2, 1, 2),
+	PMUCRU_RESET_OFFSET(SRST_RESETN_I2C2, 1, 3),
+	PMUCRU_RESET_OFFSET(SRST_PRESETN_UART0, 1, 4),
+	PMUCRU_RESET_OFFSET(SRST_SRESETN_UART0, 1, 5),
+
+	/* PMUCRU-->SOFTRST_CON02 */
+	PMUCRU_RESET_OFFSET(SRST_PRESETN_RCOSC_CTRL, 2, 0),
+	PMUCRU_RESET_OFFSET(SRST_RESETN_REF_RCOSC_CTRL, 2, 2),
+	PMUCRU_RESET_OFFSET(SRST_PRESETN_IOC_PMUIO0, 2, 3),
+	PMUCRU_RESET_OFFSET(SRST_PRESETN_CRU_PMU, 2, 4),
+	PMUCRU_RESET_OFFSET(SRST_PRESETN_PMU_GRF, 2, 5),
+	PMUCRU_RESET_OFFSET(SRST_RESETN_PREROLL, 2, 7),
+	PMUCRU_RESET_OFFSET(SRST_RESETN_PREROLL_32K, 2, 8),
+	PMUCRU_RESET_OFFSET(SRST_HRESETN_PMU_SRAM, 2, 9),
+
+	/* PMUCRU-->SOFTRST_CON03 */
+	PMUCRU_RESET_OFFSET(SRST_PRESETN_WDT_LPMCU, 3, 0),
+	PMUCRU_RESET_OFFSET(SRST_TRESETN_WDT_LPMCU, 3, 1),
+	PMUCRU_RESET_OFFSET(SRST_RESETN_LPMCU_FULL_CLUSTER, 3, 2),
+	PMUCRU_RESET_OFFSET(SRST_RESETN_LPMCU_PWUP, 3, 3),
+	PMUCRU_RESET_OFFSET(SRST_RESETN_LPMCU_ONLY_CORE, 3, 4),
+	PMUCRU_RESET_OFFSET(SRST_TRESETN_LPMCU_JTAG, 3, 5),
+	PMUCRU_RESET_OFFSET(SRST_PRESETN_LPMCU_MAILBOX, 3, 6),
+
+	/* PMU1CRU-->SOFTRST_CON00 */
+	PMU1CRU_RESET_OFFSET(SRST_PRESETN_SPI2AHB, 0, 0),
+	PMU1CRU_RESET_OFFSET(SRST_HRESETN_SPI2AHB, 0, 1),
+	PMU1CRU_RESET_OFFSET(SRST_HRESETN_FSPI1, 0, 2),
+	PMU1CRU_RESET_OFFSET(SRST_HRESETN_XIP_FSPI1, 0, 3),
+	PMU1CRU_RESET_OFFSET(SRST_SRESETN_1X_FSPI1, 0, 4),
+	PMU1CRU_RESET_OFFSET(SRST_PRESETN_IOC_PMUIO1, 0, 5),
+	PMU1CRU_RESET_OFFSET(SRST_PRESETN_CRU_PMU1, 0, 6),
+	PMU1CRU_RESET_OFFSET(SRST_PRESETN_AUDIO_ADC_PMU, 0, 7),
+	PMU1CRU_RESET_OFFSET(SRST_MRESETN_AUDIO_ADC_PMU, 0, 8),
+	PMU1CRU_RESET_OFFSET(SRST_HRESETN_PMU1_BIU, 0, 9),
+
+	/* PMU1CRU-->SOFTRST_CON01 */
+	PMU1CRU_RESET_OFFSET(SRST_PRESETN_LPDMA, 1, 0),
+	PMU1CRU_RESET_OFFSET(SRST_ARESETN_LPDMA, 1, 1),
+	PMU1CRU_RESET_OFFSET(SRST_HRESETN_LPSAI, 1, 2),
+	PMU1CRU_RESET_OFFSET(SRST_MRESETN_LPSAI, 1, 3),
+	PMU1CRU_RESET_OFFSET(SRST_PRESETN_AOA_TDD, 1, 4),
+	PMU1CRU_RESET_OFFSET(SRST_PRESETN_AOA_FE, 1, 5),
+	PMU1CRU_RESET_OFFSET(SRST_PRESETN_AOA_AAD, 1, 6),
+	PMU1CRU_RESET_OFFSET(SRST_PRESETN_AOA_APB, 1, 7),
+	PMU1CRU_RESET_OFFSET(SRST_PRESETN_AOA_SRAM, 1, 8),
+
+	/* DDRCRU-->SOFTRST_CON00 */
+	DDRCRU_RESET_OFFSET(SRST_PRESETN_DDR_BIU, 0, 1),
+	DDRCRU_RESET_OFFSET(SRST_PRESETN_DDRC, 0, 2),
+	DDRCRU_RESET_OFFSET(SRST_PRESETN_DDRMON, 0, 3),
+	DDRCRU_RESET_OFFSET(SRST_RESETN_TIMER_DDRMON, 0, 4),
+	DDRCRU_RESET_OFFSET(SRST_PRESETN_DFICTRL, 0, 5),
+	DDRCRU_RESET_OFFSET(SRST_PRESETN_DDR_GRF, 0, 6),
+	DDRCRU_RESET_OFFSET(SRST_PRESETN_CRU_DDR, 0, 7),
+	DDRCRU_RESET_OFFSET(SRST_PRESETN_DDRPHY, 0, 8),
+	DDRCRU_RESET_OFFSET(SRST_PRESETN_DMA2DDR, 0, 9),
+
+	/* SUBDDRCRU-->SOFTRST_CON00 */
+	SUBDDRCRU_RESET_OFFSET(SRST_ARESETN_SYSMEM_BIU, 0, 0),
+	SUBDDRCRU_RESET_OFFSET(SRST_ARESETN_SYSMEM, 0, 1),
+	SUBDDRCRU_RESET_OFFSET(SRST_ARESETN_DDR_BIU, 0, 2),
+	SUBDDRCRU_RESET_OFFSET(SRST_ARESETN_DDRSCH0_CPU, 0, 3),
+	SUBDDRCRU_RESET_OFFSET(SRST_ARESETN_DDRSCH1_NPU, 0, 4),
+	SUBDDRCRU_RESET_OFFSET(SRST_ARESETN_DDRSCH2_POE, 0, 5),
+	SUBDDRCRU_RESET_OFFSET(SRST_ARESETN_DDRSCH3_VI, 0, 6),
+	SUBDDRCRU_RESET_OFFSET(SRST_RESETN_CORE_DDRC, 0, 7),
+	SUBDDRCRU_RESET_OFFSET(SRST_RESETN_DDRMON, 0, 8),
+	SUBDDRCRU_RESET_OFFSET(SRST_RESETN_DFICTRL, 0, 9),
+	SUBDDRCRU_RESET_OFFSET(SRST_RESETN_RS, 0, 11),
+	SUBDDRCRU_RESET_OFFSET(SRST_ARESETN_DMA2DDR, 0, 12),
+	SUBDDRCRU_RESET_OFFSET(SRST_RESETN_DDRPHY, 0, 13),
+
+	/* VICRU-->SOFTRST_CON00 */
+	VICRU_RESET_OFFSET(SRST_RESETN_REF_PVTPLL_ISP, 0, 0),
+	VICRU_RESET_OFFSET(SRST_ARESETN_GMAC_BIU, 0, 1),
+	VICRU_RESET_OFFSET(SRST_ARESETN_VI_BIU, 0, 2),
+	VICRU_RESET_OFFSET(SRST_HRESETN_VI_BIU, 0, 3),
+	VICRU_RESET_OFFSET(SRST_PRESETN_VI_BIU, 0, 4),
+	VICRU_RESET_OFFSET(SRST_PRESETN_CRU_VI, 0, 5),
+	VICRU_RESET_OFFSET(SRST_PRESETN_VI_GRF, 0, 6),
+	VICRU_RESET_OFFSET(SRST_PRESETN_VI_PVTPLL, 0, 7),
+	VICRU_RESET_OFFSET(SRST_PRESETN_DSMC, 0, 8),
+	VICRU_RESET_OFFSET(SRST_ARESETN_DSMC, 0, 9),
+	VICRU_RESET_OFFSET(SRST_HRESETN_CAN0, 0, 10),
+	VICRU_RESET_OFFSET(SRST_RESETN_CAN0, 0, 11),
+	VICRU_RESET_OFFSET(SRST_HRESETN_CAN1, 0, 12),
+	VICRU_RESET_OFFSET(SRST_RESETN_CAN1, 0, 13),
+
+	/* VICRU-->SOFTRST_CON01 */
+	VICRU_RESET_OFFSET(SRST_PRESETN_GPIO2, 1, 0),
+	VICRU_RESET_OFFSET(SRST_DBRESETN_GPIO2, 1, 1),
+	VICRU_RESET_OFFSET(SRST_PRESETN_GPIO4, 1, 2),
+	VICRU_RESET_OFFSET(SRST_DBRESETN_GPIO4, 1, 3),
+	VICRU_RESET_OFFSET(SRST_PRESETN_GPIO5, 1, 4),
+	VICRU_RESET_OFFSET(SRST_DBRESETN_GPIO5, 1, 5),
+	VICRU_RESET_OFFSET(SRST_PRESETN_GPIO6, 1, 6),
+	VICRU_RESET_OFFSET(SRST_DBRESETN_GPIO6, 1, 7),
+	VICRU_RESET_OFFSET(SRST_PRESETN_GPIO7, 1, 8),
+	VICRU_RESET_OFFSET(SRST_DBRESETN_GPIO7, 1, 9),
+	VICRU_RESET_OFFSET(SRST_PRESETN_IOC_VCCIO2, 1, 10),
+	VICRU_RESET_OFFSET(SRST_PRESETN_IOC_VCCIO4, 1, 11),
+	VICRU_RESET_OFFSET(SRST_PRESETN_IOC_VCCIO5, 1, 12),
+	VICRU_RESET_OFFSET(SRST_PRESETN_IOC_VCCIO6, 1, 13),
+	VICRU_RESET_OFFSET(SRST_PRESETN_IOC_VCCIO7, 1, 14),
+
+	/* VICRU-->SOFTRST_CON02 */
+	VICRU_RESET_OFFSET(SRST_RESETN_CORE_ISP, 2, 0),
+	VICRU_RESET_OFFSET(SRST_HRESETN_VICAP, 2, 1),
+	VICRU_RESET_OFFSET(SRST_ARESETN_VICAP, 2, 2),
+	VICRU_RESET_OFFSET(SRST_DRESETN_VICAP, 2, 3),
+	VICRU_RESET_OFFSET(SRST_ISP0RESETN_VICAP, 2, 4),
+	VICRU_RESET_OFFSET(SRST_RESETN_CORE_VPSS, 2, 5),
+	VICRU_RESET_OFFSET(SRST_RESETN_CORE_VPSL, 2, 6),
+	VICRU_RESET_OFFSET(SRST_PRESETN_CSI2HOST0, 2, 7),
+	VICRU_RESET_OFFSET(SRST_PRESETN_CSI2HOST1, 2, 8),
+	VICRU_RESET_OFFSET(SRST_PRESETN_CSI2HOST2, 2, 9),
+	VICRU_RESET_OFFSET(SRST_PRESETN_CSI2HOST3, 2, 10),
+	VICRU_RESET_OFFSET(SRST_HRESETN_SDMMC0, 2, 11),
+	VICRU_RESET_OFFSET(SRST_ARESETN_GMAC, 2, 12),
+	VICRU_RESET_OFFSET(SRST_PRESETN_CSIPHY0, 2, 13),
+	VICRU_RESET_OFFSET(SRST_PRESETN_CSIPHY1, 2, 14),
+
+	/* VICRU-->SOFTRST_CON03 */
+	VICRU_RESET_OFFSET(SRST_PRESETN_MACPHY, 3, 0),
+	VICRU_RESET_OFFSET(SRST_RESETN_MACPHY, 3, 1),
+	VICRU_RESET_OFFSET(SRST_PRESETN_SARADC1, 3, 2),
+	VICRU_RESET_OFFSET(SRST_RESETN_SARADC1, 3, 3),
+	VICRU_RESET_OFFSET(SRST_PRESETN_SARADC2, 3, 5),
+	VICRU_RESET_OFFSET(SRST_RESETN_SARADC2, 3, 6),
+
+	/* VEPUCRU-->SOFTRST_CON00 */
+	VEPUCRU_RESET_OFFSET(SRST_RESETN_REF_PVTPLL_VEPU, 0, 0),
+	VEPUCRU_RESET_OFFSET(SRST_ARESETN_VEPU_BIU, 0, 1),
+	VEPUCRU_RESET_OFFSET(SRST_HRESETN_VEPU_BIU, 0, 2),
+	VEPUCRU_RESET_OFFSET(SRST_PRESETN_VEPU_BIU, 0, 3),
+	VEPUCRU_RESET_OFFSET(SRST_PRESETN_CRU_VEPU, 0, 4),
+	VEPUCRU_RESET_OFFSET(SRST_PRESETN_VEPU_GRF, 0, 5),
+	VEPUCRU_RESET_OFFSET(SRST_PRESETN_GPIO3, 0, 7),
+	VEPUCRU_RESET_OFFSET(SRST_DBRESETN_GPIO3, 0, 8),
+	VEPUCRU_RESET_OFFSET(SRST_PRESETN_IOC_VCCIO3, 0, 9),
+	VEPUCRU_RESET_OFFSET(SRST_PRESETN_SARADC0, 0, 10),
+	VEPUCRU_RESET_OFFSET(SRST_RESETN_SARADC0, 0, 11),
+	VEPUCRU_RESET_OFFSET(SRST_HRESETN_SDMMC1, 0, 13),
+
+	/* VEPUCRU-->SOFTRST_CON01 */
+	VEPUCRU_RESET_OFFSET(SRST_PRESETN_VEPU_PVTPLL, 1, 0),
+	VEPUCRU_RESET_OFFSET(SRST_HRESETN_VEPU, 1, 1),
+	VEPUCRU_RESET_OFFSET(SRST_ARESETN_VEPU, 1, 2),
+	VEPUCRU_RESET_OFFSET(SRST_RESETN_CORE_VEPU, 1, 3),
+
+	/* NPUCRU-->SOFTRST_CON00 */
+	NPUCRU_RESET_OFFSET(SRST_RESETN_REF_PVTPLL_NPU, 0, 0),
+	NPUCRU_RESET_OFFSET(SRST_ARESETN_NPU_BIU, 0, 2),
+	NPUCRU_RESET_OFFSET(SRST_HRESETN_NPU_BIU, 0, 3),
+	NPUCRU_RESET_OFFSET(SRST_PRESETN_NPU_BIU, 0, 4),
+	NPUCRU_RESET_OFFSET(SRST_PRESETN_CRU_NPU, 0, 5),
+	NPUCRU_RESET_OFFSET(SRST_PRESETN_NPU_GRF, 0, 6),
+	NPUCRU_RESET_OFFSET(SRST_PRESETN_NPU_PVTPLL, 0, 8),
+	NPUCRU_RESET_OFFSET(SRST_HRESETN_RKNN, 0, 9),
+	NPUCRU_RESET_OFFSET(SRST_ARESETN_RKNN, 0, 10),
+
+	/* VDOCRU-->SOFTRST_CON00 */
+	VDOCRU_RESET_OFFSET(SRST_ARESETN_RKVDEC_BIU, 0, 0),
+	VDOCRU_RESET_OFFSET(SRST_ARESETN_VDO_BIU, 0, 1),
+	VDOCRU_RESET_OFFSET(SRST_HRESETN_VDO_BIU, 0, 3),
+	VDOCRU_RESET_OFFSET(SRST_PRESETN_VDO_BIU, 0, 4),
+	VDOCRU_RESET_OFFSET(SRST_PRESETN_CRU_VDO, 0, 5),
+	VDOCRU_RESET_OFFSET(SRST_PRESETN_VDO_GRF, 0, 6),
+	VDOCRU_RESET_OFFSET(SRST_ARESETN_RKVDEC, 0, 7),
+	VDOCRU_RESET_OFFSET(SRST_HRESETN_RKVDEC, 0, 8),
+	VDOCRU_RESET_OFFSET(SRST_RESETN_HEVC_CA_RKVDEC, 0, 9),
+	VDOCRU_RESET_OFFSET(SRST_ARESETN_VOP, 0, 10),
+	VDOCRU_RESET_OFFSET(SRST_HRESETN_VOP, 0, 11),
+	VDOCRU_RESET_OFFSET(SRST_DRESETN_VOP, 0, 12),
+	VDOCRU_RESET_OFFSET(SRST_ARESETN_OOC, 0, 13),
+	VDOCRU_RESET_OFFSET(SRST_HRESETN_OOC, 0, 14),
+	VDOCRU_RESET_OFFSET(SRST_DRESETN_OOC, 0, 15),
+
+	/* VDOCRU-->SOFTRST_CON01 */
+	VDOCRU_RESET_OFFSET(SRST_HRESETN_RKJPEG, 1, 3),
+	VDOCRU_RESET_OFFSET(SRST_ARESETN_RKJPEG, 1, 4),
+	VDOCRU_RESET_OFFSET(SRST_ARESETN_RKMMU_DECOM, 1, 5),
+	VDOCRU_RESET_OFFSET(SRST_HRESETN_RKMMU_DECOM, 1, 6),
+	VDOCRU_RESET_OFFSET(SRST_DRESETN_DECOM, 1, 8),
+	VDOCRU_RESET_OFFSET(SRST_ARESETN_DECOM, 1, 9),
+	VDOCRU_RESET_OFFSET(SRST_PRESETN_DECOM, 1, 10),
+	VDOCRU_RESET_OFFSET(SRST_PRESETN_MIPI_DSI, 1, 12),
+	VDOCRU_RESET_OFFSET(SRST_PRESETN_DSIPHY, 1, 13),
+
+	/* VCPCRU-->SOFTRST_CON00 */
+	VCPCRU_RESET_OFFSET(SRST_RESETN_REF_PVTPLL_VCP, 0, 0),
+	VCPCRU_RESET_OFFSET(SRST_ARESETN_VCP_BIU, 0, 1),
+	VCPCRU_RESET_OFFSET(SRST_HRESETN_VCP_BIU, 0, 2),
+	VCPCRU_RESET_OFFSET(SRST_PRESETN_VCP_BIU, 0, 3),
+	VCPCRU_RESET_OFFSET(SRST_PRESETN_CRU_VCP, 0, 4),
+	VCPCRU_RESET_OFFSET(SRST_PRESETN_VCP_GRF, 0, 5),
+	VCPCRU_RESET_OFFSET(SRST_PRESETN_VCP_PVTPLL, 0, 7),
+	VCPCRU_RESET_OFFSET(SRST_ARESETN_AISP_BIU, 0, 8),
+	VCPCRU_RESET_OFFSET(SRST_HRESETN_AISP_BIU, 0, 9),
+	VCPCRU_RESET_OFFSET(SRST_RESETN_CORE_AISP, 0, 13),
+
+	/* VCPCRU-->SOFTRST_CON01 */
+	VCPCRU_RESET_OFFSET(SRST_HRESETN_FEC, 1, 0),
+	VCPCRU_RESET_OFFSET(SRST_ARESETN_FEC, 1, 1),
+	VCPCRU_RESET_OFFSET(SRST_RESETN_CORE_FEC, 1, 2),
+	VCPCRU_RESET_OFFSET(SRST_HRESETN_AVSP, 1, 3),
+	VCPCRU_RESET_OFFSET(SRST_ARESETN_AVSP, 1, 4),
+};
+
+void rv1126b_rst_init(struct device_node *np, void __iomem *reg_base)
+{
+	rockchip_register_softrst_lut(np,
+				      rv1126b_register_offset,
+				      ARRAY_SIZE(rv1126b_register_offset),
+				      reg_base + RV1126B_SOFTRST_CON(0),
+				      ROCKCHIP_SOFTRST_HIWORD_MASK);
+}
+
-- 
2.34.1



From zhangqing at rock-chips.com  Mon Nov  3 19:06:32 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Tue,  4 Nov 2025 11:06:32 +0800
Subject: [PATCH v6 4/5] dt-bindings: clock: rockchip: Add RK3506 clock and reset unit
In-Reply-To: <20251104030633.2721038-1-zhangqing@rock-chips.com>
References: <20251104030633.2721038-1-zhangqing@rock-chips.com>
Message-ID: <20251104030633.2721038-5-zhangqing@rock-chips.com>

From: Finley Xiao <finley.xiao at rock-chips.com>

Add device tree bindings for clock and reset unit on RK3506 SoC.
Add clock and reset IDs for RK3506 SoC.

Signed-off-by: Finley Xiao <finley.xiao at rock-chips.com>
---
 .../bindings/clock/rockchip,rk3506-cru.yaml   |  51 ++++
 .../dt-bindings/clock/rockchip,rk3506-cru.h   | 285 ++++++++++++++++++
 .../dt-bindings/reset/rockchip,rk3506-cru.h   | 211 +++++++++++++
 3 files changed, 547 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
 create mode 100644 include/dt-bindings/clock/rockchip,rk3506-cru.h
 create mode 100644 include/dt-bindings/reset/rockchip,rk3506-cru.h

diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml b/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
new file mode 100644
index 000000000000..ecb5fa497747
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/rockchip,rk3506-cru.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip RK3506 Clock and Reset Unit (CRU)
+
+maintainers:
+  - Finley Xiao <finley.xiao at rock-chips.com>
+  - Heiko Stuebner <heiko at sntech.de>
+
+description: |
+  The RK3506 CRU generates the clock and also implements reset for SoC
+  peripherals.
+
+properties:
+  compatible:
+    const: rockchip,rk3506-cru
+
+  reg:
+    maxItems: 1
+
+  "#clock-cells":
+    const: 1
+
+  "#reset-cells":
+    const: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    const: xin24m
+
+required:
+  - compatible
+  - reg
+  - "#clock-cells"
+  - "#reset-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller at ff9a0000 {
+      compatible = "rockchip,rk3506-cru";
+      reg = <0xff9a0000 0x20000>;
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+    };
diff --git a/include/dt-bindings/clock/rockchip,rk3506-cru.h b/include/dt-bindings/clock/rockchip,rk3506-cru.h
new file mode 100644
index 000000000000..71d7dda23cc9
--- /dev/null
+++ b/include/dt-bindings/clock/rockchip,rk3506-cru.h
@@ -0,0 +1,285 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2023-2025 Rockchip Electronics Co., Ltd.
+ * Author: Finley Xiao <finley.xiao at rock-chips.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3506_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_RK3506_H
+
+/* cru plls */
+#define PLL_GPLL			0
+#define PLL_V0PLL			1
+#define PLL_V1PLL			2
+
+/* cru-clocks indices */
+#define ARMCLK				3
+#define CLK_DDR				4
+#define XIN24M_GATE			5
+#define CLK_GPLL_GATE			6
+#define CLK_V0PLL_GATE			7
+#define CLK_V1PLL_GATE			8
+#define CLK_GPLL_DIV			9
+#define CLK_GPLL_DIV_100M		10
+#define CLK_V0PLL_DIV			11
+#define CLK_V1PLL_DIV			12
+#define CLK_INT_VOICE_MATRIX0		13
+#define CLK_INT_VOICE_MATRIX1		14
+#define CLK_INT_VOICE_MATRIX2		15
+#define CLK_FRAC_UART_MATRIX0_MUX	16
+#define CLK_FRAC_UART_MATRIX1_MUX	17
+#define CLK_FRAC_VOICE_MATRIX0_MUX	18
+#define CLK_FRAC_VOICE_MATRIX1_MUX	19
+#define CLK_FRAC_COMMON_MATRIX0_MUX	20
+#define CLK_FRAC_COMMON_MATRIX1_MUX	21
+#define CLK_FRAC_COMMON_MATRIX2_MUX	22
+#define CLK_FRAC_UART_MATRIX0		23
+#define CLK_FRAC_UART_MATRIX1		24
+#define CLK_FRAC_VOICE_MATRIX0		25
+#define CLK_FRAC_VOICE_MATRIX1		26
+#define CLK_FRAC_COMMON_MATRIX0		27
+#define CLK_FRAC_COMMON_MATRIX1		28
+#define CLK_FRAC_COMMON_MATRIX2		29
+#define CLK_REF_USBPHY_TOP		30
+#define CLK_REF_DPHY_TOP		31
+#define ACLK_CORE_ROOT			32
+#define PCLK_CORE_ROOT			33
+#define PCLK_DBG			34
+#define PCLK_CORE_GRF			35
+#define PCLK_CORE_CRU			36
+#define CLK_CORE_EMA_DETECT		37
+#define CLK_REF_PVTPLL_CORE		38
+#define PCLK_GPIO1			39
+#define DBCLK_GPIO1			40
+#define ACLK_CORE_PERI_ROOT		41
+#define HCLK_CORE_PERI_ROOT		42
+#define PCLK_CORE_PERI_ROOT		43
+#define CLK_DSMC			44
+#define ACLK_DSMC			45
+#define PCLK_DSMC			46
+#define CLK_FLEXBUS_TX			47
+#define CLK_FLEXBUS_RX			48
+#define ACLK_FLEXBUS			49
+#define HCLK_FLEXBUS			50
+#define ACLK_DSMC_SLV			51
+#define HCLK_DSMC_SLV			52
+#define ACLK_BUS_ROOT			53
+#define HCLK_BUS_ROOT			54
+#define PCLK_BUS_ROOT			55
+#define ACLK_SYSRAM			56
+#define HCLK_SYSRAM			57
+#define ACLK_DMAC0			58
+#define ACLK_DMAC1			59
+#define HCLK_M0				60
+#define PCLK_BUS_GRF			61
+#define PCLK_TIMER			62
+#define CLK_TIMER0_CH0			63
+#define CLK_TIMER0_CH1			64
+#define CLK_TIMER0_CH2			65
+#define CLK_TIMER0_CH3			66
+#define CLK_TIMER0_CH4			67
+#define CLK_TIMER0_CH5			68
+#define PCLK_WDT0			69
+#define TCLK_WDT0			70
+#define PCLK_WDT1			71
+#define TCLK_WDT1			72
+#define PCLK_MAILBOX			73
+#define PCLK_INTMUX			74
+#define PCLK_SPINLOCK			75
+#define PCLK_DDRC			76
+#define HCLK_DDRPHY			77
+#define PCLK_DDRMON			78
+#define CLK_DDRMON_OSC			79
+#define PCLK_STDBY			80
+#define HCLK_USBOTG0			81
+#define HCLK_USBOTG0_PMU		82
+#define CLK_USBOTG0_ADP			83
+#define HCLK_USBOTG1			84
+#define HCLK_USBOTG1_PMU		85
+#define CLK_USBOTG1_ADP			86
+#define PCLK_USBPHY			87
+#define ACLK_DMA2DDR			88
+#define PCLK_DMA2DDR			89
+#define STCLK_M0			90
+#define CLK_DDRPHY			91
+#define CLK_DDRC_SRC			92
+#define ACLK_DDRC_0			93
+#define ACLK_DDRC_1			94
+#define CLK_DDRC			95
+#define CLK_DDRMON			96
+#define HCLK_LSPERI_ROOT		97
+#define PCLK_LSPERI_ROOT		98
+#define PCLK_UART0			99
+#define PCLK_UART1			100
+#define PCLK_UART2			101
+#define PCLK_UART3			102
+#define PCLK_UART4			103
+#define SCLK_UART0			104
+#define SCLK_UART1			105
+#define SCLK_UART2			106
+#define SCLK_UART3			107
+#define SCLK_UART4			108
+#define PCLK_I2C0			109
+#define CLK_I2C0			110
+#define PCLK_I2C1			111
+#define CLK_I2C1			112
+#define PCLK_I2C2			113
+#define CLK_I2C2			114
+#define PCLK_PWM1			115
+#define CLK_PWM1			116
+#define CLK_OSC_PWM1			117
+#define CLK_RC_PWM1			118
+#define CLK_FREQ_PWM1			119
+#define CLK_COUNTER_PWM1		120
+#define PCLK_SPI0			121
+#define CLK_SPI0			122
+#define PCLK_SPI1			123
+#define CLK_SPI1			124
+#define PCLK_GPIO2			125
+#define DBCLK_GPIO2			126
+#define PCLK_GPIO3			127
+#define DBCLK_GPIO3			128
+#define PCLK_GPIO4			129
+#define DBCLK_GPIO4			130
+#define HCLK_CAN0			131
+#define CLK_CAN0			132
+#define HCLK_CAN1			133
+#define CLK_CAN1			134
+#define HCLK_PDM			135
+#define MCLK_PDM			136
+#define CLKOUT_PDM			137
+#define MCLK_SPDIFTX			138
+#define HCLK_SPDIFTX			139
+#define HCLK_SPDIFRX			140
+#define MCLK_SPDIFRX			141
+#define MCLK_SAI0			142
+#define HCLK_SAI0			143
+#define MCLK_OUT_SAI0			144
+#define MCLK_SAI1			145
+#define HCLK_SAI1			146
+#define MCLK_OUT_SAI1			147
+#define HCLK_ASRC0			148
+#define CLK_ASRC0			149
+#define HCLK_ASRC1			150
+#define CLK_ASRC1			151
+#define PCLK_CRU			152
+#define PCLK_PMU_ROOT			153
+#define MCLK_ASRC0			154
+#define MCLK_ASRC1			155
+#define MCLK_ASRC2			156
+#define MCLK_ASRC3			157
+#define LRCK_ASRC0_SRC			158
+#define LRCK_ASRC0_DST			159
+#define LRCK_ASRC1_SRC			160
+#define LRCK_ASRC1_DST			161
+#define ACLK_HSPERI_ROOT		162
+#define HCLK_HSPERI_ROOT		163
+#define PCLK_HSPERI_ROOT		164
+#define CCLK_SRC_SDMMC			165
+#define HCLK_SDMMC			166
+#define HCLK_FSPI			167
+#define SCLK_FSPI			168
+#define PCLK_SPI2			169
+#define ACLK_MAC0			170
+#define ACLK_MAC1			171
+#define PCLK_MAC0			172
+#define PCLK_MAC1			173
+#define CLK_MAC_ROOT			174
+#define CLK_MAC0			175
+#define CLK_MAC1			176
+#define MCLK_SAI2			177
+#define HCLK_SAI2			178
+#define MCLK_OUT_SAI2			179
+#define MCLK_SAI3_SRC			180
+#define HCLK_SAI3			181
+#define MCLK_SAI3			182
+#define MCLK_OUT_SAI3			183
+#define MCLK_SAI4_SRC			184
+#define HCLK_SAI4			185
+#define MCLK_SAI4			186
+#define HCLK_DSM			187
+#define MCLK_DSM			188
+#define PCLK_AUDIO_ADC			189
+#define MCLK_AUDIO_ADC			190
+#define MCLK_AUDIO_ADC_DIV4		191
+#define PCLK_SARADC			192
+#define CLK_SARADC			193
+#define PCLK_OTPC_NS			194
+#define CLK_SBPI_OTPC_NS		195
+#define CLK_USER_OTPC_NS		196
+#define PCLK_UART5			197
+#define SCLK_UART5			198
+#define PCLK_GPIO234_IOC		199
+#define CLK_MAC_PTP_ROOT		200
+#define CLK_MAC0_PTP			201
+#define CLK_MAC1_PTP			202
+#define CLK_SPI2			203
+#define ACLK_VIO_ROOT			204
+#define HCLK_VIO_ROOT			205
+#define PCLK_VIO_ROOT			206
+#define HCLK_RGA			207
+#define ACLK_RGA			208
+#define CLK_CORE_RGA			209
+#define ACLK_VOP			210
+#define HCLK_VOP			211
+#define DCLK_VOP			212
+#define PCLK_DPHY			213
+#define PCLK_DSI_HOST			214
+#define PCLK_TSADC			215
+#define CLK_TSADC			216
+#define CLK_TSADC_TSEN			217
+#define PCLK_GPIO1_IOC			218
+#define PCLK_OTPC_S			219
+#define CLK_SBPI_OTPC_S			220
+#define CLK_USER_OTPC_S			221
+#define PCLK_OTP_MASK			222
+#define PCLK_KEYREADER			223
+#define HCLK_BOOTROM			224
+#define PCLK_DDR_SERVICE		225
+#define HCLK_CRYPTO_S			226
+#define HCLK_KEYLAD			227
+#define CLK_CORE_CRYPTO			228
+#define CLK_PKA_CRYPTO			229
+#define CLK_CORE_CRYPTO_S		230
+#define CLK_PKA_CRYPTO_S		231
+#define ACLK_CRYPTO_S			232
+#define HCLK_RNG_S			233
+#define CLK_CORE_CRYPTO_NS		234
+#define CLK_PKA_CRYPTO_NS		235
+#define ACLK_CRYPTO_NS			236
+#define HCLK_CRYPTO_NS			237
+#define HCLK_RNG			238
+#define CLK_PMU				239
+#define PCLK_PMU			240
+#define CLK_PMU_32K			241
+#define PCLK_PMU_CRU			242
+#define PCLK_PMU_GRF			243
+#define PCLK_GPIO0_IOC			244
+#define PCLK_GPIO0			245
+#define DBCLK_GPIO0			246
+#define PCLK_GPIO1_SHADOW		247
+#define DBCLK_GPIO1_SHADOW		248
+#define PCLK_PMU_HP_TIMER		249
+#define CLK_PMU_HP_TIMER		250
+#define CLK_PMU_HP_TIMER_32K		251
+#define PCLK_PWM0			252
+#define CLK_PWM0			253
+#define CLK_OSC_PWM0			254
+#define CLK_RC_PWM0			255
+#define CLK_MAC_OUT			256
+#define CLK_REF_OUT0			257
+#define CLK_REF_OUT1			258
+#define CLK_32K_FRAC			259
+#define CLK_32K_RC			260
+#define CLK_32K				261
+#define CLK_32K_PMU			262
+#define PCLK_TOUCH_KEY			263
+#define CLK_TOUCH_KEY			264
+#define CLK_REF_PHY_PLL			265
+#define CLK_REF_PHY_PMU_MUX		266
+#define CLK_WIFI_OUT			267
+#define CLK_V0PLL_REF			268
+#define CLK_V1PLL_REF			269
+#define CLK_32K_FRAC_MUX		270
+
+#endif
diff --git a/include/dt-bindings/reset/rockchip,rk3506-cru.h b/include/dt-bindings/reset/rockchip,rk3506-cru.h
new file mode 100644
index 000000000000..f38cc066009b
--- /dev/null
+++ b/include/dt-bindings/reset/rockchip,rk3506-cru.h
@@ -0,0 +1,211 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2023-2025 Rockchip Electronics Co., Ltd.
+ * Author: Finley Xiao <finley.xiao at rock-chips.com>
+ */
+
+#ifndef _DT_BINDINGS_REST_ROCKCHIP_RK3506_H
+#define _DT_BINDINGS_REST_ROCKCHIP_RK3506_H
+
+/* CRU-->SOFTRST_CON00 */
+#define SRST_NCOREPORESET0_AC		0
+#define SRST_NCOREPORESET1_AC		1
+#define SRST_NCOREPORESET2_AC		2
+#define SRST_NCORESET0_AC		3
+#define SRST_NCORESET1_AC		4
+#define SRST_NCORESET2_AC		5
+#define SRST_NL2RESET_AC		6
+#define SRST_ARESETN_CORE_BIU_AC	7
+#define SRST_HRESETN_M0_AC		8
+
+/* CRU-->SOFTRST_CON02 */
+#define SRST_NDBGRESET			9
+#define SRST_PRESETN_CORE_BIU		10
+#define SRST_RESETN_PMU			11
+
+/* CRU-->SOFTRST_CON03 */
+#define SRST_PRESETN_DBG		12
+#define SRST_POTRESETN_DBG		13
+#define SRST_PRESETN_CORE_GRF		14
+#define SRST_RESETN_CORE_EMA_DETECT	15
+#define SRST_RESETN_REF_PVTPLL_CORE	16
+#define SRST_PRESETN_GPIO1		17
+#define SRST_DBRESETN_GPIO1		18
+
+/* CRU-->SOFTRST_CON04 */
+#define SRST_ARESETN_CORE_PERI_BIU	19
+#define SRST_ARESETN_DSMC		20
+#define SRST_PRESETN_DSMC		21
+#define SRST_RESETN_FLEXBUS		22
+#define SRST_ARESETN_FLEXBUS		23
+#define SRST_HRESETN_FLEXBUS		24
+#define SRST_ARESETN_DSMC_SLV		25
+#define SRST_HRESETN_DSMC_SLV		26
+#define SRST_RESETN_DSMC_SLV		27
+
+/* CRU-->SOFTRST_CON05 */
+#define SRST_ARESETN_BUS_BIU		28
+#define SRST_HRESETN_BUS_BIU		29
+#define SRST_PRESETN_BUS_BIU		30
+#define SRST_ARESETN_SYSRAM		31
+#define SRST_HRESETN_SYSRAM		32
+#define SRST_ARESETN_DMAC0		33
+#define SRST_ARESETN_DMAC1		34
+#define SRST_HRESETN_M0			35
+#define SRST_RESETN_M0_JTAG		36
+#define SRST_HRESETN_CRYPTO		37
+
+/* CRU-->SOFTRST_CON06 */
+#define SRST_HRESETN_RNG		38
+#define SRST_PRESETN_BUS_GRF		39
+#define SRST_PRESETN_TIMER0		40
+#define SRST_RESETN_TIMER0_CH0		41
+#define SRST_RESETN_TIMER0_CH1		42
+#define SRST_RESETN_TIMER0_CH2		43
+#define SRST_RESETN_TIMER0_CH3		44
+#define SRST_RESETN_TIMER0_CH4		45
+#define SRST_RESETN_TIMER0_CH5		46
+#define SRST_PRESETN_WDT0		47
+#define SRST_TRESETN_WDT0		48
+#define SRST_PRESETN_WDT1		49
+#define SRST_TRESETN_WDT1		50
+#define SRST_PRESETN_MAILBOX		51
+#define SRST_PRESETN_INTMUX		52
+#define SRST_PRESETN_SPINLOCK		53
+
+/* CRU-->SOFTRST_CON07 */
+#define SRST_PRESETN_DDRC		54
+#define SRST_HRESETN_DDRPHY		55
+#define SRST_PRESETN_DDRMON		56
+#define SRST_RESETN_DDRMON_OSC		57
+#define SRST_PRESETN_DDR_LPC		58
+#define SRST_HRESETN_USBOTG0		59
+#define SRST_RESETN_USBOTG0_ADP		60
+#define SRST_HRESETN_USBOTG1		61
+#define SRST_RESETN_USBOTG1_ADP		62
+#define SRST_PRESETN_USBPHY		63
+#define SRST_RESETN_USBPHY_POR		64
+#define SRST_RESETN_USBPHY_OTG0		65
+#define SRST_RESETN_USBPHY_OTG1		66
+
+/* CRU-->SOFTRST_CON08 */
+#define SRST_ARESETN_DMA2DDR		67
+#define SRST_PRESETN_DMA2DDR		68
+
+/* CRU-->SOFTRST_CON09 */
+#define SRST_RESETN_USBOTG0_UTMI	69
+#define SRST_RESETN_USBOTG1_UTMI	70
+
+/* CRU-->SOFTRST_CON10 */
+#define SRST_ARESETN_DDRC_0		71
+#define SRST_ARESETN_DDRC_1		72
+#define SRST_ARESETN_DDR_BIU		73
+#define SRST_RESETN_DDRC		74
+#define SRST_RESETN_DDRMON		75
+
+/* CRU-->SOFTRST_CON11 */
+#define SRST_HRESETN_LSPERI_BIU		76
+#define SRST_PRESETN_UART0		77
+#define SRST_PRESETN_UART1		78
+#define SRST_PRESETN_UART2		79
+#define SRST_PRESETN_UART3		80
+#define SRST_PRESETN_UART4		81
+#define SRST_RESETN_UART0		82
+#define SRST_RESETN_UART1		83
+#define SRST_RESETN_UART2		84
+#define SRST_RESETN_UART3		85
+#define SRST_RESETN_UART4		86
+#define SRST_PRESETN_I2C0		87
+#define SRST_RESETN_I2C0		88
+
+/* CRU-->SOFTRST_CON12 */
+#define SRST_PRESETN_I2C1		89
+#define SRST_RESETN_I2C1		90
+#define SRST_PRESETN_I2C2		91
+#define SRST_RESETN_I2C2		92
+#define SRST_PRESETN_PWM1		93
+#define SRST_RESETN_PWM1		94
+#define SRST_PRESETN_SPI0		95
+#define SRST_RESETN_SPI0		96
+#define SRST_PRESETN_SPI1		97
+#define SRST_RESETN_SPI1		98
+#define SRST_PRESETN_GPIO2		99
+#define SRST_DBRESETN_GPIO2		100
+
+/* CRU-->SOFTRST_CON13 */
+#define SRST_PRESETN_GPIO3		101
+#define SRST_DBRESETN_GPIO3		102
+#define SRST_PRESETN_GPIO4		103
+#define SRST_DBRESETN_GPIO4		104
+#define SRST_HRESETN_CAN0		105
+#define SRST_RESETN_CAN0		106
+#define SRST_HRESETN_CAN1		107
+#define SRST_RESETN_CAN1		108
+#define SRST_HRESETN_PDM		109
+#define SRST_MRESETN_PDM		110
+#define SRST_RESETN_PDM			111
+#define SRST_RESETN_SPDIFTX		112
+#define SRST_HRESETN_SPDIFTX		113
+#define SRST_HRESETN_SPDIFRX		114
+#define SRST_RESETN_SPDIFRX		115
+#define SRST_MRESETN_SAI0		116
+
+/* CRU-->SOFTRST_CON14 */
+#define SRST_HRESETN_SAI0		117
+#define SRST_MRESETN_SAI1		118
+#define SRST_HRESETN_SAI1		119
+#define SRST_HRESETN_ASRC0		120
+#define SRST_RESETN_ASRC0		121
+#define SRST_HRESETN_ASRC1		122
+#define SRST_RESETN_ASRC1		123
+
+/* CRU-->SOFTRST_CON17 */
+#define SRST_HRESETN_HSPERI_BIU		124
+#define SRST_HRESETN_SDMMC		125
+#define SRST_HRESETN_FSPI		126
+#define SRST_SRESETN_FSPI		127
+#define SRST_PRESETN_SPI2		128
+#define SRST_ARESETN_MAC0		129
+#define SRST_ARESETN_MAC1		130
+
+/* CRU-->SOFTRST_CON18 */
+#define SRST_MRESETN_SAI2		131
+#define SRST_HRESETN_SAI2		132
+#define SRST_HRESETN_SAI3		133
+#define SRST_MRESETN_SAI3		134
+#define SRST_HRESETN_SAI4		135
+#define SRST_MRESETN_SAI4		136
+#define SRST_HRESETN_DSM		137
+#define SRST_MRESETN_DSM		138
+#define SRST_PRESETN_AUDIO_ADC		139
+#define SRST_MRESETN_AUDIO_ADC		140
+
+/* CRU-->SOFTRST_CON19 */
+#define SRST_PRESETN_SARADC		141
+#define SRST_RESETN_SARADC		142
+#define SRST_RESETN_SARADC_PHY		143
+#define SRST_PRESETN_OTPC_NS		144
+#define SRST_RESETN_SBPI_OTPC_NS	145
+#define SRST_RESETN_USER_OTPC_NS	146
+#define SRST_PRESETN_UART5		147
+#define SRST_RESETN_UART5		148
+#define SRST_PRESETN_GPIO234_IOC	149
+
+/* CRU-->SOFTRST_CON21 */
+#define SRST_ARESETN_VIO_BIU		150
+#define SRST_HRESETN_VIO_BIU		151
+#define SRST_HRESETN_RGA		152
+#define SRST_ARESETN_RGA		153
+#define SRST_RESETN_CORE_RGA		154
+#define SRST_ARESETN_VOP		155
+#define SRST_HRESETN_VOP		156
+#define SRST_RESETN_VOP			157
+#define SRST_PRESETN_DPHY		158
+#define SRST_PRESETN_DSI_HOST		159
+#define SRST_PRESETN_TSADC		160
+#define SRST_RESETN_TSADC		161
+
+/* CRU-->SOFTRST_CON22 */
+#define SRST_PRESETN_GPIO1_IOC		162
+
+#endif
-- 
2.34.1



From zhangqing at rock-chips.com  Mon Nov  3 19:06:33 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Tue,  4 Nov 2025 11:06:33 +0800
Subject: [PATCH v6 5/5] clk: rockchip: Add clock and reset driver for RK3506
In-Reply-To: <20251104030633.2721038-1-zhangqing@rock-chips.com>
References: <20251104030633.2721038-1-zhangqing@rock-chips.com>
Message-ID: <20251104030633.2721038-6-zhangqing@rock-chips.com>

Add the clock and reset tree definitions for the new
RK3506 SoC.

Signed-off-by: Finley Xiao <finley.xiao at rock-chips.com>
---
 drivers/clk/rockchip/Kconfig      |   7 +
 drivers/clk/rockchip/Makefile     |   1 +
 drivers/clk/rockchip/clk-rk3506.c | 869 ++++++++++++++++++++++++++++++
 drivers/clk/rockchip/clk.h        |  13 +
 drivers/clk/rockchip/rst-rk3506.c | 226 ++++++++
 5 files changed, 1116 insertions(+)
 create mode 100644 drivers/clk/rockchip/clk-rk3506.c
 create mode 100644 drivers/clk/rockchip/rst-rk3506.c

diff --git a/drivers/clk/rockchip/Kconfig b/drivers/clk/rockchip/Kconfig
index e1ea0a098ca9..5cf1e0fd6fb3 100644
--- a/drivers/clk/rockchip/Kconfig
+++ b/drivers/clk/rockchip/Kconfig
@@ -100,6 +100,13 @@ config CLK_RK3399
 	help
 	  Build the driver for RK3399 Clock Driver.
 
+config CLK_RK3506
+	bool "Rockchip RK3506 clock controller support"
+	depends on ARM || COMPILE_TEST
+	default y
+	help
+	  Build the driver for RK3506 Clock Driver.
+
 config CLK_RK3528
 	bool "Rockchip RK3528 clock controller support"
 	depends on ARM64 || COMPILE_TEST
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index 82b4b29ad036..4d8cbb2044c7 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_CLK_RK3308)        += clk-rk3308.o
 obj-$(CONFIG_CLK_RK3328)        += clk-rk3328.o
 obj-$(CONFIG_CLK_RK3368)        += clk-rk3368.o
 obj-$(CONFIG_CLK_RK3399)        += clk-rk3399.o
+obj-$(CONFIG_CLK_RK3506)	+= clk-rk3506.o rst-rk3506.o
 obj-$(CONFIG_CLK_RK3528)	+= clk-rk3528.o rst-rk3528.o
 obj-$(CONFIG_CLK_RK3562)	+= clk-rk3562.o rst-rk3562.o
 obj-$(CONFIG_CLK_RK3568)	+= clk-rk3568.o
diff --git a/drivers/clk/rockchip/clk-rk3506.c b/drivers/clk/rockchip/clk-rk3506.c
new file mode 100644
index 000000000000..dd59bd60382e
--- /dev/null
+++ b/drivers/clk/rockchip/clk-rk3506.c
@@ -0,0 +1,869 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023-2025 Rockchip Electronics Co., Ltd.
+ * Author: Finley Xiao <finley.xiao at rock-chips.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/syscore_ops.h>
+#include <dt-bindings/clock/rockchip,rk3506-cru.h>
+#include "clk.h"
+
+#define PVTPLL_SRC_SEL_PVTPLL		(BIT(7) | BIT(23))
+
+enum rk3506_plls {
+	gpll, v0pll, v1pll,
+};
+
+/*
+ * [FRAC PLL]: GPLL, V0PLL, V1PLL
+ *   - VCO Frequency: 950MHz to 3800MHZ
+ *   - Output Frequency: 19MHz to 3800MHZ
+ *   - refdiv: 1 to 63 (Int Mode), 1 to 2 (Frac Mode)
+ *   - fbdiv: 16 to 3800 (Int Mode), 20 to 380 (Frac Mode)
+ *   - post1div: 1 to 7
+ *   - post2div: 1 to 7
+ */
+static struct rockchip_pll_rate_table rk3506_pll_rates[] = {
+	/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
+	RK3036_PLL_RATE(1896000000, 1, 79, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1800000000, 1, 75, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1704000000, 1, 71, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1512000000, 1, 63, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1350000000, 4, 225, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1179648000, 1, 49, 1, 1, 0, 2550137),
+	RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1000000000, 3, 125, 1, 1, 1, 0),
+	RK3036_PLL_RATE(993484800, 1, 41, 1, 1, 0, 6630355),
+	RK3036_PLL_RATE(983040000, 1, 40, 1, 1, 0, 16106127),
+	RK3036_PLL_RATE(960000000, 1, 80, 2, 1, 1, 0),
+	RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0),
+	RK3036_PLL_RATE(903168000, 1, 75, 2, 1, 0, 4429185),
+	RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
+	RK3036_PLL_RATE(800000000, 3, 200, 2, 1, 1, 0),
+	RK3036_PLL_RATE(600000000, 1, 50, 2, 1, 1, 0),
+	RK3036_PLL_RATE(594000000, 2, 99, 2, 1, 1, 0),
+	RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0),
+	RK3036_PLL_RATE(312000000, 1, 78, 6, 1, 1, 0),
+	RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0),
+	RK3036_PLL_RATE(96000000, 1, 48, 6, 2, 1, 0),
+	{ /* sentinel */ },
+};
+
+#define RK3506_DIV_ACLK_CORE_MASK	0xf
+#define RK3506_DIV_ACLK_CORE_SHIFT	9
+#define RK3506_DIV_PCLK_CORE_MASK	0xf
+#define RK3506_DIV_PCLK_CORE_SHIFT	0
+
+#define RK3506_CLKSEL15(_aclk_core_div)					\
+{									\
+	.reg = RK3506_CLKSEL_CON(15),					\
+	.val = HIWORD_UPDATE(_aclk_core_div, RK3506_DIV_ACLK_CORE_MASK,	\
+			     RK3506_DIV_ACLK_CORE_SHIFT),		\
+}
+
+#define RK3506_CLKSEL16(_pclk_core_div)					\
+{									\
+	.reg = RK3506_CLKSEL_CON(16),					\
+	.val = HIWORD_UPDATE(_pclk_core_div, RK3506_DIV_PCLK_CORE_MASK,	\
+			     RK3506_DIV_PCLK_CORE_SHIFT),		\
+}
+
+/* SIGN-OFF: aclk_core: 500M, pclk_core: 125M, */
+#define RK3506_CPUCLK_RATE(_prate, _aclk_core_div, _pclk_core_div)	\
+{									\
+	.prate = _prate,						\
+	.divs = {							\
+		RK3506_CLKSEL15(_aclk_core_div),			\
+		RK3506_CLKSEL16(_pclk_core_div),			\
+	},								\
+}
+
+static struct rockchip_cpuclk_rate_table rk3506_cpuclk_rates[] __initdata = {
+	RK3506_CPUCLK_RATE(1608000000, 3, 12),
+	RK3506_CPUCLK_RATE(1512000000, 3, 12),
+	RK3506_CPUCLK_RATE(1416000000, 2, 11),
+	RK3506_CPUCLK_RATE(1296000000, 2, 10),
+	RK3506_CPUCLK_RATE(1200000000, 2, 9),
+	RK3506_CPUCLK_RATE(1179648000, 2, 9),
+	RK3506_CPUCLK_RATE(1008000000, 1, 7),
+	RK3506_CPUCLK_RATE(903168000, 1, 7),
+	RK3506_CPUCLK_RATE(800000000, 1, 6),
+	RK3506_CPUCLK_RATE(750000000, 1, 5),
+	RK3506_CPUCLK_RATE(589824000, 1, 4),
+	RK3506_CPUCLK_RATE(400000000, 1, 3),
+	RK3506_CPUCLK_RATE(200000000, 1, 1),
+};
+
+PNAME(mux_pll_p)				= { "xin24m" };
+PNAME(gpll_v0pll_v1pll_parents_p)		= { "gpll", "v0pll", "v1pll" };
+PNAME(gpll_v0pll_v1pll_g_parents_p)		= { "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate" };
+PNAME(gpll_v0pll_v1pll_div_parents_p)		= { "clk_gpll_div", "clk_v0pll_div", "clk_v1pll_div" };
+PNAME(xin24m_gpll_v0pll_v1pll_g_parents_p)	= { "xin24m", "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate" };
+PNAME(xin24m_g_gpll_v0pll_v1pll_g_parents_p)	= { "xin24m_gate", "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate" };
+PNAME(xin24m_g_gpll_v0pll_v1pll_div_parents_p)	= { "xin24m_gate", "clk_gpll_div", "clk_v0pll_div", "clk_v1pll_div" };
+PNAME(xin24m_400k_32k_parents_p)		= { "xin24m", "clk_rc", "clk_32k" };
+PNAME(clk_frac_uart_matrix0_mux_parents_p)	= { "xin24m", "gpll", "clk_v0pll_gate", "clk_v1pll_gate" };
+PNAME(clk_timer0_parents_p)			= { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai0_mclk_in", "sai0_sclk_in" };
+PNAME(clk_timer1_parents_p)			= { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai1_mclk_in", "sai1_sclk_in" };
+PNAME(clk_timer2_parents_p)			= { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai2_mclk_in", "sai2_sclk_in" };
+PNAME(clk_timer3_parents_p)			= { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai3_mclk_in", "sai3_sclk_in" };
+PNAME(clk_timer4_parents_p)			= { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "mclk_asrc0" };
+PNAME(clk_timer5_parents_p)			= { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "mclk_asrc1" };
+PNAME(sclk_uart_parents_p)			= { "xin24m", "clk_gpll_gate", "clk_v0pll_gate", "clk_frac_uart_matrix0", "clk_frac_uart_matrix1",
+						    "clk_frac_common_matrix0", "clk_frac_common_matrix1", "clk_frac_common_matrix2" };
+PNAME(clk_mac_ptp_root_parents_p)		= { "gpll", "v0pll", "v1pll" };
+PNAME(clk_pwm_parents_p)			= { "clk_rc", "sai0_mclk_in", "sai1_mclk_in", "sai2_mclk_in", "sai3_mclk_in", "sai0_sclk_in", "sai1_sclk_in",
+						    "sai2_sclk_in", "sai3_sclk_in", "mclk_asrc0", "mclk_asrc1" };
+PNAME(clk_can_parents_p)			= { "xin24m", "gpll", "clk_v0pll_gate", "clk_v1pll_gate", "clk_frac_voice_matrix1",
+						    "clk_frac_common_matrix0", "clk_frac_common_matrix1", "clk_frac_common_matrix2" };
+PNAME(clk_pdm_parents_p)			= { "xin24m_gate", "clk_int_voice_matrix0", "clk_int_voice_matrix1", "clk_int_voice_matrix2",
+						    "clk_frac_voice_matrix0", "clk_frac_voice_matrix1", "clk_frac_common_matrix0", "clk_frac_common_matrix1",
+						    "clk_frac_common_matrix2", "sai0_mclk_in", "sai1_mclk_in", "sai2_mclk_in", "sai3_mclk_in", "clk_gpll_div" };
+PNAME(mclk_sai_asrc_parents_p)			= { "xin24m_gate", "clk_int_voice_matrix0", "clk_int_voice_matrix1", "clk_int_voice_matrix2",
+						    "clk_frac_voice_matrix0", "clk_frac_voice_matrix1", "clk_frac_common_matrix0", "clk_frac_common_matrix1",
+						    "clk_frac_common_matrix2", "sai0_mclk_in", "sai1_mclk_in", "sai2_mclk_in", "sai3_mclk_in" };
+PNAME(lrck_asrc_parents_p)			= { "mclk_asrc0", "mclk_asrc1", "mclk_asrc2", "mclk_asrc3", "mclk_spdiftx", "clk_spdifrx_to_asrc", "clkout_pdm",
+						    "sai0_fs", "sai1_fs", "sai2_fs", "sai3_fs", "sai4_fs" };
+PNAME(cclk_src_sdmmc_parents_p)			= { "xin24m_gate", "gpll", "clk_v0pll_gate", "clk_v1pll_gate" };
+PNAME(dclk_vop_parents_p)			= { "xin24m_gate", "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate", "dummy_vop_dclk",
+						    "dummy_vop_dclk", "dummy_vop_dclk", "dummy_vop_dclk" };
+PNAME(dbclk_gpio0_parents_p)			= { "xin24m", "clk_rc", "clk_32k_pmu" };
+PNAME(clk_pmu_hp_timer_parents_p)		= { "xin24m", "gpll_div_100m", "clk_core_pvtpll" };
+PNAME(clk_ref_out_parents_p)			= { "xin24m", "gpll", "v0pll", "v1pll" };
+PNAME(clk_32k_frac_parents_p)			= { "xin24m", "v0pll", "v1pll", "clk_rc" };
+PNAME(clk_32k_parents_p)			= { "xin32k", "clk_32k_rc", "clk_32k_frac" };
+PNAME(clk_ref_phy_pmu_mux_parents_p)		= { "xin24m", "clk_ref_phy_pll" };
+PNAME(clk_vpll_ref_parents_p)			= { "xin24m", "clk_pll_ref_io" };
+PNAME(mux_armclk_p)				= { "armclk_pll", "clk_core_pvtpll" };
+
+#define MFLAGS CLK_MUX_HIWORD_MASK
+#define DFLAGS CLK_DIVIDER_HIWORD_MASK
+#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
+
+static struct rockchip_pll_clock rk3506_pll_clks[] __initdata = {
+	[gpll] = PLL(pll_rk3328, PLL_GPLL, "gpll", mux_pll_p,
+		     CLK_IS_CRITICAL, RK3506_PLL_CON(0),
+		     RK3506_MODE_CON, 0, 2, 0, rk3506_pll_rates),
+	[v0pll] = PLL(pll_rk3328, PLL_V0PLL, "v0pll", mux_pll_p,
+		     CLK_IS_CRITICAL, RK3506_PLL_CON(8),
+		     RK3506_MODE_CON, 2, 0, 0, rk3506_pll_rates),
+	[v1pll] = PLL(pll_rk3328, PLL_V1PLL, "v1pll", mux_pll_p,
+		     CLK_IS_CRITICAL, RK3506_PLL_CON(16),
+		     RK3506_MODE_CON, 4, 1, 0, rk3506_pll_rates),
+};
+
+static struct rockchip_clk_branch rk3506_armclk __initdata =
+	MUX(ARMCLK, "armclk", mux_armclk_p, CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
+			RK3506_CLKSEL_CON(15), 8, 1, MFLAGS);
+
+static struct rockchip_clk_branch rk3506_clk_branches[] __initdata = {
+	/*
+	 * CRU Clock-Architecture
+	 */
+	/* top */
+	GATE(XIN24M_GATE, "xin24m_gate", "xin24m", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(0), 1, GFLAGS),
+	GATE(CLK_GPLL_GATE, "clk_gpll_gate", "gpll", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(0), 2, GFLAGS),
+	GATE(CLK_V0PLL_GATE, "clk_v0pll_gate", "v0pll", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(0), 3, GFLAGS),
+	GATE(CLK_V1PLL_GATE, "clk_v1pll_gate", "v1pll", 0,
+			RK3506_CLKGATE_CON(0), 4, GFLAGS),
+	COMPOSITE_NOMUX(CLK_GPLL_DIV, "clk_gpll_div", "clk_gpll_gate", CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(0), 6, 4, DFLAGS,
+			RK3506_CLKGATE_CON(0), 5, GFLAGS),
+	COMPOSITE_NOMUX(CLK_GPLL_DIV_100M, "clk_gpll_div_100m", "clk_gpll_div", 0,
+			RK3506_CLKSEL_CON(0), 10, 4, DFLAGS,
+			RK3506_CLKGATE_CON(0), 6, GFLAGS),
+	COMPOSITE_NOMUX(CLK_V0PLL_DIV, "clk_v0pll_div", "clk_v0pll_gate", CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(1), 0, 4, DFLAGS,
+			RK3506_CLKGATE_CON(0), 7, GFLAGS),
+	COMPOSITE_NOMUX(CLK_V1PLL_DIV, "clk_v1pll_div", "clk_v1pll_gate", 0,
+			RK3506_CLKSEL_CON(1), 4, 4, DFLAGS,
+			RK3506_CLKGATE_CON(0), 8, GFLAGS),
+	COMPOSITE_NOMUX(CLK_INT_VOICE_MATRIX0, "clk_int_voice_matrix0", "clk_v0pll_gate", 0,
+			RK3506_CLKSEL_CON(1), 8, 5, DFLAGS,
+			RK3506_CLKGATE_CON(0), 9, GFLAGS),
+	COMPOSITE_NOMUX(CLK_INT_VOICE_MATRIX1, "clk_int_voice_matrix1", "clk_v1pll_gate", 0,
+			RK3506_CLKSEL_CON(2), 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(0), 10, GFLAGS),
+	COMPOSITE_NOMUX(CLK_INT_VOICE_MATRIX2, "clk_int_voice_matrix2", "clk_v0pll_gate", 0,
+			RK3506_CLKSEL_CON(2), 5, 5, DFLAGS,
+			RK3506_CLKGATE_CON(0), 11, GFLAGS),
+	MUX(CLK_FRAC_UART_MATRIX0_MUX, "clk_frac_uart_matrix0_mux", clk_frac_uart_matrix0_mux_parents_p, 0,
+			RK3506_CLKSEL_CON(3), 9, 2, MFLAGS),
+	MUX(CLK_FRAC_UART_MATRIX1_MUX, "clk_frac_uart_matrix1_mux", xin24m_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(3), 11, 2, MFLAGS),
+	MUX(CLK_FRAC_VOICE_MATRIX0_MUX, "clk_frac_voice_matrix0_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(3), 13, 2, MFLAGS),
+	MUX(CLK_FRAC_VOICE_MATRIX1_MUX, "clk_frac_voice_matrix1_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(4), 0, 2, MFLAGS),
+	MUX(CLK_FRAC_COMMON_MATRIX0_MUX, "clk_frac_common_matrix0_mux", xin24m_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(4), 2, 2, MFLAGS),
+	MUX(CLK_FRAC_COMMON_MATRIX1_MUX, "clk_frac_common_matrix1_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(4), 4, 2, MFLAGS),
+	MUX(CLK_FRAC_COMMON_MATRIX2_MUX, "clk_frac_common_matrix2_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(4), 6, 2, MFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_UART_MATRIX0, "clk_frac_uart_matrix0", "clk_frac_uart_matrix0_mux", 0,
+			RK3506_CLKSEL_CON(5), 0,
+			RK3506_CLKGATE_CON(0), 13, GFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_UART_MATRIX1, "clk_frac_uart_matrix1", "clk_frac_uart_matrix1_mux", 0,
+			RK3506_CLKSEL_CON(6), 0,
+			RK3506_CLKGATE_CON(0), 14, GFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_VOICE_MATRIX0, "clk_frac_voice_matrix0", "clk_frac_voice_matrix0_mux", 0,
+			RK3506_CLKSEL_CON(7), 0,
+			RK3506_CLKGATE_CON(0), 15, GFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_VOICE_MATRIX1, "clk_frac_voice_matrix1", "clk_frac_voice_matrix1_mux", 0,
+			RK3506_CLKSEL_CON(9), 0,
+			RK3506_CLKGATE_CON(1), 0, GFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_COMMON_MATRIX0, "clk_frac_common_matrix0", "clk_frac_common_matrix0_mux", 0,
+			RK3506_CLKSEL_CON(11), 0,
+			RK3506_CLKGATE_CON(1), 1, GFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_COMMON_MATRIX1, "clk_frac_common_matrix1", "clk_frac_common_matrix1_mux", 0,
+			RK3506_CLKSEL_CON(12), 0,
+			RK3506_CLKGATE_CON(1), 2, GFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_COMMON_MATRIX2, "clk_frac_common_matrix2", "clk_frac_common_matrix2_mux", 0,
+			RK3506_CLKSEL_CON(13), 0,
+			RK3506_CLKGATE_CON(1), 3, GFLAGS),
+	GATE(CLK_REF_USBPHY_TOP, "clk_ref_usbphy_top", "xin24m", 0,
+			RK3506_CLKGATE_CON(1), 4, GFLAGS),
+	GATE(CLK_REF_DPHY_TOP, "clk_ref_dphy_top", "xin24m", 0,
+			RK3506_CLKGATE_CON(1), 5, GFLAGS),
+
+	/* core */
+	COMPOSITE_NOGATE(0, "armclk_pll", gpll_v0pll_v1pll_parents_p, CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(15), 5, 2, MFLAGS, 0, 5, DFLAGS),
+	COMPOSITE_NOMUX(ACLK_CORE_ROOT, "aclk_core_root", "armclk", CLK_IGNORE_UNUSED,
+			RK3506_CLKSEL_CON(15), 9, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
+			RK3506_CLKGATE_CON(2), 11, GFLAGS),
+	COMPOSITE_NOMUX(PCLK_CORE_ROOT, "pclk_core_root", "armclk", CLK_IGNORE_UNUSED,
+			RK3506_CLKSEL_CON(16), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
+			RK3506_CLKGATE_CON(2), 12, GFLAGS),
+	GATE(PCLK_DBG, "pclk_dbg", "pclk_core_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(3), 1, GFLAGS),
+	GATE(PCLK_CORE_GRF, "pclk_core_grf", "pclk_core_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(3), 4, GFLAGS),
+	GATE(PCLK_CORE_CRU, "pclk_core_cru", "pclk_core_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(3), 5, GFLAGS),
+	GATE(CLK_CORE_EMA_DETECT, "clk_core_ema_detect", "xin24m_gate", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(3), 6, GFLAGS),
+	GATE(PCLK_GPIO1, "pclk_gpio1", "aclk_core_root", 0,
+			RK3506_CLKGATE_CON(3), 8, GFLAGS),
+	GATE(DBCLK_GPIO1, "dbclk_gpio1", "xin24m_gate", 0,
+			RK3506_CLKGATE_CON(3), 9, GFLAGS),
+
+	/* core peri */
+	COMPOSITE(ACLK_CORE_PERI_ROOT, "aclk_core_peri_root", gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(18), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(4), 0, GFLAGS),
+	GATE(HCLK_CORE_PERI_ROOT, "hclk_core_peri_root", "aclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 1, GFLAGS),
+	GATE(PCLK_CORE_PERI_ROOT, "pclk_core_peri_root", "aclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 2, GFLAGS),
+	COMPOSITE(CLK_DSMC, "clk_dsmc", xin24m_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(18), 12, 2, MFLAGS, 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(4), 4, GFLAGS),
+	GATE(ACLK_DSMC, "aclk_dsmc", "aclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 5, GFLAGS),
+	GATE(PCLK_DSMC, "pclk_dsmc", "pclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 6, GFLAGS),
+	COMPOSITE(CLK_FLEXBUS_TX, "clk_flexbus_tx", xin24m_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(19), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(4), 7, GFLAGS),
+	COMPOSITE(CLK_FLEXBUS_RX, "clk_flexbus_rx", xin24m_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(19), 12, 2, MFLAGS, 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(4), 8, GFLAGS),
+	GATE(ACLK_FLEXBUS, "aclk_flexbus", "aclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 9, GFLAGS),
+	GATE(HCLK_FLEXBUS, "hclk_flexbus", "hclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 10, GFLAGS),
+	GATE(ACLK_DSMC_SLV, "aclk_dsmc_slv", "aclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 11, GFLAGS),
+	GATE(HCLK_DSMC_SLV, "hclk_dsmc_slv", "hclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 12, GFLAGS),
+
+	/* bus */
+	COMPOSITE(ACLK_BUS_ROOT, "aclk_bus_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(21), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(5), 0, GFLAGS),
+	COMPOSITE(HCLK_BUS_ROOT, "hclk_bus_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(21), 12, 2, MFLAGS, 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(5), 1, GFLAGS),
+	COMPOSITE(PCLK_BUS_ROOT, "pclk_bus_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(22), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(5), 2, GFLAGS),
+	GATE(ACLK_SYSRAM, "aclk_sysram", "aclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(5), 6, GFLAGS),
+	GATE(HCLK_SYSRAM, "hclk_sysram", "aclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(5), 7, GFLAGS),
+	GATE(ACLK_DMAC0, "aclk_dmac0", "aclk_bus_root", 0,
+			RK3506_CLKGATE_CON(5), 8, GFLAGS),
+	GATE(ACLK_DMAC1, "aclk_dmac1", "aclk_bus_root", 0,
+			RK3506_CLKGATE_CON(5), 9, GFLAGS),
+	GATE(HCLK_M0, "hclk_m0", "aclk_bus_root", 0,
+			RK3506_CLKGATE_CON(5), 10, GFLAGS),
+	GATE(ACLK_CRYPTO_NS, "aclk_crypto_ns", "aclk_bus_root", 0,
+			RK3506_CLKGATE_CON(5), 14, GFLAGS),
+	GATE(HCLK_CRYPTO_NS, "hclk_crypto_ns", "hclk_bus_root", 0,
+			RK3506_CLKGATE_CON(5), 15, GFLAGS),
+	GATE(HCLK_RNG, "hclk_rng", "hclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 0, GFLAGS),
+	GATE(PCLK_BUS_GRF, "pclk_bus_grf", "pclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(6), 1, GFLAGS),
+	GATE(PCLK_TIMER, "pclk_timer", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 2, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0_CH0, "clk_timer0_ch0", clk_timer0_parents_p, 0,
+			RK3506_CLKSEL_CON(22), 7, 3, MFLAGS,
+			RK3506_CLKGATE_CON(6), 3, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0_CH1, "clk_timer0_ch1", clk_timer1_parents_p, 0,
+			RK3506_CLKSEL_CON(22), 10, 3, MFLAGS,
+			RK3506_CLKGATE_CON(6), 4, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0_CH2, "clk_timer0_ch2", clk_timer2_parents_p, 0,
+			RK3506_CLKSEL_CON(22), 13, 3, MFLAGS,
+			RK3506_CLKGATE_CON(6), 5, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0_CH3, "clk_timer0_ch3", clk_timer3_parents_p, 0,
+			RK3506_CLKSEL_CON(23), 0, 3, MFLAGS,
+			RK3506_CLKGATE_CON(6), 6, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0_CH4, "clk_timer0_ch4", clk_timer4_parents_p, 0,
+			RK3506_CLKSEL_CON(23), 3, 3, MFLAGS,
+			RK3506_CLKGATE_CON(6), 7, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0_CH5, "clk_timer0_ch5", clk_timer5_parents_p, 0,
+			RK3506_CLKSEL_CON(23), 6, 3, MFLAGS,
+			RK3506_CLKGATE_CON(6), 8, GFLAGS),
+	GATE(PCLK_WDT0, "pclk_wdt0", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 9, GFLAGS),
+	GATE(TCLK_WDT0, "tclk_wdt0", "xin24m_gate", 0,
+			RK3506_CLKGATE_CON(6), 10, GFLAGS),
+	GATE(PCLK_WDT1, "pclk_wdt1", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 11, GFLAGS),
+	GATE(TCLK_WDT1, "tclk_wdt1", "xin24m_gate", 0,
+			RK3506_CLKGATE_CON(6), 12, GFLAGS),
+	GATE(PCLK_MAILBOX, "pclk_mailbox", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 13, GFLAGS),
+	GATE(PCLK_INTMUX, "pclk_intmux", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 14, GFLAGS),
+	GATE(PCLK_SPINLOCK, "pclk_spinlock", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 15, GFLAGS),
+	GATE(PCLK_DDRC, "pclk_ddrc", "pclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(7), 0, GFLAGS),
+	GATE(HCLK_DDRPHY, "hclk_ddrphy", "hclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(7), 1, GFLAGS),
+	GATE(PCLK_DDRMON, "pclk_ddrmon", "pclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(7), 2, GFLAGS),
+	GATE(CLK_DDRMON_OSC, "clk_ddrmon_osc", "xin24m_gate", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(7), 3, GFLAGS),
+	GATE(PCLK_STDBY, "pclk_stdby", "pclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(7), 4, GFLAGS),
+	GATE(HCLK_USBOTG0, "hclk_usbotg0", "hclk_bus_root", 0,
+			RK3506_CLKGATE_CON(7), 5, GFLAGS),
+	GATE(HCLK_USBOTG0_PMU, "hclk_usbotg0_pmu", "hclk_bus_root", 0,
+			RK3506_CLKGATE_CON(7), 6, GFLAGS),
+	GATE(CLK_USBOTG0_ADP, "clk_usbotg0_adp", "clk_32k", 0,
+			RK3506_CLKGATE_CON(7), 7, GFLAGS),
+	GATE(HCLK_USBOTG1, "hclk_usbotg1", "hclk_bus_root", 0,
+			RK3506_CLKGATE_CON(7), 8, GFLAGS),
+	GATE(HCLK_USBOTG1_PMU, "hclk_usbotg1_pmu", "hclk_bus_root", 0,
+			RK3506_CLKGATE_CON(7), 9, GFLAGS),
+	GATE(CLK_USBOTG1_ADP, "clk_usbotg1_adp", "clk_32k", 0,
+			RK3506_CLKGATE_CON(7), 10, GFLAGS),
+	GATE(PCLK_USBPHY, "pclk_usbphy", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(7), 11, GFLAGS),
+	GATE(ACLK_DMA2DDR, "aclk_dma2ddr", "aclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(8), 0, GFLAGS),
+	GATE(PCLK_DMA2DDR, "pclk_dma2ddr", "pclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(8), 1, GFLAGS),
+	COMPOSITE_NOMUX(STCLK_M0, "stclk_m0", "xin24m_gate", 0,
+			RK3506_CLKSEL_CON(23), 9, 6, DFLAGS,
+			RK3506_CLKGATE_CON(8), 2, GFLAGS),
+	COMPOSITE(CLK_DDRPHY, "clk_ddrphy", gpll_v0pll_v1pll_parents_p, CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKSEL_CON(4), 4, 2, MFLAGS, 0, 4, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 10, GFLAGS),
+	FACTOR(CLK_DDRC_SRC, "clk_ddrc_src", "clk_ddrphy", 0, 1, 4),
+	GATE(ACLK_DDRC_0, "aclk_ddrc_0", "clk_ddrc_src", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(10), 0, GFLAGS),
+	GATE(ACLK_DDRC_1, "aclk_ddrc_1", "clk_ddrc_src", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(10), 1, GFLAGS),
+	GATE(CLK_DDRC, "clk_ddrc", "clk_ddrc_src", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(10), 3, GFLAGS),
+	GATE(CLK_DDRMON, "clk_ddrmon", "clk_ddrc_src", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(10), 4, GFLAGS),
+
+	/* ls peri */
+	COMPOSITE(HCLK_LSPERI_ROOT, "hclk_lsperi_root", gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(29), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(11), 0, GFLAGS),
+	GATE(PCLK_LSPERI_ROOT, "pclk_lsperi_root", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 1, GFLAGS),
+	GATE(PCLK_UART0, "pclk_uart0", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 4, GFLAGS),
+	GATE(PCLK_UART1, "pclk_uart1", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 5, GFLAGS),
+	GATE(PCLK_UART2, "pclk_uart2", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 6, GFLAGS),
+	GATE(PCLK_UART3, "pclk_uart3", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 7, GFLAGS),
+	GATE(PCLK_UART4, "pclk_uart4", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 8, GFLAGS),
+	COMPOSITE(SCLK_UART0, "sclk_uart0", sclk_uart_parents_p, 0,
+			RK3506_CLKSEL_CON(29), 12, 3, MFLAGS, 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(11), 9, GFLAGS),
+	COMPOSITE(SCLK_UART1, "sclk_uart1", sclk_uart_parents_p, 0,
+			RK3506_CLKSEL_CON(30), 5, 3, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(11), 10, GFLAGS),
+	COMPOSITE(SCLK_UART2, "sclk_uart2", sclk_uart_parents_p, 0,
+			RK3506_CLKSEL_CON(30), 13, 3, MFLAGS, 8, 5, DFLAGS,
+			RK3506_CLKGATE_CON(11), 11, GFLAGS),
+	COMPOSITE(SCLK_UART3, "sclk_uart3", sclk_uart_parents_p, 0,
+			RK3506_CLKSEL_CON(31), 5, 3, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(11), 12, GFLAGS),
+	COMPOSITE(SCLK_UART4, "sclk_uart4", sclk_uart_parents_p, 0,
+			RK3506_CLKSEL_CON(31), 13, 3, MFLAGS, 8, 5, DFLAGS,
+			RK3506_CLKGATE_CON(11), 13, GFLAGS),
+	GATE(PCLK_I2C0, "pclk_i2c0", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 14, GFLAGS),
+	COMPOSITE(CLK_I2C0, "clk_i2c0", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(32), 4, 2, MFLAGS, 0, 4, DFLAGS,
+			RK3506_CLKGATE_CON(11), 15, GFLAGS),
+	GATE(PCLK_I2C1, "pclk_i2c1", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(12), 0, GFLAGS),
+	COMPOSITE(CLK_I2C1, "clk_i2c1", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(32), 10, 2, MFLAGS, 6, 4, DFLAGS,
+			RK3506_CLKGATE_CON(12), 1, GFLAGS),
+	GATE(PCLK_I2C2, "pclk_i2c2", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(12), 2, GFLAGS),
+	COMPOSITE(CLK_I2C2, "clk_i2c2", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(33), 4, 2, MFLAGS, 0, 4, DFLAGS,
+			RK3506_CLKGATE_CON(12), 3, GFLAGS),
+	GATE(PCLK_PWM1, "pclk_pwm1", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(12), 4, GFLAGS),
+	COMPOSITE(CLK_PWM1, "clk_pwm1", gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(33), 10, 2, MFLAGS, 6, 4, DFLAGS,
+			RK3506_CLKGATE_CON(12), 5, GFLAGS),
+	GATE(CLK_OSC_PWM1, "clk_osc_pwm1", "xin24m", 0,
+			RK3506_CLKGATE_CON(12), 6, GFLAGS),
+	GATE(CLK_RC_PWM1, "clk_rc_pwm1", "clk_rc", 0,
+			RK3506_CLKGATE_CON(12), 7, GFLAGS),
+	COMPOSITE_NODIV(CLK_FREQ_PWM1, "clk_freq_pwm1", clk_pwm_parents_p, 0,
+			RK3506_CLKSEL_CON(33), 12, 4, MFLAGS,
+			RK3506_CLKGATE_CON(12), 8, GFLAGS),
+	COMPOSITE_NODIV(CLK_COUNTER_PWM1, "clk_counter_pwm1", clk_pwm_parents_p, 0,
+			RK3506_CLKSEL_CON(34), 0, 4, MFLAGS,
+			RK3506_CLKGATE_CON(12), 9, GFLAGS),
+	GATE(PCLK_SPI0, "pclk_spi0", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(12), 10, GFLAGS),
+	COMPOSITE(CLK_SPI0, "clk_spi0", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(34), 8, 2, MFLAGS, 4, 4, DFLAGS,
+			RK3506_CLKGATE_CON(12), 11, GFLAGS),
+	GATE(PCLK_SPI1, "pclk_spi1", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(12), 12, GFLAGS),
+	COMPOSITE(CLK_SPI1, "clk_spi1", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(34), 14, 2, MFLAGS, 10, 4, DFLAGS,
+			RK3506_CLKGATE_CON(12), 13, GFLAGS),
+	GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(12), 14, GFLAGS),
+	COMPOSITE_NODIV(DBCLK_GPIO2, "dbclk_gpio2", xin24m_400k_32k_parents_p, 0,
+			RK3506_CLKSEL_CON(35), 0, 2, MFLAGS,
+			RK3506_CLKGATE_CON(12), 15, GFLAGS),
+	GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 0, GFLAGS),
+	COMPOSITE_NODIV(DBCLK_GPIO3, "dbclk_gpio3", xin24m_400k_32k_parents_p, 0,
+			RK3506_CLKSEL_CON(35), 2, 2, MFLAGS,
+			RK3506_CLKGATE_CON(13), 1, GFLAGS),
+	GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 2, GFLAGS),
+	COMPOSITE_NODIV(DBCLK_GPIO4, "dbclk_gpio4", xin24m_400k_32k_parents_p, 0,
+			RK3506_CLKSEL_CON(35), 4, 2, MFLAGS,
+			RK3506_CLKGATE_CON(13), 3, GFLAGS),
+	GATE(HCLK_CAN0, "hclk_can0", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 4, GFLAGS),
+	COMPOSITE(CLK_CAN0, "clk_can0", clk_can_parents_p, 0,
+			RK3506_CLKSEL_CON(35), 11, 3, MFLAGS, 6, 5, DFLAGS,
+			RK3506_CLKGATE_CON(13), 5, GFLAGS),
+	GATE(HCLK_CAN1, "hclk_can1", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 6, GFLAGS),
+	COMPOSITE(CLK_CAN1, "clk_can1", clk_can_parents_p, 0,
+			RK3506_CLKSEL_CON(36), 5, 3, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(13), 7, GFLAGS),
+	GATE(HCLK_PDM, "hclk_pdm", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 8, GFLAGS),
+	COMPOSITE(MCLK_PDM, "mclk_pdm", clk_pdm_parents_p, 0,
+			RK3506_CLKSEL_CON(37), 5, 4, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(13), 9, GFLAGS),
+	COMPOSITE(CLKOUT_PDM, "clkout_pdm", clk_pdm_parents_p, 0,
+			RK3506_CLKSEL_CON(38), 10, 4, MFLAGS, 0, 10, DFLAGS,
+			RK3506_CLKGATE_CON(13), 10, GFLAGS),
+	COMPOSITE(MCLK_SPDIFTX, "mclk_spdiftx", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(39), 5, 4, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(13), 11, GFLAGS),
+	GATE(HCLK_SPDIFTX, "hclk_spdiftx", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 12, GFLAGS),
+	GATE(HCLK_SPDIFRX, "hclk_spdifrx", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 13, GFLAGS),
+	COMPOSITE(MCLK_SPDIFRX, "mclk_spdifrx", gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(39), 14, 2, MFLAGS, 9, 5, DFLAGS,
+			RK3506_CLKGATE_CON(13), 14, GFLAGS),
+	COMPOSITE(MCLK_SAI0, "mclk_sai0", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(40), 8, 4, MFLAGS, 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(13), 15, GFLAGS),
+	GATE(HCLK_SAI0, "hclk_sai0", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(14), 0, GFLAGS),
+	GATE(MCLK_OUT_SAI0, "mclk_out_sai0", "mclk_sai0", 0,
+			RK3506_CLKGATE_CON(14), 1, GFLAGS),
+	COMPOSITE(MCLK_SAI1, "mclk_sai1", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(41), 8, 4, MFLAGS, 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(14), 2, GFLAGS),
+	GATE(HCLK_SAI1, "hclk_sai1", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(14), 3, GFLAGS),
+	GATE(MCLK_OUT_SAI1, "mclk_out_sai1", "mclk_sai1", 0,
+			RK3506_CLKGATE_CON(14), 4, GFLAGS),
+	GATE(HCLK_ASRC0, "hclk_asrc0", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(14), 5, GFLAGS),
+	COMPOSITE(CLK_ASRC0, "clk_asrc0", gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(42), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(14), 6, GFLAGS),
+	GATE(HCLK_ASRC1, "hclk_asrc1", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(14), 7, GFLAGS),
+	COMPOSITE(CLK_ASRC1, "clk_asrc1", gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(42), 12, 2, MFLAGS, 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(14), 8, GFLAGS),
+	GATE(PCLK_CRU, "pclk_cru", "pclk_lsperi_root", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(14), 9, GFLAGS),
+	GATE(PCLK_PMU_ROOT, "pclk_pmu_root", "pclk_lsperi_root", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(14), 10, GFLAGS),
+	COMPOSITE_NODIV(MCLK_ASRC0, "mclk_asrc0", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(46), 0, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 0, GFLAGS),
+	COMPOSITE_NODIV(MCLK_ASRC1, "mclk_asrc1", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(46), 4, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 1, GFLAGS),
+	COMPOSITE_NODIV(MCLK_ASRC2, "mclk_asrc2", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(46), 8, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 2, GFLAGS),
+	COMPOSITE_NODIV(MCLK_ASRC3, "mclk_asrc3", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(46), 12, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 3, GFLAGS),
+	COMPOSITE_NODIV(LRCK_ASRC0_SRC, "lrck_asrc0_src", lrck_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(47), 0, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 4, GFLAGS),
+	COMPOSITE_NODIV(LRCK_ASRC0_DST, "lrck_asrc0_dst", lrck_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(47), 4, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 5, GFLAGS),
+	COMPOSITE_NODIV(LRCK_ASRC1_SRC, "lrck_asrc1_src", lrck_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(47), 8, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 6, GFLAGS),
+	COMPOSITE_NODIV(LRCK_ASRC1_DST, "lrck_asrc1_dst", lrck_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(47), 12, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 7, GFLAGS),
+
+	/* hs peri */
+	COMPOSITE(ACLK_HSPERI_ROOT, "aclk_hsperi_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(49), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(17), 0, GFLAGS),
+	GATE(HCLK_HSPERI_ROOT, "hclk_hsperi_root", "aclk_hsperi_root", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(17), 1, GFLAGS),
+	GATE(PCLK_HSPERI_ROOT, "pclk_hsperi_root", "hclk_hsperi_root", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(17), 2, GFLAGS),
+	COMPOSITE(CCLK_SRC_SDMMC, "cclk_src_sdmmc", cclk_src_sdmmc_parents_p, 0,
+			RK3506_CLKSEL_CON(49), 13, 2, MFLAGS, 7, 6, DFLAGS,
+			RK3506_CLKGATE_CON(17), 6, GFLAGS),
+	GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 7, GFLAGS),
+	GATE(HCLK_FSPI, "hclk_fspi", "hclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 8, GFLAGS),
+	COMPOSITE(SCLK_FSPI, "sclk_fspi", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(50), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(17), 9, GFLAGS),
+	GATE(PCLK_SPI2, "pclk_spi2", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 10, GFLAGS),
+	GATE(ACLK_MAC0, "aclk_mac0", "aclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 11, GFLAGS),
+	GATE(ACLK_MAC1, "aclk_mac1", "aclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 12, GFLAGS),
+	GATE(PCLK_MAC0, "pclk_mac0", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 13, GFLAGS),
+	GATE(PCLK_MAC1, "pclk_mac1", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 14, GFLAGS),
+	COMPOSITE_NOMUX(CLK_MAC_ROOT, "clk_mac_root", "gpll", 0,
+			RK3506_CLKSEL_CON(50), 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(17), 15, GFLAGS),
+	GATE(CLK_MAC0, "clk_mac0", "clk_mac_root", 0,
+			RK3506_CLKGATE_CON(18), 0, GFLAGS),
+	GATE(CLK_MAC1, "clk_mac1", "clk_mac_root", 0,
+			RK3506_CLKGATE_CON(18), 1, GFLAGS),
+	COMPOSITE(MCLK_SAI2, "mclk_sai2", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(51), 8, 4, MFLAGS, 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(18), 2, GFLAGS),
+	GATE(HCLK_SAI2, "hclk_sai2", "hclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(18), 3, GFLAGS),
+	GATE(MCLK_OUT_SAI2, "mclk_out_sai2", "mclk_sai2", 0,
+			RK3506_CLKGATE_CON(18), 4, GFLAGS),
+	COMPOSITE(MCLK_SAI3_SRC, "mclk_sai3_src", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(52), 8, 4, MFLAGS, 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(18), 5, GFLAGS),
+	GATE(HCLK_SAI3, "hclk_sai3", "hclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(18), 6, GFLAGS),
+	GATE(MCLK_SAI3, "mclk_sai3", "mclk_sai3_src", 0,
+			RK3506_CLKGATE_CON(18), 7, GFLAGS),
+	GATE(MCLK_OUT_SAI3, "mclk_out_sai3", "mclk_sai3_src", 0,
+			RK3506_CLKGATE_CON(18), 8, GFLAGS),
+	COMPOSITE(MCLK_SAI4_SRC, "mclk_sai4_src", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(53), 8, 4, MFLAGS, 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(18), 9, GFLAGS),
+	GATE(HCLK_SAI4, "hclk_sai4", "hclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(18), 10, GFLAGS),
+	GATE(MCLK_SAI4, "mclk_sai4", "mclk_sai4_src", 0,
+			RK3506_CLKGATE_CON(18), 11, GFLAGS),
+	GATE(HCLK_DSM, "hclk_dsm", "hclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(18), 12, GFLAGS),
+	GATE(MCLK_DSM, "mclk_dsm", "mclk_sai3_src", 0,
+			RK3506_CLKGATE_CON(18), 13, GFLAGS),
+	GATE(PCLK_AUDIO_ADC, "pclk_audio_adc", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(18), 14, GFLAGS),
+	GATE(MCLK_AUDIO_ADC, "mclk_audio_adc", "mclk_sai4_src", 0,
+			RK3506_CLKGATE_CON(18), 15, GFLAGS),
+	FACTOR(MCLK_AUDIO_ADC_DIV4, "mclk_audio_adc_div4", "mclk_audio_adc", 0, 1, 4),
+	GATE(PCLK_SARADC, "pclk_saradc", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(19), 0, GFLAGS),
+	COMPOSITE(CLK_SARADC, "clk_saradc", xin24m_400k_32k_parents_p, 0,
+			RK3506_CLKSEL_CON(54), 4, 2, MFLAGS, 0, 4, DFLAGS,
+			RK3506_CLKGATE_CON(19), 1, GFLAGS),
+	GATE(PCLK_OTPC_NS, "pclk_otpc_ns", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(19), 3, GFLAGS),
+	GATE(CLK_SBPI_OTPC_NS, "clk_sbpi_otpc_ns", "xin24m_gate", 0,
+			RK3506_CLKGATE_CON(19), 4, GFLAGS),
+	FACTOR(CLK_USER_OTPC_NS, "clk_user_otpc_ns", "clk_sbpi_otpc_ns", 0, 1, 2),
+	GATE(PCLK_UART5, "pclk_uart5", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(19), 6, GFLAGS),
+	COMPOSITE(SCLK_UART5, "sclk_uart5", sclk_uart_parents_p, 0,
+			RK3506_CLKSEL_CON(54), 11, 3, MFLAGS, 6, 5, DFLAGS,
+			RK3506_CLKGATE_CON(19), 7, GFLAGS),
+	GATE(PCLK_GPIO234_IOC, "pclk_gpio234_ioc", "pclk_hsperi_root", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(19), 8, GFLAGS),
+	COMPOSITE(CLK_MAC_PTP_ROOT, "clk_mac_ptp_root", clk_mac_ptp_root_parents_p, 0,
+			RK3506_CLKSEL_CON(55), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(19), 9, GFLAGS),
+	GATE(CLK_MAC0_PTP, "clk_mac0_ptp", "clk_mac_ptp_root", 0,
+			RK3506_CLKGATE_CON(19), 10, GFLAGS),
+	GATE(CLK_MAC1_PTP, "clk_mac1_ptp", "clk_mac_ptp_root", 0,
+			RK3506_CLKGATE_CON(19), 11, GFLAGS),
+	COMPOSITE(ACLK_VIO_ROOT, "aclk_vio_root", gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(58), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(21), 0, GFLAGS),
+	COMPOSITE(HCLK_VIO_ROOT, "hclk_vio_root", gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(58), 12, 2, MFLAGS, 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(21), 1, GFLAGS),
+	GATE(PCLK_VIO_ROOT, "pclk_vio_root", "hclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 2, GFLAGS),
+	GATE(HCLK_RGA, "hclk_rga", "hclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 6, GFLAGS),
+	GATE(ACLK_RGA, "aclk_rga", "aclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 7, GFLAGS),
+	COMPOSITE(CLK_CORE_RGA, "clk_core_rga", gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(59), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(21), 8, GFLAGS),
+	GATE(ACLK_VOP, "aclk_vop", "aclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 9, GFLAGS),
+	GATE(HCLK_VOP, "hclk_vop", "hclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 10, GFLAGS),
+	COMPOSITE(DCLK_VOP, "dclk_vop", dclk_vop_parents_p, 0,
+			RK3506_CLKSEL_CON(60), 8, 3, MFLAGS, 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(21), 11, GFLAGS),
+	GATE(PCLK_DPHY, "pclk_dphy", "pclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 12, GFLAGS),
+	GATE(PCLK_DSI_HOST, "pclk_dsi_host", "pclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 13, GFLAGS),
+	GATE(PCLK_TSADC, "pclk_tsadc", "pclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 14, GFLAGS),
+	COMPOSITE_NOMUX(CLK_TSADC, "clk_tsadc", "xin24m_gate", 0,
+			RK3506_CLKSEL_CON(61), 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(21), 15, GFLAGS),
+	COMPOSITE_NOMUX(CLK_TSADC_TSEN, "clk_tsadc_tsen", "xin24m_gate", 0,
+			RK3506_CLKSEL_CON(61), 8, 3, DFLAGS,
+			RK3506_CLKGATE_CON(22), 0, GFLAGS),
+	GATE(PCLK_GPIO1_IOC, "pclk_gpio1_ioc", "pclk_vio_root", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(22), 1, GFLAGS),
+
+	/* pmu */
+	GATE(CLK_PMU, "clk_pmu", "xin24m", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 1, GFLAGS),
+	GATE(PCLK_PMU, "pclk_pmu", "pclk_pmu_root", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 2, GFLAGS),
+	GATE(PCLK_PMU_CRU, "pclk_pmu_cru", "pclk_pmu_root", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 4, GFLAGS),
+	GATE(PCLK_PMU_GRF, "pclk_pmu_grf", "pclk_pmu_root", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 5, GFLAGS),
+	GATE(PCLK_GPIO0_IOC, "pclk_gpio0_ioc", "pclk_pmu_root", CLK_IS_CRITICAL,
+			RK3506_PMU_CLKGATE_CON(0), 7, GFLAGS),
+	GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pmu_root", 0,
+			RK3506_PMU_CLKGATE_CON(0), 8, GFLAGS),
+	COMPOSITE_NODIV(DBCLK_GPIO0, "dbclk_gpio0", dbclk_gpio0_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(0), 0, 2, MFLAGS,
+			RK3506_PMU_CLKGATE_CON(0), 9, GFLAGS),
+	GATE(PCLK_GPIO1_SHADOW, "pclk_gpio1_shadow", "pclk_pmu_root", 0,
+			RK3506_PMU_CLKGATE_CON(0), 10, GFLAGS),
+	COMPOSITE_NODIV(DBCLK_GPIO1_SHADOW, "dbclk_gpio1_shadow", dbclk_gpio0_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(0), 2, 2, MFLAGS,
+			RK3506_PMU_CLKGATE_CON(0), 11, GFLAGS),
+	GATE(PCLK_PMU_HP_TIMER, "pclk_pmu_hp_timer", "pclk_pmu_root", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 12, GFLAGS),
+	MUX(CLK_PMU_HP_TIMER, "clk_pmu_hp_timer", clk_pmu_hp_timer_parents_p, CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKSEL_CON(0), 4, 2, MFLAGS),
+	GATE(PCLK_PWM0, "pclk_pwm0", "pclk_pmu_root", 0,
+			RK3506_PMU_CLKGATE_CON(0), 15, GFLAGS),
+	COMPOSITE_NOMUX(CLK_PWM0, "clk_pwm0", "clk_gpll_div_100m", 0,
+			RK3506_PMU_CLKSEL_CON(0), 6, 4, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 0, GFLAGS),
+	GATE(CLK_OSC_PWM0, "clk_osc_pwm0", "xin24m", 0,
+			RK3506_PMU_CLKGATE_CON(1), 1, GFLAGS),
+	GATE(CLK_RC_PWM0, "clk_rc_pwm0", "clk_rc", 0,
+			RK3506_PMU_CLKGATE_CON(1), 2, GFLAGS),
+	COMPOSITE_NOMUX(CLK_MAC_OUT, "clk_mac_out", "gpll", 0,
+			RK3506_PMU_CLKSEL_CON(0), 10, 6, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 3, GFLAGS),
+	COMPOSITE(CLK_REF_OUT0, "clk_ref_out0", clk_ref_out_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(1), 6, 2, MFLAGS, 0, 6, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 4, GFLAGS),
+	COMPOSITE(CLK_REF_OUT1, "clk_ref_out1", clk_ref_out_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(1), 14, 2, MFLAGS, 8, 6, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 5, GFLAGS),
+	MUX(CLK_32K_FRAC_MUX, "clk_32k_frac_mux", clk_32k_frac_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(3), 0, 2, MFLAGS),
+	COMPOSITE_FRAC(CLK_32K_FRAC, "clk_32k_frac", "clk_32k_frac_mux", 0,
+			RK3506_PMU_CLKSEL_CON(2), 0,
+			RK3506_PMU_CLKGATE_CON(1), 6, GFLAGS),
+	COMPOSITE_NOMUX(CLK_32K_RC, "clk_32k_rc", "clk_rc", CLK_IS_CRITICAL,
+			RK3506_PMU_CLKSEL_CON(3), 2, 5, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 7, GFLAGS),
+	COMPOSITE_NODIV(CLK_32K, "clk_32k", clk_32k_parents_p, CLK_IS_CRITICAL,
+			RK3506_PMU_CLKSEL_CON(3), 7, 2, MFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 8, GFLAGS),
+	COMPOSITE_NODIV(CLK_32K_PMU, "clk_32k_pmu", clk_32k_parents_p, CLK_IS_CRITICAL,
+			RK3506_PMU_CLKSEL_CON(3), 9, 2, MFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 9, GFLAGS),
+	GATE(CLK_PMU_32K, "clk_pmu_32k", "clk_32k_pmu", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 3, GFLAGS),
+	GATE(CLK_PMU_HP_TIMER_32K, "clk_pmu_hp_timer_32k", "clk_32k_pmu", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 14, GFLAGS),
+	GATE(PCLK_TOUCH_KEY, "pclk_touch_key", "pclk_pmu_root", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(1), 12, GFLAGS),
+	GATE(CLK_TOUCH_KEY, "clk_touch_key", "xin24m", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(1), 13, GFLAGS),
+	COMPOSITE(CLK_REF_PHY_PLL, "clk_ref_phy_pll", gpll_v0pll_v1pll_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(4), 13, 2, MFLAGS, 6, 7, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 14, GFLAGS),
+	MUX(CLK_REF_PHY_PMU_MUX, "clk_ref_phy_pmu_mux", clk_ref_phy_pmu_mux_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(4), 15, 1, MFLAGS),
+	GATE(CLK_WIFI_OUT, "clk_wifi_out", "xin24m", 0,
+			RK3506_PMU_CLKGATE_CON(2), 0, GFLAGS),
+	MUX(CLK_V0PLL_REF, "clk_v0pll_ref", clk_vpll_ref_parents_p, CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKSEL_CON(6), 0, 1, MFLAGS),
+	MUX(CLK_V1PLL_REF, "clk_v1pll_ref", clk_vpll_ref_parents_p, CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKSEL_CON(6), 1, 1, MFLAGS),
+
+	/* secure ns */
+	GATE(CLK_CORE_CRYPTO_NS, "clk_core_crypto_ns", "clk_core_crypto", 0,
+			RK3506_CLKGATE_CON(5), 12, GFLAGS),
+	GATE(CLK_PKA_CRYPTO_NS, "clk_pka_crypto_ns", "clk_pka_crypto", 0,
+			RK3506_CLKGATE_CON(5), 13, GFLAGS),
+
+	/* io */
+	GATE(CLK_SPI2, "clk_spi2", "clk_spi2_io", 0,
+			RK3506_CLKGATE_CON(20), 0, GFLAGS),
+};
+
+static void __init rk3506_clk_init(struct device_node *np)
+{
+	struct rockchip_clk_provider *ctx;
+	unsigned long clk_nr_clks;
+	void __iomem *reg_base;
+
+	clk_nr_clks = rockchip_clk_find_max_clk_id(rk3506_clk_branches,
+						   ARRAY_SIZE(rk3506_clk_branches)) + 1;
+
+	reg_base = of_iomap(np, 0);
+	if (!reg_base) {
+		pr_err("%s: could not map cru region\n", __func__);
+		return;
+	}
+
+	ctx = rockchip_clk_init(np, reg_base, clk_nr_clks);
+	if (IS_ERR(ctx)) {
+		pr_err("%s: rockchip clk init failed\n", __func__);
+		iounmap(reg_base);
+		return;
+	}
+
+	rockchip_clk_register_plls(ctx, rk3506_pll_clks,
+				   ARRAY_SIZE(rk3506_pll_clks),
+				   0);
+
+	rockchip_clk_register_armclk_multi_pll(ctx, &rk3506_armclk,
+					       rk3506_cpuclk_rates,
+					       ARRAY_SIZE(rk3506_cpuclk_rates));
+
+	rockchip_clk_register_branches(ctx, rk3506_clk_branches,
+				       ARRAY_SIZE(rk3506_clk_branches));
+
+	rk3506_rst_init(np, reg_base);
+
+	rockchip_register_restart_notifier(ctx, RK3506_GLB_SRST_FST, NULL);
+
+	rockchip_clk_of_add_provider(np, ctx);
+
+	/* pvtpll src init */
+	writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RK3506_CLKSEL_CON(15));
+}
+
+CLK_OF_DECLARE(rk3506_cru, "rockchip,rk3506-cru", rk3506_clk_init);
+
+struct clk_rk3506_inits {
+	void (*inits)(struct device_node *np);
+};
+
+static const struct clk_rk3506_inits clk_rk3506_cru_init = {
+	.inits = rk3506_clk_init,
+};
+
+static const struct of_device_id clk_rk3506_match_table[] = {
+	{
+		.compatible = "rockchip,rk3506-cru",
+		.data = &clk_rk3506_cru_init,
+	},
+	{ }
+};
+
+static int clk_rk3506_probe(struct platform_device *pdev)
+{
+	const struct clk_rk3506_inits *init_data;
+	struct device *dev = &pdev->dev;
+
+	init_data = device_get_match_data(dev);
+	if (!init_data)
+		return -EINVAL;
+
+	if (init_data->inits)
+		init_data->inits(dev->of_node);
+
+	return 0;
+}
+
+static struct platform_driver clk_rk3506_driver = {
+	.probe		= clk_rk3506_probe,
+	.driver		= {
+		.name	= "clk-rk3506",
+		.of_match_table = clk_rk3506_match_table,
+		.suppress_bind_attrs = true,
+	},
+};
+builtin_platform_driver_probe(clk_rk3506_driver, clk_rk3506_probe);
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index 87f09320b942..b2fff1d13a4a 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -275,6 +275,18 @@ struct clk;
 #define RK3399_PMU_CLKGATE_CON(x)	((x) * 0x4 + 0x100)
 #define RK3399_PMU_SOFTRST_CON(x)	((x) * 0x4 + 0x110)
 
+#define RK3506_PMU_CRU_BASE		0x10000
+#define RK3506_PLL_CON(x)		((x) * 0x4 + RK3506_PMU_CRU_BASE)
+#define RK3506_CLKSEL_CON(x)		((x) * 0x4 + 0x300)
+#define RK3506_CLKGATE_CON(x)		((x) * 0x4 + 0x800)
+#define RK3506_SOFTRST_CON(x)		((x) * 0x4 + 0xa00)
+#define RK3506_PMU_CLKSEL_CON(x)	((x) * 0x4 + 0x300 + RK3506_PMU_CRU_BASE)
+#define RK3506_PMU_CLKGATE_CON(x)	((x) * 0x4 + 0x800 + RK3506_PMU_CRU_BASE)
+#define RK3506_MODE_CON			0x280
+#define RK3506_GLB_CNT_TH		0xc00
+#define RK3506_GLB_SRST_FST		0xc08
+#define RK3506_GLB_SRST_SND		0xc0c
+
 #define RK3528_PMU_CRU_BASE		0x10000
 #define RK3528_PCIE_CRU_BASE		0x20000
 #define RK3528_DDRPHY_CRU_BASE		0x28000
@@ -1329,6 +1341,7 @@ static inline void rockchip_register_softrst(struct device_node *np,
 }
 
 void rv1126b_rst_init(struct device_node *np, void __iomem *reg_base);
+void rk3506_rst_init(struct device_node *np, void __iomem *reg_base);
 void rk3528_rst_init(struct device_node *np, void __iomem *reg_base);
 void rk3562_rst_init(struct device_node *np, void __iomem *reg_base);
 void rk3576_rst_init(struct device_node *np, void __iomem *reg_base);
diff --git a/drivers/clk/rockchip/rst-rk3506.c b/drivers/clk/rockchip/rst-rk3506.c
new file mode 100644
index 000000000000..f6a833ee2f5c
--- /dev/null
+++ b/drivers/clk/rockchip/rst-rk3506.c
@@ -0,0 +1,226 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2025 Rockchip Electronics Co., Ltd.
+ * Author: Finley Xiao <finley.xiao at rock-chips.com>
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <dt-bindings/reset/rockchip,rk3506-cru.h>
+#include "clk.h"
+
+/* 0xFF9A0000 + 0x0A00 */
+#define RK3506_CRU_RESET_OFFSET(id, reg, bit) [id] = (0 + reg * 16 + bit)
+
+/* mapping table for reset ID to register offset */
+static const int rk3506_register_offset[] = {
+	/* CRU-->SOFTRST_CON00 */
+	RK3506_CRU_RESET_OFFSET(SRST_NCOREPORESET0_AC, 0, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_NCOREPORESET1_AC, 0, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_NCOREPORESET2_AC, 0, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_NCORESET0_AC, 0, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_NCORESET1_AC, 0, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_NCORESET2_AC, 0, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_NL2RESET_AC, 0, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_CORE_BIU_AC, 0, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_M0_AC, 0, 10),
+
+	/* CRU-->SOFTRST_CON02 */
+	RK3506_CRU_RESET_OFFSET(SRST_NDBGRESET, 2, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_CORE_BIU, 2, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_PMU, 2, 15),
+
+	/* CRU-->SOFTRST_CON03 */
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_DBG, 3, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_POTRESETN_DBG, 3, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_CORE_GRF, 3, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_CORE_EMA_DETECT, 3, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_REF_PVTPLL_CORE, 3, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_GPIO1, 3, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_DBRESETN_GPIO1, 3, 9),
+
+	/* CRU-->SOFTRST_CON04 */
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_CORE_PERI_BIU, 4, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_DSMC, 4, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_DSMC, 4, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_FLEXBUS, 4, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_FLEXBUS, 4, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_FLEXBUS, 4, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_DSMC_SLV, 4, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_DSMC_SLV, 4, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_DSMC_SLV, 4, 13),
+
+	/* CRU-->SOFTRST_CON05 */
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_BUS_BIU, 5, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_BUS_BIU, 5, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_BUS_BIU, 5, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_SYSRAM, 5, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_SYSRAM, 5, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_DMAC0, 5, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_DMAC1, 5, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_M0, 5, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_M0_JTAG, 5, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_CRYPTO, 5, 15),
+
+	/* CRU-->SOFTRST_CON06 */
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_RNG, 6, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_BUS_GRF, 6, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_TIMER0, 6, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_TIMER0_CH0, 6, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_TIMER0_CH1, 6, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_TIMER0_CH2, 6, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_TIMER0_CH3, 6, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_TIMER0_CH4, 6, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_TIMER0_CH5, 6, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_WDT0, 6, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_TRESETN_WDT0, 6, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_WDT1, 6, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_TRESETN_WDT1, 6, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_MAILBOX, 6, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_INTMUX, 6, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_SPINLOCK, 6, 15),
+
+	/* CRU-->SOFTRST_CON07 */
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_DDRC, 7, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_DDRPHY, 7, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_DDRMON, 7, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_DDRMON_OSC, 7, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_DDR_LPC, 7, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_USBOTG0, 7, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_USBOTG0_ADP, 7, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_USBOTG1, 7, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_USBOTG1_ADP, 7, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_USBPHY, 7, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_USBPHY_POR, 7, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_USBPHY_OTG0, 7, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_USBPHY_OTG1, 7, 14),
+
+	/* CRU-->SOFTRST_CON08 */
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_DMA2DDR, 8, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_DMA2DDR, 8, 1),
+
+	/* CRU-->SOFTRST_CON09 */
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_USBOTG0_UTMI, 9, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_USBOTG1_UTMI, 9, 1),
+
+	/* CRU-->SOFTRST_CON10 */
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_DDRC_0, 10, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_DDRC_1, 10, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_DDR_BIU, 10, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_DDRC, 10, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_DDRMON, 10, 4),
+
+	/* CRU-->SOFTRST_CON11 */
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_LSPERI_BIU, 11, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_UART0, 11, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_UART1, 11, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_UART2, 11, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_UART3, 11, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_UART4, 11, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_UART0, 11, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_UART1, 11, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_UART2, 11, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_UART3, 11, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_UART4, 11, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_I2C0, 11, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_I2C0, 11, 15),
+
+	/* CRU-->SOFTRST_CON12 */
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_I2C1, 12, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_I2C1, 12, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_I2C2, 12, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_I2C2, 12, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_PWM1, 12, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_PWM1, 12, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_SPI0, 12, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_SPI0, 12, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_SPI1, 12, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_SPI1, 12, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_GPIO2, 12, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_DBRESETN_GPIO2, 12, 15),
+
+	/* CRU-->SOFTRST_CON13 */
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_GPIO3, 13, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_DBRESETN_GPIO3, 13, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_GPIO4, 13, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_DBRESETN_GPIO4, 13, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_CAN0, 13, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_CAN0, 13, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_CAN1, 13, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_CAN1, 13, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_PDM, 13, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_MRESETN_PDM, 13, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_PDM, 13, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_SPDIFTX, 13, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_SPDIFTX, 13, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_SPDIFRX, 13, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_SPDIFRX, 13, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_MRESETN_SAI0, 13, 15),
+
+	/* CRU-->SOFTRST_CON14 */
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_SAI0, 14, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_MRESETN_SAI1, 14, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_SAI1, 14, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_ASRC0, 14, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_ASRC0, 14, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_ASRC1, 14, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_ASRC1, 14, 8),
+
+	/* CRU-->SOFTRST_CON17 */
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_HSPERI_BIU, 17, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_SDMMC, 17, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_FSPI, 17, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_SRESETN_FSPI, 17, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_SPI2, 17, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_MAC0, 17, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_MAC1, 17, 12),
+
+	/* CRU-->SOFTRST_CON18 */
+	RK3506_CRU_RESET_OFFSET(SRST_MRESETN_SAI2, 18, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_SAI2, 18, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_SAI3, 18, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_MRESETN_SAI3, 18, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_SAI4, 18, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_MRESETN_SAI4, 18, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_DSM, 18, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_MRESETN_DSM, 18, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_AUDIO_ADC, 18, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_MRESETN_AUDIO_ADC, 18, 15),
+
+	/* CRU-->SOFTRST_CON19 */
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_SARADC, 19, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_SARADC, 19, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_SARADC_PHY, 19, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_OTPC_NS, 19, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_SBPI_OTPC_NS, 19, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_USER_OTPC_NS, 19, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_UART5, 19, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_UART5, 19, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_GPIO234_IOC, 19, 8),
+
+	/* CRU-->SOFTRST_CON21 */
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_VIO_BIU, 21, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_VIO_BIU, 21, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_RGA, 21, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_RGA, 21, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_CORE_RGA, 21, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_VOP, 21, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_VOP, 21, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_VOP, 21, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_DPHY, 21, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_DSI_HOST, 21, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_TSADC, 21, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_TSADC, 21, 15),
+
+	/* CRU-->SOFTRST_CON22 */
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_GPIO1_IOC, 22, 1),
+};
+
+void rk3506_rst_init(struct device_node *np, void __iomem *reg_base)
+{
+	rockchip_register_softrst_lut(np,
+				      rk3506_register_offset,
+				      ARRAY_SIZE(rk3506_register_offset),
+				      reg_base + RK3506_SOFTRST_CON(0),
+				      ROCKCHIP_SOFTRST_HIWORD_MASK);
+}
-- 
2.34.1



From shawn.lin at rock-chips.com  Mon Nov  3 19:51:23 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Tue,  4 Nov 2025 11:51:23 +0800
Subject: [PATCH] mmc: dw_mmc-rockchip: Fix wrong internal phase calculate
Message-ID: <1762228283-5025-1-git-send-email-shawn.lin@rock-chips.com>

ciu clock is 2 times of io clock, but the sample clk used is
derived from io clock provided to the card. So we should use
io clock to calculate the phase.

Fixes: 59903441f5e4 ("mmc: dw_mmc-rockchip: Add internal phase support")
Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
---

 drivers/mmc/host/dw_mmc-rockchip.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c
index 82dd906..6813549 100644
--- a/drivers/mmc/host/dw_mmc-rockchip.c
+++ b/drivers/mmc/host/dw_mmc-rockchip.c
@@ -42,7 +42,7 @@ struct dw_mci_rockchip_priv_data {
  */
 static int rockchip_mmc_get_internal_phase(struct dw_mci *host, bool sample)
 {
-	unsigned long rate = clk_get_rate(host->ciu_clk);
+	unsigned long rate = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
 	u32 raw_value;
 	u16 degrees;
 	u32 delay_num = 0;
@@ -85,7 +85,7 @@ static int rockchip_mmc_get_phase(struct dw_mci *host, bool sample)
 
 static int rockchip_mmc_set_internal_phase(struct dw_mci *host, bool sample, int degrees)
 {
-	unsigned long rate = clk_get_rate(host->ciu_clk);
+	unsigned long rate = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
 	u8 nineties, remainder;
 	u8 delay_num;
 	u32 raw_value;
-- 
2.7.4



From shawn.lin at rock-chips.com  Mon Nov  3 23:41:34 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Tue,  4 Nov 2025 15:41:34 +0800
Subject: [PATCH] mmc: dw_mmc-rockchip: Add memory clock auto-gating support
Message-ID: <1762242094-55346-1-git-send-email-shawn.lin@rock-chips.com>

Per design recommendations, the memory clock can be gated when there
is no in-flight transfer, which helps save power. This feature is
introduced alongside internal phase support, and this patch enables it.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
---

 drivers/mmc/host/dw_mmc-rockchip.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c
index 6813549..62c68cd 100644
--- a/drivers/mmc/host/dw_mmc-rockchip.c
+++ b/drivers/mmc/host/dw_mmc-rockchip.c
@@ -19,6 +19,8 @@
 #define RK3288_CLKGEN_DIV		2
 #define SDMMC_TIMING_CON0		0x130
 #define SDMMC_TIMING_CON1		0x134
+#define SDMMC_MISC_CON			0x138
+#define MEM_CLK_AUTOGATE_ENABLE		BIT(5)
 #define ROCKCHIP_MMC_DELAY_SEL		BIT(10)
 #define ROCKCHIP_MMC_DEGREE_MASK	0x3
 #define ROCKCHIP_MMC_DEGREE_OFFSET	1
@@ -470,6 +472,7 @@ static int dw_mci_rk3576_parse_dt(struct dw_mci *host)
 
 static int dw_mci_rockchip_init(struct dw_mci *host)
 {
+	struct dw_mci_rockchip_priv_data *priv = host->priv;
 	int ret, i;
 
 	/* It is slot 8 on Rockchip SoCs */
@@ -494,6 +497,9 @@ static int dw_mci_rockchip_init(struct dw_mci *host)
 			dev_warn(host->dev, "no valid minimum freq: %d\n", ret);
 	}
 
+	if (priv->internal_phase)
+		mci_writel(host, MISC_CON, MEM_CLK_AUTOGATE_ENABLE);
+
 	return 0;
 }
 
-- 
2.7.4



From krzk at kernel.org  Tue Nov  4 00:00:37 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 4 Nov 2025 09:00:37 +0100
Subject: [PATCH v5 1/3] dt-bindings: vendor-prefixes: Add 9Tripod
In-Reply-To: <20251103171702.1518730-2-coiaprant@gmail.com>
References: <20251103171702.1518730-1-coiaprant@gmail.com>
 <20251103171702.1518730-2-coiaprant@gmail.com>
Message-ID: <20251104-warm-godlike-coati-b61cc5@kuoka>

On Tue, Nov 04, 2025 at 01:17:00AM +0800, Coia Prant wrote:
> Add 9Tripod to the vendor prefixes.
> 
> Signed-off-by: Coia Prant <coiaprant at gmail.com>
> ---
>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
>  1 file changed, 2 insertions(+)

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From krzk at kernel.org  Tue Nov  4 00:01:00 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 4 Nov 2025 09:01:00 +0100
Subject: [PATCH v5 2/3] dt-bindings: arm: rockchip: Add 9Tripod X3568
 series
In-Reply-To: <20251103171702.1518730-3-coiaprant@gmail.com>
References: <20251103171702.1518730-1-coiaprant@gmail.com>
 <20251103171702.1518730-3-coiaprant@gmail.com>
Message-ID: <20251104-puma-of-undeniable-conversion-de00fb@kuoka>

On Tue, Nov 04, 2025 at 01:17:01AM +0800, Coia Prant wrote:
> This documents 9Tripod X3568 v4 which is a SBC based on RK3568 SoC.
> 
> Link: http://www.9tripod.com/showpro.php?id=117
> Link: https://appletsapi.52solution.com/media/X3568V4%E5%BC%80%E5%8F%91%E6%9D%BF%E7%A1%AC%E4%BB%B6%E6%89%8B%E5%86%8C.pdf
> 
> Signed-off-by: Coia Prant <coiaprant at gmail.com>
> ---
>  Documentation/devicetree/bindings/arm/rockchip.yaml | 6 ++++++
>  1 file changed, 6 insertions(+)

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From naoki at radxa.com  Tue Nov  4 00:52:27 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Tue,  4 Nov 2025 08:52:27 +0000
Subject: [PATCH v3] arm64: dts: rockchip: Fix USB Type-C host mode for Radxa ROCK 5B+/5T
Message-ID: <20251104085227.820-1-naoki@radxa.com>

The Radxa ROCK 5B+/5T USB Type-C port supports Dual Role Data and
should also act as a host. However, currently, when acting as a host,
only self-powered devices work.

Since the ROCK 5B+ supports Dual Role Power, set the power-role
property to "dual" and the try-power-role property to "sink". (along
with related properties)

The ROCK 5T should only support the "source" power-role.

This allows the port to act as a host, supply power to the port, and
allow bus-powered devices to work.

Note that on the ROCK 5T, with this patch applied, it has been
observed that some bus-powered devices do not work correctly. Also,
it has been observed that after connecting a device (and the data-role
switches to host), connecting a host device does not switch the
data-role back to the device role. These issues should be addressed
separately.

Note that there is a separate known issue where USB 3.0 SuperSpeed
devices do not work when oriented in reverse. This issue should also be
addressed separately. (USB 2.0/1.1 devices work in both orientations)

Fixes: 67b2c15d8fb3c ("arm64: dts: rockchip: add USB-C support for ROCK 5B/5B+/5T")
Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
Changes in v3:
- Use power-role = "source" for ROCK 5T
Changes in v2:
- Refine commit message
- Use board-specific dts to describe (try-)power-role
---
 arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi | 4 ++--
 arch/arm64/boot/dts/rockchip/rk3588-rock-5b-plus.dts    | 5 +++++
 arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts         | 4 ++++
 arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts         | 4 ++++
 4 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi
index 3bbe78810ec6f..7aac77dfc5f16 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi
@@ -331,12 +331,12 @@ usb_con: connector {
 			data-role = "dual";
 			/* fusb302 supports PD Rev 2.0 Ver 1.2 */
 			pd-revision = /bits/ 8 <0x2 0x0 0x1 0x2>;
-			power-role = "sink";
-			try-power-role = "sink";
 			op-sink-microwatt = <1000000>;
 			sink-pdos =
 				<PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>,
 				<PDO_VAR(5000, 20000, 5000)>;
+			source-pdos =
+				<PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
 
 			altmodes {
 				displayport {
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-plus.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-plus.dts
index 5e984a44120e4..07a840d9b3859 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-plus.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-plus.dts
@@ -110,6 +110,11 @@ vcc5v0_host_en: vcc5v0-host-en {
 	};
 };
 
+&usb_con {
+	power-role = "dual";
+	try-power-role = "sink";
+};
+
 &usbdp_phy0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&usbc_sbu_dc>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
index 8ef01010d985b..da13dafcbc823 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
@@ -49,6 +49,10 @@ vcc5v0_host_en: vcc5v0-host-en {
 	};
 };
 
+&usb_con {
+	power-role = "sink";
+};
+
 &usbdp_phy0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&usbc_sbu_dc>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts
index c1763835f53d4..0dd90c744380b 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts
@@ -130,6 +130,10 @@ usbc_sbu_dc: usbc-sbu-dc {
 	};
 };
 
+&usb_con {
+	power-role = "source";
+};
+
 &usbdp_phy0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&usbc_sbu_dc>;
-- 
2.43.0



From heiko at sntech.de  Tue Nov  4 02:43:03 2025
From: heiko at sntech.de (Heiko =?UTF-8?B?U3TDvGJuZXI=?=)
Date: Tue, 04 Nov 2025 11:43:03 +0100
Subject: [PATCH v1 1/3] dt-bindings: pinctrl: Add rk3506 pinctrl support
In-Reply-To: <20251104021223.2375116-2-ye.zhang@rock-chips.com>
References: <20251104021223.2375116-1-ye.zhang@rock-chips.com>
 <20251104021223.2375116-2-ye.zhang@rock-chips.com>
Message-ID: <3705122.LM0AJKV5NW@diego>

Am Dienstag, 4. November 2025, 03:12:21 Mitteleurop?ische Normalzeit schrieb Ye Zhang:
> Add the compatible string for the rk3506 SoC.
> 
> Signed-off-by: Ye Zhang <ye.zhang at rock-chips.com>

Reviewed-by: Heiko Stuebner <heiko at sntech.de>





From heiko at sntech.de  Tue Nov  4 02:43:32 2025
From: heiko at sntech.de (Heiko =?UTF-8?B?U3TDvGJuZXI=?=)
Date: Tue, 04 Nov 2025 11:43:32 +0100
Subject: [PATCH v1 2/3] pinctrl: rockchip: Add rk3506 pinctrl support
In-Reply-To: <20251104021223.2375116-3-ye.zhang@rock-chips.com>
References: <20251104021223.2375116-1-ye.zhang@rock-chips.com>
 <20251104021223.2375116-3-ye.zhang@rock-chips.com>
Message-ID: <1797465.QkHrqEjB74@diego>

Am Dienstag, 4. November 2025, 03:12:22 Mitteleurop?ische Normalzeit schrieb Ye Zhang:
> Add support for the 5 rk3506 GPIO banks.
> 
> Signed-off-by: Ye Zhang <ye.zhang at rock-chips.com>

Reviewed-by: Heiko Stuebner <heiko at sntech.de>

> ---
>  drivers/pinctrl/pinctrl-rockchip.c | 442 ++++++++++++++++++++++++++++-
>  drivers/pinctrl/pinctrl-rockchip.h |   4 +
>  2 files changed, 438 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
> index 7a68a6237649..e44ef262beec 100644
> --- a/drivers/pinctrl/pinctrl-rockchip.c
> +++ b/drivers/pinctrl/pinctrl-rockchip.c
> @@ -105,6 +105,29 @@
>  		.pull_type[3] = pull3,					\
>  	}
>  
> +#define PIN_BANK_IOMUX_FLAGS_OFFSET_DRV_FLAGS(id, pins, label, iom0,	\
> +					       iom1, iom2, iom3,	\
> +					       offset0, offset1,	\
> +					       offset2, offset3, drv0,	\
> +					       drv1, drv2, drv3)	\
> +	{								\
> +		.bank_num	= id,					\
> +		.nr_pins	= pins,					\
> +		.name		= label,				\
> +		.iomux		= {					\
> +			{ .type = iom0, .offset = offset0 },		\
> +			{ .type = iom1, .offset = offset1 },		\
> +			{ .type = iom2, .offset = offset2 },		\
> +			{ .type = iom3, .offset = offset3 },		\
> +		},							\
> +		.drv		= {					\
> +			{ .drv_type = drv0, .offset = -1 },		\
> +			{ .drv_type = drv1, .offset = -1 },		\
> +			{ .drv_type = drv2, .offset = -1 },		\
> +			{ .drv_type = drv3, .offset = -1 },		\
> +		},							\
> +	}
> +
>  #define PIN_BANK_DRV_FLAGS(id, pins, label, type0, type1, type2, type3) \
>  	{								\
>  		.bank_num	= id,					\
> @@ -233,6 +256,35 @@
>  		.pull_type[3] = pull3,					\
>  	}
>  
> +#define PIN_BANK_IOMUX_FLAGS_OFFSET_DRV_FLAGS_PULL_FLAGS(id, pins,	\
> +						label, iom0, iom1,	\
> +						iom2, iom3, offset0,	\
> +						offset1, offset2,	\
> +						offset3, drv0, drv1,	\
> +						drv2, drv3, pull0,	\
> +						pull1, pull2, pull3)	\
> +	{								\
> +		.bank_num	= id,					\
> +		.nr_pins	= pins,					\
> +		.name		= label,				\
> +		.iomux		= {					\
> +			{ .type = iom0, .offset = offset0 },		\
> +			{ .type = iom1, .offset = offset1 },		\
> +			{ .type = iom2, .offset = offset2 },		\
> +			{ .type = iom3, .offset = offset3 },		\
> +		},							\
> +		.drv		= {					\
> +			{ .drv_type = drv0, .offset = -1 },		\
> +			{ .drv_type = drv1, .offset = -1 },		\
> +			{ .drv_type = drv2, .offset = -1 },		\
> +			{ .drv_type = drv3, .offset = -1 },		\
> +		},							\
> +		.pull_type[0] = pull0,					\
> +		.pull_type[1] = pull1,					\
> +		.pull_type[2] = pull2,					\
> +		.pull_type[3] = pull3,					\
> +	}
> +
>  #define PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, FLAG)		\
>  	{								\
>  		.bank_num	= ID,					\
> @@ -1120,6 +1172,13 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
>  	else
>  		regmap = info->regmap_base;
>  
> +	if (ctrl->type == RK3506) {
> +		if (bank->bank_num == 1)
> +			regmap = info->regmap_ioc1;
> +		else if (bank->bank_num == 4)
> +			return 0;
> +	}
> +
>  	/* get basic quadrupel of mux registers and the correct reg inside */
>  	mux_type = bank->iomux[iomux_num].type;
>  	reg = bank->iomux[iomux_num].offset;
> @@ -1239,6 +1298,13 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
>  	else
>  		regmap = info->regmap_base;
>  
> +	if (ctrl->type == RK3506) {
> +		if (bank->bank_num == 1)
> +			regmap = info->regmap_ioc1;
> +		else if (bank->bank_num == 4)
> +			return 0;
> +	}
> +
>  	/* get basic quadrupel of mux registers and the correct reg inside */
>  	mux_type = bank->iomux[iomux_num].type;
>  	reg = bank->iomux[iomux_num].offset;
> @@ -2003,6 +2069,262 @@ static int rk3399_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
>  	return 0;
>  }
>  
> +#define RK3506_DRV_BITS_PER_PIN		8
> +#define RK3506_DRV_PINS_PER_REG		2
> +#define RK3506_DRV_GPIO0_A_OFFSET	0x100
> +#define RK3506_DRV_GPIO0_D_OFFSET	0x830
> +#define RK3506_DRV_GPIO1_OFFSET		0x140
> +#define RK3506_DRV_GPIO2_OFFSET		0x180
> +#define RK3506_DRV_GPIO3_OFFSET		0x1c0
> +#define RK3506_DRV_GPIO4_OFFSET		0x840
> +
> +static int rk3506_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
> +					int pin_num, struct regmap **regmap,
> +					int *reg, u8 *bit)
> +{
> +	struct rockchip_pinctrl *info = bank->drvdata;
> +	int ret = 0;
> +
> +	switch (bank->bank_num) {
> +	case 0:
> +		*regmap = info->regmap_pmu;
> +		if (pin_num > 24) {
> +			ret = -EINVAL;
> +		} else if (pin_num < 24) {
> +			*reg = RK3506_DRV_GPIO0_A_OFFSET;
> +		} else {
> +			*reg = RK3506_DRV_GPIO0_D_OFFSET;
> +			*bit = 3;
> +
> +			return 0;
> +		}
> +		break;
> +
> +	case 1:
> +		*regmap = info->regmap_ioc1;
> +		if (pin_num < 28)
> +			*reg = RK3506_DRV_GPIO1_OFFSET;
> +		else
> +			ret = -EINVAL;
> +		break;
> +
> +	case 2:
> +		*regmap = info->regmap_base;
> +		if (pin_num < 17)
> +			*reg = RK3506_DRV_GPIO2_OFFSET;
> +		else
> +			ret = -EINVAL;
> +		break;
> +
> +	case 3:
> +		*regmap = info->regmap_base;
> +		if (pin_num < 15)
> +			*reg = RK3506_DRV_GPIO3_OFFSET;
> +		else
> +			ret = -EINVAL;
> +		break;
> +
> +	case 4:
> +		*regmap = info->regmap_base;
> +		if (pin_num < 8 || pin_num > 11) {
> +			ret = -EINVAL;
> +		} else {
> +			*reg = RK3506_DRV_GPIO4_OFFSET;
> +			*bit = 10;
> +
> +			return 0;
> +		}
> +		break;
> +
> +	default:
> +		ret = -EINVAL;
> +		break;
> +	}
> +
> +	if (ret) {
> +		dev_err(info->dev, "unsupported bank_num %d pin_num %d\n", bank->bank_num, pin_num);
> +
> +		return ret;
> +	}
> +
> +	*reg += ((pin_num / RK3506_DRV_PINS_PER_REG) * 4);
> +	*bit = pin_num % RK3506_DRV_PINS_PER_REG;
> +	*bit *= RK3506_DRV_BITS_PER_PIN;
> +
> +	return 0;
> +}
> +
> +#define RK3506_PULL_BITS_PER_PIN	2
> +#define RK3506_PULL_PINS_PER_REG	8
> +#define RK3506_PULL_GPIO0_A_OFFSET	0x200
> +#define RK3506_PULL_GPIO0_D_OFFSET	0x830
> +#define RK3506_PULL_GPIO1_OFFSET	0x210
> +#define RK3506_PULL_GPIO2_OFFSET	0x220
> +#define RK3506_PULL_GPIO3_OFFSET	0x230
> +#define RK3506_PULL_GPIO4_OFFSET	0x840
> +
> +static int rk3506_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
> +					 int pin_num, struct regmap **regmap,
> +					 int *reg, u8 *bit)
> +{
> +	struct rockchip_pinctrl *info = bank->drvdata;
> +	int ret = 0;
> +
> +	switch (bank->bank_num) {
> +	case 0:
> +		*regmap = info->regmap_pmu;
> +		if (pin_num > 24) {
> +			ret = -EINVAL;
> +		} else if (pin_num < 24) {
> +			*reg = RK3506_PULL_GPIO0_A_OFFSET;
> +		} else {
> +			*reg = RK3506_PULL_GPIO0_D_OFFSET;
> +			*bit = 5;
> +
> +			return 0;
> +		}
> +		break;
> +
> +	case 1:
> +		*regmap = info->regmap_ioc1;
> +		if (pin_num < 28)
> +			*reg = RK3506_PULL_GPIO1_OFFSET;
> +		else
> +			ret = -EINVAL;
> +		break;
> +
> +	case 2:
> +		*regmap = info->regmap_base;
> +		if (pin_num < 17)
> +			*reg = RK3506_PULL_GPIO2_OFFSET;
> +		else
> +			ret = -EINVAL;
> +		break;
> +
> +	case 3:
> +		*regmap = info->regmap_base;
> +		if (pin_num < 15)
> +			*reg = RK3506_PULL_GPIO3_OFFSET;
> +		else
> +			ret = -EINVAL;
> +		break;
> +
> +	case 4:
> +		*regmap = info->regmap_base;
> +		if (pin_num < 8 || pin_num > 11) {
> +			ret = -EINVAL;
> +		} else {
> +			*reg = RK3506_PULL_GPIO4_OFFSET;
> +			*bit = 13;
> +
> +			return 0;
> +		}
> +		break;
> +
> +	default:
> +		ret = -EINVAL;
> +		break;
> +	}
> +
> +	if (ret) {
> +		dev_err(info->dev, "unsupported bank_num %d pin_num %d\n", bank->bank_num, pin_num);
> +
> +		return ret;
> +	}
> +
> +	*reg += ((pin_num / RK3506_PULL_PINS_PER_REG) * 4);
> +	*bit = pin_num % RK3506_PULL_PINS_PER_REG;
> +	*bit *= RK3506_PULL_BITS_PER_PIN;
> +
> +	return 0;
> +}
> +
> +#define RK3506_SMT_BITS_PER_PIN		1
> +#define RK3506_SMT_PINS_PER_REG		8
> +#define RK3506_SMT_GPIO0_A_OFFSET	0x400
> +#define RK3506_SMT_GPIO0_D_OFFSET	0x830
> +#define RK3506_SMT_GPIO1_OFFSET		0x410
> +#define RK3506_SMT_GPIO2_OFFSET		0x420
> +#define RK3506_SMT_GPIO3_OFFSET		0x430
> +#define RK3506_SMT_GPIO4_OFFSET		0x840
> +
> +static int rk3506_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
> +					   int pin_num,
> +					   struct regmap **regmap,
> +					   int *reg, u8 *bit)
> +{
> +	struct rockchip_pinctrl *info = bank->drvdata;
> +	int ret = 0;
> +
> +	switch (bank->bank_num) {
> +	case 0:
> +		*regmap = info->regmap_pmu;
> +		if (pin_num > 24) {
> +			ret = -EINVAL;
> +		} else if (pin_num < 24) {
> +			*reg = RK3506_SMT_GPIO0_A_OFFSET;
> +		} else {
> +			*reg = RK3506_SMT_GPIO0_D_OFFSET;
> +			*bit = 9;
> +
> +			return 0;
> +		}
> +		break;
> +
> +	case 1:
> +		*regmap = info->regmap_ioc1;
> +		if (pin_num < 28)
> +			*reg = RK3506_SMT_GPIO1_OFFSET;
> +		else
> +			ret = -EINVAL;
> +		break;
> +
> +	case 2:
> +		*regmap = info->regmap_base;
> +		if (pin_num < 17)
> +			*reg = RK3506_SMT_GPIO2_OFFSET;
> +		else
> +			ret = -EINVAL;
> +		break;
> +
> +	case 3:
> +		*regmap = info->regmap_base;
> +		if (pin_num < 15)
> +			*reg = RK3506_SMT_GPIO3_OFFSET;
> +		else
> +			ret = -EINVAL;
> +		break;
> +
> +	case 4:
> +		*regmap = info->regmap_base;
> +		if (pin_num < 8 || pin_num > 11) {
> +			ret = -EINVAL;
> +		} else {
> +			*reg = RK3506_SMT_GPIO4_OFFSET;
> +			*bit = 8;
> +
> +			return 0;
> +		}
> +		break;
> +
> +	default:
> +		ret = -EINVAL;
> +		break;
> +	}
> +
> +	if (ret) {
> +		dev_err(info->dev, "unsupported bank_num %d pin_num %d\n", bank->bank_num, pin_num);
> +
> +		return ret;
> +	}
> +
> +	*reg += ((pin_num / RK3506_SMT_PINS_PER_REG) * 4);
> +	*bit = pin_num % RK3506_SMT_PINS_PER_REG;
> +	*bit *= RK3506_SMT_BITS_PER_PIN;
> +
> +	return 0;
> +}
> +
>  #define RK3528_DRV_BITS_PER_PIN		8
>  #define RK3528_DRV_PINS_PER_REG		2
>  #define RK3528_DRV_GPIO0_OFFSET		0x100
> @@ -2749,7 +3071,8 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
>  		rmask_bits = RK3588_DRV_BITS_PER_PIN;
>  		ret = strength;
>  		goto config;
> -	} else if (ctrl->type == RK3528 ||
> +	} else if (ctrl->type == RK3506 ||
> +		   ctrl->type == RK3528 ||
>  		   ctrl->type == RK3562 ||
>  		   ctrl->type == RK3568) {
>  		rmask_bits = RK3568_DRV_BITS_PER_PIN;
> @@ -2828,12 +3151,37 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
>  	case DRV_TYPE_IO_1V8_ONLY:
>  		rmask_bits = RK3288_DRV_BITS_PER_PIN;
>  		break;
> +	case DRV_TYPE_IO_LEVEL_2_BIT:
> +		ret = regmap_read(regmap, reg, &data);
> +		if (ret)
> +			return ret;
> +		data >>= bit;
> +
> +		return data & 0x3;
> +	case DRV_TYPE_IO_LEVEL_8_BIT:
> +		ret = regmap_read(regmap, reg, &data);
> +		if (ret)
> +			return ret;
> +		data >>= bit;
> +		data &= (1 << 8) - 1;
> +
> +		ret = hweight8(data);
> +		if (ret > 0)
> +			return ret - 1;
> +		else
> +			return -EINVAL;
>  	default:
>  		dev_err(dev, "unsupported pinctrl drive type: %d\n", drv_type);
>  		return -EINVAL;
>  	}
>  
>  config:
> +	if (ctrl->type == RK3506) {
> +		if ((bank->bank_num == 0 && pin_num == 24) || bank->bank_num == 4) {
> +			rmask_bits = 2;
> +			ret = strength;
> +		}
> +	}
>  	/* enable the write to the equivalent lower bits */
>  	data = ((1 << rmask_bits) - 1) << (bit + 16);
>  	rmask = data | (data >> 16);
> @@ -2957,6 +3305,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
>  	case RK3328:
>  	case RK3368:
>  	case RK3399:
> +	case RK3506:
>  	case RK3528:
>  	case RK3562:
>  	case RK3568:
> @@ -3077,6 +3426,10 @@ static int rockchip_get_schmitt(struct rockchip_pin_bank *bank, int pin_num)
>  		break;
>  	}
>  
> +	if (ctrl->type == RK3506)
> +		if ((bank->bank_num == 0 && pin_num == 24) ||  bank->bank_num == 4)
> +			return data & 0x3;
> +
>  	return data & 0x1;
>  }
>  
> @@ -3112,6 +3465,14 @@ static int rockchip_set_schmitt(struct rockchip_pin_bank *bank,
>  		break;
>  	}
>  
> +	if (ctrl->type == RK3506) {
> +		if ((bank->bank_num == 0 && pin_num == 24) || bank->bank_num == 4) {
> +			data = 0x3 << (bit + 16);
> +			rmask = data | (data >> 16);
> +			data |= ((enable ? 0x3 : 0) << bit);
> +		}
> +	}
> +
>  	return regmap_update_bits(regmap, reg, rmask, data);
>  }
>  
> @@ -3227,6 +3588,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl,
>  	case RK3328:
>  	case RK3368:
>  	case RK3399:
> +	case RK3506:
>  	case RK3528:
>  	case RK3562:
>  	case RK3568:
> @@ -3880,13 +4242,10 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
>  	}
>  
>  	/* try to find the optional reference to the pmu syscon */
> -	node = of_parse_phandle(np, "rockchip,pmu", 0);
> -	if (node) {
> -		info->regmap_pmu = syscon_node_to_regmap(node);
> -		of_node_put(node);
> -		if (IS_ERR(info->regmap_pmu))
> -			return PTR_ERR(info->regmap_pmu);
> -	}
> +	info->regmap_pmu = syscon_regmap_lookup_by_phandle_optional(np, "rockchip,pmu");
> +
> +	/* try to find the optional reference to the ioc1 syscon */
> +	info->regmap_ioc1 = syscon_regmap_lookup_by_phandle_optional(np, "rockchip,ioc1");
>  
>  	ret = rockchip_pinctrl_register(pdev, info);
>  	if (ret)
> @@ -4350,6 +4709,71 @@ static struct rockchip_pin_ctrl rk3399_pin_ctrl = {
>  		.drv_calc_reg		= rk3399_calc_drv_reg_and_bit,
>  };
>  
> +static struct rockchip_pin_bank rk3506_pin_banks[] = {
> +	PIN_BANK_IOMUX_FLAGS_OFFSET_DRV_FLAGS_PULL_FLAGS(0, 32, "gpio0",
> +				    IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU,
> +				    IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU,
> +				    IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU,
> +				    IOMUX_WIDTH_2BIT | IOMUX_SOURCE_PMU,
> +				    0x0, 0x8, 0x10, 0x830,
> +				    DRV_TYPE_IO_LEVEL_8_BIT,
> +				    DRV_TYPE_IO_LEVEL_8_BIT,
> +				    DRV_TYPE_IO_LEVEL_8_BIT,
> +				    DRV_TYPE_IO_LEVEL_2_BIT,
> +				    0, 0, 0, 1),
> +	PIN_BANK_IOMUX_FLAGS_OFFSET_DRV_FLAGS(1, 32, "gpio1",
> +				    IOMUX_WIDTH_4BIT,
> +				    IOMUX_WIDTH_4BIT,
> +				    IOMUX_WIDTH_4BIT,
> +				    IOMUX_WIDTH_4BIT,
> +				    0x20, 0x28, 0x30, 0x38,
> +				    DRV_TYPE_IO_LEVEL_8_BIT,
> +				    DRV_TYPE_IO_LEVEL_8_BIT,
> +				    DRV_TYPE_IO_LEVEL_8_BIT,
> +				    DRV_TYPE_IO_LEVEL_8_BIT),
> +	PIN_BANK_IOMUX_FLAGS_OFFSET_DRV_FLAGS(2, 32, "gpio2",
> +				    IOMUX_WIDTH_4BIT,
> +				    IOMUX_WIDTH_4BIT,
> +				    IOMUX_WIDTH_4BIT,
> +				    IOMUX_WIDTH_4BIT,
> +				    0x40, 0x48, 0x50, 0x58,
> +				    DRV_TYPE_IO_LEVEL_8_BIT,
> +				    DRV_TYPE_IO_LEVEL_8_BIT,
> +				    DRV_TYPE_IO_LEVEL_8_BIT,
> +				    DRV_TYPE_IO_LEVEL_8_BIT),
> +	PIN_BANK_IOMUX_FLAGS_OFFSET_DRV_FLAGS(3, 32, "gpio3",
> +				    IOMUX_WIDTH_4BIT,
> +				    IOMUX_WIDTH_4BIT,
> +				    IOMUX_WIDTH_4BIT,
> +				    IOMUX_WIDTH_4BIT,
> +				    0x60, 0x68, 0x70, 0x78,
> +				    DRV_TYPE_IO_LEVEL_8_BIT,
> +				    DRV_TYPE_IO_LEVEL_8_BIT,
> +				    DRV_TYPE_IO_LEVEL_8_BIT,
> +				    DRV_TYPE_IO_LEVEL_8_BIT),
> +	PIN_BANK_IOMUX_FLAGS_OFFSET_DRV_FLAGS_PULL_FLAGS(4, 32, "gpio4",
> +				    IOMUX_WIDTH_4BIT,
> +				    IOMUX_WIDTH_4BIT,
> +				    IOMUX_WIDTH_4BIT,
> +				    IOMUX_WIDTH_4BIT,
> +				    0x80, 0x88, 0x90, 0x98,
> +				    DRV_TYPE_IO_LEVEL_2_BIT,
> +				    DRV_TYPE_IO_LEVEL_2_BIT,
> +				    DRV_TYPE_IO_LEVEL_2_BIT,
> +				    DRV_TYPE_IO_LEVEL_2_BIT,
> +				    1, 1, 1, 1),
> +};
> +
> +static struct rockchip_pin_ctrl rk3506_pin_ctrl __maybe_unused = {
> +	.pin_banks		= rk3506_pin_banks,
> +	.nr_banks		= ARRAY_SIZE(rk3506_pin_banks),
> +	.label			= "RK3506-GPIO",
> +	.type			= RK3506,
> +	.pull_calc_reg		= rk3506_calc_pull_reg_and_bit,
> +	.drv_calc_reg		= rk3506_calc_drv_reg_and_bit,
> +	.schmitt_calc_reg	= rk3506_calc_schmitt_reg_and_bit,
> +};
> +
>  static struct rockchip_pin_bank rk3528_pin_banks[] = {
>  	PIN_BANK_IOMUX_FLAGS_OFFSET(0, 32, "gpio0",
>  				    IOMUX_WIDTH_4BIT,
> @@ -4560,6 +4984,8 @@ static const struct of_device_id rockchip_pinctrl_dt_match[] = {
>  		.data = &rk3368_pin_ctrl },
>  	{ .compatible = "rockchip,rk3399-pinctrl",
>  		.data = &rk3399_pin_ctrl },
> +	{ .compatible = "rockchip,rk3506-pinctrl",
> +		.data = &rk3506_pin_ctrl },
>  	{ .compatible = "rockchip,rk3528-pinctrl",
>  		.data = &rk3528_pin_ctrl },
>  	{ .compatible = "rockchip,rk3562-pinctrl",
> diff --git a/drivers/pinctrl/pinctrl-rockchip.h b/drivers/pinctrl/pinctrl-rockchip.h
> index 35cd38079d1e..4f4aff42a80a 100644
> --- a/drivers/pinctrl/pinctrl-rockchip.h
> +++ b/drivers/pinctrl/pinctrl-rockchip.h
> @@ -196,6 +196,7 @@ enum rockchip_pinctrl_type {
>  	RK3328,
>  	RK3368,
>  	RK3399,
> +	RK3506,
>  	RK3528,
>  	RK3562,
>  	RK3568,
> @@ -260,6 +261,8 @@ enum rockchip_pin_drv_type {
>  	DRV_TYPE_IO_1V8_ONLY,
>  	DRV_TYPE_IO_1V8_3V0_AUTO,
>  	DRV_TYPE_IO_3V3_ONLY,
> +	DRV_TYPE_IO_LEVEL_2_BIT,
> +	DRV_TYPE_IO_LEVEL_8_BIT,
>  	DRV_TYPE_MAX
>  };
>  
> @@ -458,6 +461,7 @@ struct rockchip_pinctrl {
>  	int				reg_size;
>  	struct regmap			*regmap_pull;
>  	struct regmap			*regmap_pmu;
> +	struct regmap			*regmap_ioc1;
>  	struct device			*dev;
>  	struct rockchip_pin_ctrl	*ctrl;
>  	struct pinctrl_desc		pctl;
> 






From heiko at sntech.de  Tue Nov  4 03:08:52 2025
From: heiko at sntech.de (Heiko =?UTF-8?B?U3TDvGJuZXI=?=)
Date: Tue, 04 Nov 2025 12:08:52 +0100
Subject: [PATCH v1 3/3] pinctrl: rockchip: add rk3506 rmio support
In-Reply-To: <20251104021223.2375116-4-ye.zhang@rock-chips.com>
References: <20251104021223.2375116-1-ye.zhang@rock-chips.com>
 <20251104021223.2375116-4-ye.zhang@rock-chips.com>
Message-ID: <4419588.mogB4TqSGs@diego>

Am Dienstag, 4. November 2025, 03:12:23 Mitteleurop?ische Normalzeit schrieb Ye Zhang:
> Support rockchip matrix io
> 
> Signed-off-by: Ye Zhang <ye.zhang at rock-chips.com>
> ---
>  drivers/pinctrl/pinctrl-rockchip.c | 75 ++++++++++++++++++++++++++++++
>  drivers/pinctrl/pinctrl-rockchip.h |  1 +
>  2 files changed, 76 insertions(+)

Here I disagree though.

The RMIO controller is a completely separate thing and from what I understand
from the documentation

- you set the pinmux to go to the rmio controller, and then that controller
  selects the function for this pin.

For example pinmux values for gpio0a7_sel are
- 0: GPIO0_A7
- 1: F SAI0_SDI3
- 2: SPI1_CSN1
- 7: RM_IO7

With 7 being the route to the matrix-io controller.


So lumping this into the main pinctrl feels definitly wrong, as then you
create a number of "virtual" pinmuxes where they don't belong.

So instead of trying to bolt this onto the main pinctrl, I'd like things
to be separate ... for the main iomux you route the pin to the rmio
controller and then have a separate configuration for the rmio marix.

bus2: bus2 {
	rockchip,pins = <0 RK_PA0 7 &pcfg_pull_none_drv_8ma>,
		<0 RK_PA1 7 &pcfg_pull_none_drv_8ma>,
		<0 RK_PA2 7 &pcfg_pull_none_drv_8ma>,
		<0 RK_PA3 7 &pcfg_pull_none_drv_8ma>,

	rockchip,rmio-pins {
		/* some way to sanely describe the rmio-config */
		pins = "GPIO0_A0", "GPIO0_A1";
		functions = "i2c0-scl", "i2c0-sda";
	};
};

This is especially true, as each pin in the rmio-controller can have each
function. So gpio0-a0 can be uart1-tx, uart1-rx etc etc ... 98 different
functions according to the documentation.


Heiko

> 
> diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
> index e44ef262beec..89ff8d8c7fcc 100644
> --- a/drivers/pinctrl/pinctrl-rockchip.c
> +++ b/drivers/pinctrl/pinctrl-rockchip.c
> @@ -1258,6 +1258,74 @@ static int rockchip_verify_mux(struct rockchip_pin_bank *bank,
>  	return 0;
>  }
>  
> +static int rockchip_set_rmio(struct rockchip_pin_bank *bank, int pin, int *mux)
> +{
> +	struct rockchip_pinctrl *info = bank->drvdata;
> +	struct rockchip_pin_ctrl *ctrl = info->ctrl;
> +	struct regmap *regmap;
> +	int reg, function;
> +	u32 data, rmask;
> +	int ret = 0;
> +	int iomux_num = (pin / 8);
> +	u32 iomux_max, mux_type;
> +
> +	mux_type = bank->iomux[iomux_num].type;
> +	if (mux_type & IOMUX_WIDTH_4BIT)
> +		iomux_max = (1 << 4) - 1;
> +	else if (mux_type & IOMUX_WIDTH_3BIT)
> +		iomux_max = (1 << 3) - 1;
> +	else
> +		iomux_max = (1 << 2) - 1;
> +
> +	if (*mux > iomux_max)
> +		function = *mux - iomux_max;
> +	else
> +		return 0;
> +
> +	switch (ctrl->type) {
> +	case RK3506:
> +		regmap = info->regmap_rmio;
> +		if (bank->bank_num == 0) {
> +			if (pin < 24)
> +				reg = 0x80 + 0x4 * pin;
> +			else
> +				ret = -EINVAL;
> +		} else if (bank->bank_num == 1) {
> +			if (pin >= 9 && pin <= 11)
> +				reg = 0xbc + 0x4 * pin;
> +			else if (pin >= 18 && pin <= 19)
> +				reg = 0xa4 + 0x4 * pin;
> +			else if (pin >= 25 && pin <= 27)
> +				reg = 0x90 + 0x4 * pin;
> +			else
> +				ret = -EINVAL;
> +		} else {
> +			ret = -EINVAL;
> +		}
> +
> +		if (ret) {
> +			dev_err(info->dev,
> +				"rmio unsupported bank_num %d function %d\n",
> +				bank->bank_num, function);
> +
> +			return -EINVAL;
> +		}
> +
> +		rmask = 0x7f007f;
> +		data = 0x7f0000 | function;
> +		*mux = 7;
> +		ret = regmap_update_bits(regmap, reg, rmask, data);
> +		if (ret)
> +			return ret;
> +		break;
> +
> +	default:
> +		break;
> +	}
> +
> +	return 0;
> +}
> +
>  /*
>   * Set a new mux function for a pin.
>   *
> @@ -1291,6 +1359,10 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
>  
>  	dev_dbg(dev, "setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux);
>  
> +	ret = rockchip_set_rmio(bank, pin, &mux);
> +	if (ret)
> +		return ret;
> +
>  	if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
>  		regmap = info->regmap_pmu;
>  	else if (bank->iomux[iomux_num].type & IOMUX_L_SOURCE_PMU)
> @@ -4247,6 +4319,9 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
>  	/* try to find the optional reference to the ioc1 syscon */
>  	info->regmap_ioc1 = syscon_regmap_lookup_by_phandle_optional(np, "rockchip,ioc1");
>  
> +	/* try to find the optional reference to the rmio syscon */
> +	info->regmap_rmio = syscon_regmap_lookup_by_phandle_optional(np, "rockchip,rmio");
> +
>  	ret = rockchip_pinctrl_register(pdev, info);
>  	if (ret)
>  		return ret;
> diff --git a/drivers/pinctrl/pinctrl-rockchip.h b/drivers/pinctrl/pinctrl-rockchip.h
> index 4f4aff42a80a..6d79ccf73b71 100644
> --- a/drivers/pinctrl/pinctrl-rockchip.h
> +++ b/drivers/pinctrl/pinctrl-rockchip.h
> @@ -462,6 +462,7 @@ struct rockchip_pinctrl {
>  	struct regmap			*regmap_pull;
>  	struct regmap			*regmap_pmu;
>  	struct regmap			*regmap_ioc1;
> +	struct regmap			*regmap_rmio;
>  	struct device			*dev;
>  	struct rockchip_pin_ctrl	*ctrl;
>  	struct pinctrl_desc		pctl;
> 






From cassel at kernel.org  Tue Nov  4 04:30:28 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Tue, 4 Nov 2025 13:30:28 +0100
Subject: [PATCH v3] PCI: dw-rockchip: Prevent advertising L1 Substates
 support
In-Reply-To: <aaug44bngs5amid7un4plotcjpbc6ym44cztnhet7z44ybywgc@apzhg6enhxgy>
References: <20251017164558.GA1034609@bhelgaas>
 <54FD6159-AE45-432B-8F0E-4654721D16A6@kernel.org>
 <aaug44bngs5amid7un4plotcjpbc6ym44cztnhet7z44ybywgc@apzhg6enhxgy>
Message-ID: <aQnx5KZSQuBniEv-@ryzen>

Hello Mani,

On Tue, Oct 21, 2025 at 08:02:01AM +0530, Manivannan Sadhasivam wrote:
> On Sat, Oct 18, 2025 at 07:07:35AM +0200, Niklas Cassel wrote:
> > On 17 October 2025 18:45:58 CEST, Bjorn Helgaas <helgaas at kernel.org> wrote:
> > 
> > (snip)
> > 
> > >> 
> > >> Thus, prevent advertising L1 Substates support until proper driver support
> > >> is added.
> > >
> > >I think Mani is planning a change so we don't try to enable L1
> > >Substates by default, which should avoid the regression even without a
> > >patch like this.
> > 
> > Sounds good, I suggested the same:
> > https://lore.kernel.org/linux-pci/aO9tWjgHnkATroNa at ryzen/
> > 
> > 
> > >
> > >That will still leave the existing CONFIG_PCIEASPM_POWER_SUPERSAVE=y
> > >and sysfs l1_1_aspm problems.
> > 
> > Indeed, which is why I think that this patch is v6.18 material.
> > 
> 
> Not strictly a 6.18 material as the Kconfig/sysfs/cmdline issues existed even
> before we enabled the ASPM states by default in v6.18-rc1.

I don't agree that "strictly 6.18 material" means "only fixes for bugs
introduced in the 6.18 merge window".

Normally, for a strict bug fix, the fix is merged during the current
kernel release cycle (rather than waiting for the next merge window),
even if the bug was introduced in an earlier kernel version.

E.g. a fix for a bug introduced during the 6.17 release cycle is
definitely 6.18 material, IMO.

Sure, if the bug is extremely old, that probably means that it is okay
to wait until the next merge window.

In this case, the Fixes tag is a commit first introduced in kernel v5.15,
released Sun Oct 31 13:53:10 2021.

Having that said, I'm perfectly fine with delaying.


Kind regards,
Niklas


From cassel at kernel.org  Tue Nov  4 04:53:24 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Tue, 4 Nov 2025 13:53:24 +0100
Subject: [PATCH v3] PCI: dw-rockchip: Prevent advertising L1 Substates
 support
In-Reply-To: <20251103213206.GA1818418@bhelgaas>
References: <20251028190218.GA1525614@bhelgaas>
 <20251103213206.GA1818418@bhelgaas>
Message-ID: <aQn3RGrJi1lb0EO1@ryzen>

Hello Bjorn,

On Mon, Nov 03, 2025 at 03:32:06PM -0600, Bjorn Helgaas wrote:
> On Tue, Oct 28, 2025 at 02:02:18PM -0500, Bjorn Helgaas wrote:
> > On Fri, Oct 17, 2025 at 06:32:53PM +0200, Niklas Cassel wrote:
> > > The L1 substates support requires additional steps to work, namely:
> > > -Proper handling of the CLKREQ# sideband signal. (It is mostly handled by
> > >  hardware, but software still needs to set the clkreq fields in the
> > >  PCIE_CLIENT_POWER_CON register to match the hardware implementation.)
> > > -Program the frequency of the aux clock into the
> > >  DSP_PCIE_PL_AUX_CLK_FREQ_OFF register. (During L1 substates the core_clk
> > >  is turned off and the aux_clk is used instead.)
> > ...
> 
> > > +static void rockchip_pcie_disable_l1sub(struct dw_pcie *pci)
> > > +{
> > > +	u32 cap, l1subcap;
> > > +
> > > +	cap = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_L1SS);
> > > +	if (cap) {
> > > +		l1subcap = dw_pcie_readl_dbi(pci, cap + PCI_L1SS_CAP);
> > > +		l1subcap &= ~(PCI_L1SS_CAP_L1_PM_SS | PCI_L1SS_CAP_ASPM_L1_1 |
> > > +			      PCI_L1SS_CAP_ASPM_L1_2 | PCI_L1SS_CAP_PCIPM_L1_1 |
> > > +			      PCI_L1SS_CAP_PCIPM_L1_2);
> > > +		dw_pcie_writel_dbi(pci, cap + PCI_L1SS_CAP, l1subcap);
> > > +	}
> > > +}
> > 
> > I like this.  But why should we do it just for dw-rockchip?  Is there
> > something special about dw-rockchip that makes this a problem?  Maybe
> > we should consider doing this in the dwc, cadence, mobiveil, and plda
> > cores instead of trying to do it for every driver individually?
> > 
> > Advertising L1SS support via PCI_EXT_CAP_ID_L1SS means users can
> > enable L1SS via CONFIG_PCIEASPM_POWER_SUPERSAVE=y or sysfs, and that
> > seems likely to cause problems unless CLKREQ# is supported.
> 
> Any thoughts on this?  There's nothing rockchip-specific in this
> patch.  What I'm proposing is something like this:
> 
>     PCI: dwc: Prevent advertising L1 PM Substates
>     
>     L1 PM Substates require the CLKREF# signal and driver-specific support.  If
>     CLKREF# is not supported or the driver support is lacking, enabling L1.1 or
>     L1.2 may cause errors when accessing devices, e.g.,
>     
>       nvme nvme0: controller is down; will reset: CSTS=0xffffffff, PCI_STATUS=0x10
>     
>     If both ends of a link advertise support for L1 PM Substates, and the
>     kernel is built with CONFIG_PCIEASPM_POWER_SUPERSAVE=y or users enable L1.x
>     via sysfs, Linux tries to enable them.
>     
>     To prevent errors when L1.x may not work, disable advertising the L1 PM
>     Substates.  Drivers can enable advertising them if they know CLKREF# is
>     present and the Root Port is configured correctly.
>     
>     Based on Niklas's patch from
>     https://patch.msgid.link/20251017163252.598812-2-cassel at kernel.org
> 
> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> index 20c9333bcb1c..83b5330c9e45 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -950,6 +950,27 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
>  	return 0;
>  }
>  
> +static void dw_pcie_clear_l1ss_advert(struct dw_pcie_rp *pp)
> +{
> +	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> +	u16 l1ss;
> +	u32 l1ss_cap;
> +
> +	l1ss = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_L1SS);
> +	if (!l1ss)
> +		return;
> +
> +	/*
> +	 * By default, don't advertise L1 PM Substates because they require
> +	 * CLKREF# and other driver-specific support.
> +	 */
> +	l1ss_cap = dw_pcie_readl_dbi(pci, l1ss + PCI_L1SS_CAP);
> +	l1ss_cap &= ~(PCI_L1SS_CAP_PCIPM_L1_1 | PCI_L1SS_CAP_ASPM_L1_1 |
> +		      PCI_L1SS_CAP_PCIPM_L1_2 | PCI_L1SS_CAP_ASPM_L1_2 |
> +		      PCI_L1SS_CAP_L1_PM_SS);
> +	dw_pcie_writel_dbi(pci, l1ss + PCI_L1SS_CAP, l1ss_cap);
> +}
> +
>  static void dw_pcie_program_presets(struct dw_pcie_rp *pp, enum pci_bus_speed speed)
>  {
>  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> @@ -1060,6 +1081,7 @@ int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
>  		PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
>  	dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
>  
> +	dw_pcie_clear_l1ss_advert(pp);
>  	dw_pcie_config_presets(pp);
>  	/*
>  	 * If the platform provides its own child bus config accesses, it means

My patch disables L1 substates when running the controller in both root
complex mode and endpoint mode.

Your patch above only disables L1 substates when running the the controller
in root complex mode.

I think this code has to be in pcie-designware.c and then e.g.
dw_pcie_setup_rc() (pcie-designware-host.c) and
dw_pcie_ep_init_registers() (pcie-designware-ep.c) can both use it.


And like Shawn mentions. Disabling it by default for all DWC based
platforms could introduce regressions where L1 substates already is working
fine.

Sure, the only driver that checks for the DT property 'supports-clkreq' is
drivers/pci/controller/dwc/pcie-tegra194.c. However Mani claimed that the
qcom driver also has support for L1 substates already, even though it does
not check the 'supports-clkreq' DT property.


Kind regards,
Niklas


From krzk at kernel.org  Tue Nov  4 06:06:29 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 4 Nov 2025 15:06:29 +0100
Subject: [PATCH v1 1/3] dt-bindings: pinctrl: Add rk3506 pinctrl support
In-Reply-To: <20251104021223.2375116-2-ye.zhang@rock-chips.com>
References: <20251104021223.2375116-1-ye.zhang@rock-chips.com>
 <20251104021223.2375116-2-ye.zhang@rock-chips.com>
Message-ID: <20251104-successful-smilodon-of-symmetry-3ecddf@kuoka>

On Tue, Nov 04, 2025 at 10:12:21AM +0800, Ye Zhang wrote:
> Add the compatible string for the rk3506 SoC.
> 
> Signed-off-by: Ye Zhang <ye.zhang at rock-chips.com>
> ---
>  Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.yaml | 1 +
>  1 file changed, 1 insertion(+)

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From cassel at kernel.org  Tue Nov  4 07:00:08 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Tue, 4 Nov 2025 16:00:08 +0100
Subject: [PATCH v5 1/2] PCI: Configure root port MPS during host probing
In-Reply-To: <aLlmV8Qiaph1PHFY@ryzen>
References: <20250620155507.1022099-2-18255117159@163.com>
 <20250902174828.GA1165373@bhelgaas>
 <aLlmV8Qiaph1PHFY@ryzen>
Message-ID: <aQoU-JhWz6IYTpGi@ryzen>

Hello Hans,

Any chance that you have time to re-spin this series?

I've seen some new DWC based drivers like NXP that also want to
configure MPS.

Most likely we know the reason... The PCI core does not change it
without this series.


Kind regards,
Niklas

On Thu, Sep 04, 2025 at 12:13:43PM +0200, Niklas Cassel wrote:
> On Tue, Sep 02, 2025 at 12:48:28PM -0500, Bjorn Helgaas wrote:
> > On Fri, Jun 20, 2025 at 11:55:06PM +0800, Hans Zhang wrote:
> > > Current PCIe initialization logic may leave root ports operating with
> > > non-optimal Maximum Payload Size (MPS) settings. While downstream device
> > > configuration is handled during bus enumeration, root port MPS values
> > > inherited from firmware or hardware defaults ...
> > 
> > Apparently Root Port MPS configuration is different from that for
> > downstream devices?
> 
> pci_host_probe() will call pci_scan_root_bus_bridge(), which will call
> pci_scan_single_device(), which will call pci_device_add(), which will
> call pci_configure_device(), which will call pci_configure_mps().
> 
> This will be done for both bridges and endpoints.
> 
> The bridge will be scanned/added first, before devices behind the bridge.
> 
> 
> While pci_configure_device()/pci_configure_mps() will be called for both
> bridges and endpoints, pci_configure_mps() will do an early return for
> devices where pci_upstream_bridge() returns NULL, i.e. for devices where
> that does not have an upstream bridge, i.e. for the root bridge itself:
> https://github.com/torvalds/linux/blob/v6.17-rc4/drivers/pci/probe.c#L2181-L2182
> 
> So MPS will not be touched for root bridges.
> 
> This patch ensures that MPS for root bridges gets initialized to MPSS
> (Max supported MPS).
> 
> Later, when pci_configure_device()/pci_configure_mps() is called for a
> device behind the bridge, if the MPSS of the device behind the bridge is
> smaller than the MPS of the bridge, the code reduces the MPS of the bridge:
> https://github.com/torvalds/linux/blob/v6.17-rc4/drivers/pci/probe.c#L2205
> 
> 
> My only question with this patch is if there is a bridge behind a bridge,
> will the bridge behind the bridge still have pci_pcie_type() ==
> PCI_EXP_TYPE_ROOT_PORT ?
> 
> If so, perhaps we should modify this patch from:
> 
> +       if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT &&
> +           pcie_bus_config != PCIE_BUS_TUNE_OFF) {
> +               pcie_write_mps(dev, 128 << dev->pcie_mpss);
> +       }
> +
>         if (!bridge || !pci_is_pcie(bridge))
>                 return;
> 
> 
> to:
> 
> +       if (!bridge && pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT &&
> +           pcie_bus_config != PCIE_BUS_TUNE_OFF) {
> +               pcie_write_mps(dev, 128 << dev->pcie_mpss);
> +       }
> +
>         if (!bridge || !pci_is_pcie(bridge))
>                 return;
> 
> 
> 
> > > During host controller probing phase, when PCIe bus tuning is enabled,
> > > the implementation now configures root port MPS settings to their
> > > hardware-supported maximum values. Specifically, when configuring the MPS
> > > for a PCIe device, if the device is a root port and the bus tuning is not
> > > disabled (PCIE_BUS_TUNE_OFF), the MPS is set to 128 << dev->pcie_mpss to
> > > match the Root Port's maximum supported payload size. The Max Read Request
> > > Size (MRRS) is subsequently adjusted through existing companion logic to
> > > maintain compatibility with PCIe specifications.
> > > 
> > > Note that this initial setting of the root port MPS to the maximum might
> > > be reduced later during the enumeration of downstream devices if any of
> > > those devices do not support the maximum MPS of the root port.
> > > 
> > > Explicit initialization at host probing stage ensures consistent PCIe
> > > topology configuration before downstream devices perform their own MPS
> > > negotiations. This proactive approach addresses platform-specific
> > > requirements where controller drivers depend on properly initialized
> > > root port settings, while maintaining backward compatibility through
> > > PCIE_BUS_TUNE_OFF conditional checks. Hardware capabilities are fully
> > > utilized without altering existing device negotiation behaviors.
> > 
> > This last paragraph seems kind of like marketing without any real
> > content.  Is there something important in there?
> > 
> > Nits:
> > s/root port/Root Port/
> > 
> > Reword "implementation now configures" to be clear about whether "now"
> > refers to before this patch or after.
> > 
> > Update the MRRS "to maintain compatibility" part.  I'm dubious about
> > there being a spec compatibility issue with respect to MRRS.  Cite the
> > relevant section if there is an issue.
> 
> I'm not sure why the commit message mentions MRRS at all.
> 
> Sure, pcie_write_mrrs() might set MRRS to MPS, but that is existing logic
> and not really related to the change in this patch IMO.
> 
> 
> Kind regards,
> Niklas


From nicolas.dufresne at collabora.com  Tue Nov  4 08:07:08 2025
From: nicolas.dufresne at collabora.com (Nicolas Dufresne)
Date: Tue, 04 Nov 2025 11:07:08 -0500
Subject: [PATCH v4 02/15] media: v4l2-ctrls: Add hevc_ext_sps_[ls]t_rps
 controls
In-Reply-To: <6eaa8b26-edab-4bfa-9c6a-1fbb54c36b4e@kernel.org>
References: <20251022174508.284929-1-detlev.casanova@collabora.com>
	 <20251022174508.284929-3-detlev.casanova@collabora.com>
	 <6eaa8b26-edab-4bfa-9c6a-1fbb54c36b4e@kernel.org>
Message-ID: <b4c041d6603fcc107c466bd1ed8c402c96aef5e1.camel@collabora.com>

Hi,

Le jeudi 23 octobre 2025 ? 10:04 +0200, Hans Verkuil a ?crit?:
> On 22/10/2025 19:44, Detlev Casanova wrote:
> > The vdpu381 decoder found on newer Rockchip SoC need the information
> > from the long term and short term ref pic sets from the SPS.
> > 
> > So far, it wasn't included in the v4l2 API, so add it with new dynamic
> > sized controls.
> > 
> > Each element of the hevc_ext_sps_lt_rps array contains the long term ref
> > pic set at that index.
> > Each element of the hevc_ext_sps_st_rps contains the short term ref pic
> > set at that index, as the raw data.
> > It is the role of the drivers to calculate the reference sets values.
> > 
> > Signed-off-by: Detlev Casanova <detlev.casanova at collabora.com>
> > ---
> > ?drivers/media/v4l2-core/v4l2-ctrls-core.c | 18 +++++++
> > ?drivers/media/v4l2-core/v4l2-ctrls-defs.c | 10 ++++
> > ?include/uapi/linux/v4l2-controls.h??????? | 61 +++++++++++++++++++++++
> > ?include/uapi/linux/videodev2.h??????????? |? 2 +
> > ?4 files changed, 91 insertions(+)
> > 
> > diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c
> > index 7c660cd61e48..b330bd7719e9 100644
> > --- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
> > +++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
> > @@ -418,6 +418,12 @@ void v4l2_ctrl_type_op_log(const struct v4l2_ctrl *ctrl)
> > ?	case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS:
> > ?		pr_cont("HEVC_SLICE_PARAMS");
> > ?		break;
> > +	case V4L2_CTRL_TYPE_HEVC_EXT_SPS_ST_RPS:
> > +		pr_cont("HEVC_EXT_SPS_ST_RPS");
> > +		break;
> > +	case V4L2_CTRL_TYPE_HEVC_EXT_SPS_LT_RPS:
> > +		pr_cont("HEVC_EXT_SPS_LT_RPS");
> > +		break;
> > ?	case V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX:
> > ?		pr_cont("HEVC_SCALING_MATRIX");
> > ?		break;
> > @@ -1248,6 +1254,12 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
> > ?	case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS:
> > ?		break;
> > ?
> > +	case V4L2_CTRL_TYPE_HEVC_EXT_SPS_ST_RPS:
> > +		break;
> > +
> > +	case V4L2_CTRL_TYPE_HEVC_EXT_SPS_LT_RPS:
> > +		break;
> > +
> 
> There is nothing to validate here? Any value is fine? Just checking...
> 
> Is this something that should be added to the visl driver so it is tested during regression
> tests? Or does this not apply to visl?
> 
> I haven't looked in-depth into this, but I wondered about it.

Seems appropriate to add to VISL.

Nicolas

> 
> Regards,
> 
> 	Hans
> 
> > ?	case V4L2_CTRL_TYPE_HDR10_CLL_INFO:
> > ?		break;
> > ?
> > @@ -2000,6 +2012,12 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
> > ?	case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS:
> > ?		elem_size = sizeof(struct v4l2_ctrl_hevc_slice_params);
> > ?		break;
> > +	case V4L2_CTRL_TYPE_HEVC_EXT_SPS_ST_RPS:
> > +		elem_size = sizeof(struct v4l2_ctrl_hevc_ext_sps_st_rps);
> > +		break;
> > +	case V4L2_CTRL_TYPE_HEVC_EXT_SPS_LT_RPS:
> > +		elem_size = sizeof(struct v4l2_ctrl_hevc_ext_sps_lt_rps);
> > +		break;
> > ?	case V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX:
> > ?		elem_size = sizeof(struct v4l2_ctrl_hevc_scaling_matrix);
> > ?		break;
> > diff --git a/drivers/media/v4l2-core/v4l2-ctrls-defs.c b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
> > index ad41f65374e2..167286c9e424 100644
> > --- a/drivers/media/v4l2-core/v4l2-ctrls-defs.c
> > +++ b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
> > @@ -1233,6 +1233,8 @@ const char *v4l2_ctrl_get_name(u32 id)
> > ?	case V4L2_CID_STATELESS_HEVC_DECODE_MODE:		return "HEVC Decode Mode";
> > ?	case V4L2_CID_STATELESS_HEVC_START_CODE:		return "HEVC Start Code";
> > ?	case V4L2_CID_STATELESS_HEVC_ENTRY_POINT_OFFSETS:	return "HEVC Entry Point Offsets";
> > +	case V4L2_CID_STATELESS_HEVC_EXT_SPS_ST_RPS:		return "HEVC Short Term Ref Sets";
> > +	case V4L2_CID_STATELESS_HEVC_EXT_SPS_LT_RPS:		return "HEVC Long Term Ref Sets";
> > ?	case V4L2_CID_STATELESS_AV1_SEQUENCE:			return "AV1 Sequence Parameters";
> > ?	case V4L2_CID_STATELESS_AV1_TILE_GROUP_ENTRY:		return "AV1 Tile Group Entry";
> > ?	case V4L2_CID_STATELESS_AV1_FRAME:			return "AV1 Frame Parameters";
> > @@ -1578,6 +1580,14 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
> > ?		*type = V4L2_CTRL_TYPE_U32;
> > ?		*flags |= V4L2_CTRL_FLAG_DYNAMIC_ARRAY;
> > ?		break;
> > +	case V4L2_CID_STATELESS_HEVC_EXT_SPS_ST_RPS:
> > +		*type = V4L2_CTRL_TYPE_HEVC_EXT_SPS_ST_RPS;
> > +		*flags |= V4L2_CTRL_FLAG_DYNAMIC_ARRAY;
> > +		break;
> > +	case V4L2_CID_STATELESS_HEVC_EXT_SPS_LT_RPS:
> > +		*type = V4L2_CTRL_TYPE_HEVC_EXT_SPS_LT_RPS;
> > +		*flags |= V4L2_CTRL_FLAG_DYNAMIC_ARRAY;
> > +		break;
> > ?	case V4L2_CID_STATELESS_VP9_COMPRESSED_HDR:
> > ?		*type = V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR;
> > ?		break;
> > diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
> > index 2d30107e047e..dd9e29afa155 100644
> > --- a/include/uapi/linux/v4l2-controls.h
> > +++ b/include/uapi/linux/v4l2-controls.h
> > @@ -2093,6 +2093,8 @@ struct v4l2_ctrl_mpeg2_quantisation {
> > ?#define V4L2_CID_STATELESS_HEVC_DECODE_MODE	(V4L2_CID_CODEC_STATELESS_BASE + 405)
> > ?#define V4L2_CID_STATELESS_HEVC_START_CODE	(V4L2_CID_CODEC_STATELESS_BASE + 406)
> > ?#define V4L2_CID_STATELESS_HEVC_ENTRY_POINT_OFFSETS (V4L2_CID_CODEC_STATELESS_BASE + 407)
> > +#define V4L2_CID_STATELESS_HEVC_EXT_SPS_ST_RPS? (V4L2_CID_CODEC_STATELESS_BASE + 408)
> > +#define V4L2_CID_STATELESS_HEVC_EXT_SPS_LT_RPS? (V4L2_CID_CODEC_STATELESS_BASE + 409)
> > ?
> > ?enum v4l2_stateless_hevc_decode_mode {
> > ?	V4L2_STATELESS_HEVC_DECODE_MODE_SLICE_BASED,
> > @@ -2548,6 +2550,65 @@ struct v4l2_ctrl_hevc_scaling_matrix {
> > ?	__u8	scaling_list_dc_coef_32x32[2];
> > ?};
> > ?
> > +#define V4L2_HEVC_EXT_SPS_ST_RPS_FLAG_INTER_REF_PIC_SET_PRED	0x1
> > +
> > +/*
> > + * struct v4l2_ctrl_hevc_ext_sps_st_rps - HEVC short term RPS parameters
> > + *
> > + * Dynamic size 1-dimension array for short term RPS. The number of elements
> > + * is v4l2_ctrl_hevc_sps::num_short_term_ref_pic_sets. It can contain up to 65 elements.
> > + *
> > + * @delta_idx_minus1: Specifies the delta compare to the index. See details in section 7.4.8
> > + *??????????????????? "Short-term reference picture set semantics" of the specification.
> > + * @delta_rps_sign: Sign of the delta as specified in section 7.4.8 "Short-term reference picture
> > + *????????????????? set semantics" of the specification.
> > + * @abs_delta_rps_minus1: Absolute delta RPS as specified in section 7.4.8 "Short-term reference
> > + *??????????????????????? picture set semantics" of the specification.
> > + * @num_negative_pics: Number of short-term RPS entries that have picture order count values less
> > + *???????????????????? than the picture order count value of the current picture.
> > + * @num_positive_pics: Number of short-term RPS entries that have picture order count values
> > + *???????????????????? greater than the picture order count value of the current picture.
> > + * @used_by_curr_pic: Bit j specifies if short-term RPS j is used by the current picture.
> > + * @use_delta_flag: Bit j equals to 1 specifies that the j-th entry in the source candidate
> > + *????????????????? short-term RPS is included in this candidate short-term RPS.
> > + * @delta_poc_s0_minus1: Specifies the negative picture order count delta for the i-th entry in
> > + *?????????????????????? the short-term RPS. See details in section 7.4.8 "Short-term reference
> > + *?????????????????????? picture set semantics" of the specification.
> > + * @delta_poc_s1_minus1: Specifies the positive picture order count delta for the i-th entry in
> > + *?????????????????????? the short-term RPS. See details in section 7.4.8 "Short-term reference
> > + *?????????????????????? picture set semantics" of the specification.
> > + * @flags: See V4L2_HEVC_EXT_SPS_ST_RPS_FLAG_{}
> > + */
> > +struct v4l2_ctrl_hevc_ext_sps_st_rps {
> > +	__u8	delta_idx_minus1;
> > +	__u8	delta_rps_sign;
> > +	__u16	abs_delta_rps_minus1;
> > +	__u8	num_negative_pics;
> > +	__u8	num_positive_pics;
> > +	__u32	used_by_curr_pic;
> > +	__u32	use_delta_flag;
> > +	__u16	delta_poc_s0_minus1[16];
> > +	__u16	delta_poc_s1_minus1[16];
> > +	__u8	flags;
> > +};
> > +
> > +#define V4L2_HEVC_EXT_SPS_LT_RPS_FLAG_USED_LT		0x1
> > +
> > +/*
> > + * struct v4l2_ctrl_hevc_ext_sps_lt_rps - HEVC long term RPS parameters
> > + *
> > + * Dynamic size 1-dimension array for long term RPS. The number of elements
> > + * is v4l2_ctrl_hevc_sps::num_long_term_ref_pics_sps. It can contain up to 65 elements.
> > + *
> > + * @lt_ref_pic_poc_lsb_sps: picture order count modulo MaxPicOrderCntLsb of the i-th candidate
> > + *????????????????????????? long-term reference picture.
> > + * @flags: See V4L2_HEVC_EXT_SPS_LT_RPS_FLAG_{}
> > + */
> > +struct v4l2_ctrl_hevc_ext_sps_lt_rps {
> > +	__u16	lt_ref_pic_poc_lsb_sps;
> > +	__u8	flags;
> > +};
> > +
> > ?/* Stateless VP9 controls */
> > ?
> > ?#define V4L2_VP9_LOOP_FILTER_FLAG_DELTA_ENABLED	0x1
> > diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
> > index becd08fdbddb..ae1d33fd37b7 100644
> > --- a/include/uapi/linux/videodev2.h
> > +++ b/include/uapi/linux/videodev2.h
> > @@ -1981,6 +1981,8 @@ enum v4l2_ctrl_type {
> > ?	V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS	= 0x0272,
> > ?	V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX	= 0x0273,
> > ?	V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS	= 0x0274,
> > +	V4L2_CTRL_TYPE_HEVC_EXT_SPS_ST_RPS	= 0x0275,
> > +	V4L2_CTRL_TYPE_HEVC_EXT_SPS_LT_RPS	= 0x0276,
> > ?
> > ?	V4L2_CTRL_TYPE_AV1_SEQUENCE	??? = 0x280,
> > ?	V4L2_CTRL_TYPE_AV1_TILE_GROUP_ENTRY = 0x281,
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251104/8bf420a9/attachment-0001.sig>

From 18255117159 at 163.com  Tue Nov  4 08:32:14 2025
From: 18255117159 at 163.com (Hans Zhang)
Date: Wed, 5 Nov 2025 00:32:14 +0800
Subject: [PATCH v5 1/2] PCI: Configure root port MPS during host probing
In-Reply-To: <aQoU-JhWz6IYTpGi@ryzen>
References: <20250620155507.1022099-2-18255117159@163.com>
 <20250902174828.GA1165373@bhelgaas> <aLlmV8Qiaph1PHFY@ryzen>
 <aQoU-JhWz6IYTpGi@ryzen>
Message-ID: <161d6789-4e7f-456a-91ed-9ef682187eae@163.com>



On 2025/11/4 23:00, Niklas Cassel wrote:
> Hello Hans,
> 
> Any chance that you have time to re-spin this series?
> 
> I've seen some new DWC based drivers like NXP that also want to
> configure MPS.
> 
> Most likely we know the reason... The PCI core does not change it
> without this series.
> 

Hi Niklas,

I will modify a version based on Bjorn and your opinions and then send 
it out.

Best regards,
Hans

> 
> Kind regards,
> Niklas
> 
> On Thu, Sep 04, 2025 at 12:13:43PM +0200, Niklas Cassel wrote:
>> On Tue, Sep 02, 2025 at 12:48:28PM -0500, Bjorn Helgaas wrote:
>>> On Fri, Jun 20, 2025 at 11:55:06PM +0800, Hans Zhang wrote:
>>>> Current PCIe initialization logic may leave root ports operating with
>>>> non-optimal Maximum Payload Size (MPS) settings. While downstream device
>>>> configuration is handled during bus enumeration, root port MPS values
>>>> inherited from firmware or hardware defaults ...
>>>
>>> Apparently Root Port MPS configuration is different from that for
>>> downstream devices?
>>
>> pci_host_probe() will call pci_scan_root_bus_bridge(), which will call
>> pci_scan_single_device(), which will call pci_device_add(), which will
>> call pci_configure_device(), which will call pci_configure_mps().
>>
>> This will be done for both bridges and endpoints.
>>
>> The bridge will be scanned/added first, before devices behind the bridge.
>>
>>
>> While pci_configure_device()/pci_configure_mps() will be called for both
>> bridges and endpoints, pci_configure_mps() will do an early return for
>> devices where pci_upstream_bridge() returns NULL, i.e. for devices where
>> that does not have an upstream bridge, i.e. for the root bridge itself:
>> https://github.com/torvalds/linux/blob/v6.17-rc4/drivers/pci/probe.c#L2181-L2182
>>
>> So MPS will not be touched for root bridges.
>>
>> This patch ensures that MPS for root bridges gets initialized to MPSS
>> (Max supported MPS).
>>
>> Later, when pci_configure_device()/pci_configure_mps() is called for a
>> device behind the bridge, if the MPSS of the device behind the bridge is
>> smaller than the MPS of the bridge, the code reduces the MPS of the bridge:
>> https://github.com/torvalds/linux/blob/v6.17-rc4/drivers/pci/probe.c#L2205
>>
>>
>> My only question with this patch is if there is a bridge behind a bridge,
>> will the bridge behind the bridge still have pci_pcie_type() ==
>> PCI_EXP_TYPE_ROOT_PORT ?
>>
>> If so, perhaps we should modify this patch from:
>>
>> +       if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT &&
>> +           pcie_bus_config != PCIE_BUS_TUNE_OFF) {
>> +               pcie_write_mps(dev, 128 << dev->pcie_mpss);
>> +       }
>> +
>>          if (!bridge || !pci_is_pcie(bridge))
>>                  return;
>>
>>
>> to:
>>
>> +       if (!bridge && pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT &&
>> +           pcie_bus_config != PCIE_BUS_TUNE_OFF) {
>> +               pcie_write_mps(dev, 128 << dev->pcie_mpss);
>> +       }
>> +
>>          if (!bridge || !pci_is_pcie(bridge))
>>                  return;
>>
>>
>>
>>>> During host controller probing phase, when PCIe bus tuning is enabled,
>>>> the implementation now configures root port MPS settings to their
>>>> hardware-supported maximum values. Specifically, when configuring the MPS
>>>> for a PCIe device, if the device is a root port and the bus tuning is not
>>>> disabled (PCIE_BUS_TUNE_OFF), the MPS is set to 128 << dev->pcie_mpss to
>>>> match the Root Port's maximum supported payload size. The Max Read Request
>>>> Size (MRRS) is subsequently adjusted through existing companion logic to
>>>> maintain compatibility with PCIe specifications.
>>>>
>>>> Note that this initial setting of the root port MPS to the maximum might
>>>> be reduced later during the enumeration of downstream devices if any of
>>>> those devices do not support the maximum MPS of the root port.
>>>>
>>>> Explicit initialization at host probing stage ensures consistent PCIe
>>>> topology configuration before downstream devices perform their own MPS
>>>> negotiations. This proactive approach addresses platform-specific
>>>> requirements where controller drivers depend on properly initialized
>>>> root port settings, while maintaining backward compatibility through
>>>> PCIE_BUS_TUNE_OFF conditional checks. Hardware capabilities are fully
>>>> utilized without altering existing device negotiation behaviors.
>>>
>>> This last paragraph seems kind of like marketing without any real
>>> content.  Is there something important in there?
>>>
>>> Nits:
>>> s/root port/Root Port/
>>>
>>> Reword "implementation now configures" to be clear about whether "now"
>>> refers to before this patch or after.
>>>
>>> Update the MRRS "to maintain compatibility" part.  I'm dubious about
>>> there being a spec compatibility issue with respect to MRRS.  Cite the
>>> relevant section if there is an issue.
>>
>> I'm not sure why the commit message mentions MRRS at all.
>>
>> Sure, pcie_write_mrrs() might set MRRS to MPS, but that is existing logic
>> and not really related to the change in this patch IMO.
>>
>>
>> Kind regards,
>> Niklas



From 18255117159 at 163.com  Tue Nov  4 08:51:25 2025
From: 18255117159 at 163.com (Hans Zhang)
Date: Wed,  5 Nov 2025 00:51:25 +0800
Subject: [PATCH v6 2/2] PCI: dwc: Remove redundant MPS configuration
In-Reply-To: <20251104165125.174168-1-18255117159@163.com>
References: <20251104165125.174168-1-18255117159@163.com>
Message-ID: <20251104165125.174168-3-18255117159@163.com>

The Meson PCIe controller driver manually configures maximum payload
size (MPS) through meson_set_max_payload, duplicating functionality now
centralized in the PCI core.  Deprecating redundant code simplifies the
driver and aligns it with the consolidated MPS management strategy,
improving long-term maintainability.

Signed-off-by: Hans Zhang <18255117159 at 163.com>
---
 drivers/pci/controller/dwc/pci-meson.c | 17 -----------------
 1 file changed, 17 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-meson.c b/drivers/pci/controller/dwc/pci-meson.c
index 787469d1b396..3d12e1a9bb0c 100644
--- a/drivers/pci/controller/dwc/pci-meson.c
+++ b/drivers/pci/controller/dwc/pci-meson.c
@@ -261,22 +261,6 @@ static int meson_size_to_payload(struct meson_pcie *mp, int size)
 	return fls(size) - 8;
 }
 
-static void meson_set_max_payload(struct meson_pcie *mp, int size)
-{
-	struct dw_pcie *pci = &mp->pci;
-	u32 val;
-	u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
-	int max_payload_size = meson_size_to_payload(mp, size);
-
-	val = dw_pcie_readl_dbi(pci, offset + PCI_EXP_DEVCTL);
-	val &= ~PCI_EXP_DEVCTL_PAYLOAD;
-	dw_pcie_writel_dbi(pci, offset + PCI_EXP_DEVCTL, val);
-
-	val = dw_pcie_readl_dbi(pci, offset + PCI_EXP_DEVCTL);
-	val |= PCIE_CAP_MAX_PAYLOAD_SIZE(max_payload_size);
-	dw_pcie_writel_dbi(pci, offset + PCI_EXP_DEVCTL, val);
-}
-
 static void meson_set_max_rd_req_size(struct meson_pcie *mp, int size)
 {
 	struct dw_pcie *pci = &mp->pci;
@@ -381,7 +365,6 @@ static int meson_pcie_host_init(struct dw_pcie_rp *pp)
 
 	pp->bridge->ops = &meson_pci_ops;
 
-	meson_set_max_payload(mp, MAX_PAYLOAD_SIZE);
 	meson_set_max_rd_req_size(mp, MAX_READ_REQ_SIZE);
 
 	return 0;
-- 
2.34.1



From 18255117159 at 163.com  Tue Nov  4 08:51:23 2025
From: 18255117159 at 163.com (Hans Zhang)
Date: Wed,  5 Nov 2025 00:51:23 +0800
Subject: [PATCH v6 0/2] PCI: Configure Root Port MPS during host probing
Message-ID: <20251104165125.174168-1-18255117159@163.com>

Current PCIe initialization exhibits a key optimization gap: Root Ports
may operate with non-optimal Maximum Payload Size (MPS) settings. While
downstream device configuration is handled during bus enumeration, Root
Port MPS values inherited from firmware or hardware defaults often fail
to utilize the full capabilities supported by controller hardware. This
results in suboptimal data transfer efficiency throughout the PCIe
hierarchy.

This patch series addresses this by:

1.  Core PCI enhancement (Patch 1):
- Proactively configures Root Port MPS during host controller probing
- Sets initial MPS to hardware maximum (128 << dev->pcie_mpss)
- Conditional on PCIe bus tuning being enabled (PCIE_BUS_TUNE_OFF unset)
- Maintains backward compatibility via PCIE_BUS_TUNE_OFF check
- Preserves standard MPS negotiation during downstream enumeration

2.  Driver cleanup (Patch 2):
- Removes redundant MPS configuration from Meson PCIe controller driver
- Functionality is now centralized in PCI core
- Simplifies driver maintenance long-term

---
Changes for v6:
- Modify the commit message and comments. (Bjorn)
- Patch 1/2 code logic: Add !bridge check to configure MPS only for Root Ports
  without an upstream bridge (root bridges), avoiding incorrect handling of
  non-root-bridge Root Ports (Niklas).

Changes for v5:
https://patchwork.kernel.org/project/linux-pci/patch/20250620155507.1022099-1-18255117159 at 163.com/

- Use pcie_set_mps directly instead of pcie_write_mps.
- The patch 1 commit message were modified.

Changes for v4:
https://patchwork.kernel.org/project/linux-pci/patch/20250510155607.390687-1-18255117159 at 163.com/

- The patch [v4 1/2] add a comment to explain why it was done this way.
- The patch [v4 2/2] have not been modified.
- Drop patch [v3 3/3]. The Maintainer of the pci-aardvark.c file suggests
  that this patch cannot be submitted. In addition, Mani also suggests
  dropping this patch until this series of issues is resolved.

Changes for v3:
https://patchwork.kernel.org/project/linux-pci/patch/20250506173439.292460-1-18255117159 at 163.com/

- The new split is patch 2/3 and 3/3.
- Modify the patch 1/3 according to Niklas' suggestion.

Changes for v2:
https://patchwork.kernel.org/project/linux-pci/patch/20250425095708.32662-1-18255117159 at 163.com/

- According to the Maintainer's suggestion, limit the setting of MPS
  changes to platforms with controller drivers.
- Delete the MPS code set by the SOC manufacturer.
---

Hans Zhang (2):
  PCI: Configure Root Port MPS during host probing
  PCI: dwc: Remove redundant MPS configuration

 drivers/pci/controller/dwc/pci-meson.c | 17 -----------------
 drivers/pci/probe.c                    | 12 ++++++++++++
 2 files changed, 12 insertions(+), 17 deletions(-)


base-commit: 691d401c7e0e5ea34ac6f8151bc0696db1b2500a
-- 
2.34.1



From 18255117159 at 163.com  Tue Nov  4 08:51:24 2025
From: 18255117159 at 163.com (Hans Zhang)
Date: Wed,  5 Nov 2025 00:51:24 +0800
Subject: [PATCH v6 1/2] PCI: Configure Root Port MPS during host probing
In-Reply-To: <20251104165125.174168-1-18255117159@163.com>
References: <20251104165125.174168-1-18255117159@163.com>
Message-ID: <20251104165125.174168-2-18255117159@163.com>

Current PCIe initialization logic may leave Root Ports (root bridges)
operating with non-optimal Maximum Payload Size (MPS) settings. Existing
code in pci_configure_mps() returns early for devices without an upstream
bridge (!bridge) which includes Root Ports, so their MPS values remain
at firmware/hardware defaults. This fails to utilize the controller's full
capabilities, leading to suboptimal data transfer efficiency across the
PCIe hierarchy.

With this patch, during the host controller probing phase:
- When PCIe bus tuning is enabled (not PCIE_BUS_TUNE_OFF), and
- The device is a Root Port without an upstream bridge (!bridge),
The Root Port's MPS is set to its hardware-supported maximum value
(128 << dev->pcie_mpss).

Note that this initial maximum MPS setting may be reduced later, during
downstream device enumeration, if any downstream device does not suppor
the Root Port's maximum MPS.

This change ensures Root Ports are properly initialized before downstream
devices negotiate MPS, while maintaining backward compatibility via the
PCIE_BUS_TUNE_OFF check.

Suggested-by: Niklas Cassel <cassel at kernel.org>
Suggested-by: Manivannan Sadhasivam <mani at kernel.org>
Signed-off-by: Hans Zhang <18255117159 at 163.com>
---
 drivers/pci/probe.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 0ce98e18b5a8..2459def3af9b 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -2196,6 +2196,18 @@ static void pci_configure_mps(struct pci_dev *dev)
 		return;
 	}
 
+	/*
+	 * Unless MPS strategy is PCIE_BUS_TUNE_OFF (don't touch MPS at all),
+	 * start off by setting Root Ports' MPS to MPSS. This only applies to
+	 * Root Ports without an upstream bridge (root bridges), as other Root
+	 * Ports will have downstream bridges. Depending on the MPS strategy
+	 * and MPSS of downstream devices, the Root Port's MPS may be
+	 * overridden later.
+	 */
+	if (!bridge && pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT &&
+	    pcie_bus_config != PCIE_BUS_TUNE_OFF)
+		pcie_set_mps(dev, 128 << dev->pcie_mpss);
+
 	if (!bridge || !pci_is_pcie(bridge))
 		return;
 
-- 
2.34.1



From conor at kernel.org  Tue Nov  4 09:24:45 2025
From: conor at kernel.org (Conor Dooley)
Date: Tue, 4 Nov 2025 17:24:45 +0000
Subject: [PATCH v5 6/7] dt-bindings: clock: rockchip: Add RK3506 clock
 and reset unit
In-Reply-To: <6ff7370e-0e57-487d-a6d9-05958ab21e98@rock-chips.com>
References: <20251027084147.4148739-1-zhangqing@rock-chips.com>
 <20251027084147.4148739-7-zhangqing@rock-chips.com>
 <20251027-await-wound-0aee2d20e0a3@spud>
 <6ff7370e-0e57-487d-a6d9-05958ab21e98@rock-chips.com>
Message-ID: <20251104-nutty-lunchroom-36a5879db0b9@spud>

On Tue, Nov 04, 2025 at 09:48:56AM +0800, zhangqing wrote:
> 
> ? 2025/10/28 0:47, Conor Dooley ??:
> > On Mon, Oct 27, 2025 at 04:41:46PM +0800, Elaine Zhang wrote:
> > > From: Finley Xiao<finley.xiao at rock-chips.com>
> > > 
> > > Add device tree bindings for clock and reset unit on RK3506 SoC.
> > > Add clock and reset IDs for RK3506 SoC.
> > > 
> > > Signed-off-by: Finley Xiao<finley.xiao at rock-chips.com>
> > > ---
> > >   .../bindings/clock/rockchip,rk3506-cru.yaml   |  51 ++++
> > >   .../dt-bindings/clock/rockchip,rk3506-cru.h   | 285 ++++++++++++++++++
> > >   .../dt-bindings/reset/rockchip,rk3506-cru.h   | 211 +++++++++++++
> > >   3 files changed, 547 insertions(+)
> > >   create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
> > >   create mode 100644 include/dt-bindings/clock/rockchip,rk3506-cru.h
> > >   create mode 100644 include/dt-bindings/reset/rockchip,rk3506-cru.h
> > > 
> > > diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml b/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
> > > new file mode 100644
> > > index 000000000000..ecb5fa497747
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
> > > @@ -0,0 +1,51 @@
> > > +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> > > +%YAML 1.2
> > > +---
> > > +$id:http://devicetree.org/schemas/clock/rockchip,rk3506-cru.yaml#
> > > +$schema:http://devicetree.org/meta-schemas/core.yaml#
> > > +
> > > +title: Rockchip RK3506 Clock and Reset Unit (CRU)
> > > +
> > > +maintainers:
> > > +  - Finley Xiao<finley.xiao at rock-chips.com>
> > > +  - Heiko Stuebner<heiko at sntech.de>
> > > +
> > > +description: |
> > > +  The RK3506 CRU generates the clock and also implements reset for SoC
> > > +  peripherals.
> > > +
> > > +properties:
> > > +  compatible:
> > > +    const: rockchip,rk3506-cru
> > > +
> > > +  reg:
> > > +    maxItems: 1
> > > +
> > > +  "#clock-cells":
> > > +    const: 1
> > > +
> > > +  "#reset-cells":
> > > +    const: 1
> > > +
> > > +  clocks:
> > > +    maxItems: 1
> > Can you explain somewhere why the input clock is not required?
> > Feels like it really should be required, if it is what the output clocks
> > are generated from, but I can also see why it might be optional either.
> > pw-bot: changes-requested
> 
> Our default hardware input clock is 24M.
> 
> ?Some Socs and hardware input clocks support 24M?24.576M?26M. For

Other SoCs get other compatibles, so that is not relevant.

> different input frequencies, there is a need to configure clocks.

That seems like it should be required, because there's always one being
provided.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251104/369e7958/attachment.sig>

From conor at kernel.org  Tue Nov  4 09:25:18 2025
From: conor at kernel.org (Conor Dooley)
Date: Tue, 4 Nov 2025 17:25:18 +0000
Subject: [PATCH 1/3] dt-bindings: clock: rk3568: Add SCMI clock ids
In-Reply-To: <20251103234926.416137-2-heiko@sntech.de>
References: <20251103234926.416137-1-heiko@sntech.de>
 <20251103234926.416137-2-heiko@sntech.de>
Message-ID: <20251104-royal-stir-ee4df643e3ff@spud>

Acked-by: Conor Dooley <conor.dooley at microchip.com>
pw-bot: not-applicable
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251104/cbfdef23/attachment.sig>

From conor at kernel.org  Tue Nov  4 09:25:35 2025
From: conor at kernel.org (Conor Dooley)
Date: Tue, 4 Nov 2025 17:25:35 +0000
Subject: [PATCH 2/2] dt-bindings: clock: rk3568: Drop CLK_NR_CLKS define
In-Reply-To: <20251103234032.413563-3-heiko@sntech.de>
References: <20251103234032.413563-1-heiko@sntech.de>
 <20251103234032.413563-3-heiko@sntech.de>
Message-ID: <20251104-verdict-siding-1400c49da950@spud>

Acked-by: Conor Dooley <conor.dooley at microchip.com>
pw-bot: not-applicable
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251104/de582479/attachment.sig>

From helgaas at kernel.org  Tue Nov  4 14:17:24 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 4 Nov 2025 16:17:24 -0600
Subject: [PATCH v3] PCI: dw-rockchip: Prevent advertising L1 Substates
 support
In-Reply-To: <0e32766b-b951-4ab4-ae3d-c802cf649edf@rock-chips.com>
Message-ID: <20251104221724.GA1875081@bhelgaas>

On Tue, Nov 04, 2025 at 08:58:02AM +0800, Shawn Lin wrote:
> ? 2025/11/04 ??? 5:32, Bjorn Helgaas ??:
> > On Tue, Oct 28, 2025 at 02:02:18PM -0500, Bjorn Helgaas wrote:
> > > On Fri, Oct 17, 2025 at 06:32:53PM +0200, Niklas Cassel wrote:
> > > > The L1 substates support requires additional steps to work, namely:
> > > > -Proper handling of the CLKREQ# sideband signal. (It is mostly handled by
> > > >   hardware, but software still needs to set the clkreq fields in the
> > > >   PCIE_CLIENT_POWER_CON register to match the hardware implementation.)
> > > > -Program the frequency of the aux clock into the
> > > >   DSP_PCIE_PL_AUX_CLK_FREQ_OFF register. (During L1 substates the core_clk
> > > >   is turned off and the aux_clk is used instead.)
> > > ...
> > 
> > > > +static void rockchip_pcie_disable_l1sub(struct dw_pcie *pci)
> > > > +{
> > > > +	u32 cap, l1subcap;
> > > > +
> > > > +	cap = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_L1SS);
> > > > +	if (cap) {
> > > > +		l1subcap = dw_pcie_readl_dbi(pci, cap + PCI_L1SS_CAP);
> > > > +		l1subcap &= ~(PCI_L1SS_CAP_L1_PM_SS | PCI_L1SS_CAP_ASPM_L1_1 |
> > > > +			      PCI_L1SS_CAP_ASPM_L1_2 | PCI_L1SS_CAP_PCIPM_L1_1 |
> > > > +			      PCI_L1SS_CAP_PCIPM_L1_2);
> > > > +		dw_pcie_writel_dbi(pci, cap + PCI_L1SS_CAP, l1subcap);
> > > > +	}
> > > > +}
> > > 
> > > I like this.  But why should we do it just for dw-rockchip?  Is there
> > > something special about dw-rockchip that makes this a problem?  Maybe
> > > we should consider doing this in the dwc, cadence, mobiveil, and plda
> > > cores instead of trying to do it for every driver individually?
> > > 
> > > Advertising L1SS support via PCI_EXT_CAP_ID_L1SS means users can
> > > enable L1SS via CONFIG_PCIEASPM_POWER_SUPERSAVE=y or sysfs, and that
> > > seems likely to cause problems unless CLKREQ# is supported.
> > 
> > Any thoughts on this?  There's nothing rockchip-specific in this
> > patch.  What I'm proposing is something like this:
> 
> I like your idea, though. But could it be another form of regression
> that we may breaks the platform which have already support L1SS
> properly? It's even harder to detect because a functional break is easier to
> notice than increased power consumption. 

True, but I think it's unlikely because the PCI core never enabled
L1SS (except for CONFIG_PCIEASPM_POWER_SUPERSAVE=y or sysfs, which I
doubt anybody really uses).

Devicetree platforms that use L1SS should have explicit code to enable
it, like qcom does, so we should be able to find them and make sure
they do what's needed to prevent the regression.

> Or maybe we could
> just export dw_pcie_clear_l1ss_advert() in dwc for host drivers to
> call it?

I don't like the idea of host drivers having to opt in for this
because that requires changes to all of them, not just changes to
drivers that have done the work to actually support L1SS.

> >      PCI: dwc: Prevent advertising L1 PM Substates
> >      L1 PM Substates require the CLKREF# signal and driver-specific support.  If
> >      CLKREF# is not supported or the driver support is lacking, enabling L1.1 or
> >      L1.2 may cause errors when accessing devices, e.g.,
> >        nvme nvme0: controller is down; will reset: CSTS=0xffffffff, PCI_STATUS=0x10
> >      If both ends of a link advertise support for L1 PM Substates, and the
> >      kernel is built with CONFIG_PCIEASPM_POWER_SUPERSAVE=y or users enable L1.x
> >      via sysfs, Linux tries to enable them.
> >      To prevent errors when L1.x may not work, disable advertising the L1 PM
> >      Substates.  Drivers can enable advertising them if they know CLKREF# is
> >      present and the Root Port is configured correctly.
> >      Based on Niklas's patch from
> >      https://patch.msgid.link/20251017163252.598812-2-cassel at kernel.org
> > 
> > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> > index 20c9333bcb1c..83b5330c9e45 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > @@ -950,6 +950,27 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
> >   	return 0;
> >   }
> > +static void dw_pcie_clear_l1ss_advert(struct dw_pcie_rp *pp)
> > +{
> > +	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > +	u16 l1ss;
> > +	u32 l1ss_cap;
> > +
> > +	l1ss = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_L1SS);
> > +	if (!l1ss)
> > +		return;
> > +
> > +	/*
> > +	 * By default, don't advertise L1 PM Substates because they require
> > +	 * CLKREF# and other driver-specific support.
> > +	 */
> > +	l1ss_cap = dw_pcie_readl_dbi(pci, l1ss + PCI_L1SS_CAP);
> > +	l1ss_cap &= ~(PCI_L1SS_CAP_PCIPM_L1_1 | PCI_L1SS_CAP_ASPM_L1_1 |
> > +		      PCI_L1SS_CAP_PCIPM_L1_2 | PCI_L1SS_CAP_ASPM_L1_2 |
> > +		      PCI_L1SS_CAP_L1_PM_SS);
> > +	dw_pcie_writel_dbi(pci, l1ss + PCI_L1SS_CAP, l1ss_cap);
> > +}
> > +
> >   static void dw_pcie_program_presets(struct dw_pcie_rp *pp, enum pci_bus_speed speed)
> >   {
> >   	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > @@ -1060,6 +1081,7 @@ int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
> >   		PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
> >   	dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
> > +	dw_pcie_clear_l1ss_advert(pp);
> >   	dw_pcie_config_presets(pp);
> >   	/*
> >   	 * If the platform provides its own child bus config accesses, it means
> > 
> 


From helgaas at kernel.org  Tue Nov  4 14:24:59 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 4 Nov 2025 16:24:59 -0600
Subject: [PATCH v3] PCI: dw-rockchip: Prevent advertising L1 Substates
 support
In-Reply-To: <aQn3RGrJi1lb0EO1@ryzen>
Message-ID: <20251104222459.GA1875296@bhelgaas>

On Tue, Nov 04, 2025 at 01:53:24PM +0100, Niklas Cassel wrote:
> On Mon, Nov 03, 2025 at 03:32:06PM -0600, Bjorn Helgaas wrote:
> > On Tue, Oct 28, 2025 at 02:02:18PM -0500, Bjorn Helgaas wrote:
> > > On Fri, Oct 17, 2025 at 06:32:53PM +0200, Niklas Cassel wrote:
> > > > The L1 substates support requires additional steps to work, namely:
> > > > -Proper handling of the CLKREQ# sideband signal. (It is mostly handled by
> > > >  hardware, but software still needs to set the clkreq fields in the
> > > >  PCIE_CLIENT_POWER_CON register to match the hardware implementation.)
> > > > -Program the frequency of the aux clock into the
> > > >  DSP_PCIE_PL_AUX_CLK_FREQ_OFF register. (During L1 substates the core_clk
> > > >  is turned off and the aux_clk is used instead.)
> > > ...
> > 
> > > > +static void rockchip_pcie_disable_l1sub(struct dw_pcie *pci)
> > > > +{
> > > > +	u32 cap, l1subcap;
> > > > +
> > > > +	cap = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_L1SS);
> > > > +	if (cap) {
> > > > +		l1subcap = dw_pcie_readl_dbi(pci, cap + PCI_L1SS_CAP);
> > > > +		l1subcap &= ~(PCI_L1SS_CAP_L1_PM_SS | PCI_L1SS_CAP_ASPM_L1_1 |
> > > > +			      PCI_L1SS_CAP_ASPM_L1_2 | PCI_L1SS_CAP_PCIPM_L1_1 |
> > > > +			      PCI_L1SS_CAP_PCIPM_L1_2);
> > > > +		dw_pcie_writel_dbi(pci, cap + PCI_L1SS_CAP, l1subcap);
> > > > +	}
> > > > +}
> > > 
> > > I like this.  But why should we do it just for dw-rockchip?  Is there
> > > something special about dw-rockchip that makes this a problem?  Maybe
> > > we should consider doing this in the dwc, cadence, mobiveil, and plda
> > > cores instead of trying to do it for every driver individually?
> > > 
> > > Advertising L1SS support via PCI_EXT_CAP_ID_L1SS means users can
> > > enable L1SS via CONFIG_PCIEASPM_POWER_SUPERSAVE=y or sysfs, and that
> > > seems likely to cause problems unless CLKREQ# is supported.
> > 
> > Any thoughts on this?  There's nothing rockchip-specific in this
> > patch.  What I'm proposing is something like this:
> > 
> >     PCI: dwc: Prevent advertising L1 PM Substates
> >     
> >     L1 PM Substates require the CLKREF# signal and driver-specific support.  If
> >     CLKREF# is not supported or the driver support is lacking, enabling L1.1 or
> >     L1.2 may cause errors when accessing devices, e.g.,
> >     
> >       nvme nvme0: controller is down; will reset: CSTS=0xffffffff, PCI_STATUS=0x10
> >     
> >     If both ends of a link advertise support for L1 PM Substates, and the
> >     kernel is built with CONFIG_PCIEASPM_POWER_SUPERSAVE=y or users enable L1.x
> >     via sysfs, Linux tries to enable them.
> >     
> >     To prevent errors when L1.x may not work, disable advertising the L1 PM
> >     Substates.  Drivers can enable advertising them if they know CLKREF# is
> >     present and the Root Port is configured correctly.
> >     
> >     Based on Niklas's patch from
> >     https://patch.msgid.link/20251017163252.598812-2-cassel at kernel.org
> > 
> > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> > index 20c9333bcb1c..83b5330c9e45 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > @@ -950,6 +950,27 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
> >  	return 0;
> >  }
> >  
> > +static void dw_pcie_clear_l1ss_advert(struct dw_pcie_rp *pp)
> > +{
> > +	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > +	u16 l1ss;
> > +	u32 l1ss_cap;
> > +
> > +	l1ss = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_L1SS);
> > +	if (!l1ss)
> > +		return;
> > +
> > +	/*
> > +	 * By default, don't advertise L1 PM Substates because they require
> > +	 * CLKREF# and other driver-specific support.
> > +	 */
> > +	l1ss_cap = dw_pcie_readl_dbi(pci, l1ss + PCI_L1SS_CAP);
> > +	l1ss_cap &= ~(PCI_L1SS_CAP_PCIPM_L1_1 | PCI_L1SS_CAP_ASPM_L1_1 |
> > +		      PCI_L1SS_CAP_PCIPM_L1_2 | PCI_L1SS_CAP_ASPM_L1_2 |
> > +		      PCI_L1SS_CAP_L1_PM_SS);
> > +	dw_pcie_writel_dbi(pci, l1ss + PCI_L1SS_CAP, l1ss_cap);
> > +}
> > +
> >  static void dw_pcie_program_presets(struct dw_pcie_rp *pp, enum pci_bus_speed speed)
> >  {
> >  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > @@ -1060,6 +1081,7 @@ int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
> >  		PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
> >  	dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
> >  
> > +	dw_pcie_clear_l1ss_advert(pp);
> >  	dw_pcie_config_presets(pp);
> >  	/*
> >  	 * If the platform provides its own child bus config accesses, it means
> 
> My patch disables L1 substates when running the controller in both
> root complex mode and endpoint mode.
> 
> Your patch above only disables L1 substates when running the the
> controller in root complex mode.
> 
> I think this code has to be in pcie-designware.c and then e.g.
> dw_pcie_setup_rc() (pcie-designware-host.c) and
> dw_pcie_ep_init_registers() (pcie-designware-ep.c) can both use it.

I'm not opposed to doing it for endpoints as well if the endpoint mode
driver needs to configure L1SS things before it can work.

I don't think an endpoint should be enabling L1SS on the host, so
enabling L1SS probably has to be done by the host, and the host driver
knows the topology and whether CLKREQ# is supported (e.g., via DT) and
whether the RP is configured for it.

> And like Shawn mentions. Disabling it by default for all DWC based
> platforms could introduce regressions where L1 substates already is
> working fine.
> 
> Sure, the only driver that checks for the DT property
> 'supports-clkreq' is drivers/pci/controller/dwc/pcie-tegra194.c.
> However Mani claimed that the qcom driver also has support for L1
> substates already, even though it does not check the
> 'supports-clkreq' DT property.

Yes, we would need to ensure tegra, qcom, and any others that use L1SS
don't regress.  That's why I said "something like this" and didn't
include a signed-off-by.  I wanted to have exactly this conversation.

Bjorn


From sebastian.reichel at collabora.com  Tue Nov  4 17:32:07 2025
From: sebastian.reichel at collabora.com (Sebastian Reichel)
Date: Wed, 5 Nov 2025 02:32:07 +0100
Subject: [PATCH 1/2] clk: rockchip: rk3568: Drop CLK_NR_CLKS usage
In-Reply-To: <20251103234032.413563-2-heiko@sntech.de>
References: <20251103234032.413563-1-heiko@sntech.de>
 <20251103234032.413563-2-heiko@sntech.de>
Message-ID: <x7xja6v2ssq3mesj3bnuzsz522tew4lobbn5ftcgfrusdnabjm@rd47kgjdnoz4>

Hi,

On Tue, Nov 04, 2025 at 12:40:31AM +0100, Heiko Stuebner wrote:
> In order to get rid of CLK_NR_CLKS and be able to drop it from the
> bindings, use rockchip_clk_find_max_clk_id helper to find the highest
> clock id.
> 
> Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel at collabora.com>

-- Sebastian

>  drivers/clk/rockchip/clk-rk3568.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/clk/rockchip/clk-rk3568.c b/drivers/clk/rockchip/clk-rk3568.c
> index 97d279399ae8..74eabf9b2ae2 100644
> --- a/drivers/clk/rockchip/clk-rk3568.c
> +++ b/drivers/clk/rockchip/clk-rk3568.c
> @@ -1652,6 +1652,7 @@ CLK_OF_DECLARE(rk3568_cru_pmu, "rockchip,rk3568-pmucru", rk3568_pmu_clk_init);
>  static void __init rk3568_clk_init(struct device_node *np)
>  {
>  	struct rockchip_clk_provider *ctx;
> +	unsigned long clk_nr_clks;
>  	void __iomem *reg_base;
>  
>  	reg_base = of_iomap(np, 0);
> @@ -1660,7 +1661,9 @@ static void __init rk3568_clk_init(struct device_node *np)
>  		return;
>  	}
>  
> -	ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
> +	clk_nr_clks = rockchip_clk_find_max_clk_id(rk3568_clk_branches,
> +						   ARRAY_SIZE(rk3568_clk_branches)) + 1;
> +	ctx = rockchip_clk_init(np, reg_base, clk_nr_clks);
>  	if (IS_ERR(ctx)) {
>  		pr_err("%s: rockchip clk init failed\n", __func__);
>  		iounmap(reg_base);
> -- 
> 2.47.2
> 
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251105/10c170af/attachment.sig>

From naoki at radxa.com  Tue Nov  4 17:37:07 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Wed, 5 Nov 2025 10:37:07 +0900
Subject: [PATCH v3 1/3] dt-bindings: arm: rockchip: Add Radxa CM5 IO board
In-Reply-To: <f12bc562-b5bb-4bdd-b274-23582df8f2d4@kernel.org>
References: <174735136138.1544989.11909422896170025756.robh@kernel.org>
 <20250528221823.2974653-1-joseph.kogut@gmail.com>
 <20250528221823.2974653-2-joseph.kogut@gmail.com>
 <20250529-impressive-real-monkey-a7818b@kuoka>
 <6443BD03B4C4F1FE+d20c3903-e2dc-4c2b-8f6e-fac38f242898@radxa.com>
 <2f4e7f94-2921-493c-94fa-45749a060bc0@kernel.org>
 <870075785A1ED2B9+6fb5238e-dc57-406b-acf9-b88b237d8e5b@radxa.com>
 <f12bc562-b5bb-4bdd-b274-23582df8f2d4@kernel.org>
Message-ID: <E04572034CE4DC35+005c7dd7-cb2f-4f82-9889-ac14733a7647@radxa.com>

Hi Krzysztof

On 10/28/25 19:41, Krzysztof Kozlowski wrote:
> On 28/10/2025 10:44, FUKAUMI Naoki wrote:
>> Hi Joseph
>>
>> Your patch seems to be NAKed.
>> I will submit new patch soon.
> 
> Sorry, what? Don't hijack other people's work.

I have Joseph's permission to post my patch.

Furthermore, this is not the first time, to my knowledge, that someone 
else has posted another patch for the same board. (See below)

  https://lore.kernel.org/linux-rockchip/20241226005845.46473-1-naoki at radxa.com/T/#u
  https://lore.kernel.org/linux-rockchip/20250324-rock5bp-for-upstream-v1-0-6217edf15b19 at kernel.org/T/#u

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

>>
>> Best regards,
>>
>> --
>> FUKAUMI Naoki
>> Radxa Computer (Shenzhen) Co., Ltd.
>>
>> On 10/28/25 18:37, Krzysztof Kozlowski wrote:
>>> On 28/10/2025 10:33, FUKAUMI Naoki wrote:
>>>> Hi Krzysztof,
>>>>
>>>> https://patchwork.kernel.org/project/linux-rockchip/patch/20250528221823.2974653-2-joseph.kogut at gmail.com/
>>>>
>>>> On 5/29/25 18:19, Krzysztof Kozlowski wrote:
>>>>> On Wed, May 28, 2025 at 03:18:21PM GMT, Joseph Kogut wrote:
>>>>>> Add device tree binding for the Radxa CM5 IO board.
>>>>>>
>>>>>> This board is based on the rk3588s.
>>>>>
>>>>> Do not attach (thread) your patchsets to some other threads (unrelated
>>>>> or older versions). This buries them deep in the mailbox and might
>>>>> interfere with applying entire sets.
>>>>>
>>>>>
>>>>> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
>>>> Please explain the sorting rule used for this file. You must have known
>>>> the sorting rule; otherwise, how can you be sure this patch is correct?
>>>
>>> Huh? I don't have a clue about sorting rule but if you mock my review
>>> let's make it different:
>>>
>>> NAK
> 
> 
> Ah, you were poking around other patch? I should have ignored that :/
> 
> 
> Best regards,
> Krzysztof
> 



From geraldogabriel at gmail.com  Tue Nov  4 19:55:32 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Wed, 5 Nov 2025 00:55:32 -0300
Subject: [RFC PATCH 2/2] PCI: rockchip-host: drop wait on PERST# toggle
In-Reply-To: <20251103181038.GA1814635@bhelgaas>
References: <d3d0c3a387ff461e62bbd66a0bde654a9a17761e.1762150971.git.geraldogabriel@gmail.com>
 <20251103181038.GA1814635@bhelgaas>
Message-ID: <aQrKtFT0ldc70gKj@geday>

On Mon, Nov 03, 2025 at 12:10:38PM -0600, Bjorn Helgaas wrote:
> On Mon, Nov 03, 2025 at 03:27:25AM -0300, Geraldo Nascimento wrote:
> > With this change PCIe will complete link-training with a known quirky
> > device - Samsung OEM PM981a SSD. This is completely against the PCIe
> > spec and yet it works as long as the power regulator for 3v3 PCIe
> > power is not defined as always-on or boot-on.
> 
> What is against the spec?  In what way is this SSD "known quirky"?  Is
> there a published erratum for it?
> 
> Removing this delay might make this SSD work, but if this delay is
> required per PCIe spec, how can we be confident that other devices
> will still work?
> 
> Reports of devices that still work is not really enough to move this
> from the "hack that makes one device work" column to the "safe and
> effective for all devices" column.
> 
> It's easy to see how *lack* of a delay can break something, but much
> harder to imagine how *removing* a delay can make something work.
> Devices must be able to tolerate pretty much arbitrary delays.

Hi Bjorn!

I did some more testing, intrigued by why would a delay of more than
5 ms after the enablement of the power rails trigger failure in
initial link-training.

Something in my intuition kept telling me this was PERST# related,
and so I followed that rabbit-hole.

It seems the following change will allow the SSD to work with the
Rockchip-IP PCIe core without any other changes. So it is purely
a DT change and we are able to keep the mandatory 100ms delay
after driving PERST# low, as well as the always-on/boot-on
properties of the 3v3 power regulator.

This time everything is within the PCIe spec AFAICT, PERST# indeed
is an Open Drain signal, and indeed it does requires pull-up resistor
to maintain the drive after driving it high.

I'm still testing the overall stability of this, let's hope for the
best!

Thanks,
Geraldo Nascimento

diff --git a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
index aa70776e898a..1c5afc0413bc 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
@@ -383,13 +383,14 @@ &pcie_phy {
 };
 
 &pcie0 {
-	ep-gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>;
+	ep-gpios = <&gpio0 RK_PB4 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
 	num-lanes = <4>;
-	pinctrl-0 = <&pcie_clkreqnb_cpm>;
+	pinctrl-0 = <&pcie_clkreqnb_cpm>, <&pcie_perst>;
 	pinctrl-names = "default";
 	vpcie0v9-supply = <&vcca_0v9>;	/* VCC_0V9_S0 */
 	vpcie1v8-supply = <&vcca_1v8>;	/* VCC_1V8_S0 */
 	vpcie3v3-supply = <&vcc3v3_pcie>;
+	max-link-speed = <2>;
 	status = "okay";
 };
 
@@ -408,6 +409,10 @@ pcie {
 		pcie_pwr: pcie-pwr {
 			rockchip,pins = <4 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>;
 		};
+		pcie_perst: pcie-perst {
+			rockchip,pins = <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+
 	};
 
 	pmic {


From naoki at radxa.com  Tue Nov  4 21:13:33 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Wed,  5 Nov 2025 05:13:33 +0000
Subject: [PATCH v6 1/3] dt-bindings: arm: rockchip: Add Radxa CM5 IO Board
In-Reply-To: <20251105051335.17652-1-naoki@radxa.com>
References: <20251105051335.17652-1-naoki@radxa.com>
Message-ID: <20251105051335.17652-2-naoki@radxa.com>

Add device tree binding documentation for the Radxa CM5 IO Board.

Link: https://dl.radxa.com/cm5/radxa_cm5_product_brief.pdf
Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
---
 Documentation/devicetree/bindings/arm/rockchip.yaml | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
index ba61ea7436132..1829daad88ab5 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.yaml
+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
@@ -902,6 +902,13 @@ properties:
           - const: radxa,cm3i
           - const: rockchip,rk3568
 
+      - description: Radxa CM5
+        items:
+          - enum:
+              - radxa,cm5-io
+          - const: radxa,cm5
+          - const: rockchip,rk3588s
+
       - description: Radxa E20C
         items:
           - const: radxa,e20c
-- 
2.43.0



From naoki at radxa.com  Tue Nov  4 21:13:32 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Wed,  5 Nov 2025 05:13:32 +0000
Subject: [PATCH v6 0/3] Add Radxa CM5 and IO Board
Message-ID: <20251105051335.17652-1-naoki@radxa.com>

This patch series add support for the Radxa CM5 SoM and IO Board.

Changes in v6:
(Patch 1/3)
- Fix description; "Radxa CM5" is the correct name
(Patch 2/3)
- Fix #include(s)
- Include rk3588s.dtsi
- Move alias for gmac1 from io board dts
- Add Maskrom key
- Add pinctrl-* for led-0
- Add vcc_1v1_nldo_s3 regulator for pmic
- Move gmac1 (except status) from io board dts
- Fix phy-supply for gmac1
- Fix compatible for vdd_cpu_big1_s0 regulator
- Add eeprom on i2c0
- Add vdd_npu_s0 regulator for rknn
- Fix compatible for rgmii_phy1
- Add pinctrl-* and reset-* for rgmii_phy1
- Add domain-supply for pd_npu
- Add rknn_*
- Add saradc
- Fix properties in sdhci
- Move pmic from io board dts
- Fix vcc*-supply for pmic
- Add regulators in pmic
- Add tsadc
- Move vop(_mmu) from io board dts
- Trivial changes (labels, names, etc)
(Patch 3/3)
- Fix #include(s)
- Remove #include "rk3588s.dtsi"
- Fix model
- Add fan
- Add Recovery key
- Add pinctrl-* for vcc3v3_wf
- Add vcc_sysin regulator
- Add pinctrl-* for vbus5v0_typec
- Add rfkill-bt and rfkill-wlan for M.2 module
- Add sound for es8316
- Add phy-supply for combphy2_psu
- Fix power-role to "source" for fusb302
- Add rtc for hym8536
- Add audio-codec on i2c8 for es8316
- Add i2s0_8ch for es8316
- Add package_thermal for fan
- Add pinctrl-* for pcie2x1l2
- Add pwm11 for fan
- Fix properties in sdmmmc
- Add phy-supply for u2phy2_host and u2phy3_host
- Remove usb_host0_ohci
- Add pinctrl-* for usbdp_phy0
- Trivial changes (labels, names, etc)

Changes in v5:
(Patch 2/3, per Jimmy)
- Alias eMMC to mmc0
- Remove unused sdio alias
- Move gmac, hdmi0 nodes to carrier board dts
(Patch 3/3, per Jimmy)
- Enable hdmi0_sound and i2s5_8ch
- Remove redundant enablement of sdhci
- Enable usb_host2_xhci

- Tested HDMI audio

Changes in v4:
- Fixed XHCI initialization bug by changing try-power-role from source
  to sink

Changes in v3:
- Addressed YAML syntax error in dt binding (per Rob)
- Fixed whitespace issue in dts reported by checkpatch.pl
- Split base SoM and carrier board into separate patches
- Added further details about the SoM and carrier to the commit
  messages

Changes in v2:
- Added copyright header and data sheet links
- Removed non-existent property
- Sorted alphabetically
- Removed errant whitespace
- Moved status to the end of each node
- Removed pinctrl-names property from leds (indicated by CHECK_DTBS)
- Removed delays from gmac with internal delay

Link: https://lore.kernel.org/r/20250617-rk3588s-cm5-io-dts-upstream-v5-0-8d96854a5bbd at gmail.com
Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
---
I have communicated with Joseph privately and taken ownership of
moving this forward, with his blessing. All bugs belong to me.
---
FUKAUMI Naoki (3):
  dt-bindings: arm: rockchip: Add Radxa CM5 IO Board
  arm64: dts: rockchip: Add Radxa CM5
  arm64: dts: rockchip: Add Radxa CM5 IO Board

 .../devicetree/bindings/arm/rockchip.yaml     |   7 +
 arch/arm64/boot/dts/rockchip/Makefile         |   1 +
 .../dts/rockchip/rk3588s-radxa-cm5-io.dts     | 503 +++++++++++++++
 .../boot/dts/rockchip/rk3588s-radxa-cm5.dtsi  | 602 ++++++++++++++++++
 4 files changed, 1113 insertions(+)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3588s-radxa-cm5-io.dts
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3588s-radxa-cm5.dtsi

-- 
2.43.0



From naoki at radxa.com  Tue Nov  4 21:13:35 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Wed,  5 Nov 2025 05:13:35 +0000
Subject: [PATCH v6 3/3] arm64: dts: rockchip: Add Radxa CM5 IO Board
In-Reply-To: <20251105051335.17652-1-naoki@radxa.com>
References: <20251105051335.17652-1-naoki@radxa.com>
Message-ID: <20251105051335.17652-4-naoki@radxa.com>

The Radxa CM5 IO Board is an application board for the Radxa CM5.

Specification:
- 1x HDMI TX
- 2x MIPI DSI
- 2x MIPI CSI
- 1x USB 3.0 Type-A port
- 1x USB 3.0 Type-C port (supports DisplayPort Alt mode)
- 2x USB 2.0 Type-A ports
- 1x Gigabit Ethernet (supports PoE with add-on PoE HAT)
- 1x microSD card slot
- 1x Fan header
- 1x M.2 E Key slot
- 1x Headphone jack with microphone input
- 40-pin GPIO header
- RTC and battery holder
- 12V 5525 DC jack

Link: https://dl.radxa.com/cm5/io_board_v2200/radxa_cm5_io_board_v2200_schematic.pdf
Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
---
 arch/arm64/boot/dts/rockchip/Makefile         |   1 +
 .../dts/rockchip/rk3588s-radxa-cm5-io.dts     | 503 ++++++++++++++++++
 2 files changed, 504 insertions(+)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3588s-radxa-cm5-io.dts

diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index 4cd8ef607f55c..61790f41c57ba 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -205,6 +205,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-nanopi-r6c.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-odroid-m2.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-orangepi-5.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-orangepi-5b.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-radxa-cm5-io.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-roc-pc.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-rock-5a.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-rock-5c.dtb
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-radxa-cm5-io.dts b/arch/arm64/boot/dts/rockchip/rk3588s-radxa-cm5-io.dts
new file mode 100644
index 0000000000000..12fa8ba83212a
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-radxa-cm5-io.dts
@@ -0,0 +1,503 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2025 Radxa Computer (Shenzhen) Co., Ltd.
+ * Copyright (c) 2025 Joseph Kogut <joseph.kogut at gmail.com>
+ */
+
+/*
+ * CM5 IO Board schematic
+ * https://dl.radxa.com/cm5/io_board_v2200/radxa_cm5_io_board_v2200_schematic.pdf
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pwm/pwm.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
+#include <dt-bindings/usb/pd.h>
+#include "rk3588s-radxa-cm5.dtsi"
+
+/ {
+	model = "Radxa CM5 IO Board";
+	compatible = "radxa,cm5-io", "radxa,cm5", "rockchip,rk3588s";
+
+	aliases {
+		mmc1 = &sdmmc;
+	};
+
+	chosen {
+		stdout-path = "serial2:1500000n8";
+	};
+
+	fan: fan {
+		compatible = "pwm-fan";
+		#cooling-cells = <2>;
+		cooling-levels = <0 64 128 192 255>;
+		fan-supply = <&vcc5v0_sys>;
+		pwms = <&pwm11 0 60000 0>;
+	};
+
+	hdmi0-con {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi0_con_in: endpoint {
+				remote-endpoint = <&hdmi0_out_con>;
+			};
+		};
+	};
+
+	keys-1 {
+		compatible = "adc-keys";
+		io-channels = <&saradc 1>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <1800000>;
+		poll-interval = <100>;
+
+		button-1 {
+			label = "Recovery";
+			linux,code = <KEY_VENDOR>;
+			press-threshold-microvolt = <0>;
+		};
+	};
+
+	vcc12v_dcin: regulator-12v0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc12v_dcin";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+	};
+
+	vcc3v3_wf: regulator-3v3 {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio1 RK_PD3 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&wifi_pwr_en>;
+		regulator-name = "vcc3v3_wf";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+
+	vcc_sysin: regulator-4v0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_sysin";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <4000000>;
+		regulator-max-microvolt = <4000000>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+
+	vcc5v0_sys: vcc5v0_usb: regulator-5v0-0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc12v_dcin>;
+	};
+
+	vcc5v0_usb1: regulator-5v0-1 {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&usb_host_pwren_h>;
+		regulator-name = "vcc5v0_usb1";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc5v0_usb>;
+	};
+
+	vbus5v0_typec: regulator-5v0-2 {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio0 RK_PD5 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&typec5v_pwren_h>;
+		regulator-name = "vbus5v0_typec";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+
+	rfkill-bt {
+		compatible = "rfkill-gpio";
+		pinctrl-names = "default";
+		pinctrl-0 = <&host_wake_bt_h>;
+		radio-type = "bluetooth";
+		shutdown-gpios = <&gpio0 RK_PC6 GPIO_ACTIVE_HIGH>;
+	};
+
+	rfkill-wlan {
+		compatible = "rfkill-gpio";
+		pinctrl-names = "default";
+		pinctrl-0 = <&bt_reg_on_h>;
+		radio-type = "wlan";
+		shutdown-gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>;
+	};
+
+	sound {
+		compatible = "audio-graph-card";
+		label = "rk3588-es8316";
+		dais = <&i2s0_8ch_p0>;
+		routing = "MIC2", "Mic Jack",
+			  "Headphones", "HPOL",
+			  "Headphones", "HPOR";
+		widgets = "Microphone", "Mic Jack",
+			  "Headphone", "Headphones";
+	};
+};
+
+&combphy0_ps {
+	status = "okay";
+};
+
+&combphy2_psu {
+	phy-supply = <&vcc5v0_usb1>;
+	status = "okay";
+};
+
+&gmac1 {
+	status = "okay";
+};
+
+&hdmi0 {
+	status = "okay";
+};
+
+&hdmi0_in {
+	hdmi0_in_vp0: endpoint {
+		remote-endpoint = <&vp0_out_hdmi0>;
+	};
+};
+
+&hdmi0_out {
+	hdmi0_out_con: endpoint {
+		remote-endpoint = <&hdmi0_con_in>;
+	};
+};
+
+&hdmi0_sound {
+	status = "okay";
+};
+
+&hdptxphy0 {
+	status = "okay";
+};
+
+&i2c6 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c6m3_xfer>;
+	status = "okay";
+
+	usb-typec at 22 {
+		compatible = "fcs,fusb302";
+		reg = <0x22>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PC4 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&cc_int0_l>;
+		vbus-supply = <&vbus5v0_typec>;
+
+		connector {
+			compatible = "usb-c-connector";
+			data-role = "dual";
+			label = "USB-C";
+			/* fusb302 supports PD Rev 2.0 Ver 1.2 */
+			pd-revision = /bits/ 8 <0x2 0x0 0x1 0x2>;
+			power-role = "source";
+			source-pdos =
+				<PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					reg = <0>;
+
+					usbc0_hs: endpoint {
+						remote-endpoint = <&usb_host0_xhci_to_usbc0>;
+					};
+				};
+
+				port at 1 {
+					reg = <1>;
+
+					usbc0_ss: endpoint {
+						remote-endpoint = <&usbdp_phy0_ss>;
+					};
+				};
+
+				port at 2 {
+					reg = <2>;
+
+					usbc0_sbu: endpoint {
+						remote-endpoint = <&usbdp_phy0_sbu>;
+					};
+				};
+			};
+		};
+	};
+
+	rtc at 51 {
+		compatible = "haoyu,hym8563";
+		reg = <0x51>;
+		#clock-cells = <0>;
+		clock-output-names = "rtc_32k_in";
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&rtc_int_l>;
+		wakeup-source;
+	};
+};
+
+&i2c8 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c8m2_xfer>;
+	status = "okay";
+
+	audio-codec at 11 {
+		compatible = "everest,es8316";
+		reg = <0x11>;
+		assigned-clocks = <&cru I2S0_8CH_MCLKOUT>;
+		assigned-clock-rates = <12288000>;
+		clocks = <&cru I2S0_8CH_MCLKOUT>;
+		clock-names = "mclk";
+		#sound-dai-cells = <0>;
+
+		port {
+			es8316_p0_0: endpoint {
+				remote-endpoint = <&i2s0_8ch_p0_0>;
+			};
+		};
+	};
+};
+
+&i2s0_8ch {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2s0_lrck
+		     &i2s0_mclk
+		     &i2s0_sclk
+		     &i2s0_sdi0
+		     &i2s0_sdo0>;
+	status = "okay";
+
+	i2s0_8ch_p0: port {
+		i2s0_8ch_p0_0: endpoint {
+			dai-format = "i2s";
+			mclk-fs = <256>;
+			remote-endpoint = <&es8316_p0_0>;
+		};
+	};
+};
+
+&i2s5_8ch {
+	status = "okay";
+};
+
+&package_thermal {
+	polling-delay = <1000>;
+
+	trips {
+		package_fan0: package-fan0 {
+			hysteresis = <2000>;
+			temperature = <55000>;
+			type = "active";
+		};
+
+		package_fan1: package-fan1 {
+			hysteresis = <2000>;
+			temperature = <65000>;
+			type = "active";
+		};
+	};
+
+	cooling-maps {
+		map0 {
+			cooling-device = <&fan THERMAL_NO_LIMIT 1>;
+			trip = <&package_fan0>;
+		};
+
+		map1 {
+			cooling-device = <&fan 2 THERMAL_NO_LIMIT>;
+			trip = <&package_fan1>;
+		};
+	};
+};
+
+&pcie2x1l2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie20x1_2_perstn_m0>;
+	reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
+	vpcie3v3-supply = <&vcc3v3_wf>;
+	status = "okay";
+};
+
+&pinctrl {
+	pcie {
+		pcie20x1_2_perstn_m0: pcie20x1-2-perstn-m0 {
+			rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		wifi_pwr_en: wifi-pwr-en {
+			rockchip,pins = <1 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	rfkill {
+		bt_reg_on_h: bt-reg-on-h {
+			rockchip,pins = <0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+
+		host_wake_bt_h: host-wake-bt-h {
+			rockchip,pins = <0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+	};
+
+	rtc {
+		rtc_int_l: rtc-int-l {
+			rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	usb {
+		cc_int0_l: cc-int0-l {
+			rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		usb_host_pwren_h: usb-host-pwren-h {
+			rockchip,pins = <1 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		usbc_sbu_dc: usbc-sbu-dc {
+			rockchip,pins = <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>,
+					<3 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		typec5v_pwren_h: typec5v-pwren-h {
+			rockchip,pins = <0 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
+
+&pwm11 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pwm11m3_pins>;
+	status = "okay";
+};
+
+&sdmmc {
+	bus-width = <4>;
+	cap-mmc-highspeed;
+	cap-sd-highspeed;
+	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
+	disable-wp;
+	no-sdio;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd>;
+	sd-uhs-sdr104;
+	vmmc-supply = <&vcc_3v3_s3>;
+	vqmmc-supply = <&vccio_sd_s0>;
+	status = "okay";
+};
+
+&u2phy0 {
+	status = "okay";
+};
+
+&u2phy0_otg {
+	status = "okay";
+};
+
+&u2phy2 {
+	status = "okay";
+};
+
+&u2phy2_host {
+	phy-supply = <&vcc5v0_usb1>;
+	status = "okay";
+};
+
+&u2phy3 {
+	status = "okay";
+};
+
+&u2phy3_host {
+	phy-supply = <&vcc5v0_usb1>;
+	status = "okay";
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart2m0_xfer>;
+	status = "okay";
+};
+
+&usb_host0_ehci {
+	status = "okay";
+};
+
+&usb_host0_xhci {
+	usb-role-switch;
+	status = "okay";
+
+	port {
+		usb_host0_xhci_to_usbc0: endpoint {
+			remote-endpoint = <&usbc0_hs>;
+		};
+	};
+};
+
+&usb_host1_ehci {
+	status = "okay";
+};
+
+&usb_host1_ohci {
+	status = "okay";
+};
+
+&usb_host2_xhci {
+	status = "okay";
+};
+
+&usbdp_phy0 {
+	mode-switch;
+	orientation-switch;
+	pinctrl-names = "default";
+	pinctrl-0 = <&usbc_sbu_dc>;
+	sbu1-dc-gpios = <&gpio3 RK_PC4 GPIO_ACTIVE_HIGH>;
+	sbu2-dc-gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+
+	port {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		usbdp_phy0_ss: endpoint at 0 {
+			reg = <0>;
+			remote-endpoint = <&usbc0_ss>;
+		};
+
+		usbdp_phy0_sbu: endpoint at 1 {
+			reg = <1>;
+			remote-endpoint = <&usbc0_sbu>;
+		};
+	};
+};
+
+&vp0 {
+	vp0_out_hdmi0: endpoint at ROCKCHIP_VOP2_EP_HDMI0 {
+		reg = <ROCKCHIP_VOP2_EP_HDMI0>;
+		remote-endpoint = <&hdmi0_in_vp0>;
+	};
+};
-- 
2.43.0



From naoki at radxa.com  Tue Nov  4 21:13:34 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Wed,  5 Nov 2025 05:13:34 +0000
Subject: [PATCH v6 2/3] arm64: dts: rockchip: Add Radxa CM5
In-Reply-To: <20251105051335.17652-1-naoki@radxa.com>
References: <20251105051335.17652-1-naoki@radxa.com>
Message-ID: <20251105051335.17652-3-naoki@radxa.com>

The Radxa CM5 is a high performance embedded SoM based on the Rockchip
RK3588S2 SoC.

Specification:
- Quad-core Cortex-A76 and quad-core Cortex-A55 CPU
- Mali-G610 MP4 GPU
- 6TOPS NPU
- Up to 32GB LPDDR4x RAM
- Up to 128GB on-board eMMC
- On-board Gigabit Ethernet PHY
- RK806-1 PMIC

Link: https://dl.radxa.com/cm5/v2210/radxa_cm5_v2210_schematic.pdf
Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
---
 .../boot/dts/rockchip/rk3588s-radxa-cm5.dtsi  | 602 ++++++++++++++++++
 1 file changed, 602 insertions(+)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3588s-radxa-cm5.dtsi

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-radxa-cm5.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s-radxa-cm5.dtsi
new file mode 100644
index 0000000000000..f2da73126c1fe
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-radxa-cm5.dtsi
@@ -0,0 +1,602 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2025 Radxa Computer (Shenzhen) Co., Ltd.
+ * Copyright (c) 2025 Joseph Kogut <joseph.kogut at gmail.com>
+ */
+
+/*
+ * CM5 schematic
+ * https://dl.radxa.com/cm5/v2210/radxa_cm5_v2210_schematic.pdf
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rk3588s.dtsi"
+
+/ {
+	compatible = "radxa,cm5", "rockchip,rk3588s";
+
+	aliases {
+		ethernet0 = &gmac1;
+		mmc0 = &sdhci;
+	};
+
+	keys-0 {
+		compatible = "adc-keys";
+		io-channels = <&saradc 0>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <1800000>;
+		poll-interval = <100>;
+
+		button-0 {
+			label = "Maskrom";
+			linux,code = <KEY_SETUP>;
+			press-threshold-microvolt = <0>;
+		};
+	};
+
+	leds-0 {
+		compatible = "gpio-leds";
+
+		led-0 {
+			color = <LED_COLOR_ID_BLUE>;
+			default-state = "on";
+			function = LED_FUNCTION_STATUS;
+			gpios = <&gpio4 RK_PB4 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+			pinctrl-names = "default";
+			pinctrl-0 = <&gpio4_b4>;
+		};
+	};
+
+	vcc_1v1_nldo_s3: regulator-1v1 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_1v1_nldo_s3";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1100000>;
+		regulator-max-microvolt = <1100000>;
+		vin-supply = <&vcc_sysin>;
+	};
+};
+
+&cpu_b0 {
+	cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b1 {
+	cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b2 {
+	cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_b3 {
+	cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_l0 {
+	cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l1 {
+	cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l2 {
+	cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l3 {
+	cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&gmac1 {
+	clock_in_out = "output";
+	phy-handle = <&rgmii_phy1>;
+	phy-mode = "rgmii-id";
+	phy-supply = <&vcc_3v3_s3>;
+	pinctrl-0 = <&gmac1_miim
+		     &gmac1_tx_bus2
+		     &gmac1_rx_bus2
+		     &gmac1_rgmii_clk
+		     &gmac1_rgmii_bus
+		     &gmac1_clkinout>;
+	pinctrl-names = "default";
+};
+
+&gpu {
+	mali-supply = <&vdd_gpu_s0>;
+	status = "okay";
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0m2_xfer>;
+	status = "okay";
+
+	vdd_cpu_big0_s0: regulator at 42 {
+		compatible = "rockchip,rk8602";
+		reg = <0x42>;
+		fcs,suspend-voltage-selector = <1>;
+		regulator-name = "vdd_cpu_big0_s0";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <550000>;
+		regulator-max-microvolt = <1050000>;
+		regulator-ramp-delay = <2300>;
+		vin-supply = <&vcc_sysin>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+
+	vdd_cpu_big1_s0: regulator at 43 {
+		compatible = "rockchip,rk8603", "rockchip,rk8602";
+		reg = <0x43>;
+		fcs,suspend-voltage-selector = <1>;
+		regulator-name = "vdd_cpu_big1_s0";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <550000>;
+		regulator-max-microvolt = <1050000>;
+		regulator-ramp-delay = <2300>;
+		vin-supply = <&vcc_sysin>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+
+	eeprom at 50 {
+		compatible = "belling,bl24c16a", "atmel,24c16";
+		reg = <0x50>;
+		pagesize = <16>;
+		read-only;
+		vcc-supply = <&vcc_3v3_s3>;
+	};
+};
+
+&i2c2 {
+	status = "okay";
+
+	vdd_npu_s0: regulator at 42 {
+		compatible = "rockchip,rk8602";
+		reg = <0x42>;
+		fcs,suspend-voltage-selector = <1>;
+		regulator-name = "vdd_npu_s0";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <550000>;
+		regulator-max-microvolt = <950000>;
+		regulator-ramp-delay = <2300>;
+		vin-supply = <&vcc_sysin>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+};
+
+&mdio1 {
+	rgmii_phy1: ethernet-phy at 1 {
+		compatible = "ethernet-phy-id001c.c916";
+		reg = <1>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&gmac1_rstn>;
+		reset-assert-us = <20000>;
+		reset-deassert-us = <100000>;
+		reset-gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&pd_gpu {
+	domain-supply = <&vdd_gpu_s0>;
+};
+
+&pd_npu {
+	domain-supply = <&vdd_npu_s0>;
+};
+
+&pinctrl {
+	ethernet {
+		gmac1_rstn: gmac1-rstn {
+			rockchip,pins = <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	leds {
+		gpio4_b4: gpio4-b4 {
+			rockchip,pins = <4 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
+
+&rknn_core_0 {
+	npu-supply = <&vdd_npu_s0>;
+	sram-supply = <&vdd_npu_s0>;
+	status = "okay";
+};
+
+&rknn_core_1 {
+	npu-supply = <&vdd_npu_s0>;
+	sram-supply = <&vdd_npu_s0>;
+	status = "okay";
+};
+
+&rknn_core_2 {
+	npu-supply = <&vdd_npu_s0>;
+	sram-supply = <&vdd_npu_s0>;
+	status = "okay";
+};
+
+&rknn_mmu_0 {
+	status = "okay";
+};
+
+&rknn_mmu_1 {
+	status = "okay";
+};
+
+&rknn_mmu_2 {
+	status = "okay";
+};
+
+&saradc {
+	vref-supply = <&vcca_1v8_s0>;
+	status = "okay";
+};
+
+&sdhci {
+	bus-width = <8>;
+	cap-mmc-highspeed;
+	mmc-hs400-1_8v;
+	mmc-hs400-enhanced-strobe;
+	no-sd;
+	no-sdio;
+	non-removable;
+	vmmc-supply = <&vcc_3v3_s3>;
+	vqmmc-supply = <&vcc_1v8_s3>;
+	status = "okay";
+};
+
+&spi2 {
+	assigned-clocks = <&cru CLK_SPI2>;
+	assigned-clock-rates = <200000000>;
+	num-cs = <1>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
+	status = "okay";
+
+	pmic at 0 {
+		compatible = "rockchip,rk806";
+		reg = <0>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
+			    <&rk806_dvs2_null>, <&rk806_dvs3_null>;
+		spi-max-frequency = <1000000>;
+		system-power-controller;
+
+		vcc1-supply = <&vcc_sysin>;
+		vcc2-supply = <&vcc_sysin>;
+		vcc3-supply = <&vcc_sysin>;
+		vcc4-supply = <&vcc_sysin>;
+		vcc5-supply = <&vcc_sysin>;
+		vcc6-supply = <&vcc_sysin>;
+		vcc7-supply = <&vcc_sysin>;
+		vcc8-supply = <&vcc_sysin>;
+		vcc9-supply = <&vcc_sysin>;
+		vcc10-supply = <&vcc_sysin>;
+		vcc11-supply = <&vcc_2v0_pldo_s3>;
+		vcc12-supply = <&vcc_sysin>;
+		vcc13-supply = <&vcc_1v1_nldo_s3>;
+		vcc14-supply = <&vcc_1v1_nldo_s3>;
+		vcca-supply = <&vcc_sysin>;
+
+		rk806_dvs1_null: dvs1-null-pins {
+			pins = "gpio_pwrctrl1";
+			function = "pin_fun0";
+		};
+
+		rk806_dvs2_null: dvs2-null-pins {
+			pins = "gpio_pwrctrl2";
+			function = "pin_fun0";
+		};
+
+		rk806_dvs3_null: dvs3-null-pins {
+			pins = "gpio_pwrctrl3";
+			function = "pin_fun0";
+		};
+
+		regulators {
+			vdd_gpu_s0: dcdc-reg1 {
+				regulator-name = "vdd_gpu_s0";
+				regulator-boot-on;
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <950000>;
+				regulator-ramp-delay = <12500>;
+				regulator-enable-ramp-delay = <400>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_cpu_lit_s0: dcdc-reg2 {
+				regulator-name = "vdd_cpu_lit_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <950000>;
+				regulator-ramp-delay = <12500>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_logic_s0: dcdc-reg3 {
+				regulator-name = "vdd_logic_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <675000>;
+				regulator-max-microvolt = <800000>;
+				regulator-ramp-delay = <12500>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <750000>;
+				};
+			};
+
+			vdd_vdenc_s0: dcdc-reg4 {
+				regulator-name = "vdd_vdenc_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <950000>;
+				regulator-ramp-delay = <12500>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_ddr_s0: dcdc-reg5 {
+				regulator-name = "vdd_ddr_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <675000>;
+				regulator-max-microvolt = <900000>;
+				regulator-ramp-delay = <12500>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+					regulator-suspend-microvolt = <850000>;
+				};
+			};
+
+			vdd2_ddr_s3: dcdc-reg6 {
+				regulator-name = "vdd2_ddr_s3";
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			vcc_2v0_pldo_s3: dcdc-reg7 {
+				regulator-name = "vcc_2v0_pldo_s3";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <2000000>;
+				regulator-max-microvolt = <2000000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <2000000>;
+				};
+			};
+
+			vcc_3v3_s0: vcc_3v3_s3: dcdc-reg8 {
+				regulator-name = "vcc_3v3_s3";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vddq_ddr_s0: dcdc-reg9 {
+				regulator-name = "vddq_ddr_s0";
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_1v8_s3: dcdc-reg10 {
+				regulator-name = "vcc_1v8_s3";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vcc_1v8_s0: pldo-reg1 {
+				regulator-name = "vcc_1v8_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vcca_1v8_s0: pldo-reg2 {
+				regulator-name = "vcca_1v8_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vdda_1v2_s0: pldo-reg3 {
+				regulator-name = "vdda_1v2_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcca_3v3_s0: pldo-reg4 {
+				regulator-name = "vcca_3v3_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vccio_sd_s0: pldo-reg5 {
+				regulator-name = "vccio_sd_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			pldo-reg6 {
+				regulator-name = "pldo_reg6";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vdd_0v75_s3: nldo-reg1 {
+				regulator-name = "vdd_0v75_s3";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <750000>;
+				regulator-max-microvolt = <750000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <750000>;
+				};
+			};
+
+			vdda_ddr_pll_s0: nldo-reg2 {
+				regulator-name = "vdda_ddr_pll_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <850000>;
+				};
+			};
+
+			vdda_0v75_s0: nldo-reg3 {
+				regulator-name = "vdda_0v75_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <837500>;
+				regulator-max-microvolt = <837500>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <750000>;
+				};
+			};
+
+			vdda_0v85_s0: nldo-reg4 {
+				regulator-name = "vdda_0v85_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			hdmi_vdda0v85_s0: nldo-reg5 {
+				regulator-name = "hdmi_vdda0v85_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <837500>;
+				regulator-max-microvolt = <837500>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+		};
+	};
+};
+
+&tsadc {
+	rockchip,hw-tshut-mode = <1>; /* tshut mode 0:CRU 1:GPIO */
+	rockchip,hw-tshut-polarity = <0>; /* tshut polarity 0:LOW 1:HIGH */
+	status = "okay";
+};
+
+&vop {
+	status = "okay";
+};
+
+&vop_mmu {
+	status = "okay";
+};
-- 
2.43.0



From geraldogabriel at gmail.com  Tue Nov  4 21:55:10 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Wed, 5 Nov 2025 02:55:10 -0300
Subject: [PATCH] arm64: dts: rockchip: align bindings to PCIe spec
Message-ID: <4b5ffcccfef2a61838aa563521672a171acb27b2.1762321976.git.geraldogabriel@gmail.com>

The PERST# side-band signal is defined by PCIe spec as an open-drain
active-low signal that depends on a pull-up resistor to keep the
signal high when deasserted. Align bindings to the spec.

Note that the relevant driver hacks the active-low signal as
active-high and switches the normal polarity of PERST#
assertion/deassertion, 1 and 0 in that order, and instead uses
0 to signal low (assertion) and 1 to signal deassertion.

Incidentally, this change makes hardware that refused to work
with the Rockchip-IP PCIe core working for me, which was the
object of many fool's errands.

Signed-off-by: Geraldo Nascimento <geraldogabriel at gmail.com>
---
 arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
index aa70776e898a..8dcb03708145 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
@@ -383,9 +383,9 @@ &pcie_phy {
 };
 
 &pcie0 {
-	ep-gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>;
+	ep-gpios = <&gpio0 RK_PB4 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
 	num-lanes = <4>;
-	pinctrl-0 = <&pcie_clkreqnb_cpm>;
+	pinctrl-0 = <&pcie_clkreqnb_cpm>, <&pcie_perst>;
 	pinctrl-names = "default";
 	vpcie0v9-supply = <&vcca_0v9>;	/* VCC_0V9_S0 */
 	vpcie1v8-supply = <&vcca_1v8>;	/* VCC_1V8_S0 */
@@ -408,6 +408,10 @@ pcie {
 		pcie_pwr: pcie-pwr {
 			rockchip,pins = <4 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>;
 		};
+		pcie_perst: pcie-perst {
+			rockchip,pins = <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+
 	};
 
 	pmic {
-- 
2.49.0



From shawn.lin at rock-chips.com  Tue Nov  4 22:35:28 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Wed, 5 Nov 2025 14:35:28 +0800
Subject: [PATCH] arm64: dts: rockchip: align bindings to PCIe spec
In-Reply-To: <4b5ffcccfef2a61838aa563521672a171acb27b2.1762321976.git.geraldogabriel@gmail.com>
References: <4b5ffcccfef2a61838aa563521672a171acb27b2.1762321976.git.geraldogabriel@gmail.com>
Message-ID: <ba120577-42da-424d-8102-9d085c1494c8@rock-chips.com>

Hi Geraldo,

? 2025/11/05 ??? 13:55, Geraldo Nascimento ??:
> The PERST# side-band signal is defined by PCIe spec as an open-drain

I couldn't find any clue that says PERST# is an open-drain signal. Could
you quote it from PCI Express Card Electromechanical Specification?

> active-low signal that depends on a pull-up resistor to keep the
> signal high when deasserted. Align bindings to the spec.

This is not true from my POV. An open-drain PCIe side-band  signal
is used for both of EP and RC to achieve some special work-flow, like
CLKREQ# for L1ss, etc. Since both ends could control it. But PERST# is a
fundamental reset signal driven by RC which should be in sure state,
high or low, has nothing to do with open-drain.

> 
> Note that the relevant driver hacks the active-low signal as
> active-high and switches the normal polarity of PERST#
> assertion/deassertion, 1 and 0 in that order, and instead uses
> 0 to signal low (assertion) and 1 to signal deassertion.
> 
> Incidentally, this change makes hardware that refused to work
> with the Rockchip-IP PCIe core working for me, which was the
> object of many fool's errands.
> 
> Signed-off-by: Geraldo Nascimento <geraldogabriel at gmail.com>
> ---
>   arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi | 8 ++++++--
>   1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
> index aa70776e898a..8dcb03708145 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
> @@ -383,9 +383,9 @@ &pcie_phy {
>   };
>   
>   &pcie0 {
> -	ep-gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>;
> +	ep-gpios = <&gpio0 RK_PB4 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;

So my biggest guess is we don't need this change at all.
gpio0b4 is used as gpio function, the problem you faced is that it
didn't set gpio0b4 as pull-up, because the defaut state is pull-down.

Maybe the drive current of this IO is too weak, making it unable to 
fully drive high in the pull-down state? If that's the case, can you see 
a half-level signal on the oscilloscope?

>   	num-lanes = <4>;
> -	pinctrl-0 = <&pcie_clkreqnb_cpm>;
> +	pinctrl-0 = <&pcie_clkreqnb_cpm>, <&pcie_perst>;
>   	pinctrl-names = "default";
>   	vpcie0v9-supply = <&vcca_0v9>;	/* VCC_0V9_S0 */
>   	vpcie1v8-supply = <&vcca_1v8>;	/* VCC_1V8_S0 */
> @@ -408,6 +408,10 @@ pcie {
>   		pcie_pwr: pcie-pwr {
>   			rockchip,pins = <4 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>;
>   		};
> +		pcie_perst: pcie-perst {
> +			rockchip,pins = <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>;
> +		};
> +
>   	};
>   
>   	pmic {



From krzk at kernel.org  Tue Nov  4 22:42:17 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 5 Nov 2025 07:42:17 +0100
Subject: [PATCH v3 1/3] dt-bindings: arm: rockchip: Add Radxa CM5 IO board
In-Reply-To: <E04572034CE4DC35+005c7dd7-cb2f-4f82-9889-ac14733a7647@radxa.com>
References: <174735136138.1544989.11909422896170025756.robh@kernel.org>
 <20250528221823.2974653-1-joseph.kogut@gmail.com>
 <20250528221823.2974653-2-joseph.kogut@gmail.com>
 <20250529-impressive-real-monkey-a7818b@kuoka>
 <6443BD03B4C4F1FE+d20c3903-e2dc-4c2b-8f6e-fac38f242898@radxa.com>
 <2f4e7f94-2921-493c-94fa-45749a060bc0@kernel.org>
 <870075785A1ED2B9+6fb5238e-dc57-406b-acf9-b88b237d8e5b@radxa.com>
 <f12bc562-b5bb-4bdd-b274-23582df8f2d4@kernel.org>
 <E04572034CE4DC35+005c7dd7-cb2f-4f82-9889-ac14733a7647@radxa.com>
Message-ID: <86939056-7617-4730-9464-f7ecbd0e4537@kernel.org>

On 05/11/2025 02:37, FUKAUMI Naoki wrote:
> Hi Krzysztof
> 
> On 10/28/25 19:41, Krzysztof Kozlowski wrote:
>> On 28/10/2025 10:44, FUKAUMI Naoki wrote:
>>> Hi Joseph
>>>
>>> Your patch seems to be NAKed.
>>> I will submit new patch soon.
>>
>> Sorry, what? Don't hijack other people's work.
> 
> I have Joseph's permission to post my patch.

This patch is correct, so you taking and hijacking it is not acceptable.

Best regards,
Krzysztof


From krzk at kernel.org  Tue Nov  4 22:43:13 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 5 Nov 2025 07:43:13 +0100
Subject: [PATCH v6 1/3] dt-bindings: arm: rockchip: Add Radxa CM5 IO Board
In-Reply-To: <20251105051335.17652-2-naoki@radxa.com>
References: <20251105051335.17652-1-naoki@radxa.com>
 <20251105051335.17652-2-naoki@radxa.com>
Message-ID: <ce6e6369-a7e4-4a35-80f8-70ef41c3b877@kernel.org>

On 05/11/2025 06:13, FUKAUMI Naoki wrote:
> Add device tree binding documentation for the Radxa CM5 IO Board.
> 
> Link: https://dl.radxa.com/cm5/radxa_cm5_product_brief.pdf
> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>

Wrong DCO chain.

> ---
>  Documentation/devicetree/bindings/arm/rockchip.yaml | 7 +++++++

NAK, you just stolen ownership of an already posted patch.

Best regards,
Krzysztof


From krzk at kernel.org  Tue Nov  4 22:45:14 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 5 Nov 2025 07:45:14 +0100
Subject: [PATCH v6 2/3] arm64: dts: rockchip: Add Radxa CM5
In-Reply-To: <20251105051335.17652-3-naoki@radxa.com>
References: <20251105051335.17652-1-naoki@radxa.com>
 <20251105051335.17652-3-naoki@radxa.com>
Message-ID: <f2f0e888-253a-4b4c-b7f7-da35e7fa5532@kernel.org>

On 05/11/2025 06:13, FUKAUMI Naoki wrote:
> The Radxa CM5 is a high performance embedded SoM based on the Rockchip
> RK3588S2 SoC.
> 
> Specification:
> - Quad-core Cortex-A76 and quad-core Cortex-A55 CPU
> - Mali-G610 MP4 GPU
> - 6TOPS NPU
> - Up to 32GB LPDDR4x RAM
> - Up to 128GB on-board eMMC
> - On-board Gigabit Ethernet PHY
> - RK806-1 PMIC
> 
> Link: https://dl.radxa.com/cm5/v2210/radxa_cm5_v2210_schematic.pdf
> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>


NAK, wrong DCO chain and not attributed true authorship.

Stop taking other people's work. This was already posted.

Best regards,
Krzysztof


From krzk at kernel.org  Tue Nov  4 22:46:52 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 5 Nov 2025 07:46:52 +0100
Subject: [PATCH v6 3/3] arm64: dts: rockchip: Add Radxa CM5 IO Board
In-Reply-To: <20251105051335.17652-4-naoki@radxa.com>
References: <20251105051335.17652-1-naoki@radxa.com>
 <20251105051335.17652-4-naoki@radxa.com>
Message-ID: <d84d8f14-bc97-46c2-ad72-82d530af2b75@kernel.org>

On 05/11/2025 06:13, FUKAUMI Naoki wrote:
> The Radxa CM5 IO Board is an application board for the Radxa CM5.
> 
> Specification:
> - 1x HDMI TX
> - 2x MIPI DSI
> - 2x MIPI CSI
> - 1x USB 3.0 Type-A port
> - 1x USB 3.0 Type-C port (supports DisplayPort Alt mode)
> - 2x USB 2.0 Type-A ports
> - 1x Gigabit Ethernet (supports PoE with add-on PoE HAT)
> - 1x microSD card slot
> - 1x Fan header
> - 1x M.2 E Key slot
> - 1x Headphone jack with microphone input
> - 40-pin GPIO header
> - RTC and battery holder
> - 12V 5525 DC jack
> 
> Link: https://dl.radxa.com/cm5/io_board_v2200/radxa_cm5_io_board_v2200_schematic.pdf
> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>


Wrong here as well - incorrect author. You cannot just take other
people's work like that!

Best regards,
Krzysztof


From kevin.tian at intel.com  Tue Nov  4 22:57:31 2025
From: kevin.tian at intel.com (Tian, Kevin)
Date: Wed, 5 Nov 2025 06:57:31 +0000
Subject: [PATCH v1 02/20] iommu: Introduce a test_dev domain op and an
 internal helper
In-Reply-To: <20251103185400.GA1537560@nvidia.com>
References: <cover.1760312725.git.nicolinc@nvidia.com>
 <32ce256a2ece5d63e99d5858f953586859818ffc.1760312725.git.nicolinc@nvidia.com>
 <BN9PR11MB5276D10BD480FE66881870B08CFBA@BN9PR11MB5276.namprd11.prod.outlook.com>
 <aQO//+6/B/WbdK2h@Asurada-Nvidia> <20251103185400.GA1537560@nvidia.com>
Message-ID: <BN9PR11MB527638C0E43E8AA000410B878CC5A@BN9PR11MB5276.namprd11.prod.outlook.com>

> From: Jason Gunthorpe <jgg at nvidia.com>
> Sent: Tuesday, November 4, 2025 2:54 AM
> 
> On Thu, Oct 30, 2025 at 12:43:59PM -0700, Nicolin Chen wrote:
> 
> > FWIW, I am thinking of another design based on Jason's remarks:
> > https://lore.kernel.org/linux-iommu/aQBopHFub8wyQh5C at Asurada-
> Nvidia/
> >
> > So, instead of core initiating the round trip between the blocking
> > domain and group->domain, it forwards dev_reset_prepare/done to the
> > driver where it does a low-level attachment that wouldn't fail:
> >   For SMMUv3, it's an STE update.
> >   For intel_iommu, it seems to be the context table update?
> 
> Kevin, how bad do you think the UAPI issue is if we ignore it?
> 

yeah probably better to leave it. I didn't see a clean way and the
value didn't justify the complexity.

Regarding to PF reset, it's a devastating operation while the vf user
is operating the vf w/o any awareness. there must be certain
coordination in userspace. otherwise nobody can recover the
registers. Comparing to that, solving the domain attach problem
is less important...


From naoki at radxa.com  Tue Nov  4 22:57:08 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Wed, 5 Nov 2025 15:57:08 +0900
Subject: [PATCH v6 1/3] dt-bindings: arm: rockchip: Add Radxa CM5 IO Board
In-Reply-To: <ce6e6369-a7e4-4a35-80f8-70ef41c3b877@kernel.org>
References: <20251105051335.17652-1-naoki@radxa.com>
 <20251105051335.17652-2-naoki@radxa.com>
 <ce6e6369-a7e4-4a35-80f8-70ef41c3b877@kernel.org>
Message-ID: <A6C1199E2A0D3F37+f3fe0fd5-4ca5-4d3d-bc1d-45f46b48f89b@radxa.com>

On 11/5/25 15:43, Krzysztof Kozlowski wrote:
> On 05/11/2025 06:13, FUKAUMI Naoki wrote:
>> Add device tree binding documentation for the Radxa CM5 IO Board.
>>
>> Link: https://dl.radxa.com/cm5/radxa_cm5_product_brief.pdf
>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
>> Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
> 
> Wrong DCO chain.
> 
>> ---
>>   Documentation/devicetree/bindings/arm/rockchip.yaml | 7 +++++++
> 
> NAK, you just stolen ownership of an already posted patch.

Read "Changes in v6" and patches; my patches are not the same as v5.
Your reply is totally inappropriate.

> Best regards,
> Krzysztof
> 




From krzk at kernel.org  Tue Nov  4 23:08:25 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 5 Nov 2025 08:08:25 +0100
Subject: [PATCH v6 1/3] dt-bindings: arm: rockchip: Add Radxa CM5 IO Board
In-Reply-To: <A6C1199E2A0D3F37+f3fe0fd5-4ca5-4d3d-bc1d-45f46b48f89b@radxa.com>
References: <20251105051335.17652-1-naoki@radxa.com>
 <20251105051335.17652-2-naoki@radxa.com>
 <ce6e6369-a7e4-4a35-80f8-70ef41c3b877@kernel.org>
 <A6C1199E2A0D3F37+f3fe0fd5-4ca5-4d3d-bc1d-45f46b48f89b@radxa.com>
Message-ID: <93deab54-bd5e-433e-acbc-13f6ead47f43@kernel.org>

On 05/11/2025 07:57, FUKAUMI Naoki wrote:
> On 11/5/25 15:43, Krzysztof Kozlowski wrote:
>> On 05/11/2025 06:13, FUKAUMI Naoki wrote:
>>> Add device tree binding documentation for the Radxa CM5 IO Board.
>>>
>>> Link: https://dl.radxa.com/cm5/radxa_cm5_product_brief.pdf
>>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
>>> Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
>>
>> Wrong DCO chain.
>>
>>> ---
>>>   Documentation/devicetree/bindings/arm/rockchip.yaml | 7 +++++++
>>
>> NAK, you just stolen ownership of an already posted patch.
> 
> Read "Changes in v6" and patches; my patches are not the same as v5.
> Your reply is totally inappropriate.

Inappropriate is taking authorship of someone's patch, because we all
expect to preserve the original authorship. That's not only basic
decency but actually a standard.

Additionally, read Joseph's reply that he wants to continue the work:
https://lore.kernel.org/all/CAMWSM7iHtAxewW4JkRqRsifVnccqeFviaCgeOyprKDr92FOurg at mail.gmail.com/

You clearly do not understand how to continue with someone's work.

It is still a NAK.

Best regards,
Krzysztof


From geraldogabriel at gmail.com  Wed Nov  5 00:18:37 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Wed, 5 Nov 2025 05:18:37 -0300
Subject: [PATCH] arm64: dts: rockchip: align bindings to PCIe spec
In-Reply-To: <ba120577-42da-424d-8102-9d085c1494c8@rock-chips.com>
References: <4b5ffcccfef2a61838aa563521672a171acb27b2.1762321976.git.geraldogabriel@gmail.com>
 <ba120577-42da-424d-8102-9d085c1494c8@rock-chips.com>
Message-ID: <aQsIXcQzeYop6a0B@geday>

On Wed, Nov 05, 2025 at 02:35:28PM +0800, Shawn Lin wrote:
> Hi Geraldo,
> 
> ? 2025/11/05 ??? 13:55, Geraldo Nascimento ??:
> > The PERST# side-band signal is defined by PCIe spec as an open-drain
> 
> I couldn't find any clue that says PERST# is an open-drain signal. Could
> you quote it from PCI Express Card Electromechanical Specification?
> 
> > active-low signal that depends on a pull-up resistor to keep the
> > signal high when deasserted. Align bindings to the spec.
> 
> This is not true from my POV. An open-drain PCIe side-band  signal
> is used for both of EP and RC to achieve some special work-flow, like
> CLKREQ# for L1ss, etc. Since both ends could control it. But PERST# is a
> fundamental reset signal driven by RC which should be in sure state,
> high or low, has nothing to do with open-drain.
> 
> > 
> > Note that the relevant driver hacks the active-low signal as
> > active-high and switches the normal polarity of PERST#
> > assertion/deassertion, 1 and 0 in that order, and instead uses
> > 0 to signal low (assertion) and 1 to signal deassertion.
> > 
> > Incidentally, this change makes hardware that refused to work
> > with the Rockchip-IP PCIe core working for me, which was the
> > object of many fool's errands.
> > 
> > Signed-off-by: Geraldo Nascimento <geraldogabriel at gmail.com>
> > ---
> >   arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi | 8 ++++++--
> >   1 file changed, 6 insertions(+), 2 deletions(-)
> > 
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
> > index aa70776e898a..8dcb03708145 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
> > +++ b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
> > @@ -383,9 +383,9 @@ &pcie_phy {
> >   };
> >   
> >   &pcie0 {
> > -	ep-gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>;
> > +	ep-gpios = <&gpio0 RK_PB4 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
> 
> So my biggest guess is we don't need this change at all.
> gpio0b4 is used as gpio function, the problem you faced is that it
> didn't set gpio0b4 as pull-up, because the defaut state is pull-down.
> 
> Maybe the drive current of this IO is too weak, making it unable to 
> fully drive high in the pull-down state? If that's the case, can you see 
> a half-level signal on the oscilloscope?
> 
> >   	num-lanes = <4>;
> > -	pinctrl-0 = <&pcie_clkreqnb_cpm>;
> > +	pinctrl-0 = <&pcie_clkreqnb_cpm>, <&pcie_perst>;
> >   	pinctrl-names = "default";
> >   	vpcie0v9-supply = <&vcca_0v9>;	/* VCC_0V9_S0 */
> >   	vpcie1v8-supply = <&vcca_1v8>;	/* VCC_1V8_S0 */
> > @@ -408,6 +408,10 @@ pcie {
> >   		pcie_pwr: pcie-pwr {
> >   			rockchip,pins = <4 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>;
> >   		};
> > +		pcie_perst: pcie-perst {
> > +			rockchip,pins = <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>;
> > +		};
> > +
> >   	};
> >   
> >   	pmic {
>

Hi Shawn, glad to hear from you.

Perhaps the following change is better? It resolves the issue
without the added complication of open drain. After you questioned
if open drain is actually part of the spec, I remembered that
GPIO_OPEN_DRAIN is actually (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_DRAIN)
so I decided to test with just GPIO_SINGLE_ENDED and it works.

Thanks,
Geraldo Nascimento

---

diff --git a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
index aa70776e898a..b3d19dce539f 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
@@ -383,7 +383,7 @@ &pcie_phy {
 };
 
 &pcie0 {
-	ep-gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>;
+	ep-gpios = <&gpio0 RK_PB4 (GPIO_ACTIVE_HIGH | GPIO_SINGLE_ENDED)>;
 	num-lanes = <4>;
 	pinctrl-0 = <&pcie_clkreqnb_cpm>;
 	pinctrl-names = "default";


From shawn.lin at rock-chips.com  Wed Nov  5 00:56:36 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Wed, 5 Nov 2025 16:56:36 +0800
Subject: [PATCH] arm64: dts: rockchip: align bindings to PCIe spec
In-Reply-To: <aQsIXcQzeYop6a0B@geday>
References: <4b5ffcccfef2a61838aa563521672a171acb27b2.1762321976.git.geraldogabriel@gmail.com>
 <ba120577-42da-424d-8102-9d085c1494c8@rock-chips.com>
 <aQsIXcQzeYop6a0B@geday>
Message-ID: <67b605b0-7046-448a-bc9b-d3ac56333809@rock-chips.com>

? 2025/11/05 ??? 16:18, Geraldo Nascimento ??:
> On Wed, Nov 05, 2025 at 02:35:28PM +0800, Shawn Lin wrote:
>> Hi Geraldo,
>>
>> ? 2025/11/05 ??? 13:55, Geraldo Nascimento ??:
>>> The PERST# side-band signal is defined by PCIe spec as an open-drain
>>
>> I couldn't find any clue that says PERST# is an open-drain signal. Could
>> you quote it from PCI Express Card Electromechanical Specification?
>>
>>> active-low signal that depends on a pull-up resistor to keep the
>>> signal high when deasserted. Align bindings to the spec.
>>
>> This is not true from my POV. An open-drain PCIe side-band  signal
>> is used for both of EP and RC to achieve some special work-flow, like
>> CLKREQ# for L1ss, etc. Since both ends could control it. But PERST# is a
>> fundamental reset signal driven by RC which should be in sure state,
>> high or low, has nothing to do with open-drain.
>>
>>>
>>> Note that the relevant driver hacks the active-low signal as
>>> active-high and switches the normal polarity of PERST#
>>> assertion/deassertion, 1 and 0 in that order, and instead uses
>>> 0 to signal low (assertion) and 1 to signal deassertion.
>>>
>>> Incidentally, this change makes hardware that refused to work
>>> with the Rockchip-IP PCIe core working for me, which was the
>>> object of many fool's errands.
>>>
>>> Signed-off-by: Geraldo Nascimento <geraldogabriel at gmail.com>
>>> ---
>>>    arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi | 8 ++++++--
>>>    1 file changed, 6 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
>>> index aa70776e898a..8dcb03708145 100644
>>> --- a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
>>> +++ b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
>>> @@ -383,9 +383,9 @@ &pcie_phy {
>>>    };
>>>    
>>>    &pcie0 {
>>> -	ep-gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>;
>>> +	ep-gpios = <&gpio0 RK_PB4 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
>>
>> So my biggest guess is we don't need this change at all.
>> gpio0b4 is used as gpio function, the problem you faced is that it
>> didn't set gpio0b4 as pull-up, because the defaut state is pull-down.
>>
>> Maybe the drive current of this IO is too weak, making it unable to
>> fully drive high in the pull-down state? If that's the case, can you see
>> a half-level signal on the oscilloscope?
>>
>>>    	num-lanes = <4>;
>>> -	pinctrl-0 = <&pcie_clkreqnb_cpm>;
>>> +	pinctrl-0 = <&pcie_clkreqnb_cpm>, <&pcie_perst>;
>>>    	pinctrl-names = "default";
>>>    	vpcie0v9-supply = <&vcca_0v9>;	/* VCC_0V9_S0 */
>>>    	vpcie1v8-supply = <&vcca_1v8>;	/* VCC_1V8_S0 */
>>> @@ -408,6 +408,10 @@ pcie {
>>>    		pcie_pwr: pcie-pwr {
>>>    			rockchip,pins = <4 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>;
>>>    		};
>>> +		pcie_perst: pcie-perst {
>>> +			rockchip,pins = <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>;
>>> +		};
>>> +
>>>    	};
>>>    
>>>    	pmic {
>>
> 
> Hi Shawn, glad to hear from you.
> 
> Perhaps the following change is better? It resolves the issue
> without the added complication of open drain. After you questioned
> if open drain is actually part of the spec, I remembered that
> GPIO_OPEN_DRAIN is actually (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_DRAIN)
> so I decided to test with just GPIO_SINGLE_ENDED and it works.


Does that work for you too?

&pcie0 {
	ep-gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>;
  	num-lanes = <4>;
-	pinctrl-0 = <&pcie_clkreqnb_cpm>;
+	pinctrl-0 = <&pcie_clkreqnb_cpm>, <&pcie_perst>;
  	pinctrl-names = "default";
  	vpcie0v9-supply = <&vcca_0v9>;	/* VCC_0V9_S0 */
  	vpcie1v8-supply = <&vcca_1v8>;	/* VCC_1V8_S0 */
@@ -408,6 +408,10 @@ pcie {
  		pcie_pwr: pcie-pwr {
  			rockchip,pins = <4 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>;
  		};
+		pcie_perst: pcie-perst {
+			rockchip,pins = <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+
  	};

> 
> Thanks,
> Geraldo Nascimento
> 
> ---
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
> index aa70776e898a..b3d19dce539f 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
> @@ -383,7 +383,7 @@ &pcie_phy {
>   };
>   
>   &pcie0 {
> -	ep-gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>;
> +	ep-gpios = <&gpio0 RK_PB4 (GPIO_ACTIVE_HIGH | GPIO_SINGLE_ENDED)>;
>   	num-lanes = <4>;
>   	pinctrl-0 = <&pcie_clkreqnb_cpm>;
>   	pinctrl-names = "default";
> 



From diederik at cknow-tech.com  Wed Nov  5 01:06:53 2025
From: diederik at cknow-tech.com (Diederik de Haas)
Date: Wed, 05 Nov 2025 10:06:53 +0100
Subject: [RFC PATCH 2/2] PCI: rockchip-host: drop wait on PERST# toggle
In-Reply-To: <aQrKtFT0ldc70gKj@geday>
References: <d3d0c3a387ff461e62bbd66a0bde654a9a17761e.1762150971.git.geraldogabriel@gmail.com> <20251103181038.GA1814635@bhelgaas> <aQrKtFT0ldc70gKj@geday>
Message-ID: <DE0N4LA8MOJD.236O12UZ3I3C4@cknow-tech.com>

On Wed Nov 5, 2025 at 4:55 AM CET, Geraldo Nascimento wrote:
> On Mon, Nov 03, 2025 at 12:10:38PM -0600, Bjorn Helgaas wrote:
>> On Mon, Nov 03, 2025 at 03:27:25AM -0300, Geraldo Nascimento wrote:
>> > With this change PCIe will complete link-training with a known quirky
>> > device - Samsung OEM PM981a SSD. This is completely against the PCIe
>
> Something in my intuition kept telling me this was PERST# related,
> and so I followed that rabbit-hole.
>
> It seems the following change will allow the SSD to work with the
> Rockchip-IP PCIe core without any other changes. So it is purely
> a DT change and we are able to keep the mandatory 100ms delay
> after driving PERST# low, as well as the always-on/boot-on
> properties of the 3v3 power regulator.
>
> This time everything is within the PCIe spec AFAICT, PERST# indeed
> is an Open Drain signal, and indeed it does requires pull-up resistor
> to maintain the drive after driving it high.
>
> I'm still testing the overall stability of this, let's hope for the
> best!

I have a Samsung PM981 (without the 'a') and AFAICT it works fine.
I had noticed that the PERST# (pinctrl) was missing, but 'ep-gpios'
was/is new to me and I hadn't had time to research that properly yet.
Good to see you already found it yourself :-)

Cheers,
  Diederik

> diff --git a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
> index aa70776e898a..1c5afc0413bc 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
> @@ -383,13 +383,14 @@ &pcie_phy {
>  };
>  
>  &pcie0 {
> -	ep-gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>;
> +	ep-gpios = <&gpio0 RK_PB4 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
>  	num-lanes = <4>;
> -	pinctrl-0 = <&pcie_clkreqnb_cpm>;
> +	pinctrl-0 = <&pcie_clkreqnb_cpm>, <&pcie_perst>;
>  	pinctrl-names = "default";
>  	vpcie0v9-supply = <&vcca_0v9>;	/* VCC_0V9_S0 */
>  	vpcie1v8-supply = <&vcca_1v8>;	/* VCC_1V8_S0 */
>  	vpcie3v3-supply = <&vcc3v3_pcie>;
> +	max-link-speed = <2>;
>  	status = "okay";
>  };
>  
> @@ -408,6 +409,10 @@ pcie {
>  		pcie_pwr: pcie-pwr {
>  			rockchip,pins = <4 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>;
>  		};
> +		pcie_perst: pcie-perst {
> +			rockchip,pins = <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>;
> +		};
> +
>  	};
>  
>  	pmic {
>


From k.yankevich at omp.ru  Wed Nov  5 02:04:39 2025
From: k.yankevich at omp.ru (Karina Yankevich)
Date: Wed, 5 Nov 2025 13:04:39 +0300
Subject: [PATCH] drm/rockchip: gem: Fix memory leak when drm object init failed
Message-ID: <20251105100439.2780370-1-k.yankevich@omp.ru>

If drm_gem_object_init() call in rockchip_gem_alloc_object() fails
then rk_obj isn't freed. Fix this by checking drm_gem_object_init()'s
result.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes: 6fd0bfe2f7ea ("drm/rockchip: support prime import sg table")
Signed-off-by: Karina Yankevich <k.yankevich at omp.ru>
Reviewed-by: Sergey Shtylyov <s.shtylyov at omp.ru>
---
 drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index 6330b883efc3..ad888f9379db 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -284,6 +284,7 @@ static struct rockchip_gem_object *
 {
 	struct rockchip_gem_object *rk_obj;
 	struct drm_gem_object *obj;
+	int ret;
 
 	size = round_up(size, PAGE_SIZE);
 
@@ -295,7 +296,12 @@ static struct rockchip_gem_object *
 
 	obj->funcs = &rockchip_gem_object_funcs;
 
-	drm_gem_object_init(drm, obj, size);
+	ret = drm_gem_object_init(drm, obj, size);
+	if (ret) {
+		DRM_ERROR("failed to initialize gem object: %d\n", ret);
+		kfree(rk_obj);
+		return ERR_PTR(ret);
+	}
 
 	return rk_obj;
 }
-- 
2.34.1



From linux.amoon at gmail.com  Wed Nov  5 03:59:12 2025
From: linux.amoon at gmail.com (Anand Moon)
Date: Wed, 5 Nov 2025 17:29:12 +0530
Subject: [PATCH] arm64: dts: rockchip: fix eMMC corruption on NanoPC-T6
 with A3A444 chips
In-Reply-To: <e52de2b5-bf10-ce0e-66b7-66b1c46525f3@manjaro.org>
References: <20251017073954.130710-1-cnsztl@gmail.com> <08911ae2-fef3-432d-a236-d820c9cb67ac@gmail.com>
 <5af928c4-4b6e-489c-ad39-26cef3dd7473@gmail.com> <10751338.nUPlyArG6x@phil> <e52de2b5-bf10-ce0e-66b7-66b1c46525f3@manjaro.org>
Message-ID: <CANAwSgRXwozYr8sYtV8RRb1jJAb=9VNPfsLGMmW=f38XV-u=MQ@mail.gmail.com>

Hi All,

On Sat, 1 Nov 2025 at 18:21, Dragan Simic <dsimic at manjaro.org> wrote:
>
> Hello Heiko,
>
> On Saturday, November 01, 2025 12:54 CET, Heiko Stuebner <heiko at sntech.de> wrote:
> > Am Montag, 27. Oktober 2025, 18:34:25 Mitteleurop?ische Normalzeit schrieb Tianling Shen:
> > > On 2025/10/20 12:44, Tianling Shen wrote:
> > > > On 2025/10/20 9:53, Shawn Lin wrote:
> > > >> On 2025/10/17 Friday 15:39, Tianling Shen wrote:
> > > >>> From: Grzegorz Sterniczuk <grzegorz at sternicz.uk>
> > > >>>
> > > >>> Some NanoPC-T6 boards with A3A444 eMMC chips experience I/O errors and
> > > >>> corruption when using HS400 mode. Downgrade to HS200 mode to ensure
> > > >>> stable operation.
> > > >>
> > > >> May I ask you to test another patch I just posted to see if it fixes
> > > >> your issue?
> > > >>
> > > >> https://patchwork.kernel.org/project/linux-mmc/
> > > >> patch/1760924981-52339-1- git-send-email-shawn.lin at rock-chips.com/
> > > >
> > > > Thank you for the patch! I will ask my friend to test it but he uses
> > > > this board as a home router, so it may take a few days or weeks to
> > > > report the result.
> > >
> > > Hi all, sorry for the late. My friend has tested this patch and it works
> > > fine after 50 times dd operation. A big thanks to Shawn!
> >
> > So I guess, we don't need the patch reducing the speed anymore, right?
>
> Exactly, the approach of lowering the speed of eMMC to improve
> its reliability is no longer needed, thanks to Shawn correcting
> the DLL_STRBIN_TAPNUM_DEFAULT value in the above-linked patch.
>
> We just need to test does HS400 work on the ROCK 5 ITX reliably
> as well, so the previous lowering to HS200 in commit b36402e4a077
> ("arm64: dts: rockchip: slow down emmc freq for rock 5 itx", 2025-
> 02-28) could be reverted as no longer needed.
>
> > > And hi Jianfeng, I found you made a similiar patch[1] for the ROCK 5 ITX
> > > board to lower down the mmc speed, could you please check if this patch
> > > also fixes your issue?
> > >
> > > [1] https://lore.kernel.org/linux-rockchip/20250228143341.70244-1-liujianfeng1994 at gmail.com/
> > >
> > > >>> Signed-off-by: Grzegorz Sterniczuk <grzegorz at sternicz.uk>
> > > >>> Signed-off-by: Tianling Shen <cnsztl at gmail.com>
> > > >>> ---
> > > >>>   arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi | 3 +--
> > > >>>   1 file changed, 1 insertion(+), 2 deletions(-)
> > > >>>
> > > >>> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi b/
> > > >>> arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
> > > >>> index fafeabe9adf9..5f63f38f7326 100644
> > > >>> --- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
> > > >>> +++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
> > > >>> @@ -717,8 +717,7 @@ &sdhci {
> > > >>>       no-sd;
> > > >>>       non-removable;
> > > >>>       max-frequency = <200000000>;
> > > >>> -    mmc-hs400-1_8v;
> > > >>> -    mmc-hs400-enhanced-strobe;
> > > >>> +    mmc-hs200-1_8v;
> > > >>>       status = "okay";
> > > >>>   };
>
You can also try this patch, which enables stober in the eMMC controller..

diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c
b/drivers/mmc/host/sdhci-of-dwcmshc.c
index eebd45389956..62c9faf8ec85 100644
--- a/drivers/mmc/host/sdhci-of-dwcmshc.c
+++ b/drivers/mmc/host/sdhci-of-dwcmshc.c
@@ -77,6 +77,10 @@
 #define CV18XX_RETRY_TUNING_MAX                        50

 /* Rockchip specific Registers */
+#define DWCMSHC_EMMC_CTRL              0x52c
+#define  EMMC_CTRL_CARD_IS_EMMC        BIT(0)
+#define  EMMC_CTRL_ENH_STROBE_ENABLE   BIT(8)
+
 #define DWCMSHC_EMMC_DLL_CTRL          0x800
 #define DWCMSHC_EMMC_DLL_RXCLK         0x804
 #define DWCMSHC_EMMC_DLL_TXCLK         0x808
@@ -660,6 +664,12 @@ static void dwcmshc_rk3568_set_clock(struct
sdhci_host *host, unsigned int clock
                        DLL_CMDOUT_TAPNUM_90_DEGREES |
                        DLL_CMDOUT_TAPNUM_FROM_SW;
                sdhci_writel(host, extra, DECMSHC_EMMC_DLL_CMDOUT);
+
+               extra = sdhci_readl(host, DWCMSHC_EMMC_CTRL);
+               if (extra & EMMC_CTRL_CARD_IS_EMMC) {
+                       extra |= EMMC_CTRL_ENH_STROBE_ENABLE;
+                       sdhci_writel(host, extra, DWCMSHC_EMMC_CTRL);
+               }
        }

        extra = DWCMSHC_EMMC_DLL_DLYENA |

Thamks
-Anand


From naoki at radxa.com  Wed Nov  5 04:15:11 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Wed, 5 Nov 2025 21:15:11 +0900
Subject: [PATCH v6 0/3] Add Radxa CM5 and IO Board
In-Reply-To: <20251105051335.17652-1-naoki@radxa.com>
References: <20251105051335.17652-1-naoki@radxa.com>
Message-ID: <199E172C8E20ED38+71169242-5525-4d60-9e37-a03ad172d639@radxa.com>

I'd like to clarify the situation regarding the v6 patch series I submitted.

The original device tree work for the Radxa CM5 and IO Board was 
authored by Joseph Kogut. I took over the responsibility of getting it 
upstreamed with his agreement.

However, I now understand that I should have preserved the original 
Signed-off-by chain (and DCO) in the v6 series. This was my oversight.

To correct this, I would prefer for Joseph to post the patches himself, 
which will not include my Signed-off-by.

My apologies for the confusion this caused. Thank you for pointing this out.

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

On 11/5/25 14:13, FUKAUMI Naoki wrote:
> This patch series add support for the Radxa CM5 SoM and IO Board.
> 
> Changes in v6:
> (Patch 1/3)
> - Fix description; "Radxa CM5" is the correct name
> (Patch 2/3)
> - Fix #include(s)
> - Include rk3588s.dtsi
> - Move alias for gmac1 from io board dts
> - Add Maskrom key
> - Add pinctrl-* for led-0
> - Add vcc_1v1_nldo_s3 regulator for pmic
> - Move gmac1 (except status) from io board dts
> - Fix phy-supply for gmac1
> - Fix compatible for vdd_cpu_big1_s0 regulator
> - Add eeprom on i2c0
> - Add vdd_npu_s0 regulator for rknn
> - Fix compatible for rgmii_phy1
> - Add pinctrl-* and reset-* for rgmii_phy1
> - Add domain-supply for pd_npu
> - Add rknn_*
> - Add saradc
> - Fix properties in sdhci
> - Move pmic from io board dts
> - Fix vcc*-supply for pmic
> - Add regulators in pmic
> - Add tsadc
> - Move vop(_mmu) from io board dts
> - Trivial changes (labels, names, etc)
> (Patch 3/3)
> - Fix #include(s)
> - Remove #include "rk3588s.dtsi"
> - Fix model
> - Add fan
> - Add Recovery key
> - Add pinctrl-* for vcc3v3_wf
> - Add vcc_sysin regulator
> - Add pinctrl-* for vbus5v0_typec
> - Add rfkill-bt and rfkill-wlan for M.2 module
> - Add sound for es8316
> - Add phy-supply for combphy2_psu
> - Fix power-role to "source" for fusb302
> - Add rtc for hym8536
> - Add audio-codec on i2c8 for es8316
> - Add i2s0_8ch for es8316
> - Add package_thermal for fan
> - Add pinctrl-* for pcie2x1l2
> - Add pwm11 for fan
> - Fix properties in sdmmmc
> - Add phy-supply for u2phy2_host and u2phy3_host
> - Remove usb_host0_ohci
> - Add pinctrl-* for usbdp_phy0
> - Trivial changes (labels, names, etc)
> 
> Changes in v5:
> (Patch 2/3, per Jimmy)
> - Alias eMMC to mmc0
> - Remove unused sdio alias
> - Move gmac, hdmi0 nodes to carrier board dts
> (Patch 3/3, per Jimmy)
> - Enable hdmi0_sound and i2s5_8ch
> - Remove redundant enablement of sdhci
> - Enable usb_host2_xhci
> 
> - Tested HDMI audio
> 
> Changes in v4:
> - Fixed XHCI initialization bug by changing try-power-role from source
>    to sink
> 
> Changes in v3:
> - Addressed YAML syntax error in dt binding (per Rob)
> - Fixed whitespace issue in dts reported by checkpatch.pl
> - Split base SoM and carrier board into separate patches
> - Added further details about the SoM and carrier to the commit
>    messages
> 
> Changes in v2:
> - Added copyright header and data sheet links
> - Removed non-existent property
> - Sorted alphabetically
> - Removed errant whitespace
> - Moved status to the end of each node
> - Removed pinctrl-names property from leds (indicated by CHECK_DTBS)
> - Removed delays from gmac with internal delay
> 
> Link: https://lore.kernel.org/r/20250617-rk3588s-cm5-io-dts-upstream-v5-0-8d96854a5bbd at gmail.com
> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
> ---
> I have communicated with Joseph privately and taken ownership of
> moving this forward, with his blessing. All bugs belong to me.
> ---
> FUKAUMI Naoki (3):
>    dt-bindings: arm: rockchip: Add Radxa CM5 IO Board
>    arm64: dts: rockchip: Add Radxa CM5
>    arm64: dts: rockchip: Add Radxa CM5 IO Board
> 
>   .../devicetree/bindings/arm/rockchip.yaml     |   7 +
>   arch/arm64/boot/dts/rockchip/Makefile         |   1 +
>   .../dts/rockchip/rk3588s-radxa-cm5-io.dts     | 503 +++++++++++++++
>   .../boot/dts/rockchip/rk3588s-radxa-cm5.dtsi  | 602 ++++++++++++++++++
>   4 files changed, 1113 insertions(+)
>   create mode 100644 arch/arm64/boot/dts/rockchip/rk3588s-radxa-cm5-io.dts
>   create mode 100644 arch/arm64/boot/dts/rockchip/rk3588s-radxa-cm5.dtsi




From diederik at cknow-tech.com  Wed Nov  5 05:08:59 2025
From: diederik at cknow-tech.com (Diederik de Haas)
Date: Wed, 05 Nov 2025 14:08:59 +0100
Subject: [PATCH 1/3] dt-bindings: clock: rk3568: Add SCMI clock ids
In-Reply-To: <20251103234926.416137-2-heiko@sntech.de>
References: <20251103234926.416137-1-heiko@sntech.de>
 <20251103234926.416137-2-heiko@sntech.de>
Message-ID: <DE0S9YBDI0NK.2892TZHYSQLFM@cknow-tech.com>

On Tue Nov 4, 2025 at 12:49 AM CET, Heiko Stuebner wrote:
> The Trusted Firmware on RK3568 exposes 3 clocks via the SCMI clock
> interface. Add descriptive IDs for them.
>
> The clock ids are used in both the older vendor-binary TF-A, as well
> as the recently merged upstream SCMI clock implementation.
>
> Link: https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/31265
> Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> ---
>  include/dt-bindings/clock/rk3568-cru.h | 6 ++++++
>  1 file changed, 6 insertions(+)
>
> diff --git a/include/dt-bindings/clock/rk3568-cru.h b/include/dt-bindings/clock/rk3568-cru.h
> index f01f0e9ce8f1..1e0aef8a645d 100644
> --- a/include/dt-bindings/clock/rk3568-cru.h
> +++ b/include/dt-bindings/clock/rk3568-cru.h
> @@ -483,6 +483,12 @@
>  
>  #define PCLK_CORE_PVTM		450
>  
> +/* scmi-clocks indices */
> +
> +#define SCMI_CLK_CPU		0
> +#define SCMI_CLK_GPU		1
> +#define SCMI_CLK_NPU		2
> +

This corresponds with the id's in ``clock_table`` in TF-A's
``plat/rockchip/rk3568/drivers/scmi/rk3568_clk.c`` file, so

Reviewed-by: Diederik de Haas <diederik at cknow-tech.com>

>  /* pmu soft-reset indices */
>  /* pmucru_softrst_con0 */
>  #define SRST_P_PDPMU_NIU	0



From diederik at cknow-tech.com  Wed Nov  5 05:16:42 2025
From: diederik at cknow-tech.com (Diederik de Haas)
Date: Wed, 05 Nov 2025 14:16:42 +0100
Subject: [PATCH 2/3] arm64: dts: rockchip: use SCMI clock id for cpu
 clock on rk356x
In-Reply-To: <20251103234926.416137-3-heiko@sntech.de>
References: <20251103234926.416137-1-heiko@sntech.de>
 <20251103234926.416137-3-heiko@sntech.de>
Message-ID: <DE0SFV203UMS.1ZV2JE6QEPN29@cknow-tech.com>

Hi Heiko,

On Tue Nov 4, 2025 at 12:49 AM CET, Heiko Stuebner wrote:
> Instead of hard-coding 0, use the more descriptive ID from the binding
> to reference the SCMI clock for the cpu on rk356x.

Any particular reason you only did it for the cpu, but not the gpu?

> Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> ---
>  arch/arm64/boot/dts/rockchip/rk356x-base.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
> index a3361527d4fe..d0c76401b45e 100644
> --- a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
> @@ -53,7 +53,7 @@ cpu0: cpu at 0 {
>  			device_type = "cpu";
>  			compatible = "arm,cortex-a55";
>  			reg = <0x0 0x0>;
> -			clocks = <&scmi_clk 0>;
> +			clocks = <&scmi_clk SCMI_CLK_CPU>;

Regardless of the above comment, feel free to add

Reviewed-by: Diederik de Haas <diederik at cknow-tech.com>

Cheers,
  Diederik

>  			#cooling-cells = <2>;
>  			enable-method = "psci";
>  			i-cache-size = <0x8000>;



From diederik at cknow-tech.com  Wed Nov  5 05:18:21 2025
From: diederik at cknow-tech.com (Diederik de Haas)
Date: Wed, 05 Nov 2025 14:18:21 +0100
Subject: [PATCH 3/3] arm64: dts: rockchip: add missing clocks for cpu
 cores on rk356x
In-Reply-To: <20251103234926.416137-4-heiko@sntech.de>
References: <20251103234926.416137-1-heiko@sntech.de>
 <20251103234926.416137-4-heiko@sntech.de>
Message-ID: <DE0SH4UBVXBH.77ADEH3224GK@cknow-tech.com>

On Tue Nov 4, 2025 at 12:49 AM CET, Heiko Stuebner wrote:
> All cpu cores are supplied by the same clock, but all except the first
> core are missing that clocks reference - add the missing ones.

I noticed it myself some time ago (but failed to sent a patch), so

Reviewed-by: Diederik de Haas <diederik at cknow-tech.com>

Cheers,
  Diederik

> Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> ---
>  arch/arm64/boot/dts/rockchip/rk356x-base.dtsi | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
> index d0c76401b45e..a1815f8a96e1 100644
> --- a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
> @@ -69,6 +69,7 @@ cpu1: cpu at 100 {
>  			device_type = "cpu";
>  			compatible = "arm,cortex-a55";
>  			reg = <0x0 0x100>;
> +			clocks = <&scmi_clk SCMI_CLK_CPU>;
>  			#cooling-cells = <2>;
>  			enable-method = "psci";
>  			i-cache-size = <0x8000>;
> @@ -84,6 +85,7 @@ cpu2: cpu at 200 {
>  			device_type = "cpu";
>  			compatible = "arm,cortex-a55";
>  			reg = <0x0 0x200>;
> +			clocks = <&scmi_clk SCMI_CLK_CPU>;
>  			#cooling-cells = <2>;
>  			enable-method = "psci";
>  			i-cache-size = <0x8000>;
> @@ -99,6 +101,7 @@ cpu3: cpu at 300 {
>  			device_type = "cpu";
>  			compatible = "arm,cortex-a55";
>  			reg = <0x0 0x300>;
> +			clocks = <&scmi_clk SCMI_CLK_CPU>;
>  			#cooling-cells = <2>;
>  			enable-method = "psci";
>  			i-cache-size = <0x8000>;



From k.yankevich at omp.ru  Wed Nov  5 06:52:04 2025
From: k.yankevich at omp.ru (Karina Yankevich)
Date: Wed, 5 Nov 2025 17:52:04 +0300
Subject: [PATCH] crypto: rockchip - drop redundant crypto_skcipher_ivsize() calls
Message-ID: <20251105145204.2888978-1-k.yankevich@omp.ru>

The function already initialized the ivsize variable 
at the point of declaration, let's use it instead of 
calling crypto_skcipher_ivsize() extra couple times.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes: 57d67c6e8219 ("crypto: rockchip - rework by using crypto_engine")
Signed-off-by: Karina Yankevich <k.yankevich at omp.ru>
Reviewed-by: Sergey Shtylyov <s.shtylyov at omp.ru>
---
 drivers/crypto/rockchip/rk3288_crypto_skcipher.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
index 9393e10671c2..e80f9148c012 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
@@ -321,8 +321,7 @@ static int rk_cipher_run(struct crypto_engine *engine, void *async_req)
 	algt->stat_req++;
 	rkc->nreq++;
 
-	ivsize = crypto_skcipher_ivsize(tfm);
-	if (areq->iv && crypto_skcipher_ivsize(tfm) > 0) {
+	if (areq->iv && ivsize > 0) {
 		if (rctx->mode & RK_CRYPTO_DEC) {
 			offset = areq->cryptlen - ivsize;
 			scatterwalk_map_and_copy(rctx->backup_iv, areq->src,
-- 
2.34.1



From k.yankevich at omp.ru  Wed Nov  5 08:07:16 2025
From: k.yankevich at omp.ru (Karina Yankevich)
Date: Wed, 5 Nov 2025 19:07:16 +0300
Subject: [PATCH 0/3] drm/rockchip: avoid overflow of clock rate
Message-ID: <20251105160719.2917175-1-k.yankevich@omp.ru>

This patchset fixes conversion of the clock frequency from kHz to Hz in
Rockchip DRM driver to avoid potential integer overflow on 64-bit arches
(it is not possible to avoid on 32-bit arches due to the clk API using
'unsigned long' for the clock frequency).

Karina Yankevich (3):
  drm/rockchip: vop: avoid overflow of clock rate in
    vop_crtc_mode_fixup()
  drm/rockchip: vop: avoid overflow of clock rate in
    vop_crtc_atomic_enable()
  drm/rockchip: dw_hdmi: avoid overflow of clock rate in
    dw_hdmi_rockchip_encoder_mode_set()

 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 2 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

-- 
2.34.1



From k.yankevich at omp.ru  Wed Nov  5 08:07:17 2025
From: k.yankevich at omp.ru (Karina Yankevich)
Date: Wed, 5 Nov 2025 19:07:17 +0300
Subject: [PATCH 1/3] drm/rockchip: vop: avoid overflow of clock rate in vop_crtc_mode_fixup()
In-Reply-To: <20251105160719.2917175-1-k.yankevich@omp.ru>
References: <20251105160719.2917175-1-k.yankevich@omp.ru>
Message-ID: <20251105160719.2917175-2-k.yankevich@omp.ru>

Conversion of clock frequency from kHz to Hz in vop_crtc_mode_fixup()
can lead to integer overflow, since type of drm_display_mode::clock 
is 'int'. Fix it by using 1000UL multiplier to avoid overflow 
at least on 64-bit arches.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes: b59b8de31497 ("drm/rockchip: return a true clock rate to adjusted_mode")
Signed-off-by: Karina Yankevich <k.yankevich at omp.ru>
Reviewed-by: Sergey Shtylyov <s.shtylyov at omp.ru>
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index ba6b0528d1e5..b1e2ca84c26d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -1239,10 +1239,10 @@ static bool vop_crtc_mode_fixup(struct drm_crtc *crtc,
 	 * 4. Store the rounded up rate so that we don't need to worry about
 	 *    this in the actual clk_set_rate().
 	 */
-	rate = clk_round_rate(vop->dclk, adjusted_mode->clock * 1000);
+	rate = clk_round_rate(vop->dclk, adjusted_mode->clock * 1000UL);
 	if (rate / 1000 != adjusted_mode->clock)
 		rate = clk_round_rate(vop->dclk,
-				      adjusted_mode->clock * 1000 + 999);
+				      adjusted_mode->clock * 1000UL + 999);
 	adjusted_mode->clock = DIV_ROUND_UP(rate, 1000);
 
 	return true;
-- 
2.34.1



From k.yankevich at omp.ru  Wed Nov  5 08:07:18 2025
From: k.yankevich at omp.ru (Karina Yankevich)
Date: Wed, 5 Nov 2025 19:07:18 +0300
Subject: [PATCH 2/3] drm/rockchip: vop: avoid overflow of clock rate in vop_crtc_atomic_enable()
In-Reply-To: <20251105160719.2917175-1-k.yankevich@omp.ru>
References: <20251105160719.2917175-1-k.yankevich@omp.ru>
Message-ID: <20251105160719.2917175-3-k.yankevich@omp.ru>

Conversion of clock frequency from kHz to Hz in vop_crtc_atomic_enable()
can lead to integer overflow, since type of drm_display_mode::clock 
is 'int'. Fix it by using 1000UL multiplier to avoid overflow 
at least on 64-bit arches.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes: 2048e3286f34 ("drm: rockchip: Add basic drm driver")
Signed-off-by: Karina Yankevich <k.yankevich at omp.ru>
Reviewed-by: Sergey Shtylyov <s.shtylyov at omp.ru>
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index b1e2ca84c26d..9a6395db455d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -1473,7 +1473,7 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
 
 	VOP_REG_SET(vop, intr, line_flag_num[0], vact_end);
 
-	clk_set_rate(vop->dclk, adjusted_mode->clock * 1000);
+	clk_set_rate(vop->dclk, adjusted_mode->clock * 1000UL);
 
 	VOP_REG_SET(vop, common, standby, 0);
 	mutex_unlock(&vop->vop_lock);
-- 
2.34.1



From k.yankevich at omp.ru  Wed Nov  5 08:07:19 2025
From: k.yankevich at omp.ru (Karina Yankevich)
Date: Wed, 5 Nov 2025 19:07:19 +0300
Subject: [PATCH 3/3] drm/rockchip: dw_hdmi: avoid overflow of clock rate in dw_hdmi_rockchip_encoder_mode_set()
In-Reply-To: <20251105160719.2917175-1-k.yankevich@omp.ru>
References: <20251105160719.2917175-1-k.yankevich@omp.ru>
Message-ID: <20251105160719.2917175-4-k.yankevich@omp.ru>

Conversion of clock frequency from kHz to Hz in
dw_hdmi_rockchip_encoder_mode_set() can lead to integer overflow,
since type of drm_display_mode::clock is 'int'. Fix it by using
1000UL multiplier to avoid overflow at least on 64-bit arches.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes: 5e3bc6d1ab48 ("drm/rockchip: dw_hdmi: introduce the VPLL clock setting")
Signed-off-by: Karina Yankevich <k.yankevich at omp.ru>
Reviewed-by: Sergey Shtylyov <s.shtylyov at omp.ru>
---
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 727cdf768161..ca31c2a4e440 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -277,7 +277,7 @@ static void dw_hdmi_rockchip_encoder_mode_set(struct drm_encoder *encoder,
 {
 	struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
 
-	clk_set_rate(hdmi->ref_clk, adj_mode->clock * 1000);
+	clk_set_rate(hdmi->ref_clk, adj_mode->clock * 1000UL);
 }
 
 static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder)
-- 
2.34.1



From Markus.Elfring at web.de  Wed Nov  5 08:55:56 2025
From: Markus.Elfring at web.de (Markus Elfring)
Date: Wed, 5 Nov 2025 17:55:56 +0100
Subject: [PATCH] crypto: rockchip - drop redundant
 crypto_skcipher_ivsize() calls
In-Reply-To: <20251105145204.2888978-1-k.yankevich@omp.ru>
References: <20251105145204.2888978-1-k.yankevich@omp.ru>
Message-ID: <70685d39-9fc4-4e1d-a6a6-bd82cac9b007@web.de>

> The function already initialized the ivsize variable 
> at the point of declaration, let's use it instead of 
> calling crypto_skcipher_ivsize() extra couple times.
?

* You may occasionally put more than 52 characters into text lines
  of such a change description.
  https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/submitting-patches.rst?h=v6.18-rc4#n658

* How do you think about to reduce the scope for such a local variable?


Regards,
Markus


From joseph.kogut at gmail.com  Wed Nov  5 09:48:02 2025
From: joseph.kogut at gmail.com (Joseph Kogut)
Date: Wed, 5 Nov 2025 09:48:02 -0800
Subject: [PATCH v6 0/3] Add Radxa CM5 and IO Board
In-Reply-To: <199E172C8E20ED38+71169242-5525-4d60-9e37-a03ad172d639@radxa.com>
References: <20251105051335.17652-1-naoki@radxa.com> <199E172C8E20ED38+71169242-5525-4d60-9e37-a03ad172d639@radxa.com>
Message-ID: <CAMWSM7gezjVSoF+-7ivboTeB=5gQAE-QVrbAbKu3M=obmb3Axg@mail.gmail.com>

Hello all,

On Wed, Nov 5, 2025 at 4:15?AM FUKAUMI Naoki <naoki at radxa.com> wrote:
>
> I'd like to clarify the situation regarding the v6 patch series I submitted.
>
> The original device tree work for the Radxa CM5 and IO Board was
> authored by Joseph Kogut. I took over the responsibility of getting it
> upstreamed with his agreement.

I'll confirm this. I've been in communication with Naoki. They made a
large number of revisions to my original patch series, which I think
have technical merit. I suggested they submit the patches themselves,
and gave them explicit permission to add my Signed-off-by and CC me.

I assume this was the correct way for them to continue the work I
started, but if not, please let us know the best way to proceed.

Best,
Joseph


From honyuenkwun at gmail.com  Wed Nov  5 10:10:32 2025
From: honyuenkwun at gmail.com (Jimmy Hon)
Date: Wed, 5 Nov 2025 12:10:32 -0600
Subject: [PATCH v6 0/3] Add Radxa CM5 and IO Board
In-Reply-To: <20251105051335.17652-1-naoki@radxa.com>
References: <20251105051335.17652-1-naoki@radxa.com>
Message-ID: <CALWfF7JsB-i4tgbPfMzrH92dCO-=EMkt7yY16dKzEPE-4RC58A@mail.gmail.com>

On Tue, Nov 4, 2025 at 11:14?PM FUKAUMI Naoki <naoki at radxa.com> wrote:
>
> This patch series add support for the Radxa CM5 SoM and IO Board.
>
> Changes in v6:
> (Patch 1/3)
> - Fix description; "Radxa CM5" is the correct name
> (Patch 2/3)
> - Fix #include(s)
> - Include rk3588s.dtsi
> - Move alias for gmac1 from io board dts

I'm curious why the alias was moved to the SoM? If the carrier board
does not enable the gmac1, shouldn't we leave out the alias?
i.e. for the handheld without RJ45 jack [1], it wouldn't want the alias, right?

[1] https://github.com/StonedEdge/Retro-Lite-CM5

Jimmy


From nicolinc at nvidia.com  Wed Nov  5 10:18:01 2025
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Wed, 5 Nov 2025 10:18:01 -0800
Subject: [PATCH v1 02/20] iommu: Introduce a test_dev domain op and an
 internal helper
In-Reply-To: <BN9PR11MB527638C0E43E8AA000410B878CC5A@BN9PR11MB5276.namprd11.prod.outlook.com>
References: <cover.1760312725.git.nicolinc@nvidia.com>
 <32ce256a2ece5d63e99d5858f953586859818ffc.1760312725.git.nicolinc@nvidia.com>
 <BN9PR11MB5276D10BD480FE66881870B08CFBA@BN9PR11MB5276.namprd11.prod.outlook.com>
 <aQO//+6/B/WbdK2h@Asurada-Nvidia>
 <20251103185400.GA1537560@nvidia.com>
 <BN9PR11MB527638C0E43E8AA000410B878CC5A@BN9PR11MB5276.namprd11.prod.outlook.com>
Message-ID: <aQuU2dic75VkSyjr@Asurada-Nvidia>

On Wed, Nov 05, 2025 at 06:57:31AM +0000, Tian, Kevin wrote:
> > From: Jason Gunthorpe <jgg at nvidia.com>
> > Sent: Tuesday, November 4, 2025 2:54 AM
> > 
> > On Thu, Oct 30, 2025 at 12:43:59PM -0700, Nicolin Chen wrote:
> > 
> > > FWIW, I am thinking of another design based on Jason's remarks:
> > > https://lore.kernel.org/linux-iommu/aQBopHFub8wyQh5C at Asurada-
> > Nvidia/
> > >
> > > So, instead of core initiating the round trip between the blocking
> > > domain and group->domain, it forwards dev_reset_prepare/done to the
> > > driver where it does a low-level attachment that wouldn't fail:
> > >   For SMMUv3, it's an STE update.
> > >   For intel_iommu, it seems to be the context table update?
> > 
> > Kevin, how bad do you think the UAPI issue is if we ignore it?
> > 
> 
> yeah probably better to leave it. I didn't see a clean way and the
> value didn't justify the complexity.
> 
> Regarding to PF reset, it's a devastating operation while the vf user
> is operating the vf w/o any awareness. there must be certain
> coordination in userspace. otherwise nobody can recover the
> registers. Comparing to that, solving the domain attach problem
> is less important...

If I capture these correctly, we should go with a -EBUSY version:
 - Reject concurrent attachments during a device reset
 - Skip reset for devices having sibling group devices
 - Allow PF to stop IOMMU, ignoring VFs
?

That sounds pretty much like this v4:
https://lore.kernel.org/linux-iommu/0f6021b500c74db33af8118210dd7a2b2fd31b3c.1756682135.git.nicolinc at nvidia.com/
by dropping the SRIOV concern.

Thanks
Nicolin


From laurent.pinchart at ideasonboard.com  Wed Nov  5 10:21:59 2025
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Wed, 5 Nov 2025 20:21:59 +0200
Subject: [PATCH] media: rkisp1: Fix enum_framesizes accepting invalid
 pixel formats
In-Reply-To: <20250829101425.95442-1-tarang.raval@siliconsignals.io>
References: <20250829101425.95442-1-tarang.raval@siliconsignals.io>
Message-ID: <20251105182159.GE6046@pendragon.ideasonboard.com>

Hi Tarang,

Thank you for the patch.

On Fri, Aug 29, 2025 at 03:44:24PM +0530, Tarang Raval wrote:
> Reject unsupported pixel formats in rkisp1_enum_framesizes() to
> fix v4l2-compliance failure.
> 
> v4l2-compliance test failure:
> 
> fail: ../utils/v4l2-compliance/v4l2-test-formats.cpp(403): Accepted framesize for invalid format
> test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: FAIL
> 
> Tested on: Debix i.MX8MP Model A
> Kernel version: v6.17-rc3
> v4l2-compliance: 1.31.0-5387
> 
> Signed-off-by: Tarang Raval <tarang.raval at siliconsignals.io>

I've tested this with libcamera, so

Tested-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

> ---
>  drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
> index 6dcefd144d5a..107937b77153 100644
> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
> @@ -1383,6 +1383,9 @@ static int rkisp1_enum_framesizes(struct file *file, void *fh,
>  	};
>  	struct rkisp1_capture *cap = video_drvdata(file);
>  
> +	if (!rkisp1_find_fmt_cfg(cap, fsize->pixel_format))
> +		return -EINVAL;
> +
>  	if (fsize->index != 0)
>  		return -EINVAL;
>  

-- 
Regards,

Laurent Pinchart


From honyuenkwun at gmail.com  Wed Nov  5 10:27:03 2025
From: honyuenkwun at gmail.com (Jimmy Hon)
Date: Wed, 5 Nov 2025 12:27:03 -0600
Subject: [PATCH v6 3/3] arm64: dts: rockchip: Add Radxa CM5 IO Board
In-Reply-To: <20251105051335.17652-4-naoki@radxa.com>
References: <20251105051335.17652-1-naoki@radxa.com> <20251105051335.17652-4-naoki@radxa.com>
Message-ID: <CALWfF7KyTfpXSyjVQaFzqtn6KyDxuyZOBpPR8y-jf6sduNxq5A@mail.gmail.com>

On Tue, Nov 4, 2025 at 11:14?PM FUKAUMI Naoki <naoki at radxa.com> wrote:
>
> The Radxa CM5 IO Board is an application board for the Radxa CM5.
>
> Specification:

> - 1x microSD card slot

[ snip ]

> +
> +&sdmmc {
> +       bus-width = <4>;
> +       cap-mmc-highspeed;
> +       cap-sd-highspeed;
> +       cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
> +       disable-wp;
> +       no-sdio;
> +       pinctrl-names = "default";
> +       pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd>;
> +       sd-uhs-sdr104;
> +       vmmc-supply = <&vcc_3v3_s3>;
> +       vqmmc-supply = <&vccio_sd_s0>;
> +       status = "okay";
> +};

When used as a TF slot, shouldn't there be a "no-mmc" also?
That's how the Rock 5A, 5B, and 5C were defined.

Jimmy


From geraldogabriel at gmail.com  Wed Nov  5 12:02:21 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Wed, 5 Nov 2025 17:02:21 -0300
Subject: [PATCH] arm64: dts: rockchip: align bindings to PCIe spec
In-Reply-To: <67b605b0-7046-448a-bc9b-d3ac56333809@rock-chips.com>
References: <4b5ffcccfef2a61838aa563521672a171acb27b2.1762321976.git.geraldogabriel@gmail.com>
 <ba120577-42da-424d-8102-9d085c1494c8@rock-chips.com>
 <aQsIXcQzeYop6a0B@geday>
 <67b605b0-7046-448a-bc9b-d3ac56333809@rock-chips.com>
Message-ID: <aQutTbzS8rfW-Esm@geday>

On Wed, Nov 05, 2025 at 04:56:36PM +0800, Shawn Lin wrote:
> ? 2025/11/05 ??? 16:18, Geraldo Nascimento ??:
> > 
> > Hi Shawn, glad to hear from you.
> > 
> > Perhaps the following change is better? It resolves the issue
> > without the added complication of open drain. After you questioned
> > if open drain is actually part of the spec, I remembered that
> > GPIO_OPEN_DRAIN is actually (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_DRAIN)
> > so I decided to test with just GPIO_SINGLE_ENDED and it works.
> 
> 
> Does that work for you too?
> 
> &pcie0 {
> 	ep-gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>;
>   	num-lanes = <4>;
> -	pinctrl-0 = <&pcie_clkreqnb_cpm>;
> +	pinctrl-0 = <&pcie_clkreqnb_cpm>, <&pcie_perst>;
>   	pinctrl-names = "default";
>   	vpcie0v9-supply = <&vcca_0v9>;	/* VCC_0V9_S0 */
>   	vpcie1v8-supply = <&vcca_1v8>;	/* VCC_1V8_S0 */
> @@ -408,6 +408,10 @@ pcie {
>   		pcie_pwr: pcie-pwr {
>   			rockchip,pins = <4 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>;
>   		};
> +		pcie_perst: pcie-perst {
> +			rockchip,pins = <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>;
> +		};
> +
>   	};

Hi Shawn,

No, that does not work.

I believe the pull-up mux became needed because I was forcing open drain
on PERST#.

Thanks,
Geraldo Nascimento


From macroalpha82 at gmail.com  Wed Nov  5 12:57:03 2025
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Wed,  5 Nov 2025 14:57:03 -0600
Subject: [PATCH 0/5] Indiedroid Nova Devicetree Updates
Message-ID: <20251105205708.732125-1-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

This series fixes up a few remaining issues with the devicetree for the
Indiedroid Nova. Namely it adds or updates a few pinctrl definitions,
it removes a few workarounds that no longer appear to be necessary for
eMMC and bluetooth, it adds support for the NPU, and it sets the device
type as embedded.

Chris Morgan (5):
  arm64: dts: rockchip: Add device type for Indiedroid Nova.
  arm64: dts: rockchip: Add Additional pinctrl defs for Indiedroid Nova
  arm64: dts: rockchip: enable NPU on Indiedroid Nova
  arm64: dts: rockchip: Enable HS400 for Indiedroid Nova
  arm64: dts: rockchip: Fix DMA for Indiedroid Nova Bluetooth

 .../dts/rockchip/rk3588s-indiedroid-nova.dts  | 85 ++++++++++++++-----
 1 file changed, 65 insertions(+), 20 deletions(-)

-- 
2.43.0



From macroalpha82 at gmail.com  Wed Nov  5 12:57:04 2025
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Wed,  5 Nov 2025 14:57:04 -0600
Subject: [PATCH 1/5] arm64: dts: rockchip: Add device type for Indiedroid Nova.
In-Reply-To: <20251105205708.732125-1-macroalpha82@gmail.com>
References: <20251105205708.732125-1-macroalpha82@gmail.com>
Message-ID: <20251105205708.732125-2-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

Update the devicetree node to note the device category of the
Indiedroid Nova as an embedded device.

Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
---
 arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
index 4ec7bc4a9e96..debab7732b71 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
@@ -11,6 +11,7 @@
 
 / {
 	model = "Indiedroid Nova";
+	chassis-type = "embedded";
 	compatible = "indiedroid,nova", "rockchip,rk3588s";
 
 	adc-keys-0 {
-- 
2.43.0



From macroalpha82 at gmail.com  Wed Nov  5 12:57:05 2025
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Wed,  5 Nov 2025 14:57:05 -0600
Subject: [PATCH 2/5] arm64: dts: rockchip: Add Additional pinctrl defs for Indiedroid Nova
In-Reply-To: <20251105205708.732125-1-macroalpha82@gmail.com>
References: <20251105205708.732125-1-macroalpha82@gmail.com>
Message-ID: <20251105205708.732125-3-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

Define the pinctrl nodes for the WiFi interrupts, correct the pinctrl
for the ethernet according to the schematic, and add the clk32k_in
control for the RTC. Add the correct regulator mapping for the PCIE
too.

Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
---
 .../dts/rockchip/rk3588s-indiedroid-nova.dts  | 43 ++++++++++++-------
 1 file changed, 28 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
index debab7732b71..f40782b6c7db 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
@@ -406,7 +406,7 @@ rtc_hym8563: rtc at 51 {
 		clock-output-names = "hym8563";
 		interrupt-parent = <&gpio0>;
 		interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>;
-		pinctrl-0 = <&hym8563_int>;
+		pinctrl-0 = <&hym8563_int>, <&clk32k_in>;
 		pinctrl-names = "default";
 		wakeup-source;
 	};
@@ -459,8 +459,11 @@ &i2s5_8ch {
 };
 
 &pcie2x1l2 {
-	pinctrl-0 = <&rtl8111_perstb>;
+	pinctrl-0 = <&pcie20x1m0_perstn>, <&pcie20x1m0_clkreqn>,
+		    <&pcie20x1m0_waken>;
 	pinctrl-names = "default";
+	reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
+	vpcie3v3-supply = <&vcc_3v3_s3>;
 	status = "okay";
 };
 
@@ -486,12 +489,6 @@ bt_wake_host: bt-wake-host {
 		};
 	};
 
-	ethernet-pins {
-		rtl8111_perstb: rtl8111-perstb {
-			rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>;
-		};
-	};
-
 	hym8563 {
 
 		hym8563_int: hym8563-int {
@@ -500,13 +497,6 @@ hym8563_int: hym8563-int {
 		};
 	};
 
-	sdio-pwrseq {
-		wifi_enable_h: wifi-enable-h {
-			rockchip,pins =
-				<0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>;
-		};
-	};
-
 	usb-typec {
 		usbc0_int: usbc0-int {
 			rockchip,pins =
@@ -518,6 +508,18 @@ typec5v_pwren: typec5v-pwren {
 				<4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
 		};
 	};
+
+	wifi {
+		wifi_enable_h: wifi-enable-h {
+			rockchip,pins =
+				<0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		wifi_host_wake_irq: wifi-host-wake-irq {
+			rockchip,pins =
+				<0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+	};
 };
 
 &saradc {
@@ -538,6 +540,7 @@ &sdhci {
 };
 
 &sdio {
+	#address-cells = <1>;
 	bus-width = <4>;
 	cap-sd-highspeed;
 	cap-sdio-irq;
@@ -549,9 +552,19 @@ &sdio {
 	no-sd;
 	non-removable;
 	sd-uhs-sdr104;
+	#size-cells = <0>;
 	vmmc-supply = <&vcc_3v3_s3>;
 	vqmmc-supply = <&vcc_1v8_s3>;
 	status = "okay";
+
+	sdio_wifi: wifi at 1 {
+		reg = <1>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PA0 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-names = "host-wake";
+		pinctrl-0 = <&wifi_host_wake_irq>;
+		pinctrl-names = "default";
+	};
 };
 
 &sdmmc {
-- 
2.43.0



From macroalpha82 at gmail.com  Wed Nov  5 12:57:06 2025
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Wed,  5 Nov 2025 14:57:06 -0600
Subject: [PATCH 3/5] arm64: dts: rockchip: enable NPU on Indiedroid Nova
In-Reply-To: <20251105205708.732125-1-macroalpha82@gmail.com>
References: <20251105205708.732125-1-macroalpha82@gmail.com>
Message-ID: <20251105205708.732125-4-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

Enable the NPU on the Indiedroid Nova.

Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
---
 .../dts/rockchip/rk3588s-indiedroid-nova.dts  | 34 +++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
index f40782b6c7db..62c8c8f68713 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
@@ -471,6 +471,10 @@ &pd_gpu {
 	domain-supply = <&vdd_gpu_s0>;
 };
 
+&pd_npu {
+	domain-supply = <&vdd_npu_s0>;
+};
+
 &pinctrl {
 	bluetooth-pins {
 		bt_reset: bt-reset {
@@ -522,6 +526,36 @@ wifi_host_wake_irq: wifi-host-wake-irq {
 	};
 };
 
+&rknn_core_0 {
+	npu-supply = <&vdd_npu_s0>;
+	sram-supply = <&vdd_npu_s0>;
+	status = "okay";
+};
+
+&rknn_core_1 {
+	npu-supply = <&vdd_npu_s0>;
+	sram-supply = <&vdd_npu_s0>;
+	status = "okay";
+};
+
+&rknn_core_2 {
+	npu-supply = <&vdd_npu_s0>;
+	sram-supply = <&vdd_npu_s0>;
+	status = "okay";
+};
+
+&rknn_mmu_0 {
+	status = "okay";
+};
+
+&rknn_mmu_1 {
+	status = "okay";
+};
+
+&rknn_mmu_2 {
+	status = "okay";
+};
+
 &saradc {
 	vref-supply = <&vcca_1v8_s0>;
 	status = "okay";
-- 
2.43.0



From macroalpha82 at gmail.com  Wed Nov  5 12:57:07 2025
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Wed,  5 Nov 2025 14:57:07 -0600
Subject: [PATCH 4/5] arm64: dts: rockchip: Enable HS400 for Indiedroid Nova
In-Reply-To: <20251105205708.732125-1-macroalpha82@gmail.com>
References: <20251105205708.732125-1-macroalpha82@gmail.com>
Message-ID: <20251105205708.732125-5-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

Once the DLL_STRBIN_TAPNUM_DEFAULT is set to the correct value [1], the
workaround to ensure stable eMMC operation is no longer needed. I
have observed testing this that hdparm went from:
"Timing buffered disk reads: 502 MB in  3.00 seconds = 167.14 MB/sec"
to the following:
"Timing buffered disk reads: 832 MB in  3.00 seconds = 277.32 MB/sec"

[1] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/drivers/mmc/host/sdhci-of-dwcmshc.c?id=a28352cf2d2f8380e7aca8cb61682396dca7a991

Fixes: 3900160e164b ("arm64: dts: rockchip: Add Indiedroid Nova board")
Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
---
 arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
index 62c8c8f68713..0796ba6d2504 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
@@ -561,10 +561,10 @@ &saradc {
 	status = "okay";
 };
 
-/* HS400 modes seemed to cause io errors. */
 &sdhci {
 	bus-width = <8>;
-	no-mmc-hs400;
+	mmc-hs400-1_8v;
+	mmc-hs400-enhanced-strobe;
 	no-sd;
 	no-sdio;
 	non-removable;
-- 
2.43.0



From macroalpha82 at gmail.com  Wed Nov  5 12:57:08 2025
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Wed,  5 Nov 2025 14:57:08 -0600
Subject: [PATCH 5/5] arm64: dts: rockchip: Fix DMA for Indiedroid Nova Bluetooth
In-Reply-To: <20251105205708.732125-1-macroalpha82@gmail.com>
References: <20251105205708.732125-1-macroalpha82@gmail.com>
Message-ID: <20251105205708.732125-6-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

When the device was first added, there was a problem with the bluetooth
controller that manifested when DMA was enabled for the underlying UART
interface. At some point in the intervening time the problem appears to
have been resolved. Add the UART rx and tx channels back to re-enable
UART.

Fixes: 3900160e164b ("arm64: dts: rockchip: Add Indiedroid Nova board")
Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
---
 arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
index 0796ba6d2504..dee053afc6b6 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
@@ -944,12 +944,9 @@ &uart2 {
 	status = "okay";
 };
 
-/* DMA seems to interfere with bluetooth device normal operation. */
 &uart9 {
 	pinctrl-0 = <&uart9m2_xfer>, <&uart9m2_ctsn>, <&uart9m2_rtsn>;
 	pinctrl-names = "default";
-	/delete-property/ dma-names;
-	/delete-property/ dmas;
 	uart-has-rtscts;
 	status = "okay";
 
-- 
2.43.0



From andreil499 at gmail.com  Wed Nov  5 13:07:33 2025
From: andreil499 at gmail.com (Andrey Leonchikov)
Date: Wed,  5 Nov 2025 22:07:33 +0100
Subject: [PATCH] arm64: dts: rockchip: Fix USB power enable pin for BTT CB2 and Pi2
Message-ID: <20251105210741.850031-1-andreil499@gmail.com>


 Fix typo into regulator GPIO definition. With current
 definition - USB powered off. Valid definition can be found on "pinctrl"
 section:
 		vcc5v0_usb2t_en: vcc5v0-usb2t-en {
 				rockchip,pins = <3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
 				 		};

 		vcc5v0_usb2b_en: vcc5v0-usb2b-en {
 			rockchip,pins = <4 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
 		};

Fixes: bfbc663d2733a ("arm64: dts: rockchip: Add BigTreeTech CB2 and Pi2")
Signed-off-by: Andrey Leonchikov <andreil499 at gmail.com>
---
 arch/arm64/boot/dts/rockchip/rk3566-bigtreetech-cb2.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3566-bigtreetech-cb2.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-bigtreetech-cb2.dtsi
index f74590af7e33..b6cf03a7ba66 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-bigtreetech-cb2.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3566-bigtreetech-cb2.dtsi
@@ -187,7 +187,7 @@ vcc5v0_usb: regulator-vcc5v0-usb {
 	vcc5v0_usb2b: regulator-vcc5v0-usb2b {
 		compatible = "regulator-fixed";
 		enable-active-high;
-		gpio = <&gpio0 RK_PC4 GPIO_ACTIVE_HIGH>;
+		gpio = <&gpio4 RK_PC4 GPIO_ACTIVE_HIGH>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&vcc5v0_usb2b_en>;
 		regulator-name = "vcc5v0_usb2b";
@@ -199,7 +199,7 @@ vcc5v0_usb2b: regulator-vcc5v0-usb2b {
 	vcc5v0_usb2t: regulator-vcc5v0-usb2t {
 		compatible = "regulator-fixed";
 		enable-active-high;
-		gpios = <&gpio0 RK_PD5 GPIO_ACTIVE_HIGH>;
+		gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&vcc5v0_usb2t_en>;
 		regulator-name = "vcc5v0_usb2t";
-- 
2.51.0



From geraldogabriel at gmail.com  Wed Nov  5 13:22:00 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Wed, 5 Nov 2025 18:22:00 -0300
Subject: [RFC PATCH 2/2] PCI: rockchip-host: drop wait on PERST# toggle
In-Reply-To: <DE0N4LA8MOJD.236O12UZ3I3C4@cknow-tech.com>
References: <d3d0c3a387ff461e62bbd66a0bde654a9a17761e.1762150971.git.geraldogabriel@gmail.com>
 <20251103181038.GA1814635@bhelgaas>
 <aQrKtFT0ldc70gKj@geday>
 <DE0N4LA8MOJD.236O12UZ3I3C4@cknow-tech.com>
Message-ID: <aQu_-JDy7qqeviUm@geday>

On Wed, Nov 05, 2025 at 10:06:53AM +0100, Diederik de Haas wrote:
> I have a Samsung PM981 (without the 'a') and AFAICT it works fine.
> I had noticed that the PERST# (pinctrl) was missing, but 'ep-gpios'
> was/is new to me and I hadn't had time to research that properly yet.
> Good to see you already found it yourself :-)
> 
> Cheers,
>   Diederik

Hello Diederik,

Thanks for the heads up!

Would you mind testing the following DT change to make sure your PM981
continues to work fine?

Thank you,
Geraldo Nascimento

---

diff --git a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
index aa70776e898a..b3d19dce539f 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
@@ -383,7 +383,7 @@ &pcie_phy {
 };
 
 &pcie0 {
-	ep-gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>;
+	ep-gpios = <&gpio0 RK_PB4 (GPIO_ACTIVE_HIGH | GPIO_SINGLE_ENDED)>;
 	num-lanes = <4>;
 	pinctrl-0 = <&pcie_clkreqnb_cpm>;
 	pinctrl-names = "default";


From heiko at sntech.de  Wed Nov  5 15:18:51 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Thu, 06 Nov 2025 00:18:51 +0100
Subject: [PATCH 4/5] arm64: dts: rockchip: Enable HS400 for Indiedroid Nova
In-Reply-To: <20251105205708.732125-5-macroalpha82@gmail.com>
References: <20251105205708.732125-1-macroalpha82@gmail.com>
 <20251105205708.732125-5-macroalpha82@gmail.com>
Message-ID: <2864346.mvXUDI8C0e@phil>

Am Mittwoch, 5. November 2025, 21:57:07 Mitteleurop?ische Normalzeit schrieb Chris Morgan:
> From: Chris Morgan <macromorgan at hotmail.com>
> 
> Once the DLL_STRBIN_TAPNUM_DEFAULT is set to the correct value [1], the
> workaround to ensure stable eMMC operation is no longer needed. I
> have observed testing this that hdparm went from:
> "Timing buffered disk reads: 502 MB in  3.00 seconds = 167.14 MB/sec"
> to the following:
> "Timing buffered disk reads: 832 MB in  3.00 seconds = 277.32 MB/sec"
> 
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/drivers/mmc/host/sdhci-of-dwcmshc.c?id=a28352cf2d2f8380e7aca8cb61682396dca7a991
> 
> Fixes: 3900160e164b ("arm64: dts: rockchip: Add Indiedroid Nova board")

This needs the patch you linked to, to actually work, so I'll drop
the fixes tag when applying, because this should likely not be
backported to older kernels.

Same reasoning for patch 5.


Heiko

> Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
> ---
>  arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
> index 62c8c8f68713..0796ba6d2504 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
> @@ -561,10 +561,10 @@ &saradc {
>  	status = "okay";
>  };
>  
> -/* HS400 modes seemed to cause io errors. */
>  &sdhci {
>  	bus-width = <8>;
> -	no-mmc-hs400;
> +	mmc-hs400-1_8v;
> +	mmc-hs400-enhanced-strobe;
>  	no-sd;
>  	no-sdio;
>  	non-removable;
> 






From heiko at sntech.de  Wed Nov  5 15:26:32 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Thu,  6 Nov 2025 00:26:32 +0100
Subject: [PATCH 0/2] Drop RK3568's variant of the CLK_NR_CLKS constant
In-Reply-To: <20251103234032.413563-1-heiko@sntech.de>
References: <20251103234032.413563-1-heiko@sntech.de>
Message-ID: <176238518188.156498.3345794880564705981.b4-ty@sntech.de>


On Tue, 04 Nov 2025 00:40:30 +0100, Heiko Stuebner wrote:
> This drops the use of the CLK_NR_CLKS constant from the rk3568 clock
> driver and after that, drops the constant from the binding that should
> not have been part of it in the first place.
> 
> Heiko Stuebner (2):
>   clk: rockchip: rk3568: Drop CLK_NR_CLKS usage
>   dt-bindings: clock: rk3568: Drop CLK_NR_CLKS define
> 
> [...]

Applied, thanks!

[1/2] clk: rockchip: rk3568: Drop CLK_NR_CLKS usage
      commit: 2a42e3210d4331dddfb04b020050bd774cf99659
[2/2] dt-bindings: clock: rk3568: Drop CLK_NR_CLKS define
      commit: ca38f0f65eefd79889b409c89c6932d7e2fe0993

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Wed Nov  5 15:26:33 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Thu,  6 Nov 2025 00:26:33 +0100
Subject: [PATCH 0/3] SCMI clocks on RK356x
In-Reply-To: <20251103234926.416137-1-heiko@sntech.de>
References: <20251103234926.416137-1-heiko@sntech.de>
Message-ID: <176238518187.156498.15783284183828303705.b4-ty@sntech.de>


On Tue, 04 Nov 2025 00:49:23 +0100, Heiko Stuebner wrote:
> This cleans up the existing use of SCMI clocks on the RK356x SoCs.
> 
> 
> Heiko Stuebner (3):
>   dt-bindings: clock: rk3568: Add SCMI clock ids
>   arm64: dts: rockchip: use SCMI clock id for cpu clock on rk356x
>   arm64: dts: rockchip: add missing clocks for cpu cores on rk356
> 
> [...]

Applied, thanks!

[1/3] dt-bindings: clock: rk3568: Add SCMI clock ids
      commit: 88b6a93af4345e901206d0576bdb4e88ea3eaeb8
[2/3] arm64: dts: rockchip: use SCMI clock id for cpu clock on rk356x
      commit: ff8912700f31782021ec28c530de1482fa99eab3
[3/3] arm64: dts: rockchip: add missing clocks for cpu cores on rk356x
      commit: e06a419eaab9cee7cd5bbb0cfcfbe49e443a9d75

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From naoki at radxa.com  Wed Nov  5 15:27:58 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Thu, 6 Nov 2025 08:27:58 +0900
Subject: [PATCH v6 0/3] Add Radxa CM5 and IO Board
In-Reply-To: <CALWfF7JsB-i4tgbPfMzrH92dCO-=EMkt7yY16dKzEPE-4RC58A@mail.gmail.com>
References: <20251105051335.17652-1-naoki@radxa.com>
 <CALWfF7JsB-i4tgbPfMzrH92dCO-=EMkt7yY16dKzEPE-4RC58A@mail.gmail.com>
Message-ID: <7A636B2C51748041+9013a190-a997-4006-a136-20d18db85763@radxa.com>

Hi Jimmy,

On 11/6/25 03:10, Jimmy Hon wrote:
> On Tue, Nov 4, 2025 at 11:14?PM FUKAUMI Naoki <naoki at radxa.com> wrote:
>>
>> This patch series add support for the Radxa CM5 SoM and IO Board.
>>
>> Changes in v6:
>> (Patch 1/3)
>> - Fix description; "Radxa CM5" is the correct name
>> (Patch 2/3)
>> - Fix #include(s)
>> - Include rk3588s.dtsi
>> - Move alias for gmac1 from io board dts
> 
> I'm curious why the alias was moved to the SoM? If the carrier board
> does not enable the gmac1, shouldn't we leave out the alias?
> i.e. for the handheld without RJ45 jack [1], it wouldn't want the alias, right?

Indeed.

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> [1] https://github.com/StonedEdge/Retro-Lite-CM5
> 
> Jimmy
> 




From naoki at radxa.com  Wed Nov  5 15:38:49 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Thu, 6 Nov 2025 08:38:49 +0900
Subject: [PATCH v6 3/3] arm64: dts: rockchip: Add Radxa CM5 IO Board
In-Reply-To: <CALWfF7KyTfpXSyjVQaFzqtn6KyDxuyZOBpPR8y-jf6sduNxq5A@mail.gmail.com>
References: <20251105051335.17652-1-naoki@radxa.com>
 <20251105051335.17652-4-naoki@radxa.com>
 <CALWfF7KyTfpXSyjVQaFzqtn6KyDxuyZOBpPR8y-jf6sduNxq5A@mail.gmail.com>
Message-ID: <1EE1A1D9D7C100DA+1b365782-98c4-4ee0-ab96-920990841903@radxa.com>

Hi Jimmy,

On 11/6/25 03:27, Jimmy Hon wrote:
> On Tue, Nov 4, 2025 at 11:14?PM FUKAUMI Naoki <naoki at radxa.com> wrote:
>>
>> The Radxa CM5 IO Board is an application board for the Radxa CM5.
>>
>> Specification:
> 
>> - 1x microSD card slot
> 
> [ snip ]
> 
>> +
>> +&sdmmc {
>> +       bus-width = <4>;
>> +       cap-mmc-highspeed;
>> +       cap-sd-highspeed;
>> +       cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
>> +       disable-wp;
>> +       no-sdio;
>> +       pinctrl-names = "default";
>> +       pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd>;
>> +       sd-uhs-sdr104;
>> +       vmmc-supply = <&vcc_3v3_s3>;
>> +       vqmmc-supply = <&vccio_sd_s0>;
>> +       status = "okay";
>> +};
> 
> When used as a TF slot, shouldn't there be a "no-mmc" also?

We have "eMMC to uSD."
  https://radxa.com/products/accessories/emmc-to-usd

[  202.176757] mmc_host mmc1: Bus speed (slot 0) = 49500000Hz (slot req 
52000000Hz, actual 49500000HZ div = 0)
[  202.178477] mmc1: new high speed MMC card at address 0001
[  202.179534] mmcblk1: mmc1:0001 SLD64G 57.6 GiB
[  202.207336] mmcblk1boot0: mmc1:0001 SLD64G 4.00 MiB
[  202.210374] mmcblk1boot1: mmc1:0001 SLD64G 4.00 MiB
[  202.212967] mmcblk1rpmb: mmc1:0001 SLD64G 4.00 MiB, chardev (511:1)

(I'm not sure why it says "Not work with the SD slot on the board." I 
will check.)

> That's how the Rock 5A, 5B, and 5C were defined.

I have submitted a patch without "no-mmc" before. I intend to send one 
again when I have the chance.

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> Jimmy
> 




From heiko at sntech.de  Wed Nov  5 15:43:26 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Thu, 06 Nov 2025 00:43:26 +0100
Subject: [PATCH 2/3] arm64: dts: rockchip: use SCMI clock id for cpu clock on
 rk356x
In-Reply-To: <DE0SFV203UMS.1ZV2JE6QEPN29@cknow-tech.com>
References: <20251103234926.416137-1-heiko@sntech.de>
 <20251103234926.416137-3-heiko@sntech.de>
 <DE0SFV203UMS.1ZV2JE6QEPN29@cknow-tech.com>
Message-ID: <5996423.DvuYhMxLoT@phil>

Am Mittwoch, 5. November 2025, 14:16:42 Mitteleurop?ische Normalzeit schrieb Diederik de Haas:
> Hi Heiko,
> 
> On Tue Nov 4, 2025 at 12:49 AM CET, Heiko Stuebner wrote:
> > Instead of hard-coding 0, use the more descriptive ID from the binding
> > to reference the SCMI clock for the cpu on rk356x.
> 
> Any particular reason you only did it for the cpu, but not the gpu?

Didn't think of if at the time :-) .

Will prepare another one for the GPU.


Heiko

> 
> > Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> > ---
> >  arch/arm64/boot/dts/rockchip/rk356x-base.dtsi | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
> > index a3361527d4fe..d0c76401b45e 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
> > +++ b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
> > @@ -53,7 +53,7 @@ cpu0: cpu at 0 {
> >  			device_type = "cpu";
> >  			compatible = "arm,cortex-a55";
> >  			reg = <0x0 0x0>;
> > -			clocks = <&scmi_clk 0>;
> > +			clocks = <&scmi_clk SCMI_CLK_CPU>;
> 
> Regardless of the above comment, feel free to add
> 
> Reviewed-by: Diederik de Haas <diederik at cknow-tech.com>
> 
> Cheers,
>   Diederik
> 
> >  			#cooling-cells = <2>;
> >  			enable-method = "psci";
> >  			i-cache-size = <0x8000>;
> 
> 






From heiko at sntech.de  Wed Nov  5 15:46:04 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Thu, 06 Nov 2025 00:46:04 +0100
Subject: [PATCH v6 4/5] dt-bindings: clock: rockchip: Add RK3506 clock and reset
 unit
In-Reply-To: <20251104030633.2721038-5-zhangqing@rock-chips.com>
References: <20251104030633.2721038-1-zhangqing@rock-chips.com>
 <20251104030633.2721038-5-zhangqing@rock-chips.com>
Message-ID: <5112280.31r3eYUQgx@phil>

Hi Elaine,

Am Dienstag, 4. November 2025, 04:06:32 Mitteleurop?ische Normalzeit schrieb Elaine Zhang:
> From: Finley Xiao <finley.xiao at rock-chips.com>
> 
> Add device tree bindings for clock and reset unit on RK3506 SoC.
> Add clock and reset IDs for RK3506 SoC.
> 
> Signed-off-by: Finley Xiao <finley.xiao at rock-chips.com>

This needs an additional Signed-off-by line from you please.
Authorship and first SoB is correct, but you as the patch sender
also need to sign off on it.

Same for patch5

Thanks a lot
Heiko

> ---
>  .../bindings/clock/rockchip,rk3506-cru.yaml   |  51 ++++
>  .../dt-bindings/clock/rockchip,rk3506-cru.h   | 285 ++++++++++++++++++
>  .../dt-bindings/reset/rockchip,rk3506-cru.h   | 211 +++++++++++++
>  3 files changed, 547 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
>  create mode 100644 include/dt-bindings/clock/rockchip,rk3506-cru.h
>  create mode 100644 include/dt-bindings/reset/rockchip,rk3506-cru.h
> 
> diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml b/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
> new file mode 100644
> index 000000000000..ecb5fa497747
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
> @@ -0,0 +1,51 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/rockchip,rk3506-cru.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Rockchip RK3506 Clock and Reset Unit (CRU)
> +
> +maintainers:
> +  - Finley Xiao <finley.xiao at rock-chips.com>
> +  - Heiko Stuebner <heiko at sntech.de>
> +
> +description: |
> +  The RK3506 CRU generates the clock and also implements reset for SoC
> +  peripherals.
> +
> +properties:
> +  compatible:
> +    const: rockchip,rk3506-cru
> +
> +  reg:
> +    maxItems: 1
> +
> +  "#clock-cells":
> +    const: 1
> +
> +  "#reset-cells":
> +    const: 1
> +
> +  clocks:
> +    maxItems: 1
> +
> +  clock-names:
> +    const: xin24m
> +
> +required:
> +  - compatible
> +  - reg
> +  - "#clock-cells"
> +  - "#reset-cells"
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    clock-controller at ff9a0000 {
> +      compatible = "rockchip,rk3506-cru";
> +      reg = <0xff9a0000 0x20000>;
> +      #clock-cells = <1>;
> +      #reset-cells = <1>;
> +    };
> diff --git a/include/dt-bindings/clock/rockchip,rk3506-cru.h b/include/dt-bindings/clock/rockchip,rk3506-cru.h
> new file mode 100644
> index 000000000000..71d7dda23cc9
> --- /dev/null
> +++ b/include/dt-bindings/clock/rockchip,rk3506-cru.h
> @@ -0,0 +1,285 @@
> +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
> +/*
> + * Copyright (c) 2023-2025 Rockchip Electronics Co., Ltd.
> + * Author: Finley Xiao <finley.xiao at rock-chips.com>
> + */
> +
> +#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3506_H
> +#define _DT_BINDINGS_CLK_ROCKCHIP_RK3506_H
> +
> +/* cru plls */
> +#define PLL_GPLL			0
> +#define PLL_V0PLL			1
> +#define PLL_V1PLL			2
> +
> +/* cru-clocks indices */
> +#define ARMCLK				3
> +#define CLK_DDR				4
> +#define XIN24M_GATE			5
> +#define CLK_GPLL_GATE			6
> +#define CLK_V0PLL_GATE			7
> +#define CLK_V1PLL_GATE			8
> +#define CLK_GPLL_DIV			9
> +#define CLK_GPLL_DIV_100M		10
> +#define CLK_V0PLL_DIV			11
> +#define CLK_V1PLL_DIV			12
> +#define CLK_INT_VOICE_MATRIX0		13
> +#define CLK_INT_VOICE_MATRIX1		14
> +#define CLK_INT_VOICE_MATRIX2		15
> +#define CLK_FRAC_UART_MATRIX0_MUX	16
> +#define CLK_FRAC_UART_MATRIX1_MUX	17
> +#define CLK_FRAC_VOICE_MATRIX0_MUX	18
> +#define CLK_FRAC_VOICE_MATRIX1_MUX	19
> +#define CLK_FRAC_COMMON_MATRIX0_MUX	20
> +#define CLK_FRAC_COMMON_MATRIX1_MUX	21
> +#define CLK_FRAC_COMMON_MATRIX2_MUX	22
> +#define CLK_FRAC_UART_MATRIX0		23
> +#define CLK_FRAC_UART_MATRIX1		24
> +#define CLK_FRAC_VOICE_MATRIX0		25
> +#define CLK_FRAC_VOICE_MATRIX1		26
> +#define CLK_FRAC_COMMON_MATRIX0		27
> +#define CLK_FRAC_COMMON_MATRIX1		28
> +#define CLK_FRAC_COMMON_MATRIX2		29
> +#define CLK_REF_USBPHY_TOP		30
> +#define CLK_REF_DPHY_TOP		31
> +#define ACLK_CORE_ROOT			32
> +#define PCLK_CORE_ROOT			33
> +#define PCLK_DBG			34
> +#define PCLK_CORE_GRF			35
> +#define PCLK_CORE_CRU			36
> +#define CLK_CORE_EMA_DETECT		37
> +#define CLK_REF_PVTPLL_CORE		38
> +#define PCLK_GPIO1			39
> +#define DBCLK_GPIO1			40
> +#define ACLK_CORE_PERI_ROOT		41
> +#define HCLK_CORE_PERI_ROOT		42
> +#define PCLK_CORE_PERI_ROOT		43
> +#define CLK_DSMC			44
> +#define ACLK_DSMC			45
> +#define PCLK_DSMC			46
> +#define CLK_FLEXBUS_TX			47
> +#define CLK_FLEXBUS_RX			48
> +#define ACLK_FLEXBUS			49
> +#define HCLK_FLEXBUS			50
> +#define ACLK_DSMC_SLV			51
> +#define HCLK_DSMC_SLV			52
> +#define ACLK_BUS_ROOT			53
> +#define HCLK_BUS_ROOT			54
> +#define PCLK_BUS_ROOT			55
> +#define ACLK_SYSRAM			56
> +#define HCLK_SYSRAM			57
> +#define ACLK_DMAC0			58
> +#define ACLK_DMAC1			59
> +#define HCLK_M0				60
> +#define PCLK_BUS_GRF			61
> +#define PCLK_TIMER			62
> +#define CLK_TIMER0_CH0			63
> +#define CLK_TIMER0_CH1			64
> +#define CLK_TIMER0_CH2			65
> +#define CLK_TIMER0_CH3			66
> +#define CLK_TIMER0_CH4			67
> +#define CLK_TIMER0_CH5			68
> +#define PCLK_WDT0			69
> +#define TCLK_WDT0			70
> +#define PCLK_WDT1			71
> +#define TCLK_WDT1			72
> +#define PCLK_MAILBOX			73
> +#define PCLK_INTMUX			74
> +#define PCLK_SPINLOCK			75
> +#define PCLK_DDRC			76
> +#define HCLK_DDRPHY			77
> +#define PCLK_DDRMON			78
> +#define CLK_DDRMON_OSC			79
> +#define PCLK_STDBY			80
> +#define HCLK_USBOTG0			81
> +#define HCLK_USBOTG0_PMU		82
> +#define CLK_USBOTG0_ADP			83
> +#define HCLK_USBOTG1			84
> +#define HCLK_USBOTG1_PMU		85
> +#define CLK_USBOTG1_ADP			86
> +#define PCLK_USBPHY			87
> +#define ACLK_DMA2DDR			88
> +#define PCLK_DMA2DDR			89
> +#define STCLK_M0			90
> +#define CLK_DDRPHY			91
> +#define CLK_DDRC_SRC			92
> +#define ACLK_DDRC_0			93
> +#define ACLK_DDRC_1			94
> +#define CLK_DDRC			95
> +#define CLK_DDRMON			96
> +#define HCLK_LSPERI_ROOT		97
> +#define PCLK_LSPERI_ROOT		98
> +#define PCLK_UART0			99
> +#define PCLK_UART1			100
> +#define PCLK_UART2			101
> +#define PCLK_UART3			102
> +#define PCLK_UART4			103
> +#define SCLK_UART0			104
> +#define SCLK_UART1			105
> +#define SCLK_UART2			106
> +#define SCLK_UART3			107
> +#define SCLK_UART4			108
> +#define PCLK_I2C0			109
> +#define CLK_I2C0			110
> +#define PCLK_I2C1			111
> +#define CLK_I2C1			112
> +#define PCLK_I2C2			113
> +#define CLK_I2C2			114
> +#define PCLK_PWM1			115
> +#define CLK_PWM1			116
> +#define CLK_OSC_PWM1			117
> +#define CLK_RC_PWM1			118
> +#define CLK_FREQ_PWM1			119
> +#define CLK_COUNTER_PWM1		120
> +#define PCLK_SPI0			121
> +#define CLK_SPI0			122
> +#define PCLK_SPI1			123
> +#define CLK_SPI1			124
> +#define PCLK_GPIO2			125
> +#define DBCLK_GPIO2			126
> +#define PCLK_GPIO3			127
> +#define DBCLK_GPIO3			128
> +#define PCLK_GPIO4			129
> +#define DBCLK_GPIO4			130
> +#define HCLK_CAN0			131
> +#define CLK_CAN0			132
> +#define HCLK_CAN1			133
> +#define CLK_CAN1			134
> +#define HCLK_PDM			135
> +#define MCLK_PDM			136
> +#define CLKOUT_PDM			137
> +#define MCLK_SPDIFTX			138
> +#define HCLK_SPDIFTX			139
> +#define HCLK_SPDIFRX			140
> +#define MCLK_SPDIFRX			141
> +#define MCLK_SAI0			142
> +#define HCLK_SAI0			143
> +#define MCLK_OUT_SAI0			144
> +#define MCLK_SAI1			145
> +#define HCLK_SAI1			146
> +#define MCLK_OUT_SAI1			147
> +#define HCLK_ASRC0			148
> +#define CLK_ASRC0			149
> +#define HCLK_ASRC1			150
> +#define CLK_ASRC1			151
> +#define PCLK_CRU			152
> +#define PCLK_PMU_ROOT			153
> +#define MCLK_ASRC0			154
> +#define MCLK_ASRC1			155
> +#define MCLK_ASRC2			156
> +#define MCLK_ASRC3			157
> +#define LRCK_ASRC0_SRC			158
> +#define LRCK_ASRC0_DST			159
> +#define LRCK_ASRC1_SRC			160
> +#define LRCK_ASRC1_DST			161
> +#define ACLK_HSPERI_ROOT		162
> +#define HCLK_HSPERI_ROOT		163
> +#define PCLK_HSPERI_ROOT		164
> +#define CCLK_SRC_SDMMC			165
> +#define HCLK_SDMMC			166
> +#define HCLK_FSPI			167
> +#define SCLK_FSPI			168
> +#define PCLK_SPI2			169
> +#define ACLK_MAC0			170
> +#define ACLK_MAC1			171
> +#define PCLK_MAC0			172
> +#define PCLK_MAC1			173
> +#define CLK_MAC_ROOT			174
> +#define CLK_MAC0			175
> +#define CLK_MAC1			176
> +#define MCLK_SAI2			177
> +#define HCLK_SAI2			178
> +#define MCLK_OUT_SAI2			179
> +#define MCLK_SAI3_SRC			180
> +#define HCLK_SAI3			181
> +#define MCLK_SAI3			182
> +#define MCLK_OUT_SAI3			183
> +#define MCLK_SAI4_SRC			184
> +#define HCLK_SAI4			185
> +#define MCLK_SAI4			186
> +#define HCLK_DSM			187
> +#define MCLK_DSM			188
> +#define PCLK_AUDIO_ADC			189
> +#define MCLK_AUDIO_ADC			190
> +#define MCLK_AUDIO_ADC_DIV4		191
> +#define PCLK_SARADC			192
> +#define CLK_SARADC			193
> +#define PCLK_OTPC_NS			194
> +#define CLK_SBPI_OTPC_NS		195
> +#define CLK_USER_OTPC_NS		196
> +#define PCLK_UART5			197
> +#define SCLK_UART5			198
> +#define PCLK_GPIO234_IOC		199
> +#define CLK_MAC_PTP_ROOT		200
> +#define CLK_MAC0_PTP			201
> +#define CLK_MAC1_PTP			202
> +#define CLK_SPI2			203
> +#define ACLK_VIO_ROOT			204
> +#define HCLK_VIO_ROOT			205
> +#define PCLK_VIO_ROOT			206
> +#define HCLK_RGA			207
> +#define ACLK_RGA			208
> +#define CLK_CORE_RGA			209
> +#define ACLK_VOP			210
> +#define HCLK_VOP			211
> +#define DCLK_VOP			212
> +#define PCLK_DPHY			213
> +#define PCLK_DSI_HOST			214
> +#define PCLK_TSADC			215
> +#define CLK_TSADC			216
> +#define CLK_TSADC_TSEN			217
> +#define PCLK_GPIO1_IOC			218
> +#define PCLK_OTPC_S			219
> +#define CLK_SBPI_OTPC_S			220
> +#define CLK_USER_OTPC_S			221
> +#define PCLK_OTP_MASK			222
> +#define PCLK_KEYREADER			223
> +#define HCLK_BOOTROM			224
> +#define PCLK_DDR_SERVICE		225
> +#define HCLK_CRYPTO_S			226
> +#define HCLK_KEYLAD			227
> +#define CLK_CORE_CRYPTO			228
> +#define CLK_PKA_CRYPTO			229
> +#define CLK_CORE_CRYPTO_S		230
> +#define CLK_PKA_CRYPTO_S		231
> +#define ACLK_CRYPTO_S			232
> +#define HCLK_RNG_S			233
> +#define CLK_CORE_CRYPTO_NS		234
> +#define CLK_PKA_CRYPTO_NS		235
> +#define ACLK_CRYPTO_NS			236
> +#define HCLK_CRYPTO_NS			237
> +#define HCLK_RNG			238
> +#define CLK_PMU				239
> +#define PCLK_PMU			240
> +#define CLK_PMU_32K			241
> +#define PCLK_PMU_CRU			242
> +#define PCLK_PMU_GRF			243
> +#define PCLK_GPIO0_IOC			244
> +#define PCLK_GPIO0			245
> +#define DBCLK_GPIO0			246
> +#define PCLK_GPIO1_SHADOW		247
> +#define DBCLK_GPIO1_SHADOW		248
> +#define PCLK_PMU_HP_TIMER		249
> +#define CLK_PMU_HP_TIMER		250
> +#define CLK_PMU_HP_TIMER_32K		251
> +#define PCLK_PWM0			252
> +#define CLK_PWM0			253
> +#define CLK_OSC_PWM0			254
> +#define CLK_RC_PWM0			255
> +#define CLK_MAC_OUT			256
> +#define CLK_REF_OUT0			257
> +#define CLK_REF_OUT1			258
> +#define CLK_32K_FRAC			259
> +#define CLK_32K_RC			260
> +#define CLK_32K				261
> +#define CLK_32K_PMU			262
> +#define PCLK_TOUCH_KEY			263
> +#define CLK_TOUCH_KEY			264
> +#define CLK_REF_PHY_PLL			265
> +#define CLK_REF_PHY_PMU_MUX		266
> +#define CLK_WIFI_OUT			267
> +#define CLK_V0PLL_REF			268
> +#define CLK_V1PLL_REF			269
> +#define CLK_32K_FRAC_MUX		270
> +
> +#endif
> diff --git a/include/dt-bindings/reset/rockchip,rk3506-cru.h b/include/dt-bindings/reset/rockchip,rk3506-cru.h
> new file mode 100644
> index 000000000000..f38cc066009b
> --- /dev/null
> +++ b/include/dt-bindings/reset/rockchip,rk3506-cru.h
> @@ -0,0 +1,211 @@
> +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
> +/*
> + * Copyright (c) 2023-2025 Rockchip Electronics Co., Ltd.
> + * Author: Finley Xiao <finley.xiao at rock-chips.com>
> + */
> +
> +#ifndef _DT_BINDINGS_REST_ROCKCHIP_RK3506_H
> +#define _DT_BINDINGS_REST_ROCKCHIP_RK3506_H
> +
> +/* CRU-->SOFTRST_CON00 */
> +#define SRST_NCOREPORESET0_AC		0
> +#define SRST_NCOREPORESET1_AC		1
> +#define SRST_NCOREPORESET2_AC		2
> +#define SRST_NCORESET0_AC		3
> +#define SRST_NCORESET1_AC		4
> +#define SRST_NCORESET2_AC		5
> +#define SRST_NL2RESET_AC		6
> +#define SRST_ARESETN_CORE_BIU_AC	7
> +#define SRST_HRESETN_M0_AC		8
> +
> +/* CRU-->SOFTRST_CON02 */
> +#define SRST_NDBGRESET			9
> +#define SRST_PRESETN_CORE_BIU		10
> +#define SRST_RESETN_PMU			11
> +
> +/* CRU-->SOFTRST_CON03 */
> +#define SRST_PRESETN_DBG		12
> +#define SRST_POTRESETN_DBG		13
> +#define SRST_PRESETN_CORE_GRF		14
> +#define SRST_RESETN_CORE_EMA_DETECT	15
> +#define SRST_RESETN_REF_PVTPLL_CORE	16
> +#define SRST_PRESETN_GPIO1		17
> +#define SRST_DBRESETN_GPIO1		18
> +
> +/* CRU-->SOFTRST_CON04 */
> +#define SRST_ARESETN_CORE_PERI_BIU	19
> +#define SRST_ARESETN_DSMC		20
> +#define SRST_PRESETN_DSMC		21
> +#define SRST_RESETN_FLEXBUS		22
> +#define SRST_ARESETN_FLEXBUS		23
> +#define SRST_HRESETN_FLEXBUS		24
> +#define SRST_ARESETN_DSMC_SLV		25
> +#define SRST_HRESETN_DSMC_SLV		26
> +#define SRST_RESETN_DSMC_SLV		27
> +
> +/* CRU-->SOFTRST_CON05 */
> +#define SRST_ARESETN_BUS_BIU		28
> +#define SRST_HRESETN_BUS_BIU		29
> +#define SRST_PRESETN_BUS_BIU		30
> +#define SRST_ARESETN_SYSRAM		31
> +#define SRST_HRESETN_SYSRAM		32
> +#define SRST_ARESETN_DMAC0		33
> +#define SRST_ARESETN_DMAC1		34
> +#define SRST_HRESETN_M0			35
> +#define SRST_RESETN_M0_JTAG		36
> +#define SRST_HRESETN_CRYPTO		37
> +
> +/* CRU-->SOFTRST_CON06 */
> +#define SRST_HRESETN_RNG		38
> +#define SRST_PRESETN_BUS_GRF		39
> +#define SRST_PRESETN_TIMER0		40
> +#define SRST_RESETN_TIMER0_CH0		41
> +#define SRST_RESETN_TIMER0_CH1		42
> +#define SRST_RESETN_TIMER0_CH2		43
> +#define SRST_RESETN_TIMER0_CH3		44
> +#define SRST_RESETN_TIMER0_CH4		45
> +#define SRST_RESETN_TIMER0_CH5		46
> +#define SRST_PRESETN_WDT0		47
> +#define SRST_TRESETN_WDT0		48
> +#define SRST_PRESETN_WDT1		49
> +#define SRST_TRESETN_WDT1		50
> +#define SRST_PRESETN_MAILBOX		51
> +#define SRST_PRESETN_INTMUX		52
> +#define SRST_PRESETN_SPINLOCK		53
> +
> +/* CRU-->SOFTRST_CON07 */
> +#define SRST_PRESETN_DDRC		54
> +#define SRST_HRESETN_DDRPHY		55
> +#define SRST_PRESETN_DDRMON		56
> +#define SRST_RESETN_DDRMON_OSC		57
> +#define SRST_PRESETN_DDR_LPC		58
> +#define SRST_HRESETN_USBOTG0		59
> +#define SRST_RESETN_USBOTG0_ADP		60
> +#define SRST_HRESETN_USBOTG1		61
> +#define SRST_RESETN_USBOTG1_ADP		62
> +#define SRST_PRESETN_USBPHY		63
> +#define SRST_RESETN_USBPHY_POR		64
> +#define SRST_RESETN_USBPHY_OTG0		65
> +#define SRST_RESETN_USBPHY_OTG1		66
> +
> +/* CRU-->SOFTRST_CON08 */
> +#define SRST_ARESETN_DMA2DDR		67
> +#define SRST_PRESETN_DMA2DDR		68
> +
> +/* CRU-->SOFTRST_CON09 */
> +#define SRST_RESETN_USBOTG0_UTMI	69
> +#define SRST_RESETN_USBOTG1_UTMI	70
> +
> +/* CRU-->SOFTRST_CON10 */
> +#define SRST_ARESETN_DDRC_0		71
> +#define SRST_ARESETN_DDRC_1		72
> +#define SRST_ARESETN_DDR_BIU		73
> +#define SRST_RESETN_DDRC		74
> +#define SRST_RESETN_DDRMON		75
> +
> +/* CRU-->SOFTRST_CON11 */
> +#define SRST_HRESETN_LSPERI_BIU		76
> +#define SRST_PRESETN_UART0		77
> +#define SRST_PRESETN_UART1		78
> +#define SRST_PRESETN_UART2		79
> +#define SRST_PRESETN_UART3		80
> +#define SRST_PRESETN_UART4		81
> +#define SRST_RESETN_UART0		82
> +#define SRST_RESETN_UART1		83
> +#define SRST_RESETN_UART2		84
> +#define SRST_RESETN_UART3		85
> +#define SRST_RESETN_UART4		86
> +#define SRST_PRESETN_I2C0		87
> +#define SRST_RESETN_I2C0		88
> +
> +/* CRU-->SOFTRST_CON12 */
> +#define SRST_PRESETN_I2C1		89
> +#define SRST_RESETN_I2C1		90
> +#define SRST_PRESETN_I2C2		91
> +#define SRST_RESETN_I2C2		92
> +#define SRST_PRESETN_PWM1		93
> +#define SRST_RESETN_PWM1		94
> +#define SRST_PRESETN_SPI0		95
> +#define SRST_RESETN_SPI0		96
> +#define SRST_PRESETN_SPI1		97
> +#define SRST_RESETN_SPI1		98
> +#define SRST_PRESETN_GPIO2		99
> +#define SRST_DBRESETN_GPIO2		100
> +
> +/* CRU-->SOFTRST_CON13 */
> +#define SRST_PRESETN_GPIO3		101
> +#define SRST_DBRESETN_GPIO3		102
> +#define SRST_PRESETN_GPIO4		103
> +#define SRST_DBRESETN_GPIO4		104
> +#define SRST_HRESETN_CAN0		105
> +#define SRST_RESETN_CAN0		106
> +#define SRST_HRESETN_CAN1		107
> +#define SRST_RESETN_CAN1		108
> +#define SRST_HRESETN_PDM		109
> +#define SRST_MRESETN_PDM		110
> +#define SRST_RESETN_PDM			111
> +#define SRST_RESETN_SPDIFTX		112
> +#define SRST_HRESETN_SPDIFTX		113
> +#define SRST_HRESETN_SPDIFRX		114
> +#define SRST_RESETN_SPDIFRX		115
> +#define SRST_MRESETN_SAI0		116
> +
> +/* CRU-->SOFTRST_CON14 */
> +#define SRST_HRESETN_SAI0		117
> +#define SRST_MRESETN_SAI1		118
> +#define SRST_HRESETN_SAI1		119
> +#define SRST_HRESETN_ASRC0		120
> +#define SRST_RESETN_ASRC0		121
> +#define SRST_HRESETN_ASRC1		122
> +#define SRST_RESETN_ASRC1		123
> +
> +/* CRU-->SOFTRST_CON17 */
> +#define SRST_HRESETN_HSPERI_BIU		124
> +#define SRST_HRESETN_SDMMC		125
> +#define SRST_HRESETN_FSPI		126
> +#define SRST_SRESETN_FSPI		127
> +#define SRST_PRESETN_SPI2		128
> +#define SRST_ARESETN_MAC0		129
> +#define SRST_ARESETN_MAC1		130
> +
> +/* CRU-->SOFTRST_CON18 */
> +#define SRST_MRESETN_SAI2		131
> +#define SRST_HRESETN_SAI2		132
> +#define SRST_HRESETN_SAI3		133
> +#define SRST_MRESETN_SAI3		134
> +#define SRST_HRESETN_SAI4		135
> +#define SRST_MRESETN_SAI4		136
> +#define SRST_HRESETN_DSM		137
> +#define SRST_MRESETN_DSM		138
> +#define SRST_PRESETN_AUDIO_ADC		139
> +#define SRST_MRESETN_AUDIO_ADC		140
> +
> +/* CRU-->SOFTRST_CON19 */
> +#define SRST_PRESETN_SARADC		141
> +#define SRST_RESETN_SARADC		142
> +#define SRST_RESETN_SARADC_PHY		143
> +#define SRST_PRESETN_OTPC_NS		144
> +#define SRST_RESETN_SBPI_OTPC_NS	145
> +#define SRST_RESETN_USER_OTPC_NS	146
> +#define SRST_PRESETN_UART5		147
> +#define SRST_RESETN_UART5		148
> +#define SRST_PRESETN_GPIO234_IOC	149
> +
> +/* CRU-->SOFTRST_CON21 */
> +#define SRST_ARESETN_VIO_BIU		150
> +#define SRST_HRESETN_VIO_BIU		151
> +#define SRST_HRESETN_RGA		152
> +#define SRST_ARESETN_RGA		153
> +#define SRST_RESETN_CORE_RGA		154
> +#define SRST_ARESETN_VOP		155
> +#define SRST_HRESETN_VOP		156
> +#define SRST_RESETN_VOP			157
> +#define SRST_PRESETN_DPHY		158
> +#define SRST_PRESETN_DSI_HOST		159
> +#define SRST_PRESETN_TSADC		160
> +#define SRST_RESETN_TSADC		161
> +
> +/* CRU-->SOFTRST_CON22 */
> +#define SRST_PRESETN_GPIO1_IOC		162
> +
> +#endif
> 






From heiko at sntech.de  Wed Nov  5 15:54:08 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Thu,  6 Nov 2025 00:54:08 +0100
Subject: [PATCH] arm64: dts: rockchip: use SCMI clock id for gpu clock on rk356x
Message-ID: <20251105235408.163282-1-heiko@sntech.de>

Instead of hard-coding 1, use the more descriptive ID from the binding
to reference the SCMI clock for the gpu on rk356x.

Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
 arch/arm64/boot/dts/rockchip/rk356x-base.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
index a1815f8a96e1..16773904ff66 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
@@ -616,7 +616,7 @@ gpu: gpu at fde60000 {
 			     <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
 			     <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "job", "mmu", "gpu";
-		clocks = <&scmi_clk 1>, <&cru CLK_GPU>;
+		clocks = <&scmi_clk SCMI_CLK_GPU>, <&cru CLK_GPU>;
 		clock-names = "gpu", "bus";
 		#cooling-cells = <2>;
 		power-domains = <&power RK3568_PD_GPU>;
-- 
2.47.2



From macromorgan at hotmail.com  Wed Nov  5 17:06:41 2025
From: macromorgan at hotmail.com (Chris Morgan)
Date: Wed, 5 Nov 2025 19:06:41 -0600
Subject: [PATCH 4/5] arm64: dts: rockchip: Enable HS400 for Indiedroid
 Nova
In-Reply-To: <2864346.mvXUDI8C0e@phil>
References: <20251105205708.732125-1-macroalpha82@gmail.com>
 <20251105205708.732125-5-macroalpha82@gmail.com>
 <2864346.mvXUDI8C0e@phil>
Message-ID: <DM5PR19MB4646879FCC2D1B807A20E067A5C2A@DM5PR19MB4646.namprd19.prod.outlook.com>

On Thu, Nov 06, 2025 at 12:18:51AM +0100, Heiko Stuebner wrote:
> Am Mittwoch, 5. November 2025, 21:57:07 Mitteleurop?ische Normalzeit schrieb Chris Morgan:
> > From: Chris Morgan <macromorgan at hotmail.com>
> > 
> > Once the DLL_STRBIN_TAPNUM_DEFAULT is set to the correct value [1], the
> > workaround to ensure stable eMMC operation is no longer needed. I
> > have observed testing this that hdparm went from:
> > "Timing buffered disk reads: 502 MB in  3.00 seconds = 167.14 MB/sec"
> > to the following:
> > "Timing buffered disk reads: 832 MB in  3.00 seconds = 277.32 MB/sec"
> > 
> > [1] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/drivers/mmc/host/sdhci-of-dwcmshc.c?id=a28352cf2d2f8380e7aca8cb61682396dca7a991
> > 
> > Fixes: 3900160e164b ("arm64: dts: rockchip: Add Indiedroid Nova board")
> 
> This needs the patch you linked to, to actually work, so I'll drop
> the fixes tag when applying, because this should likely not be
> backported to older kernels.
> 
> Same reasoning for patch 5.

Thank you, I wasn't sure about that or not. I can say with certanty
you don't want the eMMC device tree changes prior to that patch going
through or bad things will happen.

Chris

> 
> 
> Heiko
> 
> > Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
> > ---
> >  arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
> > index 62c8c8f68713..0796ba6d2504 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
> > +++ b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
> > @@ -561,10 +561,10 @@ &saradc {
> >  	status = "okay";
> >  };
> >  
> > -/* HS400 modes seemed to cause io errors. */
> >  &sdhci {
> >  	bus-width = <8>;
> > -	no-mmc-hs400;
> > +	mmc-hs400-1_8v;
> > +	mmc-hs400-enhanced-strobe;
> >  	no-sd;
> >  	no-sdio;
> >  	non-removable;
> > 
> 
> 
> 
> 


From kernel at airkyi.com  Wed Nov  5 18:06:23 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Thu,  6 Nov 2025 10:06:23 +0800
Subject: [PATCH 0/9] drm/rockchip: Introduce Rockchip RK3506 VOP
Message-ID: <20251106020632.92-1-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

The VOP on rk3506:
- Support 2 lane MIPI DSI interface, 1.5Gbps/lane.
- Support RGB interface.
- Max output resolution is 1280x1280 at 60fps.
- WIN1 layer support RGB888/ARGB8888/RGB565.
- Support Gamma LUT.

This series adds basic support for rk3506 VOP. And tested on the
rk3506g-evb1-v10 board with a Wanchanglong W552946AAA DSI panel.

Chaoyi Chen (9):
  dt-bindings: ili9881c: Add compatible string for Wanchanglong
    w552946aaa
  dt-bindings: phy: rockchip-inno-dsidphy: Add compatible for rk3506
  dt-bindings: display: rockchip,dw-mipi-dsi: Add compatible for rk3506
  dt-bindings: display: rockchip,vop: Add compatible for rk3506
  drm/panel: ilitek-ili9881d: Add support for Wanchanglong W552946AAA
    panel
  phy: rockchip: inno-dsidphy: Add support for rk3506
  drm/rockchip: dsi: Add support for rk3506
  drm/rockchip: Drop ROCKCHIP_IOMMU depend for DRM_ROCKCHIP
  drm/rockchip: vop: Add support for rk3506

 .../display/panel/ilitek,ili9881c.yaml        |   1 +
 .../rockchip/rockchip,dw-mipi-dsi.yaml        |   1 +
 .../display/rockchip/rockchip-vop.yaml        |   1 +
 .../bindings/phy/rockchip,px30-dsi-dphy.yaml  |   1 +
 drivers/gpu/drm/panel/panel-ilitek-ili9881c.c | 225 ++++++++++++++++++
 drivers/gpu/drm/rockchip/Kconfig              |   3 +-
 .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c   |  20 ++
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c   |  57 +++++
 drivers/gpu/drm/rockchip/rockchip_vop_reg.h   |  14 ++
 .../phy/rockchip/phy-rockchip-inno-dsidphy.c  |  91 ++++++-
 10 files changed, 410 insertions(+), 4 deletions(-)

-- 
2.51.1



From kernel at airkyi.com  Wed Nov  5 18:06:25 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Thu,  6 Nov 2025 10:06:25 +0800
Subject: [PATCH 2/9] dt-bindings: phy: rockchip-inno-dsidphy: Add compatible for rk3506
In-Reply-To: <20251106020632.92-1-kernel@airkyi.com>
References: <20251106020632.92-1-kernel@airkyi.com>
Message-ID: <20251106020632.92-3-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

Document a compatible string for the rk3506 dsi-dphy.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---
 .../devicetree/bindings/phy/rockchip,px30-dsi-dphy.yaml          | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/phy/rockchip,px30-dsi-dphy.yaml b/Documentation/devicetree/bindings/phy/rockchip,px30-dsi-dphy.yaml
index 46e64fa293d5..83e7c825860c 100644
--- a/Documentation/devicetree/bindings/phy/rockchip,px30-dsi-dphy.yaml
+++ b/Documentation/devicetree/bindings/phy/rockchip,px30-dsi-dphy.yaml
@@ -18,6 +18,7 @@ properties:
       - rockchip,px30-dsi-dphy
       - rockchip,rk3128-dsi-dphy
       - rockchip,rk3368-dsi-dphy
+      - rockchip,rk3506-dsi-dphy
       - rockchip,rk3568-dsi-dphy
       - rockchip,rv1126-dsi-dphy
 
-- 
2.51.1




From kernel at airkyi.com  Wed Nov  5 18:06:24 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Thu,  6 Nov 2025 10:06:24 +0800
Subject: [PATCH 1/9] dt-bindings: ili9881c: Add compatible string for Wanchanglong w552946aaa
In-Reply-To: <20251106020632.92-1-kernel@airkyi.com>
References: <20251106020632.92-1-kernel@airkyi.com>
Message-ID: <20251106020632.92-2-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

Like w552946aba, w552946aaa uses the Ilitek ILI9881D controller chip,
and it supports up to 2 lanes.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---
 .../devicetree/bindings/display/panel/ilitek,ili9881c.yaml       | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml b/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml
index 434cc6af9c95..f331a47cc759 100644
--- a/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml
+++ b/Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml
@@ -23,6 +23,7 @@ properties:
           - raspberrypi,dsi-7inch
           - startek,kd050hdfia020
           - tdo,tl050hdv35
+          - wanchanglong,w552946aaa
           - wanchanglong,w552946aba
       - const: ilitek,ili9881c
 
-- 
2.51.1



From kernel at airkyi.com  Wed Nov  5 18:06:27 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Thu,  6 Nov 2025 10:06:27 +0800
Subject: [PATCH 4/9] dt-bindings: display: rockchip,vop: Add compatible for rk3506
In-Reply-To: <20251106020632.92-1-kernel@airkyi.com>
References: <20251106020632.92-1-kernel@airkyi.com>
Message-ID: <20251106020632.92-5-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

The rk3506 VOP has adopted a new implementation.
Add a new compatible string for it.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---
 .../devicetree/bindings/display/rockchip/rockchip-vop.yaml       | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.yaml
index 8b5f58103dda..fdf4b1109da2 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.yaml
@@ -31,6 +31,7 @@ properties:
       - rockchip,rk3368-vop
       - rockchip,rk3399-vop-big
       - rockchip,rk3399-vop-lit
+      - rockchip,rk3506-vop
       - rockchip,rv1126-vop
 
   reg:
-- 
2.51.1



From kernel at airkyi.com  Wed Nov  5 18:06:26 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Thu,  6 Nov 2025 10:06:26 +0800
Subject: [PATCH 3/9] dt-bindings: display: rockchip,dw-mipi-dsi: Add compatible for rk3506
In-Reply-To: <20251106020632.92-1-kernel@airkyi.com>
References: <20251106020632.92-1-kernel@airkyi.com>
Message-ID: <20251106020632.92-4-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

Document a compatible string for the rk3506 mipi-dsi.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---
 .../bindings/display/rockchip/rockchip,dw-mipi-dsi.yaml          | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-mipi-dsi.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-mipi-dsi.yaml
index c59df3c1a3f7..d949750a3afd 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-mipi-dsi.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-mipi-dsi.yaml
@@ -73,6 +73,7 @@ allOf:
             enum:
               - rockchip,px30-mipi-dsi
               - rockchip,rk3128-mipi-dsi
+              - rockchip,rk3506-mipi-dsi
               - rockchip,rk3568-mipi-dsi
               - rockchip,rv1126-mipi-dsi
 
-- 
2.51.1



From kernel at airkyi.com  Wed Nov  5 18:06:29 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Thu,  6 Nov 2025 10:06:29 +0800
Subject: [PATCH 6/9] phy: rockchip: inno-dsidphy: Add support for rk3506
In-Reply-To: <20251106020632.92-1-kernel@airkyi.com>
References: <20251106020632.92-1-kernel@airkyi.com>
Message-ID: <20251106020632.92-7-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

For MIPI mode, the inno-dsidphy found on RK3506 supports up to 2 lanes
and a maximum data rate of 1.5GHz.

Signed-off-by: Hongming Zou <hongming.zou at rock-chips.com>
Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---
 .../phy/rockchip/phy-rockchip-inno-dsidphy.c  | 91 ++++++++++++++++++-
 1 file changed, 88 insertions(+), 3 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
index d5b1a4e2f7d3..30d5e5ddff4a 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
@@ -99,10 +99,30 @@
 #define VOD_MID_RANGE				0x3
 #define VOD_BIG_RANGE				0x7
 #define VOD_MAX_RANGE				0xf
+/* Analog Register Part: reg18 */
+#define LANE0_PRE_EMPHASIS_ENABLE_MASK		BIT(6)
+#define LANE0_PRE_EMPHASIS_ENABLE		BIT(6)
+#define LANE0_PRE_EMPHASIS_DISABLE		0
+#define LANE1_PRE_EMPHASIS_ENABLE_MASK		BIT(5)
+#define LANE1_PRE_EMPHASIS_ENABLE		BIT(5)
+#define LANE1_PRE_EMPHASIS_DISABLE		0
+/* Analog Register Part: reg19 */
+#define PRE_EMPHASIS_RANGE_SET_MASK		GENMASK(7, 6)
+#define PRE_EMPHASIS_RANGE_SET(x)		UPDATE(x, 7, 6)
 /* Analog Register Part: reg1E */
 #define PLL_MODE_SEL_MASK			GENMASK(6, 5)
 #define PLL_MODE_SEL_LVDS_MODE			0
 #define PLL_MODE_SEL_MIPI_MODE			BIT(5)
+/* Analog Register Part: reg20 */
+#define LANE0_PRE_EMPHASIS_RANGE_SET_MASK	GENMASK(7, 6)
+#define LANE0_PRE_EMPHASIS_RANGE_SET(x)		UPDATE(x, 7, 6)
+/* Analog Register Part: reg21 */
+#define LANE1_PRE_EMPHASIS_RANGE_SET_MASK	GENMASK(7, 6)
+#define LANE1_PRE_EMPHASIS_RANGE_SET(x)		UPDATE(x, 7, 6)
+#define PRE_EMPHASIS_MIN_RANGE			0x0
+#define PRE_EMPHASIS_MID_RANGE			0x1
+#define PRE_EMPHASIS_MAX_RANGE			0x2
+#define PRE_EMPHASIS_RESERVED_RANGE		0x3
 /* Digital Register Part: reg00 */
 #define REG_DIG_RSTN_MASK			BIT(0)
 #define REG_DIG_RSTN_NORMAL			BIT(0)
@@ -193,6 +213,7 @@
 
 enum phy_max_rate {
 	MAX_1GHZ,
+	MAX_1_5GHZ,
 	MAX_2_5GHZ,
 };
 
@@ -200,6 +221,7 @@ struct inno_video_phy_plat_data {
 	const struct inno_mipi_dphy_timing *inno_mipi_dphy_timing_table;
 	const unsigned int num_timings;
 	enum phy_max_rate max_rate;
+	unsigned int max_lanes;
 };
 
 struct inno_dsidphy {
@@ -258,6 +280,24 @@ struct inno_mipi_dphy_timing inno_mipi_dphy_timing_table_max_1ghz[] = {
 	{1000000000, 0x0, 0x09, 0x20, 0x09, 0x27},
 };
 
+static const
+struct inno_mipi_dphy_timing inno_mipi_dphy_timing_table_max_1_5ghz[] = {
+	{ 110, 0x02, 0x7f, 0x16, 0x02, 0x02},
+	{ 150, 0x02, 0x7f, 0x16, 0x03, 0x02},
+	{ 200, 0x02, 0x7f, 0x17, 0x04, 0x02},
+	{ 250, 0x02, 0x7f, 0x17, 0x05, 0x04},
+	{ 300, 0x02, 0x7f, 0x18, 0x06, 0x04},
+	{ 400, 0x03, 0x7e, 0x19, 0x07, 0x04},
+	{ 500, 0x03, 0x7c, 0x1b, 0x07, 0x08},
+	{ 600, 0x03, 0x70, 0x1d, 0x08, 0x10},
+	{ 700, 0x05, 0x40, 0x1e, 0x08, 0x30},
+	{ 800, 0x05, 0x02, 0x1f, 0x09, 0x30},
+	{1000, 0x05, 0x08, 0x20, 0x09, 0x30},
+	{1200, 0x06, 0x03, 0x32, 0x14, 0x0f},
+	{1400, 0x09, 0x03, 0x32, 0x14, 0x0f},
+	{1500, 0x0d, 0x42, 0x36, 0x0e, 0x0f},
+};
+
 static const
 struct inno_mipi_dphy_timing inno_mipi_dphy_timing_table_max_2_5ghz[] = {
 	{ 110000000, 0x02, 0x7f, 0x16, 0x02, 0x02},
@@ -372,6 +412,7 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
 	u32 hs_exit, clk_post, clk_pre, wakeup, lpx, ta_go, ta_sure, ta_wait;
 	u32 hs_prepare, hs_trail, hs_zero, clk_lane_hs_zero, data_lane_hs_zero;
 	unsigned int i;
+	u32 val;
 
 	timings = inno->pdata->inno_mipi_dphy_timing_table;
 
@@ -393,6 +434,23 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
 		phy_update_bits(inno, REGISTER_PART_ANALOG, 0x0b,
 				CLOCK_LANE_VOD_RANGE_SET_MASK,
 				CLOCK_LANE_VOD_RANGE_SET(VOD_MAX_RANGE));
+	} else if (inno->pdata->max_rate == MAX_1_5GHZ) {
+		phy_update_bits(inno, REGISTER_PART_ANALOG, 0x18,
+				LANE0_PRE_EMPHASIS_ENABLE_MASK, LANE0_PRE_EMPHASIS_ENABLE);
+		phy_update_bits(inno, REGISTER_PART_ANALOG, 0x18,
+				LANE1_PRE_EMPHASIS_ENABLE_MASK, LANE1_PRE_EMPHASIS_ENABLE);
+		phy_update_bits(inno, REGISTER_PART_ANALOG, 0x19,
+				PRE_EMPHASIS_RANGE_SET_MASK,
+				PRE_EMPHASIS_RANGE_SET(PRE_EMPHASIS_MID_RANGE));
+		phy_update_bits(inno, REGISTER_PART_ANALOG, 0x1a,
+				LANE0_PRE_EMPHASIS_RANGE_SET_MASK,
+				LANE0_PRE_EMPHASIS_RANGE_SET(PRE_EMPHASIS_MID_RANGE));
+		phy_update_bits(inno, REGISTER_PART_ANALOG, 0x1b,
+				LANE1_PRE_EMPHASIS_RANGE_SET_MASK,
+				LANE1_PRE_EMPHASIS_RANGE_SET(PRE_EMPHASIS_MID_RANGE));
+		phy_update_bits(inno, REGISTER_PART_ANALOG, 0x0b,
+				CLOCK_LANE_VOD_RANGE_SET_MASK,
+				CLOCK_LANE_VOD_RANGE_SET(VOD_MAX_RANGE));
 	}
 	/* Enable PLL and LDO */
 	phy_update_bits(inno, REGISTER_PART_ANALOG, 0x01,
@@ -518,10 +576,25 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
 				T_TA_WAIT_CNT(ta_wait));
 	}
 
-	/* Enable all lanes on analog part */
+	/* Enable lanes on analog part */
+	switch (inno->pdata->max_lanes) {
+	case 1:
+		val =  LANE_EN_0;
+		break;
+	case 2:
+		val =  LANE_EN_0 | LANE_EN_1;
+		break;
+	case 3:
+		val = LANE_EN_0 | LANE_EN_1 | LANE_EN_2;
+		break;
+	case 4:
+	default:
+		val = LANE_EN_0 | LANE_EN_1 | LANE_EN_2 | LANE_EN_3;
+		break;
+	}
+
 	phy_update_bits(inno, REGISTER_PART_ANALOG, 0x00,
-			LANE_EN_MASK, LANE_EN_CK | LANE_EN_3 | LANE_EN_2 |
-			LANE_EN_1 | LANE_EN_0);
+			LANE_EN_MASK, LANE_EN_CK | val);
 }
 
 static void inno_dsidphy_lvds_mode_enable(struct inno_dsidphy *inno)
@@ -680,12 +753,21 @@ static const struct inno_video_phy_plat_data max_1ghz_video_phy_plat_data = {
 	.inno_mipi_dphy_timing_table = inno_mipi_dphy_timing_table_max_1ghz,
 	.num_timings = ARRAY_SIZE(inno_mipi_dphy_timing_table_max_1ghz),
 	.max_rate = MAX_1GHZ,
+	.max_lanes = 4,
+};
+
+static const struct inno_video_phy_plat_data max_1_5ghz_video_phy_plat_data = {
+	.inno_mipi_dphy_timing_table = inno_mipi_dphy_timing_table_max_1_5ghz,
+	.num_timings = ARRAY_SIZE(inno_mipi_dphy_timing_table_max_1_5ghz),
+	.max_rate = MAX_1_5GHZ,
+	.max_lanes = 2,
 };
 
 static const struct inno_video_phy_plat_data max_2_5ghz_video_phy_plat_data = {
 	.inno_mipi_dphy_timing_table = inno_mipi_dphy_timing_table_max_2_5ghz,
 	.num_timings = ARRAY_SIZE(inno_mipi_dphy_timing_table_max_2_5ghz),
 	.max_rate = MAX_2_5GHZ,
+	.max_lanes = 4,
 };
 
 static int inno_dsidphy_probe(struct platform_device *pdev)
@@ -767,6 +849,9 @@ static const struct of_device_id inno_dsidphy_of_match[] = {
 	}, {
 		.compatible = "rockchip,rk3368-dsi-dphy",
 		.data = &max_1ghz_video_phy_plat_data,
+	}, {
+		.compatible = "rockchip,rk3506-dsi-dphy",
+		.data = &max_1_5ghz_video_phy_plat_data,
 	}, {
 		.compatible = "rockchip,rk3568-dsi-dphy",
 		.data = &max_2_5ghz_video_phy_plat_data,
-- 
2.51.1



From kernel at airkyi.com  Wed Nov  5 18:06:31 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Thu,  6 Nov 2025 10:06:31 +0800
Subject: [PATCH 8/9] drm/rockchip: Drop ROCKCHIP_IOMMU depend for DRM_ROCKCHIP
In-Reply-To: <20251106020632.92-1-kernel@airkyi.com>
References: <20251106020632.92-1-kernel@airkyi.com>
Message-ID: <20251106020632.92-9-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

On the RK3506 platform, there is no iommu hardware. And even on
platform that have iommu hardware, it should be possible to use
VOP without enabling iommu. In this case, a contiguous memory
space like CMA should be used.

So this patch removes the dependency on ROCKCHIP_IOMMU.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---
 drivers/gpu/drm/rockchip/Kconfig | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index b7b025814e72..a056d419190c 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -1,7 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0-only
 config DRM_ROCKCHIP
 	tristate "DRM Support for Rockchip"
-	depends on DRM && ROCKCHIP_IOMMU
+	depends on DRM
+	depends on ROCKCHIP_IOMMU || !ROCKCHIP_IOMMU
 	depends on OF
 	select DRM_CLIENT_SELECTION
 	select DRM_GEM_DMA_HELPER
-- 
2.51.1



From kernel at airkyi.com  Wed Nov  5 18:06:28 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Thu,  6 Nov 2025 10:06:28 +0800
Subject: [PATCH 5/9] drm/panel: ilitek-ili9881d: Add support for Wanchanglong W552946AAA panel
In-Reply-To: <20251106020632.92-1-kernel@airkyi.com>
References: <20251106020632.92-1-kernel@airkyi.com>
Message-ID: <20251106020632.92-6-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

W552946AAA is a panel by Wanchanglong. This panel utilizes the
Ilitek ILI9881D controller.

W552946AAA is similar to W552946ABA, but the W552946AAA only
uses 2 lanes.

Tested on rk3506g-evb1-v10.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---
 drivers/gpu/drm/panel/panel-ilitek-ili9881c.c | 225 ++++++++++++++++++
 1 file changed, 225 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c
index ad4993b2f92a..9b3e9450808d 100644
--- a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c
+++ b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c
@@ -820,6 +820,204 @@ static const struct ili9881c_instr tl050hdv35_init[] = {
 	ILI9881C_COMMAND_INSTR(0xd3, 0x39),
 };
 
+static const struct ili9881c_instr w552946aaa_init[] = {
+	ILI9881C_SWITCH_PAGE_INSTR(3),
+	ILI9881C_COMMAND_INSTR(0x01, 0x00),
+	ILI9881C_COMMAND_INSTR(0x02, 0x00),
+	ILI9881C_COMMAND_INSTR(0x03, 0x53),
+	ILI9881C_COMMAND_INSTR(0x04, 0x53),
+	ILI9881C_COMMAND_INSTR(0x05, 0x13),
+	ILI9881C_COMMAND_INSTR(0x06, 0x04),
+	ILI9881C_COMMAND_INSTR(0x07, 0x02),
+	ILI9881C_COMMAND_INSTR(0x08, 0x02),
+	ILI9881C_COMMAND_INSTR(0x09, 0x00),
+	ILI9881C_COMMAND_INSTR(0x0a, 0x00),
+	ILI9881C_COMMAND_INSTR(0x0b, 0x00),
+	ILI9881C_COMMAND_INSTR(0x0c, 0x00),
+	ILI9881C_COMMAND_INSTR(0x0d, 0x00),
+	ILI9881C_COMMAND_INSTR(0x0e, 0x00),
+	ILI9881C_COMMAND_INSTR(0x0f, 0x00),
+	ILI9881C_COMMAND_INSTR(0x10, 0x00),
+	ILI9881C_COMMAND_INSTR(0x11, 0x00),
+	ILI9881C_COMMAND_INSTR(0x12, 0x00),
+	ILI9881C_COMMAND_INSTR(0x13, 0x00),
+	ILI9881C_COMMAND_INSTR(0x14, 0x00),
+	ILI9881C_COMMAND_INSTR(0x15, 0x08),
+	ILI9881C_COMMAND_INSTR(0x16, 0x10),
+	ILI9881C_COMMAND_INSTR(0x17, 0x00),
+	ILI9881C_COMMAND_INSTR(0x18, 0x08),
+	ILI9881C_COMMAND_INSTR(0x19, 0x00),
+	ILI9881C_COMMAND_INSTR(0x1a, 0x00),
+	ILI9881C_COMMAND_INSTR(0x1b, 0x00),
+	ILI9881C_COMMAND_INSTR(0x1c, 0x00),
+	ILI9881C_COMMAND_INSTR(0x1d, 0x00),
+	ILI9881C_COMMAND_INSTR(0x1e, 0xc0),
+	ILI9881C_COMMAND_INSTR(0x1f, 0x80),
+	ILI9881C_COMMAND_INSTR(0x20, 0x02),
+	ILI9881C_COMMAND_INSTR(0x21, 0x09),
+	ILI9881C_COMMAND_INSTR(0x22, 0x00),
+	ILI9881C_COMMAND_INSTR(0x23, 0x00),
+	ILI9881C_COMMAND_INSTR(0x24, 0x00),
+	ILI9881C_COMMAND_INSTR(0x25, 0x00),
+	ILI9881C_COMMAND_INSTR(0x26, 0x00),
+	ILI9881C_COMMAND_INSTR(0x27, 0x00),
+	ILI9881C_COMMAND_INSTR(0x28, 0x55),
+	ILI9881C_COMMAND_INSTR(0x29, 0x03),
+	ILI9881C_COMMAND_INSTR(0x2a, 0x00),
+	ILI9881C_COMMAND_INSTR(0x2b, 0x00),
+	ILI9881C_COMMAND_INSTR(0x2c, 0x00),
+	ILI9881C_COMMAND_INSTR(0x2d, 0x00),
+	ILI9881C_COMMAND_INSTR(0x2e, 0x00),
+	ILI9881C_COMMAND_INSTR(0x2f, 0x00),
+	ILI9881C_COMMAND_INSTR(0x30, 0x00),
+	ILI9881C_COMMAND_INSTR(0x31, 0x00),
+	ILI9881C_COMMAND_INSTR(0x32, 0x00),
+	ILI9881C_COMMAND_INSTR(0x33, 0x00),
+	ILI9881C_COMMAND_INSTR(0x34, 0x04),
+	ILI9881C_COMMAND_INSTR(0x35, 0x05),
+	ILI9881C_COMMAND_INSTR(0x36, 0x05),
+	ILI9881C_COMMAND_INSTR(0x37, 0x00),
+	ILI9881C_COMMAND_INSTR(0x38, 0x3c),
+	ILI9881C_COMMAND_INSTR(0x39, 0x35),
+	ILI9881C_COMMAND_INSTR(0x3a, 0x00),
+	ILI9881C_COMMAND_INSTR(0x3b, 0x40),
+	ILI9881C_COMMAND_INSTR(0x3c, 0x00),
+	ILI9881C_COMMAND_INSTR(0x3d, 0x00),
+	ILI9881C_COMMAND_INSTR(0x3e, 0x00),
+	ILI9881C_COMMAND_INSTR(0x3f, 0x00),
+	ILI9881C_COMMAND_INSTR(0x40, 0x00),
+	ILI9881C_COMMAND_INSTR(0x41, 0x88),
+	ILI9881C_COMMAND_INSTR(0x42, 0x00),
+	ILI9881C_COMMAND_INSTR(0x43, 0x00),
+	ILI9881C_COMMAND_INSTR(0x44, 0x1f),
+	ILI9881C_COMMAND_INSTR(0x50, 0x01),
+	ILI9881C_COMMAND_INSTR(0x51, 0x23),
+	ILI9881C_COMMAND_INSTR(0x52, 0x45),
+	ILI9881C_COMMAND_INSTR(0x53, 0x67),
+	ILI9881C_COMMAND_INSTR(0x54, 0x89),
+	ILI9881C_COMMAND_INSTR(0x55, 0xab),
+	ILI9881C_COMMAND_INSTR(0x56, 0x01),
+	ILI9881C_COMMAND_INSTR(0x57, 0x23),
+	ILI9881C_COMMAND_INSTR(0x58, 0x45),
+	ILI9881C_COMMAND_INSTR(0x59, 0x67),
+	ILI9881C_COMMAND_INSTR(0x5a, 0x89),
+	ILI9881C_COMMAND_INSTR(0x5b, 0xab),
+	ILI9881C_COMMAND_INSTR(0x5c, 0xcd),
+	ILI9881C_COMMAND_INSTR(0x5d, 0xef),
+	ILI9881C_COMMAND_INSTR(0x5e, 0x03),
+	ILI9881C_COMMAND_INSTR(0x5f, 0x14),
+	ILI9881C_COMMAND_INSTR(0x60, 0x15),
+	ILI9881C_COMMAND_INSTR(0x61, 0x0c),
+	ILI9881C_COMMAND_INSTR(0x62, 0x0d),
+	ILI9881C_COMMAND_INSTR(0x63, 0x0e),
+	ILI9881C_COMMAND_INSTR(0x64, 0x0f),
+	ILI9881C_COMMAND_INSTR(0x65, 0x10),
+	ILI9881C_COMMAND_INSTR(0x66, 0x11),
+	ILI9881C_COMMAND_INSTR(0x67, 0x08),
+	ILI9881C_COMMAND_INSTR(0x68, 0x02),
+	ILI9881C_COMMAND_INSTR(0x69, 0x0a),
+	ILI9881C_COMMAND_INSTR(0x6a, 0x02),
+	ILI9881C_COMMAND_INSTR(0x6b, 0x02),
+	ILI9881C_COMMAND_INSTR(0x6c, 0x02),
+	ILI9881C_COMMAND_INSTR(0x6d, 0x02),
+	ILI9881C_COMMAND_INSTR(0x6e, 0x02),
+	ILI9881C_COMMAND_INSTR(0x6f, 0x02),
+	ILI9881C_COMMAND_INSTR(0x70, 0x02),
+	ILI9881C_COMMAND_INSTR(0x71, 0x02),
+	ILI9881C_COMMAND_INSTR(0x72, 0x06),
+	ILI9881C_COMMAND_INSTR(0x73, 0x02),
+	ILI9881C_COMMAND_INSTR(0x74, 0x02),
+	ILI9881C_COMMAND_INSTR(0x75, 0x14),
+	ILI9881C_COMMAND_INSTR(0x76, 0x15),
+	ILI9881C_COMMAND_INSTR(0x77, 0x0f),
+	ILI9881C_COMMAND_INSTR(0x78, 0x0e),
+	ILI9881C_COMMAND_INSTR(0x79, 0x0d),
+	ILI9881C_COMMAND_INSTR(0x7a, 0x0c),
+	ILI9881C_COMMAND_INSTR(0x7b, 0x11),
+	ILI9881C_COMMAND_INSTR(0x7c, 0x10),
+	ILI9881C_COMMAND_INSTR(0x7d, 0x06),
+	ILI9881C_COMMAND_INSTR(0x7e, 0x02),
+	ILI9881C_COMMAND_INSTR(0x7f, 0x0a),
+	ILI9881C_COMMAND_INSTR(0x80, 0x02),
+	ILI9881C_COMMAND_INSTR(0x81, 0x02),
+	ILI9881C_COMMAND_INSTR(0x82, 0x02),
+	ILI9881C_COMMAND_INSTR(0x83, 0x02),
+	ILI9881C_COMMAND_INSTR(0x84, 0x02),
+	ILI9881C_COMMAND_INSTR(0x85, 0x02),
+	ILI9881C_COMMAND_INSTR(0x86, 0x02),
+	ILI9881C_COMMAND_INSTR(0x87, 0x02),
+	ILI9881C_COMMAND_INSTR(0x88, 0x08),
+	ILI9881C_COMMAND_INSTR(0x89, 0x02),
+	ILI9881C_COMMAND_INSTR(0x8a, 0x02),
+	ILI9881C_SWITCH_PAGE_INSTR(4),
+	ILI9881C_COMMAND_INSTR(0x00, 0x80),
+	ILI9881C_COMMAND_INSTR(0x70, 0x00),
+	ILI9881C_COMMAND_INSTR(0x71, 0x00),
+	ILI9881C_COMMAND_INSTR(0x66, 0xfe),
+	ILI9881C_COMMAND_INSTR(0x82, 0x15),
+	ILI9881C_COMMAND_INSTR(0x84, 0x15),
+	ILI9881C_COMMAND_INSTR(0x85, 0x15),
+	ILI9881C_COMMAND_INSTR(0x3a, 0x24),
+	ILI9881C_COMMAND_INSTR(0x32, 0xac),
+	ILI9881C_COMMAND_INSTR(0x8c, 0x80),
+	ILI9881C_COMMAND_INSTR(0x3c, 0xf5),
+	ILI9881C_COMMAND_INSTR(0x88, 0x33),
+	ILI9881C_SWITCH_PAGE_INSTR(1),
+	ILI9881C_COMMAND_INSTR(0x22, 0x0a),
+	ILI9881C_COMMAND_INSTR(0x31, 0x00),
+	ILI9881C_COMMAND_INSTR(0x53, 0x78),
+	ILI9881C_COMMAND_INSTR(0x55, 0x7b),
+	ILI9881C_COMMAND_INSTR(0x60, 0x20),
+	ILI9881C_COMMAND_INSTR(0x61, 0x00),
+	ILI9881C_COMMAND_INSTR(0x62, 0x0d),
+	ILI9881C_COMMAND_INSTR(0x63, 0x00),
+	ILI9881C_COMMAND_INSTR(0xa0, 0x00),
+	ILI9881C_COMMAND_INSTR(0xa1, 0x10),
+	ILI9881C_COMMAND_INSTR(0xa2, 0x1c),
+	ILI9881C_COMMAND_INSTR(0xa3, 0x13),
+	ILI9881C_COMMAND_INSTR(0xa4, 0x15),
+	ILI9881C_COMMAND_INSTR(0xa5, 0x26),
+	ILI9881C_COMMAND_INSTR(0xa6, 0x1a),
+	ILI9881C_COMMAND_INSTR(0xa7, 0x1d),
+	ILI9881C_COMMAND_INSTR(0xa8, 0x67),
+	ILI9881C_COMMAND_INSTR(0xa9, 0x1c),
+	ILI9881C_COMMAND_INSTR(0xaa, 0x29),
+	ILI9881C_COMMAND_INSTR(0xab, 0x5b),
+	ILI9881C_COMMAND_INSTR(0xac, 0x26),
+	ILI9881C_COMMAND_INSTR(0xad, 0x28),
+	ILI9881C_COMMAND_INSTR(0xae, 0x5c),
+	ILI9881C_COMMAND_INSTR(0xaf, 0x30),
+	ILI9881C_COMMAND_INSTR(0xb0, 0x31),
+	ILI9881C_COMMAND_INSTR(0xb1, 0x32),
+	ILI9881C_COMMAND_INSTR(0xb2, 0x00),
+	ILI9881C_COMMAND_INSTR(0xb1, 0x2e),
+	ILI9881C_COMMAND_INSTR(0xb2, 0x32),
+	ILI9881C_COMMAND_INSTR(0xb3, 0x00),
+	ILI9881C_COMMAND_INSTR(0xb6, 0x02),
+	ILI9881C_COMMAND_INSTR(0xb7, 0x03),
+	ILI9881C_COMMAND_INSTR(0xc0, 0x00),
+	ILI9881C_COMMAND_INSTR(0xc1, 0x10),
+	ILI9881C_COMMAND_INSTR(0xc2, 0x1c),
+	ILI9881C_COMMAND_INSTR(0xc3, 0x13),
+	ILI9881C_COMMAND_INSTR(0xc4, 0x15),
+	ILI9881C_COMMAND_INSTR(0xc5, 0x26),
+	ILI9881C_COMMAND_INSTR(0xc6, 0x1a),
+	ILI9881C_COMMAND_INSTR(0xc7, 0x1d),
+	ILI9881C_COMMAND_INSTR(0xc8, 0x67),
+	ILI9881C_COMMAND_INSTR(0xc9, 0x1c),
+	ILI9881C_COMMAND_INSTR(0xca, 0x29),
+	ILI9881C_COMMAND_INSTR(0xcb, 0x5b),
+	ILI9881C_COMMAND_INSTR(0xcc, 0x26),
+	ILI9881C_COMMAND_INSTR(0xcd, 0x28),
+	ILI9881C_COMMAND_INSTR(0xce, 0x5c),
+	ILI9881C_COMMAND_INSTR(0xcf, 0x30),
+	ILI9881C_COMMAND_INSTR(0xd0, 0x31),
+	ILI9881C_COMMAND_INSTR(0xd1, 0x2e),
+	ILI9881C_COMMAND_INSTR(0xd2, 0x32),
+	ILI9881C_COMMAND_INSTR(0xd3, 0x00),
+	ILI9881C_SWITCH_PAGE_INSTR(0),
+};
+
 static const struct ili9881c_instr w552946ab_init[] = {
 	ILI9881C_SWITCH_PAGE_INSTR(3),
 	ILI9881C_COMMAND_INSTR(0x01, 0x00),
@@ -1772,6 +1970,23 @@ static const struct drm_display_mode tl050hdv35_default_mode = {
 	.height_mm	= 110,
 };
 
+static const struct drm_display_mode w552946aaa_default_mode = {
+	.clock		= 65000,
+
+	.hdisplay	= 720,
+	.hsync_start	= 720 + 52,
+	.hsync_end	= 720 + 52 + 8,
+	.htotal		= 720 + 52 + 8 + 48,
+
+	.vdisplay	= 1280,
+	.vsync_start	= 1280 + 16,
+	.vsync_end	= 1280 + 16 + 6,
+	.vtotal		= 1280 + 16 + 6 + 15,
+
+	.width_mm	= 68,
+	.height_mm	= 121,
+};
+
 static const struct drm_display_mode w552946aba_default_mode = {
 	.clock		= 64000,
 
@@ -1983,6 +2198,15 @@ static const struct ili9881c_desc tl050hdv35_desc = {
 	.default_address_mode = 0x03,
 };
 
+static const struct ili9881c_desc w552946aaa_desc = {
+	.init = w552946aaa_init,
+	.init_length = ARRAY_SIZE(w552946aaa_init),
+	.mode = &w552946aaa_default_mode,
+	.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
+		      MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_NO_EOT_PACKET,
+	.lanes = 2,
+};
+
 static const struct ili9881c_desc w552946aba_desc = {
 	.init = w552946ab_init,
 	.init_length = ARRAY_SIZE(w552946ab_init),
@@ -2023,6 +2247,7 @@ static const struct of_device_id ili9881c_of_match[] = {
 	{ .compatible = "feixin,k101-im2byl02", .data = &k101_im2byl02_desc },
 	{ .compatible = "startek,kd050hdfia020", .data = &kd050hdfia020_desc },
 	{ .compatible = "tdo,tl050hdv35", .data = &tl050hdv35_desc },
+	{ .compatible = "wanchanglong,w552946aaa", .data = &w552946aaa_desc },
 	{ .compatible = "wanchanglong,w552946aba", .data = &w552946aba_desc },
 	{ .compatible = "ampire,am8001280g", .data = &am8001280g_desc },
 	{ .compatible = "raspberrypi,dsi-7inch", &rpi_7inch_desc },
-- 
2.51.1



From kernel at airkyi.com  Wed Nov  5 18:06:30 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Thu,  6 Nov 2025 10:06:30 +0800
Subject: [PATCH 7/9] drm/rockchip: dsi: Add support for rk3506
In-Reply-To: <20251106020632.92-1-kernel@airkyi.com>
References: <20251106020632.92-1-kernel@airkyi.com>
Message-ID: <20251106020632.92-8-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

The dsi controller found on RK3506 supports up to 2 lanes.

Signed-off-by: Hongming Zou <hongming.zou at rock-chips.com>
Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---
 .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c   | 20 +++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
index 5523911b990d..06e58cf287d3 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
@@ -192,6 +192,11 @@
 #define RK3568_DSI0_TURNDISABLE		BIT(2)
 #define RK3568_DSI0_FORCERXMODE		BIT(0)
 
+#define RK3506_SYS_GRF_SOC_CON6		0x0018
+#define RK3506_DSI_FORCETXSTOPMODE	(0xf << 4)
+#define RK3506_DSI_TURNDISABLE		BIT(2)
+#define RK3506_DSI_FORCERXMODE		BIT(0)
+
 /*
  * Note these registers do not appear in the datasheet, they are
  * however present in the BSP driver which is where these values
@@ -1643,6 +1648,18 @@ static const struct rockchip_dw_dsi_chip_data rk3399_chip_data[] = {
 	{ /* sentinel */ }
 };
 
+static const struct rockchip_dw_dsi_chip_data rk3506_chip_data[] = {
+	{
+		.reg = 0xff640000,
+		.lanecfg1_grf_reg = RK3506_SYS_GRF_SOC_CON6,
+		.lanecfg1 = (FIELD_PREP_WM16_CONST(RK3506_DSI_TURNDISABLE, 0) |
+			     FIELD_PREP_WM16_CONST(RK3506_DSI_FORCERXMODE, 0) |
+			     FIELD_PREP_WM16_CONST(RK3506_DSI_FORCETXSTOPMODE, 0)),
+		.max_data_lanes = 2,
+	},
+	{ /* sentinel */ }
+};
+
 static const struct rockchip_dw_dsi_chip_data rk3568_chip_data[] = {
 	{
 		.reg = 0xfe060000,
@@ -1690,6 +1707,9 @@ static const struct of_device_id dw_mipi_dsi_rockchip_dt_ids[] = {
 	}, {
 	 .compatible = "rockchip,rk3399-mipi-dsi",
 	 .data = &rk3399_chip_data,
+	}, {
+	 .compatible = "rockchip,rk3506-mipi-dsi",
+	 .data = &rk3506_chip_data,
 	}, {
 	 .compatible = "rockchip,rk3568-mipi-dsi",
 	 .data = &rk3568_chip_data,
-- 
2.51.1



From kernel at airkyi.com  Wed Nov  5 18:06:32 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Thu,  6 Nov 2025 10:06:32 +0800
Subject: [PATCH 9/9] drm/rockchip: vop: Add support for rk3506
In-Reply-To: <20251106020632.92-1-kernel@airkyi.com>
References: <20251106020632.92-1-kernel@airkyi.com>
Message-ID: <20251106020632.92-10-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

The VOP on rk3506:
- Support 2 lane MIPI DSI interface, 1.5Gbps/lane.
- Support RGB interface.
- Max output resolution is 1280x1280 at 60fps.
- WIN1 layer support RGB888/ARGB8888/RGB565.
- Support Gamma LUT.
- ...

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 57 +++++++++++++++++++++
 drivers/gpu/drm/rockchip/rockchip_vop_reg.h | 14 +++++
 2 files changed, 71 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index d1f788763318..6b654b682a94 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -1179,6 +1179,61 @@ static const struct vop_data rk3328_vop = {
 	.max_output = { 4096, 2160 },
 };
 
+static const struct vop_common rk3506_common = {
+	.standby = VOP_REG_SYNC(RK3506_SYS_CTRL2, 0x1, 1),
+	.out_mode = VOP_REG(RK3506_DSP_CTRL2, 0xf, 16),
+	.dsp_blank = VOP_REG(RK3506_DSP_CTRL2, 0x1, 14),
+	.dither_down_en = VOP_REG(RK3506_DSP_CTRL2, 0x1, 8),
+	.dither_down_sel = VOP_REG(RK3506_DSP_CTRL2, 0x1, 7),
+	.dither_down_mode = VOP_REG(RK3506_DSP_CTRL2, 0x1, 6),
+	.dsp_lut_en = VOP_REG(RK3506_DSP_CTRL2, 0x1, 5),
+	.dither_up = VOP_REG(RK3506_DSP_CTRL2, 0x1, 2),
+	.cfg_done = VOP_REG_SYNC(RK3506_REG_CFG_DONE, 0x1, 0),
+};
+
+static const struct vop_output rk3506_output = {
+	.rgb_en = VOP_REG(RK3506_DSP_CTRL0, 0x1, 0),
+	.rgb_pin_pol = VOP_REG(RK3506_DSP_CTRL0, 0x7, 2),
+	.mipi_en = VOP_REG(RK3506_DSP_CTRL0, 0x1, 24),
+	.mipi_dclk_pol = VOP_REG(RK3506_DSP_CTRL0, 0x1, 25),
+	.mipi_pin_pol = VOP_REG(RK3506_DSP_CTRL0, 0x7, 26),
+};
+
+static const struct vop_win_phy rk3506_win1_data = {
+	.data_formats = formats_win_lite,
+	.nformats = ARRAY_SIZE(formats_win_lite),
+	.format_modifiers = format_modifiers_win_lite,
+	.enable = VOP_REG(RK3506_WIN1_CTRL0, 0x1, 0),
+	.format = VOP_REG(RK3506_WIN1_CTRL0, 0x7, 4),
+	.rb_swap = VOP_REG(RK3506_WIN1_CTRL0, 0x1, 12),
+	.channel = VOP_REG(RK3506_WIN1_CTRL1, 0xf, 8),
+	.yrgb_vir = VOP_REG(RK3506_WIN1_VIR, 0x1fff, 0),
+	.yrgb_mst = VOP_REG(RK3506_WIN1_MST, 0xffffffff, 0),
+	.dsp_info = VOP_REG(RK3506_WIN1_DSP_INFO, 0xffffffff, 0),
+	.dsp_st = VOP_REG(RK3506_WIN1_DSP_ST, 0xffffffff, 0),
+	.alpha_en = VOP_REG(RK3506_WIN1_ALPHA_CTRL, 0x1, 0),
+	.alpha_mode = VOP_REG(RK3506_WIN1_ALPHA_CTRL, 0x1, 1),
+	.alpha_pre_mul = VOP_REG(RK3506_WIN1_ALPHA_CTRL, 0x1, 2),
+};
+
+static const struct vop_win_data rk3506_vop_win_data[] = {
+	{ .base = 0x00, .phy = &rk3506_win1_data,
+	  .type = DRM_PLANE_TYPE_PRIMARY },
+};
+
+static const struct vop_data rk3506_vop = {
+	.version = VOP_VERSION(2, 0xe),
+	.feature = VOP_FEATURE_INTERNAL_RGB,
+	.intr = &px30_intr,
+	.common = &rk3506_common,
+	.modeset = &px30_modeset,
+	.output = &rk3506_output,
+	.win = rk3506_vop_win_data,
+	.win_size = ARRAY_SIZE(rk3506_vop_win_data),
+	.lut_size = 256,
+	.max_output = { 1280, 1280 },
+};
+
 static const struct vop_common rv1126_common = {
 	.standby = VOP_REG_SYNC(PX30_SYS_CTRL2, 0x1, 1),
 	.out_mode = VOP_REG(PX30_DSP_CTRL2, 0xf, 16),
@@ -1259,6 +1314,8 @@ static const struct of_device_id vop_driver_dt_match[] = {
 	  .data = &rk3228_vop },
 	{ .compatible = "rockchip,rk3328-vop",
 	  .data = &rk3328_vop },
+	{ .compatible = "rockchip,rk3506-vop",
+	  .data = &rk3506_vop },
 	{ .compatible = "rockchip,rv1126-vop",
 	  .data = &rv1126_vop },
 	{},
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.h b/drivers/gpu/drm/rockchip/rockchip_vop_reg.h
index addf8ca085f6..7805533e88bc 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.h
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.h
@@ -1033,4 +1033,18 @@
 #define RK3066_DSP_LUT_ADDR		0x800
 /* rk3066 register definition end */
 
+/* rk3506 register definition */
+#define RK3506_REG_CFG_DONE		0x00
+#define RK3506_SYS_CTRL2		0x18
+#define RK3506_DSP_CTRL0		0x20
+#define RK3506_DSP_CTRL2		0x28
+#define RK3506_WIN1_CTRL0		0x90
+#define RK3506_WIN1_CTRL1		0x94
+#define RK3506_WIN1_VIR			0x98
+#define RK3506_WIN1_MST			0xa0
+#define RK3506_WIN1_DSP_INFO		0xa4
+#define RK3506_WIN1_DSP_ST		0xa8
+#define RK3506_WIN1_ALPHA_CTRL		0xbc
+/* rk3506 register definition end */
+
 #endif /* _ROCKCHIP_VOP_REG_H */
-- 
2.51.1



From chaoyi.chen at rock-chips.com  Wed Nov  5 19:06:54 2025
From: chaoyi.chen at rock-chips.com (Chaoyi Chen)
Date: Thu, 6 Nov 2025 11:06:54 +0800
Subject: [PATCH v8 03/10] drm/bridge: Implement generic USB Type-C DP HPD
 bridge
In-Reply-To: <rzozpbqmymdczerh3iijxxtz3xnsznoku7w2mquikwv6u5osvo@7h43hwc2fpzm>
References: <20251029071435.88-1-kernel@airkyi.com>
 <20251029071435.88-4-kernel@airkyi.com>
 <rzozpbqmymdczerh3iijxxtz3xnsznoku7w2mquikwv6u5osvo@7h43hwc2fpzm>
Message-ID: <64de56d4-43e8-4e77-a171-0bd0855ad816@rock-chips.com>

On 11/3/2025 12:00 PM, Dmitry Baryshkov wrote:

> On Wed, Oct 29, 2025 at 03:14:28PM +0800, Chaoyi Chen wrote:
>> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
>>
>> Several USB-C controller drivers have already implemented the DP HPD
>> bridge function provided by aux-hpd-bridge.c, but there are still
>> some USB-C controller driver that have not yet implemented it.
>>
>> This patch implements a generic DP HPD bridge based on aux-hpd-bridge.c,
>> so that other USB-C controller drivers don't need to implement it again.
> This doesn't describe the problem that you are trying to solve.
>
>> Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
>> ---
>>
>> Changes in v8:
>> - Merge generic DP HPD bridge into one module.
>>
>>   drivers/gpu/drm/bridge/Kconfig                |  5 +-
>>   drivers/gpu/drm/bridge/Makefile               |  8 +++-
>>   drivers/gpu/drm/bridge/aux-hpd-bridge.c       | 23 ++++++++-
>>   drivers/gpu/drm/bridge/aux-hpd-bridge.h       | 13 +++++
>>   .../gpu/drm/bridge/aux-hpd-typec-dp-bridge.c  | 47 +++++++++++++++++++
>>   5 files changed, 93 insertions(+), 3 deletions(-)
>>   create mode 100644 drivers/gpu/drm/bridge/aux-hpd-bridge.h
>>   create mode 100644 drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
>>
>> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
>> index a250afd8d662..17257b223a28 100644
>> --- a/drivers/gpu/drm/bridge/Kconfig
>> +++ b/drivers/gpu/drm/bridge/Kconfig
>> @@ -23,13 +23,16 @@ config DRM_AUX_BRIDGE
>>   	  build bridges chain.
>>   
>>   config DRM_AUX_HPD_BRIDGE
>> -	tristate
>> +	tristate "AUX HPD bridge support"
> Why? No, this is supposed to be selected by other drivers. Users don't
> know an wouldn't know what is this.
>
Sorry, I might have misunderstood you point. In v7, I added a new DRM_AUX_TYPEC_DP_HPD_BRIDGE module to select DRM_AUX_HPD_BRIDGE. This seems to fit the "selected by other drivers" scenario, but I think you might not want to expose any information to the users.

And the other one is what Heikki said:

+if DRM_AUX_HPD_BRIDGE + +config DRM_AUX_HPD_TYPEC_BRIDGE + tristate + depends on TYPEC || !TYPEC + default TYPEC + +endif /* DRM_AUX_HPD_BRIDGE */ + menu "Display Interface Bridges" depends on DRM && DRM_BRIDGE

If I understand correctly, in this scenario we need to select DRM_AUX_HPD_BRIDGE in the DP driver. When Type-C is available, DRM_AUX_HPD_TYPEC_BRIDGE will be selected automatically.

Is the method mentioned by Heikki what you want? Thank you.

-- 
Best,
Chaoyi



From naoki at radxa.com  Wed Nov  5 19:17:22 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Thu, 6 Nov 2025 12:17:22 +0900
Subject: [PATCH v6 3/3] arm64: dts: rockchip: Add Radxa CM5 IO Board
In-Reply-To: <1EE1A1D9D7C100DA+1b365782-98c4-4ee0-ab96-920990841903@radxa.com>
References: <20251105051335.17652-1-naoki@radxa.com>
 <20251105051335.17652-4-naoki@radxa.com>
 <CALWfF7KyTfpXSyjVQaFzqtn6KyDxuyZOBpPR8y-jf6sduNxq5A@mail.gmail.com>
 <1EE1A1D9D7C100DA+1b365782-98c4-4ee0-ab96-920990841903@radxa.com>
Message-ID: <65F6DECE54D6A0E2+06d33e7a-1054-44b3-919e-181e30cdb932@radxa.com>

On 11/6/25 08:38, FUKAUMI Naoki wrote:
> Hi Jimmy,
> 
> On 11/6/25 03:27, Jimmy Hon wrote:
>> On Tue, Nov 4, 2025 at 11:14?PM FUKAUMI Naoki <naoki at radxa.com> wrote:
>>>
>>> The Radxa CM5 IO Board is an application board for the Radxa CM5.
>>>
>>> Specification:
>>
>>> - 1x microSD card slot
>>
>> [ snip ]
>>
>>> +
>>> +&sdmmc {
>>> +?????? bus-width = <4>;
>>> +?????? cap-mmc-highspeed;
>>> +?????? cap-sd-highspeed;
>>> +?????? cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
>>> +?????? disable-wp;
>>> +?????? no-sdio;
>>> +?????? pinctrl-names = "default";
>>> +?????? pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd>;
>>> +?????? sd-uhs-sdr104;
>>> +?????? vmmc-supply = <&vcc_3v3_s3>;
>>> +?????? vqmmc-supply = <&vccio_sd_s0>;
>>> +?????? status = "okay";
>>> +};
>>
>> When used as a TF slot, shouldn't there be a "no-mmc" also?
> 
> We have "eMMC to uSD."
>  ?https://radxa.com/products/accessories/emmc-to-usd
> 
> [? 202.176757] mmc_host mmc1: Bus speed (slot 0) = 49500000Hz (slot req 
> 52000000Hz, actual 49500000HZ div = 0)
> [? 202.178477] mmc1: new high speed MMC card at address 0001
> [? 202.179534] mmcblk1: mmc1:0001 SLD64G 57.6 GiB
> [? 202.207336] mmcblk1boot0: mmc1:0001 SLD64G 4.00 MiB
> [? 202.210374] mmcblk1boot1: mmc1:0001 SLD64G 4.00 MiB
> [? 202.212967] mmcblk1rpmb: mmc1:0001 SLD64G 4.00 MiB, chardev (511:1)
> 
> (I'm not sure why it says "Not work with the SD slot on the board." I 
> will check.)

There is no hardware limitation. "eMMC to uSD" should work with microSD 
card slot on the board.

That notice means "dts need to be changed".

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

>> That's how the Rock 5A, 5B, and 5C were defined.
> 
> I have submitted a patch without "no-mmc" before. I intend to send one 
> again when I have the chance.
> 
> Best regards,
> 
> -- 
> FUKAUMI Naoki
> Radxa Computer (Shenzhen) Co., Ltd.
> 
>> Jimmy
>>
> 
> 



From dsimic at manjaro.org  Wed Nov  5 19:31:27 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Thu, 06 Nov 2025 04:31:27 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v6 3/3] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= Add Radxa CM5 IO Board
In-Reply-To: <1EE1A1D9D7C100DA+1b365782-98c4-4ee0-ab96-920990841903@radxa.com>
References: <20251105051335.17652-1-naoki@radxa.com>
 <20251105051335.17652-4-naoki@radxa.com>
 <CALWfF7KyTfpXSyjVQaFzqtn6KyDxuyZOBpPR8y-jf6sduNxq5A@mail.gmail.com> <1EE1A1D9D7C100DA+1b365782-98c4-4ee0-ab96-920990841903@radxa.com>
Message-ID: <35ff8e6f-dd2b-d909-70c7-b19240e32ccf@manjaro.org>

Hello Naoki,

On Thursday, November 06, 2025 00:38 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> On 11/6/25 03:27, Jimmy Hon wrote:
> > On Tue, Nov 4, 2025 at 11:14?PM FUKAUMI Naoki <naoki at radxa.com> wrote:
> >>
> >> The Radxa CM5 IO Board is an application board for the Radxa CM5.
> >>
> >> Specification:
> > 
> >> - 1x microSD card slot
> > 
> > [ snip ]
> > 
> >> +
> >> +&sdmmc {
> >> +       bus-width = <4>;
> >> +       cap-mmc-highspeed;
> >> +       cap-sd-highspeed;
> >> +       cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
> >> +       disable-wp;
> >> +       no-sdio;
> >> +       pinctrl-names = "default";
> >> +       pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd>;
> >> +       sd-uhs-sdr104;
> >> +       vmmc-supply = <&vcc_3v3_s3>;
> >> +       vqmmc-supply = <&vccio_sd_s0>;
> >> +       status = "okay";
> >> +};
> > 
> > When used as a TF slot, shouldn't there be a "no-mmc" also?
> 
> We have "eMMC to uSD."
>   https://radxa.com/products/accessories/emmc-to-usd
> 
> [  202.176757] mmc_host mmc1: Bus speed (slot 0) = 49500000Hz (slot req 
> 52000000Hz, actual 49500000HZ div = 0)
> [  202.178477] mmc1: new high speed MMC card at address 0001
> [  202.179534] mmcblk1: mmc1:0001 SLD64G 57.6 GiB
> [  202.207336] mmcblk1boot0: mmc1:0001 SLD64G 4.00 MiB
> [  202.210374] mmcblk1boot1: mmc1:0001 SLD64G 4.00 MiB
> [  202.212967] mmcblk1rpmb: mmc1:0001 SLD64G 4.00 MiB, chardev (511:1)
> 
> (I'm not sure why it says "Not work with the SD slot on the board." I 
> will check.)

Thanks for bringing this up, I've always wondered how are such
simple eMMC-to-microSD adapters supposed to work, so this was
a good opportunity to research that a bit further.

In a few words, they're not supposed to work in true microSD card
slots, and they seem to rely on USB card readers that support
multiple card interface standards, but not more than a single card
at once, by wiring their single interface lines in parallel to the
different types of card slots that they provide.

To explain it a bit further, an eMMC chip supports different data
bus widths and a backward-compatible MMC card mode, but they have
very little knowledge about the SD specification, despite being
somewhat similar; the exception is the simplified eMMC boot mode.
This is explained further in the JEDEC JESD84-B51 standard, which
is available freely from the JEDEC website after registration.

This is also confirmed by the kernel messages quoted above, which
show that the eMMC chip is detected as an MMC card this way.

With all that in mind, we should specify "no-mmc" here, because
we're describing a microSD slot, instead of describing some hybrid
MMC/microSD slot.  That also explains why the adapter sold by Radxa
is described as not to be used with microSD card slots on SBCs.  I'd
also like to hear is this adapter/eMMC chip combo recognized by the
kernel when "no-mmc" is specified; it should fail.

Actually, not specifying "no-mmc" here may result in some unforeseen
issues with some (or perhaps many?) microSD cards, because the MMC
drivers will treat them as MMC-capable devices and try to initialize
them as such, which may cause all kinds of issues.  In fact, I'm not
really sure that the MMC drivers are actually implemented in a way
that avoids all possible issues with the storage controllers that
are capable of both SD and MMC modes when neither of "no-sd" and
"no-mmc" is specified in their DT nodes.

Furthermore, it seems that specifying "cap-mmc-highspeed" together
with "no-emmc" is actually redundant, which would make sense, but
further research of the MMC drivers is needed.  I've added that to
my ever-growing TODO list. :)

> > That's how the Rock 5A, 5B, and 5C were defined.
> 
> I have submitted a patch without "no-mmc" before. I intend to send one 
> again when I have the chance.



From dsimic at manjaro.org  Wed Nov  5 19:38:42 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Thu, 06 Nov 2025 04:38:42 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v6 3/3] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= Add Radxa CM5 IO Board
In-Reply-To: <65F6DECE54D6A0E2+06d33e7a-1054-44b3-919e-181e30cdb932@radxa.com>
References: <20251105051335.17652-1-naoki@radxa.com>
 <20251105051335.17652-4-naoki@radxa.com>
 <CALWfF7KyTfpXSyjVQaFzqtn6KyDxuyZOBpPR8y-jf6sduNxq5A@mail.gmail.com>
 <1EE1A1D9D7C100DA+1b365782-98c4-4ee0-ab96-920990841903@radxa.com> <65F6DECE54D6A0E2+06d33e7a-1054-44b3-919e-181e30cdb932@radxa.com>
Message-ID: <1c84d2f5-811b-4f0f-46b9-3c0e7828d0db@manjaro.org>

Hello Naoki,

On Thursday, November 06, 2025 04:17 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> On 11/6/25 08:38, FUKAUMI Naoki wrote:
> > On 11/6/25 03:27, Jimmy Hon wrote:
> >> On Tue, Nov 4, 2025 at 11:14?PM FUKAUMI Naoki <naoki at radxa.com> wrote:
> >>>
> >>> The Radxa CM5 IO Board is an application board for the Radxa CM5.
> >>>
> >>> Specification:
> >>
> >>> - 1x microSD card slot
> >>
> >> [ snip ]
> >>
> >>> +
> >>> +&sdmmc {
> >>> +?????? bus-width = <4>;
> >>> +?????? cap-mmc-highspeed;
> >>> +?????? cap-sd-highspeed;
> >>> +?????? cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
> >>> +?????? disable-wp;
> >>> +?????? no-sdio;
> >>> +?????? pinctrl-names = "default";
> >>> +?????? pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd>;
> >>> +?????? sd-uhs-sdr104;
> >>> +?????? vmmc-supply = <&vcc_3v3_s3>;
> >>> +?????? vqmmc-supply = <&vccio_sd_s0>;
> >>> +?????? status = "okay";
> >>> +};
> >>
> >> When used as a TF slot, shouldn't there be a "no-mmc" also?
> > 
> > We have "eMMC to uSD."
> >  ?https://radxa.com/products/accessories/emmc-to-usd
> > 
> > [? 202.176757] mmc_host mmc1: Bus speed (slot 0) = 49500000Hz (slot req 
> > 52000000Hz, actual 49500000HZ div = 0)
> > [? 202.178477] mmc1: new high speed MMC card at address 0001
> > [? 202.179534] mmcblk1: mmc1:0001 SLD64G 57.6 GiB
> > [? 202.207336] mmcblk1boot0: mmc1:0001 SLD64G 4.00 MiB
> > [? 202.210374] mmcblk1boot1: mmc1:0001 SLD64G 4.00 MiB
> > [? 202.212967] mmcblk1rpmb: mmc1:0001 SLD64G 4.00 MiB, chardev (511:1)
> > 
> > (I'm not sure why it says "Not work with the SD slot on the board." I 
> > will check.)
> 
> There is no hardware limitation. "eMMC to uSD" should work with microSD 
> card slot on the board.
> 
> That notice means "dts need to be changed".

True, it can work when the microSD slot is put into the hybrid
MMC/microSD mode, which I described in my previous response, but
that's pretty much a hardware hack similar to accessing JTAG
through the microSD slot on Rockchip boards, or to reconfiguring
the USB 3.0 port to work as a native SATA port on the Pine64
Quartz64 SBC.



From shawn.lin at rock-chips.com  Wed Nov  5 19:51:59 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Thu,  6 Nov 2025 11:51:59 +0800
Subject: [PATCH] PCI: Add ASPM quirk for Hi1105 PCIe Wi-Fi
Message-ID: <1762401119-232631-1-git-send-email-shawn.lin@rock-chips.com>

This Wi-Fi advertises the L0s and L1 capabilities but actually
it doesn't support them. This's comfirmed by Hisilicon team in
actual productization.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
---

 drivers/pci/quirks.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 214ed06..67250d4 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -2526,6 +2526,12 @@ static void quirk_disable_aspm_l0s_l1(struct pci_dev *dev)
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ASMEDIA, 0x1080, quirk_disable_aspm_l0s_l1);
 
 /*
+ * The Hi1105 PCIe Wi-Fi doesn't support L0s and L1 but advertise the capability.
+ * Disable both L0s and L1 for now.
+ */
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_HUAWEI, 0x1105, quirk_disable_aspm_l0s_l1);
+
+/*
  * Some Pericom PCIe-to-PCI bridges in reverse mode need the PCIe Retrain
  * Link bit cleared after starting the link retrain process to allow this
  * process to finish.
-- 
2.7.4



From naoki at radxa.com  Wed Nov  5 20:29:21 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Thu, 6 Nov 2025 13:29:21 +0900
Subject: [PATCH v6 3/3] arm64: dts: rockchip: Add Radxa CM5 IO Board
In-Reply-To: <35ff8e6f-dd2b-d909-70c7-b19240e32ccf@manjaro.org>
References: <20251105051335.17652-1-naoki@radxa.com>
 <20251105051335.17652-4-naoki@radxa.com>
 <CALWfF7KyTfpXSyjVQaFzqtn6KyDxuyZOBpPR8y-jf6sduNxq5A@mail.gmail.com>
 <1EE1A1D9D7C100DA+1b365782-98c4-4ee0-ab96-920990841903@radxa.com>
 <35ff8e6f-dd2b-d909-70c7-b19240e32ccf@manjaro.org>
Message-ID: <62149259BA8D0C0B+f4370c28-0eee-4095-9bf8-cd5e307a4c84@radxa.com>

Hi Dragan,

On 11/6/25 12:31, Dragan Simic wrote:
> Hello Naoki,
> 
> On Thursday, November 06, 2025 00:38 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
>> On 11/6/25 03:27, Jimmy Hon wrote:
>>> On Tue, Nov 4, 2025 at 11:14?PM FUKAUMI Naoki <naoki at radxa.com> wrote:
>>>>
>>>> The Radxa CM5 IO Board is an application board for the Radxa CM5.
>>>>
>>>> Specification:
>>>
>>>> - 1x microSD card slot
>>>
>>> [ snip ]
>>>
>>>> +
>>>> +&sdmmc {
>>>> +       bus-width = <4>;
>>>> +       cap-mmc-highspeed;
>>>> +       cap-sd-highspeed;
>>>> +       cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
>>>> +       disable-wp;
>>>> +       no-sdio;
>>>> +       pinctrl-names = "default";
>>>> +       pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd>;
>>>> +       sd-uhs-sdr104;
>>>> +       vmmc-supply = <&vcc_3v3_s3>;
>>>> +       vqmmc-supply = <&vccio_sd_s0>;
>>>> +       status = "okay";
>>>> +};
>>>
>>> When used as a TF slot, shouldn't there be a "no-mmc" also?
>>
>> We have "eMMC to uSD."
>>    https://radxa.com/products/accessories/emmc-to-usd
>>
>> [  202.176757] mmc_host mmc1: Bus speed (slot 0) = 49500000Hz (slot req
>> 52000000Hz, actual 49500000HZ div = 0)
>> [  202.178477] mmc1: new high speed MMC card at address 0001
>> [  202.179534] mmcblk1: mmc1:0001 SLD64G 57.6 GiB
>> [  202.207336] mmcblk1boot0: mmc1:0001 SLD64G 4.00 MiB
>> [  202.210374] mmcblk1boot1: mmc1:0001 SLD64G 4.00 MiB
>> [  202.212967] mmcblk1rpmb: mmc1:0001 SLD64G 4.00 MiB, chardev (511:1)
>>
>> (I'm not sure why it says "Not work with the SD slot on the board." I
>> will check.)
> 
> Thanks for bringing this up, I've always wondered how are such
> simple eMMC-to-microSD adapters supposed to work, so this was
> a good opportunity to research that a bit further.
> 
> In a few words, they're not supposed to work in true microSD card
> slots, and they seem to rely on USB card readers that support
> multiple card interface standards, but not more than a single card
> at once, by wiring their single interface lines in parallel to the
> different types of card slots that they provide.
> 
> To explain it a bit further, an eMMC chip supports different data
> bus widths and a backward-compatible MMC card mode, but they have
> very little knowledge about the SD specification, despite being
> somewhat similar; the exception is the simplified eMMC boot mode.
> This is explained further in the JEDEC JESD84-B51 standard, which
> is available freely from the JEDEC website after registration.
> 
> This is also confirmed by the kernel messages quoted above, which
> show that the eMMC chip is detected as an MMC card this way.
> 
> With all that in mind, we should specify "no-mmc" here, because
> we're describing a microSD slot, instead of describing some hybrid
> MMC/microSD slot.  That also explains why the adapter sold by Radxa
> is described as not to be used with microSD card slots on SBCs.  I'd
> also like to hear is this adapter/eMMC chip combo recognized by the
> kernel when "no-mmc" is specified; it should fail.
> 
> Actually, not specifying "no-mmc" here may result in some unforeseen
> issues with some (or perhaps many?) microSD cards, because the MMC
> drivers will treat them as MMC-capable devices and try to initialize
> them as such, which may cause all kinds of issues.  In fact, I'm not
> really sure that the MMC drivers are actually implemented in a way
> that avoids all possible issues with the storage controllers that
> are capable of both SD and MMC modes when neither of "no-sd" and
> "no-mmc" is specified in their DT nodes.

I have no objection to specifying no-mmc (and removing 
cap-mmc-highspeed). We have a USB eMMC/UFS Module Reader, which is much 
faster than an eMMC to uSD reader :)

> Furthermore, it seems that specifying "cap-mmc-highspeed" together
> with "no-emmc" is actually redundant, which would make sense, but
> further research of the MMC drivers is needed.  I've added that to
> my ever-growing TODO list. :)

Good luck with your ever-growing TODO list!

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

>>> That's how the Rock 5A, 5B, and 5C were defined.
>>
>> I have submitted a patch without "no-mmc" before. I intend to send one
>> again when I have the chance.
> 
> 




From honyuenkwun at gmail.com  Wed Nov  5 20:53:20 2025
From: honyuenkwun at gmail.com (Jimmy Hon)
Date: Wed, 5 Nov 2025 22:53:20 -0600
Subject: [PATCH v6 3/3] arm64: dts: rockchip: Add Radxa CM5 IO Board
In-Reply-To: <35ff8e6f-dd2b-d909-70c7-b19240e32ccf@manjaro.org>
References: <20251105051335.17652-1-naoki@radxa.com> <20251105051335.17652-4-naoki@radxa.com>
 <CALWfF7KyTfpXSyjVQaFzqtn6KyDxuyZOBpPR8y-jf6sduNxq5A@mail.gmail.com>
 <1EE1A1D9D7C100DA+1b365782-98c4-4ee0-ab96-920990841903@radxa.com> <35ff8e6f-dd2b-d909-70c7-b19240e32ccf@manjaro.org>
Message-ID: <CALWfF7K3zNxSsXVpW8pLc_xWi793HG99OvbshtP-0=764JmPKw@mail.gmail.com>

On Wed, Nov 5, 2025 at 9:31?PM Dragan Simic <dsimic at manjaro.org> wrote:

[ snip ]

>
> With all that in mind, we should specify "no-mmc" here, because
> we're describing a microSD slot, instead of describing some hybrid
> MMC/microSD slot.  That also explains why the adapter sold by Radxa
> is described as not to be used with microSD card slots on SBCs.  I'd
> also like to hear is this adapter/eMMC chip combo recognized by the
> kernel when "no-mmc" is specified; it should fail.
>
> Actually, not specifying "no-mmc" here may result in some unforeseen
> issues with some (or perhaps many?) microSD cards, because the MMC
> drivers will treat them as MMC-capable devices and try to initialize
> them as such, which may cause all kinds of issues.  In fact, I'm not
> really sure that the MMC drivers are actually implemented in a way
> that avoids all possible issues with the storage controllers that
> are capable of both SD and MMC modes when neither of "no-sd" and
> "no-mmc" is specified in their DT nodes.

Hybrid MMC and SD slots are pretty normal on USB card readers. So it's
normal for the host controller to figure out what kind of card is in
the slot.
https://uditagarwal.in/understanding-sd-sdio-and-mmc-interface/

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6ae3e537eab9f560b516b001eb89f0cd568bdced
was the commit that introduced the device tree properties. By the
wording of the commit message, these device tree properties are used
to indicate to the driver if the host controller hardware is capable
of MMC initialization or SD initialization.

Since the host controller in the RK3588 is capable of all the modes,
these properties do not need to be specified.

Since Radxa has the eMMC to uSD adapter, it makes sense Radxa would
want to configure their microSD card slot on their boards to be a
hybrid SD/MMC slot.

Now, the more fun question is if the adapter can handle eMMC HS200
using the 4-bit bus?

Jimmy


From naoki at radxa.com  Wed Nov  5 21:08:46 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Thu, 6 Nov 2025 14:08:46 +0900
Subject: [PATCH v6 3/3] arm64: dts: rockchip: Add Radxa CM5 IO Board
In-Reply-To: <CALWfF7K3zNxSsXVpW8pLc_xWi793HG99OvbshtP-0=764JmPKw@mail.gmail.com>
References: <20251105051335.17652-1-naoki@radxa.com>
 <20251105051335.17652-4-naoki@radxa.com>
 <CALWfF7KyTfpXSyjVQaFzqtn6KyDxuyZOBpPR8y-jf6sduNxq5A@mail.gmail.com>
 <1EE1A1D9D7C100DA+1b365782-98c4-4ee0-ab96-920990841903@radxa.com>
 <35ff8e6f-dd2b-d909-70c7-b19240e32ccf@manjaro.org>
 <CALWfF7K3zNxSsXVpW8pLc_xWi793HG99OvbshtP-0=764JmPKw@mail.gmail.com>
Message-ID: <57F9C541303D73B3+4c84cba4-8378-4b65-8065-46e28217694b@radxa.com>

Hi Jimmy,

On 11/6/25 13:53, Jimmy Hon wrote:
> On Wed, Nov 5, 2025 at 9:31?PM Dragan Simic <dsimic at manjaro.org> wrote:
> 
> [ snip ]
> 
>>
>> With all that in mind, we should specify "no-mmc" here, because
>> we're describing a microSD slot, instead of describing some hybrid
>> MMC/microSD slot.  That also explains why the adapter sold by Radxa
>> is described as not to be used with microSD card slots on SBCs.  I'd
>> also like to hear is this adapter/eMMC chip combo recognized by the
>> kernel when "no-mmc" is specified; it should fail.
>>
>> Actually, not specifying "no-mmc" here may result in some unforeseen
>> issues with some (or perhaps many?) microSD cards, because the MMC
>> drivers will treat them as MMC-capable devices and try to initialize
>> them as such, which may cause all kinds of issues.  In fact, I'm not
>> really sure that the MMC drivers are actually implemented in a way
>> that avoids all possible issues with the storage controllers that
>> are capable of both SD and MMC modes when neither of "no-sd" and
>> "no-mmc" is specified in their DT nodes.
> 
> Hybrid MMC and SD slots are pretty normal on USB card readers. So it's
> normal for the host controller to figure out what kind of card is in
> the slot.
> https://uditagarwal.in/understanding-sd-sdio-and-mmc-interface/
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6ae3e537eab9f560b516b001eb89f0cd568bdced
> was the commit that introduced the device tree properties. By the
> wording of the commit message, these device tree properties are used
> to indicate to the driver if the host controller hardware is capable
> of MMC initialization or SD initialization.
> 
> Since the host controller in the RK3588 is capable of all the modes,
> these properties do not need to be specified.
> 
> Since Radxa has the eMMC to uSD adapter, it makes sense Radxa would
> want to configure their microSD card slot on their boards to be a
> hybrid SD/MMC slot.
> 
> Now, the more fun question is if the adapter can handle eMMC HS200
> using the 4-bit bus?

I added
  mmc-hs200-1_8v;

I got

[  226.099510] mmc_host mmc1: Bus speed (slot 0) = 400000Hz (slot req 
400000Hz, actual 400000HZ div = 0)
[  226.546246] mmc_host mmc1: Bus speed (slot 0) = 49500000Hz (slot req 
52000000Hz, actual 49500000HZ div = 0)
[  226.546371] mmc_host mmc1: Bus speed (slot 0) = 198000000Hz (slot req 
200000000Hz, actual 198000000HZ div = 0)
[  226.656853] dwmmc_rockchip fe2c0000.mmc: Successfully tuned phase to 76
[  226.657011] mmc1: error -110 whilst initialising MMC card
[  226.671469] mmc_host mmc1: Bus speed (slot 0) = 300000Hz (slot req 
300000Hz, actual 300000HZ div = 0)
[  226.793733] mmc1: switch to bus width 4 failed
[  226.798915] mmc1: mmc_select_hs200 failed, error -110
[  226.799390] mmc1: error -110 whilst initialising MMC card
[  226.811549] mmc_host mmc1: Bus speed (slot 0) = 200000Hz (slot req 
200000Hz, actual 200000HZ div = 0)
[  226.947518] mmc1: switch to bus width 4 failed
[  226.954978] mmc1: mmc_select_hs200 failed, error -110
[  226.955454] mmc1: error -110 whilst initialising MMC card

I don't know if this is board-dependent.

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> Jimmy
> 




From honyuenkwun at gmail.com  Wed Nov  5 21:50:42 2025
From: honyuenkwun at gmail.com (Jimmy Hon)
Date: Wed, 5 Nov 2025 23:50:42 -0600
Subject: [PATCH v6 3/3] arm64: dts: rockchip: Add Radxa CM5 IO Board
In-Reply-To: <57F9C541303D73B3+4c84cba4-8378-4b65-8065-46e28217694b@radxa.com>
References: <20251105051335.17652-1-naoki@radxa.com> <20251105051335.17652-4-naoki@radxa.com>
 <CALWfF7KyTfpXSyjVQaFzqtn6KyDxuyZOBpPR8y-jf6sduNxq5A@mail.gmail.com>
 <1EE1A1D9D7C100DA+1b365782-98c4-4ee0-ab96-920990841903@radxa.com>
 <35ff8e6f-dd2b-d909-70c7-b19240e32ccf@manjaro.org> <CALWfF7K3zNxSsXVpW8pLc_xWi793HG99OvbshtP-0=764JmPKw@mail.gmail.com>
 <57F9C541303D73B3+4c84cba4-8378-4b65-8065-46e28217694b@radxa.com>
Message-ID: <CALWfF7+0_MOhUNNSekYB4P5xrsgevz_ZvcX883iyCt94K6h7OQ@mail.gmail.com>

On Wed, Nov 5, 2025 at 11:09?PM FUKAUMI Naoki <naoki at radxa.com> wrote:
>
> Hi Jimmy,
>
> On 11/6/25 13:53, Jimmy Hon wrote:
> > On Wed, Nov 5, 2025 at 9:31?PM Dragan Simic <dsimic at manjaro.org> wrote:
> >
> > [ snip ]
> >
> >>
> >> With all that in mind, we should specify "no-mmc" here, because
> >> we're describing a microSD slot, instead of describing some hybrid
> >> MMC/microSD slot.  That also explains why the adapter sold by Radxa
> >> is described as not to be used with microSD card slots on SBCs.  I'd
> >> also like to hear is this adapter/eMMC chip combo recognized by the
> >> kernel when "no-mmc" is specified; it should fail.
> >>
> >> Actually, not specifying "no-mmc" here may result in some unforeseen
> >> issues with some (or perhaps many?) microSD cards, because the MMC
> >> drivers will treat them as MMC-capable devices and try to initialize
> >> them as such, which may cause all kinds of issues.  In fact, I'm not
> >> really sure that the MMC drivers are actually implemented in a way
> >> that avoids all possible issues with the storage controllers that
> >> are capable of both SD and MMC modes when neither of "no-sd" and
> >> "no-mmc" is specified in their DT nodes.
> >
> > Hybrid MMC and SD slots are pretty normal on USB card readers. So it's
> > normal for the host controller to figure out what kind of card is in
> > the slot.
> > https://uditagarwal.in/understanding-sd-sdio-and-mmc-interface/
> >
> > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6ae3e537eab9f560b516b001eb89f0cd568bdced
> > was the commit that introduced the device tree properties. By the
> > wording of the commit message, these device tree properties are used
> > to indicate to the driver if the host controller hardware is capable
> > of MMC initialization or SD initialization.
> >
> > Since the host controller in the RK3588 is capable of all the modes,
> > these properties do not need to be specified.
> >
> > Since Radxa has the eMMC to uSD adapter, it makes sense Radxa would
> > want to configure their microSD card slot on their boards to be a
> > hybrid SD/MMC slot.
> >
> > Now, the more fun question is if the adapter can handle eMMC HS200
> > using the 4-bit bus?
>
> I added
>   mmc-hs200-1_8v;
>
> I got
>
> [  226.099510] mmc_host mmc1: Bus speed (slot 0) = 400000Hz (slot req
> 400000Hz, actual 400000HZ div = 0)
> [  226.546246] mmc_host mmc1: Bus speed (slot 0) = 49500000Hz (slot req
> 52000000Hz, actual 49500000HZ div = 0)
> [  226.546371] mmc_host mmc1: Bus speed (slot 0) = 198000000Hz (slot req
> 200000000Hz, actual 198000000HZ div = 0)
> [  226.656853] dwmmc_rockchip fe2c0000.mmc: Successfully tuned phase to 76
> [  226.657011] mmc1: error -110 whilst initialising MMC card
> [  226.671469] mmc_host mmc1: Bus speed (slot 0) = 300000Hz (slot req
> 300000Hz, actual 300000HZ div = 0)
> [  226.793733] mmc1: switch to bus width 4 failed
> [  226.798915] mmc1: mmc_select_hs200 failed, error -110
> [  226.799390] mmc1: error -110 whilst initialising MMC card
> [  226.811549] mmc_host mmc1: Bus speed (slot 0) = 200000Hz (slot req
> 200000Hz, actual 200000HZ div = 0)
> [  226.947518] mmc1: switch to bus width 4 failed
> [  226.954978] mmc1: mmc_select_hs200 failed, error -110
> [  226.955454] mmc1: error -110 whilst initialising MMC card
>
> I don't know if this is board-dependent.

I was hoping for too much.

In the "RK3588 Datasheet", under the "eMMC Interface", it specifically
lists support for HS400. However, for the "SD/MMC Interface", it only
mentions "SD3.0, MMC ver4.51", so the more performant eMMC modes are
not available on that interface.

Jimmy

>
> Best regards,
>
> --
> FUKAUMI Naoki
> Radxa Computer (Shenzhen) Co., Ltd.
>
> > Jimmy
> >
>
>


From mani at kernel.org  Wed Nov  5 23:06:41 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Thu, 6 Nov 2025 12:36:41 +0530
Subject: [PATCH v3] PCI: dw-rockchip: Prevent advertising L1 Substates
 support
In-Reply-To: <20251104221724.GA1875081@bhelgaas>
References: <0e32766b-b951-4ab4-ae3d-c802cf649edf@rock-chips.com>
 <20251104221724.GA1875081@bhelgaas>
Message-ID: <oa57mn3wrigno2kzigdo2lh46z5xmesv74nzjtg4jz4ea6urrh@icti3ewoll4r>

On Tue, Nov 04, 2025 at 04:17:24PM -0600, Bjorn Helgaas wrote:
> On Tue, Nov 04, 2025 at 08:58:02AM +0800, Shawn Lin wrote:
> > ? 2025/11/04 ??? 5:32, Bjorn Helgaas ??:
> > > On Tue, Oct 28, 2025 at 02:02:18PM -0500, Bjorn Helgaas wrote:
> > > > On Fri, Oct 17, 2025 at 06:32:53PM +0200, Niklas Cassel wrote:
> > > > > The L1 substates support requires additional steps to work, namely:
> > > > > -Proper handling of the CLKREQ# sideband signal. (It is mostly handled by
> > > > >   hardware, but software still needs to set the clkreq fields in the
> > > > >   PCIE_CLIENT_POWER_CON register to match the hardware implementation.)
> > > > > -Program the frequency of the aux clock into the
> > > > >   DSP_PCIE_PL_AUX_CLK_FREQ_OFF register. (During L1 substates the core_clk
> > > > >   is turned off and the aux_clk is used instead.)
> > > > ...
> > > 
> > > > > +static void rockchip_pcie_disable_l1sub(struct dw_pcie *pci)
> > > > > +{
> > > > > +	u32 cap, l1subcap;
> > > > > +
> > > > > +	cap = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_L1SS);
> > > > > +	if (cap) {
> > > > > +		l1subcap = dw_pcie_readl_dbi(pci, cap + PCI_L1SS_CAP);
> > > > > +		l1subcap &= ~(PCI_L1SS_CAP_L1_PM_SS | PCI_L1SS_CAP_ASPM_L1_1 |
> > > > > +			      PCI_L1SS_CAP_ASPM_L1_2 | PCI_L1SS_CAP_PCIPM_L1_1 |
> > > > > +			      PCI_L1SS_CAP_PCIPM_L1_2);
> > > > > +		dw_pcie_writel_dbi(pci, cap + PCI_L1SS_CAP, l1subcap);
> > > > > +	}
> > > > > +}
> > > > 
> > > > I like this.  But why should we do it just for dw-rockchip?  Is there
> > > > something special about dw-rockchip that makes this a problem?  Maybe
> > > > we should consider doing this in the dwc, cadence, mobiveil, and plda
> > > > cores instead of trying to do it for every driver individually?
> > > > 
> > > > Advertising L1SS support via PCI_EXT_CAP_ID_L1SS means users can
> > > > enable L1SS via CONFIG_PCIEASPM_POWER_SUPERSAVE=y or sysfs, and that
> > > > seems likely to cause problems unless CLKREQ# is supported.
> > > 
> > > Any thoughts on this?  There's nothing rockchip-specific in this
> > > patch.  What I'm proposing is something like this:
> > 
> > I like your idea, though. But could it be another form of regression
> > that we may breaks the platform which have already support L1SS
> > properly? It's even harder to detect because a functional break is easier to
> > notice than increased power consumption. 
> 
> True, but I think it's unlikely because the PCI core never enabled
> L1SS (except for CONFIG_PCIEASPM_POWER_SUPERSAVE=y or sysfs, which I
> doubt anybody really uses).
> 
> Devicetree platforms that use L1SS should have explicit code to enable
> it, like qcom does, so we should be able to find them and make sure
> they do what's needed to prevent the regression.
> 
> > Or maybe we could
> > just export dw_pcie_clear_l1ss_advert() in dwc for host drivers to
> > call it?
> 
> I don't like the idea of host drivers having to opt in for this
> because that requires changes to all of them, not just changes to
> drivers that have done the work to actually support L1SS.
> 

Otherwise, we may have to introduce a flag for the controller drivers to opt-out
of this disablement. Like, dw_pcie_rp::native_clkreq and bailing out early if
this flag is set.

- Mani

-- 
????????? ????????


From shawn.lin at rock-chips.com  Thu Nov  6 00:40:14 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Thu, 6 Nov 2025 16:40:14 +0800
Subject: [PATCH v6 3/3] arm64: dts: rockchip: Add Radxa CM5 IO Board
In-Reply-To: <35ff8e6f-dd2b-d909-70c7-b19240e32ccf@manjaro.org>
References: <20251105051335.17652-1-naoki@radxa.com>
 <20251105051335.17652-4-naoki@radxa.com>
 <CALWfF7KyTfpXSyjVQaFzqtn6KyDxuyZOBpPR8y-jf6sduNxq5A@mail.gmail.com>
 <1EE1A1D9D7C100DA+1b365782-98c4-4ee0-ab96-920990841903@radxa.com>
 <35ff8e6f-dd2b-d909-70c7-b19240e32ccf@manjaro.org>
Message-ID: <a624f36b-5a06-44f5-98b2-4a194ecebc6a@rock-chips.com>

? 2025/11/06 ??? 11:31, Dragan Simic ??:
> Hello Naoki,
> 
> On Thursday, November 06, 2025 00:38 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
>> On 11/6/25 03:27, Jimmy Hon wrote:
>>> On Tue, Nov 4, 2025 at 11:14?PM FUKAUMI Naoki <naoki at radxa.com> wrote:
>>>>
>>>> The Radxa CM5 IO Board is an application board for the Radxa CM5.
>>>>
>>>> Specification:
>>>
>>>> - 1x microSD card slot
>>>
>>> [ snip ]
>>>
>>>> +
>>>> +&sdmmc {
>>>> +       bus-width = <4>;
>>>> +       cap-mmc-highspeed;
>>>> +       cap-sd-highspeed;
>>>> +       cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
>>>> +       disable-wp;
>>>> +       no-sdio;
>>>> +       pinctrl-names = "default";
>>>> +       pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd>;
>>>> +       sd-uhs-sdr104;
>>>> +       vmmc-supply = <&vcc_3v3_s3>;
>>>> +       vqmmc-supply = <&vccio_sd_s0>;
>>>> +       status = "okay";
>>>> +};
>>>
>>> When used as a TF slot, shouldn't there be a "no-mmc" also?
>>
>> We have "eMMC to uSD."
>>    https://radxa.com/products/accessories/emmc-to-usd
>>
>> [  202.176757] mmc_host mmc1: Bus speed (slot 0) = 49500000Hz (slot req
>> 52000000Hz, actual 49500000HZ div = 0)
>> [  202.178477] mmc1: new high speed MMC card at address 0001
>> [  202.179534] mmcblk1: mmc1:0001 SLD64G 57.6 GiB
>> [  202.207336] mmcblk1boot0: mmc1:0001 SLD64G 4.00 MiB
>> [  202.210374] mmcblk1boot1: mmc1:0001 SLD64G 4.00 MiB
>> [  202.212967] mmcblk1rpmb: mmc1:0001 SLD64G 4.00 MiB, chardev (511:1)
>>
>> (I'm not sure why it says "Not work with the SD slot on the board." I
>> will check.)
> 
> Thanks for bringing this up, I've always wondered how are such
> simple eMMC-to-microSD adapters supposed to work, so this was
> a good opportunity to research that a bit further.
> 
> In a few words, they're not supposed to work in true microSD card
> slots, and they seem to rely on USB card readers that support
> multiple card interface standards, but not more than a single card
> at once, by wiring their single interface lines in parallel to the
> different types of card slots that they provide.
> 
> To explain it a bit further, an eMMC chip supports different data
> bus widths and a backward-compatible MMC card mode, but they have
> very little knowledge about the SD specification, despite being
> somewhat similar; the exception is the simplified eMMC boot mode.
> This is explained further in the JEDEC JESD84-B51 standard, which
> is available freely from the JEDEC website after registration.
> 
> This is also confirmed by the kernel messages quoted above, which
> show that the eMMC chip is detected as an MMC card this way.
> 
> With all that in mind, we should specify "no-mmc" here, because
> we're describing a microSD slot, instead of describing some hybrid
> MMC/microSD slot.  That also explains why the adapter sold by Radxa
> is described as not to be used with microSD card slots on SBCs.  I'd
> also like to hear is this adapter/eMMC chip combo recognized by the
> kernel when "no-mmc" is specified; it should fail.
> 
> Actually, not specifying "no-mmc" here may result in some unforeseen
> issues with some (or perhaps many?) microSD cards, because the MMC
> drivers will treat them as MMC-capable devices and try to initialize

Just chime in: The reason why we introduced these, is for controllers
not cards. AFAITC, before commit 6ae3e537eab9f5, we had done that way
for a decade, but rarely saw problems in this field.

> them as such, which may cause all kinds of issues.  In fact, I'm not
> really sure that the MMC drivers are actually implemented in a way
> that avoids all possible issues with the storage controllers that
> are capable of both SD and MMC modes when neither of "no-sd" and
> "no-mmc" is specified in their DT nodes.
> 
> Furthermore, it seems that specifying "cap-mmc-highspeed" together
> with "no-emmc" is actually redundant, which would make sense, but
> further research of the MMC drivers is needed.  I've added that to
> my ever-growing TODO list. :)
> 
>>> That's how the Rock 5A, 5B, and 5C were defined.
>>
>> I have submitted a patch without "no-mmc" before. I intend to send one
>> again when I have the chance.
> 
> 
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip



From dsimic at manjaro.org  Sat Nov  1 09:59:10 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Sat, 01 Nov 2025 17:59:10 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= pwm-fan overlay for NanoPC-T6
Message-ID: <0ac61ea1-9e22-7101-646d-694e350ec1b4@manjaro.org>

Hello Hugh,

On Saturday, November 01, 2025 14:14 CET, Hugh Cole-Baker <sigmaris at gmail.com> wrote:
> On 01/11/2025 11:44, Heiko Stuebner wrote:
> > Personally, I'm more on the less complication side.
> > 
> > I.e. if there is an actual fan-connector on the board we should describe
> > it as such.
> > 
> > Overlays I see for things where you attach hats to generic pin headers
> > to create specific functionality on top of a generic interface.
> > 
> > But if the board itself has an actual fan header, it should be described
> > as such. Because that then _is_ the standard use of that.
> 
> The board does have a fan connector, just no fan by default. But anyway,
> since it sounds like the preferred approach I'll send a v2 which puts the
> fan into the base board .dts.
> 
> Dragan, you mentioned there's no need for more than 2 trip points - if
> I remove the trip points between "SoC is warm, start fan at slow speed"
> and "SoC is v. hot, run fan at full speed" is the OS/kernel expected to
> interpolate between those 2 trip points (if you have a link to docs or
> code about this it'd be interesting, I couldn't find anything in the
> dt-bindings)?

True, that isn't described in the bindings, because it basically
doesn't belong there.  Thus, the most specific description of the
associated cooling stuff, as provided by the bindings, is the
following excerpt from Documentation/devicetree/bindings/thermal/
thermal-zones.yaml:

  209 cooling-device:
  210   $ref: /schemas/types.yaml#/definitions/phandle-array
  211   description:
  212     A list of cooling device phandles along with the minimum
  213     and maximum cooling state specifiers for each cooling
  214     device. Using the THERMAL_NO_LIMIT (-1UL) constant in the
  215     cooling-device phandle limit specifier lets the framework
  216     use the minimum and maximum cooling state for that cooling
  217     device automatically.

That's where the cooling hardware description ends, so that's also
where the associated binding ends.  Everything else belongs to the
thermal governors, because they actually decide on how to best use
the available cooling features.

For example, the chain of events may look like this:

  (1) The rockchip_thermal_alarm_irq_thread() function, defined in
      drivers/thermal/rockchip_thermal.c, gets triggered by TSADC
      within the parameters of DT-defined "active" trip types

  (2) It calls the thermal_zone_device_update() function defined
      in drivers/thermal/thermal_core.c

  (3) This ends up calling the step_wise_manage() function that's
      defined in drivers/thermal/gov_step_wise.c, which handles
      the previously triggered "active" trip

  (4) This calls the drivers/thermal/gov_step_wise.c's locally
      defined thermal_zone_trip_update() and get_target_state()
      functions, which end up ramping the fan speed up and down
      as needed, while respecting the upper and lower limits
      defined through the "cooling-device" DT map properties,
      which correspond to the "cooling-levels" defined in the
      DT fan property

Here's also an excerpt from drivers/thermal/gov_step_wise.c, which
confirms all this and explains it a bit further:

  113  /*
  114   * Throttling Logic: Use the trend of the thermal zone to throttle.
  115   * If the thermal zone is 'heating up', throttle all of the cooling
  116   * devices associated with each trip point by one step. If the zone
  117   * is 'cooling down', it brings back the performance of the devices
  118   * by one step.
  119   */

With all that in mind, the fan will ramp its speed up and down
nicely, according to the current temperature, with no need for
having multiple manually defined steps.

The intended benefit of having the two usual, distinct "active"
thermal trips and cooling maps is to lower the fan-induced noise
a bit while not affecting the cooling much.  This is all visible
in rk3399-rockpro64.dtsi, for example.



From brgl at bgdev.pl  Tue Nov  4 05:08:51 2025
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Tue, 04 Nov 2025 14:08:51 +0100
Subject: [PATCH v4 0/8] net: stmmac: qcom-ethqos: add support for SCMI
 power domains
Message-ID: <20251104-qcom-sa8255p-emac-v4-0-f76660087cea@linaro.org>

Add support for the firmware-managed variant of the DesignWare MAC on
the sa8255p platform. This series contains new DT bindings and driver
changes required to support the MAC in the STMMAC driver.

It also reorganizes the ethqos code quite a bit to make the introduction
of power domains into the driver a bit easier on the eye.

The DTS changes will go in separately.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
Changes in v4:
- Remove the phys property from the SCMI bindings
- Mark the power-domain-names property as required
- Set maxItems for power-domains to 1 for all existing bindings to
  maintain the current requirements after modifying the value in the
  top-level document
- Link to v3: https://lore.kernel.org/r/20251027-qcom-sa8255p-emac-v3-0-75767b9230ab at linaro.org

Changes in v3:
- Drop 'power' and 'perf' prefixes from power domain names
- Rebase on top of Russell's changes to dwmac
- Rebase on top of even more changes from Russell that are not yet
  in next (E1vB6ld-0000000BIPy-2Qi4 at rmk-PC.armlinux.org.uk)
- Link to v2: https://lore.kernel.org/all/20251008-qcom-sa8255p-emac-v2-0-92bc29309fce at linaro.org/

Changes in v2:
- Fix the power-domains property in DT bindings
- Rework the DT bindings example
- Drop the DTS patch, it will go upstream separately
- Link to v1: https://lore.kernel.org/r/20250910-qcom-sa8255p-emac-v1-0-32a79cf1e668 at linaro.org

---
Bartosz Golaszewski (8):
      dt-bindings: net: qcom: document the ethqos device for SCMI-based systems
      net: stmmac: qcom-ethqos: use generic device properties
      net: stmmac: qcom-ethqos: improve typing in devres callback
      net: stmmac: qcom-ethqos: wrap emac driver data in additional structure
      net: stmmac: qcom-ethqos: split power management fields into a separate structure
      net: stmmac: qcom-ethqos: split power management context into a separate struct
      net: stmmac: qcom-ethqos: define a callback for setting the serdes speed
      net: stmmac: qcom-ethqos: add support for sa8255p

 .../bindings/net/allwinner,sun7i-a20-gmac.yaml     |   3 +
 .../bindings/net/altr,socfpga-stmmac.yaml          |   3 +
 .../bindings/net/amlogic,meson-dwmac.yaml          |   3 +
 .../devicetree/bindings/net/eswin,eic7700-eth.yaml |   3 +
 .../devicetree/bindings/net/intel,dwmac-plat.yaml  |   3 +
 .../bindings/net/loongson,ls1b-gmac.yaml           |   3 +
 .../bindings/net/loongson,ls1c-emac.yaml           |   3 +
 .../devicetree/bindings/net/nxp,dwmac-imx.yaml     |   3 +
 .../devicetree/bindings/net/nxp,lpc1850-dwmac.yaml |   3 +
 .../devicetree/bindings/net/nxp,s32-dwmac.yaml     |   3 +
 .../devicetree/bindings/net/qcom,ethqos-scmi.yaml  |  97 ++++++
 .../devicetree/bindings/net/qcom,ethqos.yaml       |   3 +
 .../devicetree/bindings/net/renesas,rzn1-gmac.yaml |   3 +
 .../bindings/net/renesas,rzv2h-gbeth.yaml          |   3 +
 .../devicetree/bindings/net/rockchip-dwmac.yaml    |   3 +
 .../devicetree/bindings/net/snps,dwmac.yaml        |   5 +-
 .../bindings/net/sophgo,cv1800b-dwmac.yaml         |   3 +
 .../bindings/net/sophgo,sg2044-dwmac.yaml          |   3 +
 .../bindings/net/starfive,jh7110-dwmac.yaml        |   3 +
 .../devicetree/bindings/net/stm32-dwmac.yaml       |   3 +
 .../devicetree/bindings/net/tesla,fsd-ethqos.yaml  |   3 +
 .../devicetree/bindings/net/thead,th1520-gmac.yaml |   3 +
 .../bindings/net/toshiba,visconti-dwmac.yaml       |   3 +
 MAINTAINERS                                        |   1 +
 drivers/net/ethernet/stmicro/stmmac/Kconfig        |   2 +-
 .../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c    | 342 +++++++++++++++++----
 26 files changed, 447 insertions(+), 63 deletions(-)
---
base-commit: 9823120909776bbca58a3c55ef1f27d49283c1f3
change-id: 20250704-qcom-sa8255p-emac-8460235ac512

Best regards,
-- 
Bartosz Golaszewski <bartosz.golaszewski at linaro.org>



From brgl at bgdev.pl  Tue Nov  4 05:08:52 2025
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Tue, 04 Nov 2025 14:08:52 +0100
Subject: [PATCH v4 1/8] dt-bindings: net: qcom: document the ethqos device
 for SCMI-based systems
In-Reply-To: <20251104-qcom-sa8255p-emac-v4-0-f76660087cea@linaro.org>
References: <20251104-qcom-sa8255p-emac-v4-0-f76660087cea@linaro.org>
Message-ID: <20251104-qcom-sa8255p-emac-v4-1-f76660087cea@linaro.org>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

Describe the firmware-managed variant of the QCom DesignWare MAC. As the
properties here differ a lot from the HLOS-managed variant, lets put it
in a separate file. Since we need to update the maximum number of power
domains, let's update existing bindings referencing the top-level
snps,dwmac.yaml and limit their maxItems for power-domains to 1.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 .../bindings/net/allwinner,sun7i-a20-gmac.yaml     |  3 +
 .../bindings/net/altr,socfpga-stmmac.yaml          |  3 +
 .../bindings/net/amlogic,meson-dwmac.yaml          |  3 +
 .../devicetree/bindings/net/eswin,eic7700-eth.yaml |  3 +
 .../devicetree/bindings/net/intel,dwmac-plat.yaml  |  3 +
 .../bindings/net/loongson,ls1b-gmac.yaml           |  3 +
 .../bindings/net/loongson,ls1c-emac.yaml           |  3 +
 .../devicetree/bindings/net/nxp,dwmac-imx.yaml     |  3 +
 .../devicetree/bindings/net/nxp,lpc1850-dwmac.yaml |  3 +
 .../devicetree/bindings/net/nxp,s32-dwmac.yaml     |  3 +
 .../devicetree/bindings/net/qcom,ethqos-scmi.yaml  | 97 ++++++++++++++++++++++
 .../devicetree/bindings/net/qcom,ethqos.yaml       |  3 +
 .../devicetree/bindings/net/renesas,rzn1-gmac.yaml |  3 +
 .../bindings/net/renesas,rzv2h-gbeth.yaml          |  3 +
 .../devicetree/bindings/net/rockchip-dwmac.yaml    |  3 +
 .../devicetree/bindings/net/snps,dwmac.yaml        |  5 +-
 .../bindings/net/sophgo,cv1800b-dwmac.yaml         |  3 +
 .../bindings/net/sophgo,sg2044-dwmac.yaml          |  3 +
 .../bindings/net/starfive,jh7110-dwmac.yaml        |  3 +
 .../devicetree/bindings/net/stm32-dwmac.yaml       |  3 +
 .../devicetree/bindings/net/tesla,fsd-ethqos.yaml  |  3 +
 .../devicetree/bindings/net/thead,th1520-gmac.yaml |  3 +
 .../bindings/net/toshiba,visconti-dwmac.yaml       |  3 +
 MAINTAINERS                                        |  1 +
 24 files changed, 165 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/net/allwinner,sun7i-a20-gmac.yaml b/Documentation/devicetree/bindings/net/allwinner,sun7i-a20-gmac.yaml
index 23e92be33ac8609a16db530782989caed22a5730..b12632545673b2ad0148a677f45a7447309a43cd 100644
--- a/Documentation/devicetree/bindings/net/allwinner,sun7i-a20-gmac.yaml
+++ b/Documentation/devicetree/bindings/net/allwinner,sun7i-a20-gmac.yaml
@@ -40,6 +40,9 @@ properties:
     description:
       PHY regulator
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
diff --git a/Documentation/devicetree/bindings/net/altr,socfpga-stmmac.yaml b/Documentation/devicetree/bindings/net/altr,socfpga-stmmac.yaml
index fc445ad5a1f1ac490e921696d6f7ca83d15de459..448e617cddc4cda8dbc77e83324495ffd5dfb9be 100644
--- a/Documentation/devicetree/bindings/net/altr,socfpga-stmmac.yaml
+++ b/Documentation/devicetree/bindings/net/altr,socfpga-stmmac.yaml
@@ -140,6 +140,9 @@ properties:
           - description: offset of the control register
           - description: shift within the control register
 
+  power-domains:
+    maxItems: 1
+
 patternProperties:
   "^mdio[0-9]$":
     type: object
diff --git a/Documentation/devicetree/bindings/net/amlogic,meson-dwmac.yaml b/Documentation/devicetree/bindings/net/amlogic,meson-dwmac.yaml
index 5c91716d1f21e617543b03c5a90b993f8aee053c..9c9cc3ef384da0270489c21b3426572ea46d9499 100644
--- a/Documentation/devicetree/bindings/net/amlogic,meson-dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/amlogic,meson-dwmac.yaml
@@ -158,6 +158,9 @@ properties:
   interrupt-names:
     const: macirq
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
diff --git a/Documentation/devicetree/bindings/net/eswin,eic7700-eth.yaml b/Documentation/devicetree/bindings/net/eswin,eic7700-eth.yaml
index 9ddbfe219ae2ed675149fe7f2e50b71a117941d4..a5ff7abb1cdfd859a087eb7514059722f979f3f6 100644
--- a/Documentation/devicetree/bindings/net/eswin,eic7700-eth.yaml
+++ b/Documentation/devicetree/bindings/net/eswin,eic7700-eth.yaml
@@ -81,6 +81,9 @@ properties:
       High-Speed Peripheral device needed to configure clock selection,
       clock low-power mode and clock delay.
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
diff --git a/Documentation/devicetree/bindings/net/intel,dwmac-plat.yaml b/Documentation/devicetree/bindings/net/intel,dwmac-plat.yaml
index 62c1da36a2b5a29290e5e01be87c48158c4adf89..e41851931b947559c89b0cd6f4756f71046f9594 100644
--- a/Documentation/devicetree/bindings/net/intel,dwmac-plat.yaml
+++ b/Documentation/devicetree/bindings/net/intel,dwmac-plat.yaml
@@ -47,6 +47,9 @@ properties:
   interrupt-names:
     const: macirq
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - clocks
diff --git a/Documentation/devicetree/bindings/net/loongson,ls1b-gmac.yaml b/Documentation/devicetree/bindings/net/loongson,ls1b-gmac.yaml
index c4f3224bad387b87a5b4a3049dabd75f2c4bd42f..c9a131b8d8304c41559a416b324df749c0a87d14 100644
--- a/Documentation/devicetree/bindings/net/loongson,ls1b-gmac.yaml
+++ b/Documentation/devicetree/bindings/net/loongson,ls1b-gmac.yaml
@@ -66,6 +66,9 @@ properties:
       - mii
       - rgmii-id
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
diff --git a/Documentation/devicetree/bindings/net/loongson,ls1c-emac.yaml b/Documentation/devicetree/bindings/net/loongson,ls1c-emac.yaml
index 99001b940b8361f69bb917617f857ee99f4b3fa5..49db18423dd807683b9bb297978f5da8ea6cee3d 100644
--- a/Documentation/devicetree/bindings/net/loongson,ls1c-emac.yaml
+++ b/Documentation/devicetree/bindings/net/loongson,ls1c-emac.yaml
@@ -65,6 +65,9 @@ properties:
       - mii
       - rmii
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
diff --git a/Documentation/devicetree/bindings/net/nxp,dwmac-imx.yaml b/Documentation/devicetree/bindings/net/nxp,dwmac-imx.yaml
index e5db346beca9649be4f97727b78fda8973095912..b240c76e7dd5254d0c3752610c4aa848a3c3d65b 100644
--- a/Documentation/devicetree/bindings/net/nxp,dwmac-imx.yaml
+++ b/Documentation/devicetree/bindings/net/nxp,dwmac-imx.yaml
@@ -83,6 +83,9 @@ properties:
     description:
       To select RMII reference clock from external.
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - clocks
diff --git a/Documentation/devicetree/bindings/net/nxp,lpc1850-dwmac.yaml b/Documentation/devicetree/bindings/net/nxp,lpc1850-dwmac.yaml
index 05acd9bc7616356e68090ebdd4df20e42f70dd7e..f61188ab0dbe3c0cec5b10f7a65dfaff4dc3898f 100644
--- a/Documentation/devicetree/bindings/net/nxp,lpc1850-dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/nxp,lpc1850-dwmac.yaml
@@ -51,6 +51,9 @@ properties:
     items:
       - const: stmmaceth
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
diff --git a/Documentation/devicetree/bindings/net/nxp,s32-dwmac.yaml b/Documentation/devicetree/bindings/net/nxp,s32-dwmac.yaml
index 2b8b74c5feec8378750358e1b9335cc2c2762bb6..716407a750796ff27e8fbcdb75267f3922ef64f5 100644
--- a/Documentation/devicetree/bindings/net/nxp,s32-dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/nxp,s32-dwmac.yaml
@@ -52,6 +52,9 @@ properties:
       - const: rx
       - const: ptp_ref
 
+  power-domains:
+    maxItems: 1
+
 required:
   - clocks
   - clock-names
diff --git a/Documentation/devicetree/bindings/net/qcom,ethqos-scmi.yaml b/Documentation/devicetree/bindings/net/qcom,ethqos-scmi.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..ff70d785d326f39a8fe5698759c56ab2cb7f7eef
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/qcom,ethqos-scmi.yaml
@@ -0,0 +1,97 @@
+# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/qcom,ethqos-scmi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Ethernet ETHQOS device (firmware managed)
+
+maintainers:
+  - Bjorn Andersson <andersson at kernel.org>
+  - Konrad Dybcio <konradybcio at kernel.org>
+  - Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
+
+description:
+  dwmmac based Qualcomm ethernet devices which support Gigabit
+  ethernet (version v2.3.0 and onwards) with clocks, interconnects, etc.
+  managed by firmware
+
+allOf:
+  - $ref: snps,dwmac.yaml#
+
+properties:
+  compatible:
+    const: qcom,sa8255p-ethqos
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: stmmaceth
+      - const: rgmii
+
+  interrupts:
+    items:
+      - description: Combined signal for various interrupt events
+      - description: The interrupt that occurs when HW safety error triggered
+
+  interrupt-names:
+    items:
+      - const: macirq
+      - const: sfty
+
+  power-domains:
+    minItems: 3
+
+  power-domain-names:
+    items:
+      - const: core
+      - const: mdio
+      - const: serdes
+
+  iommus:
+    maxItems: 1
+
+  dma-coherent: true
+
+required:
+  - compatible
+  - reg-names
+  - power-domains
+  - power-domain-names
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    ethernet: ethernet at 7a80000 {
+        compatible = "qcom,sa8255p-ethqos";
+        reg = <0x23040000 0x10000>,
+              <0x23056000 0x100>;
+        reg-names = "stmmaceth", "rgmii";
+
+        iommus = <&apps_smmu 0x120 0x7>;
+
+        interrupts = <GIC_SPI 946 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 782 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-names = "macirq", "sfty";
+
+        dma-coherent;
+
+        snps,tso;
+        snps,pbl = <32>;
+        rx-fifo-depth = <16384>;
+        tx-fifo-depth = <16384>;
+
+        phy-handle = <&ethernet_phy>;
+        phy-mode = "2500base-x";
+
+        snps,mtl-rx-config = <&mtl_rx_setup1>;
+        snps,mtl-tx-config = <&mtl_tx_setup1>;
+
+        power-domains = <&scmi8_pd 0>, <&scmi8_pd 1>, <&scmi8_dvfs 0>;
+        power-domain-names = "core", "mdio","serdes";
+    };
diff --git a/Documentation/devicetree/bindings/net/qcom,ethqos.yaml b/Documentation/devicetree/bindings/net/qcom,ethqos.yaml
index 423959cb928d945aa3e758a3c803d12bd61ec42b..ef520f8105773e22c0536ff419dad55fe316e1bd 100644
--- a/Documentation/devicetree/bindings/net/qcom,ethqos.yaml
+++ b/Documentation/devicetree/bindings/net/qcom,ethqos.yaml
@@ -86,6 +86,9 @@ properties:
   phy-names:
     const: serdes
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - clocks
diff --git a/Documentation/devicetree/bindings/net/renesas,rzn1-gmac.yaml b/Documentation/devicetree/bindings/net/renesas,rzn1-gmac.yaml
index 16dd7a2631abf6fb7dc8e0c90755ab1e81915b38..ed0d10a19ca4c47c05f6873c64b0537b90acd15a 100644
--- a/Documentation/devicetree/bindings/net/renesas,rzn1-gmac.yaml
+++ b/Documentation/devicetree/bindings/net/renesas,rzn1-gmac.yaml
@@ -44,6 +44,9 @@ properties:
       phandle pointing to a PCS sub-node compatible with
       renesas,rzn1-miic.yaml#
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
 
diff --git a/Documentation/devicetree/bindings/net/renesas,rzv2h-gbeth.yaml b/Documentation/devicetree/bindings/net/renesas,rzv2h-gbeth.yaml
index bd53ab300f5003ea1f951d3957cefc702301217a..bc5054b05f6d7f1bcd5cd8640deb89293d9f69a6 100644
--- a/Documentation/devicetree/bindings/net/renesas,rzv2h-gbeth.yaml
+++ b/Documentation/devicetree/bindings/net/renesas,rzv2h-gbeth.yaml
@@ -123,6 +123,9 @@ properties:
       Documentation/devicetree/bindings/net/pcs/renesas,rzn1-miic.yaml#
       (Refer RZ/T2H portion in the DT-binding file)
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
diff --git a/Documentation/devicetree/bindings/net/rockchip-dwmac.yaml b/Documentation/devicetree/bindings/net/rockchip-dwmac.yaml
index d17112527dab0a5104ffaf2627fdcb73603d5db7..ef82ff2a2884d994c5ae6c98e0b3483b56dda653 100644
--- a/Documentation/devicetree/bindings/net/rockchip-dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/rockchip-dwmac.yaml
@@ -121,6 +121,9 @@ properties:
   phy-supply:
     description: PHY regulator
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - clocks
diff --git a/Documentation/devicetree/bindings/net/snps,dwmac.yaml b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
index dd3c72e8363e70d101ed2702e2ea3235ee38e2a0..312d1bbc2ad1051520355039f5587381cbd1e01c 100644
--- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
@@ -71,6 +71,7 @@ properties:
         - loongson,ls7a-dwmac
         - nxp,s32g2-dwmac
         - qcom,qcs404-ethqos
+        - qcom,sa8255p-ethqos
         - qcom,sa8775p-ethqos
         - qcom,sc8280xp-ethqos
         - qcom,sm8150-ethqos
@@ -180,7 +181,8 @@ properties:
           - const: ahb
 
   power-domains:
-    maxItems: 1
+    minItems: 1
+    maxItems: 3
 
   mac-mode:
     $ref: ethernet-controller.yaml#/properties/phy-connection-type
@@ -643,6 +645,7 @@ allOf:
                 - ingenic,x1830-mac
                 - ingenic,x2000-mac
                 - qcom,qcs404-ethqos
+                - qcom,sa8255p-ethqos
                 - qcom,sa8775p-ethqos
                 - qcom,sc8280xp-ethqos
                 - qcom,sm8150-ethqos
diff --git a/Documentation/devicetree/bindings/net/sophgo,cv1800b-dwmac.yaml b/Documentation/devicetree/bindings/net/sophgo,cv1800b-dwmac.yaml
index b89456f0ef830991135bd17626da98661429596c..e78cbf594c695204040a53ab1e367daa9e12246b 100644
--- a/Documentation/devicetree/bindings/net/sophgo,cv1800b-dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/sophgo,cv1800b-dwmac.yaml
@@ -49,6 +49,9 @@ properties:
   reset-names:
     const: stmmaceth
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
diff --git a/Documentation/devicetree/bindings/net/sophgo,sg2044-dwmac.yaml b/Documentation/devicetree/bindings/net/sophgo,sg2044-dwmac.yaml
index ce21979a2d9a438adb1e59d1a479bc6c1961bdca..e124cfc9bd90e37cf950e3576fc8030361ce6a11 100644
--- a/Documentation/devicetree/bindings/net/sophgo,sg2044-dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/sophgo,sg2044-dwmac.yaml
@@ -52,6 +52,9 @@ properties:
   interrupt-names:
     maxItems: 1
 
+  power-domains:
+    maxItems: 1
+
   resets:
     maxItems: 1
 
diff --git a/Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml b/Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml
index 313a15331661208a1fa64386739d87a4f11b7e20..8a68c6d7b5c6d6629a780d002299d767088def77 100644
--- a/Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml
@@ -71,6 +71,9 @@ properties:
       The argument one is the offset of phy mode selection, the
       argument two is the shift of phy mode selection.
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
diff --git a/Documentation/devicetree/bindings/net/stm32-dwmac.yaml b/Documentation/devicetree/bindings/net/stm32-dwmac.yaml
index 987254900d0da7aab81237f20b1540ad8a17bd21..29b878079ff0c1a0ef95fc63f2035f478ee039b2 100644
--- a/Documentation/devicetree/bindings/net/stm32-dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/stm32-dwmac.yaml
@@ -121,6 +121,9 @@ properties:
     minItems: 1
     maxItems: 2
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - clocks
diff --git a/Documentation/devicetree/bindings/net/tesla,fsd-ethqos.yaml b/Documentation/devicetree/bindings/net/tesla,fsd-ethqos.yaml
index dd7481bb16e59982c26c1a54ae82b8cff85fdfe0..ad635529d676ed6b752ab3bde5152d5cbddcb519 100644
--- a/Documentation/devicetree/bindings/net/tesla,fsd-ethqos.yaml
+++ b/Documentation/devicetree/bindings/net/tesla,fsd-ethqos.yaml
@@ -67,6 +67,9 @@ properties:
       - rgmii-rxid
       - rgmii-txid
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
diff --git a/Documentation/devicetree/bindings/net/thead,th1520-gmac.yaml b/Documentation/devicetree/bindings/net/thead,th1520-gmac.yaml
index b3492a9aa4effa73fadf92a63a76ba8bb65a8769..c859f8bb5d582af8b8782f2f89ab5e6ee3d7a46c 100644
--- a/Documentation/devicetree/bindings/net/thead,th1520-gmac.yaml
+++ b/Documentation/devicetree/bindings/net/thead,th1520-gmac.yaml
@@ -78,6 +78,9 @@ properties:
     items:
       - const: macirq
 
+  power-domains:
+    maxItems: 1
+
 required:
   - clocks
   - clock-names
diff --git a/Documentation/devicetree/bindings/net/toshiba,visconti-dwmac.yaml b/Documentation/devicetree/bindings/net/toshiba,visconti-dwmac.yaml
index f0f32e18fc8550e6f63b87b60a095972453836c9..efa39eab0256a1102b01872bd848749788c9b4e8 100644
--- a/Documentation/devicetree/bindings/net/toshiba,visconti-dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/toshiba,visconti-dwmac.yaml
@@ -48,6 +48,9 @@ properties:
   interrupt-names:
     const: macirq
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
diff --git a/MAINTAINERS b/MAINTAINERS
index 38383f9d8a31e28c64447032d1052827dd5d3ea5..67175e31be5ac94d9e590f48e0d97b1cbbf69b83 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -21232,6 +21232,7 @@ M:	Vinod Koul <vkoul at kernel.org>
 L:	netdev at vger.kernel.org
 L:	linux-arm-msm at vger.kernel.org
 S:	Maintained
+F:	Documentation/devicetree/bindings/net/qcom,ethqos-scmi.yaml
 F:	Documentation/devicetree/bindings/net/qcom,ethqos.yaml
 F:	drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
 

-- 
2.51.0



From brgl at bgdev.pl  Tue Nov  4 05:08:53 2025
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Tue, 04 Nov 2025 14:08:53 +0100
Subject: [PATCH v4 2/8] net: stmmac: qcom-ethqos: use generic device
 properties
In-Reply-To: <20251104-qcom-sa8255p-emac-v4-0-f76660087cea@linaro.org>
References: <20251104-qcom-sa8255p-emac-v4-0-f76660087cea@linaro.org>
Message-ID: <20251104-qcom-sa8255p-emac-v4-2-f76660087cea@linaro.org>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

In order to drop the dependency on CONFIG_OF, convert all device property
getters from OF-specific to generic device properties and stop pulling
in any linux/of.h symbols.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 drivers/net/ethernet/stmicro/stmmac/Kconfig             | 2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 9 ++++-----
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
index 87c5bea6c2a243f3be998b2c3935bc1dc23bfe22..22d0eaab35eaffac0bca58f8625ecc5c955b6631 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -135,7 +135,7 @@ config DWMAC_MESON
 config DWMAC_QCOM_ETHQOS
 	tristate "Qualcomm ETHQOS support"
 	default ARCH_QCOM
-	depends on OF && (ARCH_QCOM || COMPILE_TEST)
+	depends on ARCH_QCOM || COMPILE_TEST
 	help
 	  Support for the Qualcomm ETHQOS core.
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 1a616a71c36ace29a74a0aa23fc8173443aa49a5..8578a2df8cf0d1d8808bcf7e7b57c93eb14c87db 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -1,8 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0
 // Copyright (c) 2018-19, Linaro Limited
 
+#include <linux/mod_devicetable.h>
 #include <linux/module.h>
-#include <linux/of.h>
 #include <linux/of_net.h>
 #include <linux/platform_device.h>
 #include <linux/phy.h>
@@ -748,7 +748,6 @@ static void ethqos_ptp_clk_freq_config(struct stmmac_priv *priv)
 
 static int qcom_ethqos_probe(struct platform_device *pdev)
 {
-	struct device_node *np = pdev->dev.of_node;
 	const struct ethqos_emac_driver_data *data;
 	struct plat_stmmacenet_data *plat_dat;
 	struct stmmac_resources stmmac_res;
@@ -799,7 +798,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 
 	ethqos->mac_base = stmmac_res.addr;
 
-	data = of_device_get_match_data(dev);
+	data = device_get_match_data(dev);
 	ethqos->por = data->por;
 	ethqos->num_por = data->num_por;
 	ethqos->rgmii_config_loopback_en = data->rgmii_config_loopback_en;
@@ -836,9 +835,9 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 	if (ethqos->has_emac_ge_3)
 		plat_dat->dwmac4_addrs = &data->dwmac4_addrs;
 	plat_dat->pmt = 1;
-	if (of_property_read_bool(np, "snps,tso"))
+	if (device_property_present(dev, "snps,tso"))
 		plat_dat->flags |= STMMAC_FLAG_TSO_EN;
-	if (of_device_is_compatible(np, "qcom,qcs404-ethqos"))
+	if (device_is_compatible(dev, "qcom,qcs404-ethqos"))
 		plat_dat->flags |= STMMAC_FLAG_RX_CLK_RUNS_IN_LPI;
 	if (data->dma_addr_width)
 		plat_dat->host_dma_width = data->dma_addr_width;

-- 
2.51.0



From brgl at bgdev.pl  Tue Nov  4 05:08:54 2025
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Tue, 04 Nov 2025 14:08:54 +0100
Subject: [PATCH v4 3/8] net: stmmac: qcom-ethqos: improve typing in devres
 callback
In-Reply-To: <20251104-qcom-sa8255p-emac-v4-0-f76660087cea@linaro.org>
References: <20251104-qcom-sa8255p-emac-v4-0-f76660087cea@linaro.org>
Message-ID: <20251104-qcom-sa8255p-emac-v4-3-f76660087cea@linaro.org>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

It's bad practice to just directly pass void pointers to functions which
expect concrete types. Make it more clear what type ethqos_clks_config()
expects.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 8578a2df8cf0d1d8808bcf7e7b57c93eb14c87db..8493131ca32f5c6ca7e1654da0bbf4ffa1eefa4e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -726,7 +726,9 @@ static int ethqos_clks_config(void *priv, bool enabled)
 
 static void ethqos_clks_disable(void *data)
 {
-	ethqos_clks_config(data, false);
+	struct qcom_ethqos *ethqos = data;
+
+	ethqos_clks_config(ethqos, false);
 }
 
 static void ethqos_ptp_clk_freq_config(struct stmmac_priv *priv)

-- 
2.51.0



From brgl at bgdev.pl  Tue Nov  4 05:08:55 2025
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Tue, 04 Nov 2025 14:08:55 +0100
Subject: [PATCH v4 4/8] net: stmmac: qcom-ethqos: wrap emac driver data in
 additional structure
In-Reply-To: <20251104-qcom-sa8255p-emac-v4-0-f76660087cea@linaro.org>
References: <20251104-qcom-sa8255p-emac-v4-0-f76660087cea@linaro.org>
Message-ID: <20251104-qcom-sa8255p-emac-v4-4-f76660087cea@linaro.org>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

As the first step in enabling power domain support in the driver, we'll
split the device match data and runtime data structures into their
general and power-management-specific parts. To allow that: first wrap
the emac driver data in another layer which will later be expanded.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 .../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c    | 51 ++++++++++++++++------
 1 file changed, 37 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 8493131ca32f5c6ca7e1654da0bbf4ffa1eefa4e..9cafe101049d5412d649b3beaca350c497ffc981 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -97,6 +97,10 @@ struct ethqos_emac_driver_data {
 	bool needs_sgmii_loopback;
 };
 
+struct ethqos_emac_match_data {
+	const struct ethqos_emac_driver_data *drv_data;
+};
+
 struct qcom_ethqos {
 	struct platform_device *pdev;
 	void __iomem *rgmii_base;
@@ -214,6 +218,10 @@ static const struct ethqos_emac_driver_data emac_v2_3_0_data = {
 	.has_emac_ge_3 = false,
 };
 
+static const struct ethqos_emac_match_data emac_qcs404_data = {
+	.drv_data = &emac_v2_3_0_data,
+};
+
 static const struct ethqos_emac_por emac_v2_1_0_por[] = {
 	{ .offset = RGMII_IO_MACRO_CONFIG,	.value = 0x40C01343 },
 	{ .offset = SDCC_HC_REG_DLL_CONFIG,	.value = 0x2004642C },
@@ -230,6 +238,10 @@ static const struct ethqos_emac_driver_data emac_v2_1_0_data = {
 	.has_emac_ge_3 = false,
 };
 
+static const struct ethqos_emac_match_data emac_sm8150_data = {
+	.drv_data = &emac_v2_1_0_data,
+};
+
 static const struct ethqos_emac_por emac_v3_0_0_por[] = {
 	{ .offset = RGMII_IO_MACRO_CONFIG,	.value = 0x40c01343 },
 	{ .offset = SDCC_HC_REG_DLL_CONFIG,	.value = 0x2004642c },
@@ -262,6 +274,10 @@ static const struct ethqos_emac_driver_data emac_v3_0_0_data = {
 	},
 };
 
+static const struct ethqos_emac_match_data emac_sc8280xp_data = {
+	.drv_data = &emac_v3_0_0_data,
+};
+
 static const struct ethqos_emac_por emac_v4_0_0_por[] = {
 	{ .offset = RGMII_IO_MACRO_CONFIG,	.value = 0x40c01343 },
 	{ .offset = SDCC_HC_REG_DLL_CONFIG,	.value = 0x2004642c },
@@ -297,6 +313,10 @@ static const struct ethqos_emac_driver_data emac_v4_0_0_data = {
 	},
 };
 
+static const struct ethqos_emac_match_data emac_sa8775p_data = {
+	.drv_data = &emac_v4_0_0_data,
+};
+
 static int ethqos_dll_configure(struct qcom_ethqos *ethqos)
 {
 	struct device *dev = &ethqos->pdev->dev;
@@ -750,7 +770,8 @@ static void ethqos_ptp_clk_freq_config(struct stmmac_priv *priv)
 
 static int qcom_ethqos_probe(struct platform_device *pdev)
 {
-	const struct ethqos_emac_driver_data *data;
+	const struct ethqos_emac_driver_data *drv_data;
+	const struct ethqos_emac_match_data *data;
 	struct plat_stmmacenet_data *plat_dat;
 	struct stmmac_resources stmmac_res;
 	struct device *dev = &pdev->dev;
@@ -801,13 +822,15 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 	ethqos->mac_base = stmmac_res.addr;
 
 	data = device_get_match_data(dev);
-	ethqos->por = data->por;
-	ethqos->num_por = data->num_por;
-	ethqos->rgmii_config_loopback_en = data->rgmii_config_loopback_en;
-	ethqos->has_emac_ge_3 = data->has_emac_ge_3;
-	ethqos->needs_sgmii_loopback = data->needs_sgmii_loopback;
+	drv_data = data->drv_data;
 
-	ethqos->link_clk = devm_clk_get(dev, data->link_clk_name ?: "rgmii");
+	ethqos->por = drv_data->por;
+	ethqos->num_por = drv_data->num_por;
+	ethqos->rgmii_config_loopback_en = drv_data->rgmii_config_loopback_en;
+	ethqos->has_emac_ge_3 = drv_data->has_emac_ge_3;
+	ethqos->needs_sgmii_loopback = drv_data->needs_sgmii_loopback;
+
+	ethqos->link_clk = devm_clk_get(dev, drv_data->link_clk_name ?: "rgmii");
 	if (IS_ERR(ethqos->link_clk))
 		return dev_err_probe(dev, PTR_ERR(ethqos->link_clk),
 				     "Failed to get link_clk\n");
@@ -835,14 +858,14 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 	plat_dat->ptp_clk_freq_config = ethqos_ptp_clk_freq_config;
 	plat_dat->core_type = DWMAC_CORE_GMAC4;
 	if (ethqos->has_emac_ge_3)
-		plat_dat->dwmac4_addrs = &data->dwmac4_addrs;
+		plat_dat->dwmac4_addrs = &drv_data->dwmac4_addrs;
 	plat_dat->pmt = 1;
 	if (device_property_present(dev, "snps,tso"))
 		plat_dat->flags |= STMMAC_FLAG_TSO_EN;
 	if (device_is_compatible(dev, "qcom,qcs404-ethqos"))
 		plat_dat->flags |= STMMAC_FLAG_RX_CLK_RUNS_IN_LPI;
-	if (data->dma_addr_width)
-		plat_dat->host_dma_width = data->dma_addr_width;
+	if (drv_data->dma_addr_width)
+		plat_dat->host_dma_width = drv_data->dma_addr_width;
 
 	if (ethqos->serdes_phy) {
 		plat_dat->serdes_powerup = qcom_ethqos_serdes_powerup;
@@ -857,10 +880,10 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 }
 
 static const struct of_device_id qcom_ethqos_match[] = {
-	{ .compatible = "qcom,qcs404-ethqos", .data = &emac_v2_3_0_data},
-	{ .compatible = "qcom,sa8775p-ethqos", .data = &emac_v4_0_0_data},
-	{ .compatible = "qcom,sc8280xp-ethqos", .data = &emac_v3_0_0_data},
-	{ .compatible = "qcom,sm8150-ethqos", .data = &emac_v2_1_0_data},
+	{ .compatible = "qcom,qcs404-ethqos", .data = &emac_qcs404_data},
+	{ .compatible = "qcom,sa8775p-ethqos", .data = &emac_sa8775p_data},
+	{ .compatible = "qcom,sc8280xp-ethqos", .data = &emac_sc8280xp_data},
+	{ .compatible = "qcom,sm8150-ethqos", .data = &emac_sm8150_data},
 	{ }
 };
 MODULE_DEVICE_TABLE(of, qcom_ethqos_match);

-- 
2.51.0



From brgl at bgdev.pl  Tue Nov  4 05:08:56 2025
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Tue, 04 Nov 2025 14:08:56 +0100
Subject: [PATCH v4 5/8] net: stmmac: qcom-ethqos: split power management
 fields into a separate structure
In-Reply-To: <20251104-qcom-sa8255p-emac-v4-0-f76660087cea@linaro.org>
References: <20251104-qcom-sa8255p-emac-v4-0-f76660087cea@linaro.org>
Message-ID: <20251104-qcom-sa8255p-emac-v4-5-f76660087cea@linaro.org>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

Now that we have a separate wrapper for device match data, let's extend
this structure with a pointer to the structure containing fields related
to power-management only. This is done because a device may have the
same device settings but different power management mode (e.g.: firmware
vs manual).

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 .../net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c   | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 9cafe101049d5412d649b3beaca350c497ffc981..1f00556bbad997e2ec76b521cffe2eb14fabb79e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -91,14 +91,18 @@ struct ethqos_emac_driver_data {
 	unsigned int num_por;
 	bool rgmii_config_loopback_en;
 	bool has_emac_ge_3;
-	const char *link_clk_name;
 	u32 dma_addr_width;
 	struct dwmac4_addrs dwmac4_addrs;
 	bool needs_sgmii_loopback;
 };
 
+struct ethqos_emac_pm_data {
+	const char *link_clk_name;
+};
+
 struct ethqos_emac_match_data {
 	const struct ethqos_emac_driver_data *drv_data;
+	const struct ethqos_emac_pm_data *pm_data;
 };
 
 struct qcom_ethqos {
@@ -292,7 +296,6 @@ static const struct ethqos_emac_driver_data emac_v4_0_0_data = {
 	.num_por = ARRAY_SIZE(emac_v4_0_0_por),
 	.rgmii_config_loopback_en = false,
 	.has_emac_ge_3 = true,
-	.link_clk_name = "phyaux",
 	.needs_sgmii_loopback = true,
 	.dma_addr_width = 36,
 	.dwmac4_addrs = {
@@ -313,8 +316,13 @@ static const struct ethqos_emac_driver_data emac_v4_0_0_data = {
 	},
 };
 
+static const struct ethqos_emac_pm_data emac_sa8775p_pm_data = {
+	.link_clk_name = "phyaux",
+};
+
 static const struct ethqos_emac_match_data emac_sa8775p_data = {
 	.drv_data = &emac_v4_0_0_data,
+	.pm_data = &emac_sa8775p_pm_data,
 };
 
 static int ethqos_dll_configure(struct qcom_ethqos *ethqos)
@@ -771,11 +779,13 @@ static void ethqos_ptp_clk_freq_config(struct stmmac_priv *priv)
 static int qcom_ethqos_probe(struct platform_device *pdev)
 {
 	const struct ethqos_emac_driver_data *drv_data;
+	const struct ethqos_emac_pm_data *pm_data;
 	const struct ethqos_emac_match_data *data;
 	struct plat_stmmacenet_data *plat_dat;
 	struct stmmac_resources stmmac_res;
 	struct device *dev = &pdev->dev;
 	struct qcom_ethqos *ethqos;
+	const char *clk_name;
 	int ret, i;
 
 	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
@@ -823,6 +833,9 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 
 	data = device_get_match_data(dev);
 	drv_data = data->drv_data;
+	pm_data = data->pm_data;
+	clk_name = pm_data && pm_data->link_clk_name ?
+				pm_data->link_clk_name : "rgmii";
 
 	ethqos->por = drv_data->por;
 	ethqos->num_por = drv_data->num_por;
@@ -830,7 +843,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 	ethqos->has_emac_ge_3 = drv_data->has_emac_ge_3;
 	ethqos->needs_sgmii_loopback = drv_data->needs_sgmii_loopback;
 
-	ethqos->link_clk = devm_clk_get(dev, drv_data->link_clk_name ?: "rgmii");
+	ethqos->link_clk = devm_clk_get(dev, clk_name);
 	if (IS_ERR(ethqos->link_clk))
 		return dev_err_probe(dev, PTR_ERR(ethqos->link_clk),
 				     "Failed to get link_clk\n");

-- 
2.51.0



From brgl at bgdev.pl  Tue Nov  4 05:08:57 2025
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Tue, 04 Nov 2025 14:08:57 +0100
Subject: [PATCH v4 6/8] net: stmmac: qcom-ethqos: split power management
 context into a separate struct
In-Reply-To: <20251104-qcom-sa8255p-emac-v4-0-f76660087cea@linaro.org>
References: <20251104-qcom-sa8255p-emac-v4-0-f76660087cea@linaro.org>
Message-ID: <20251104-qcom-sa8255p-emac-v4-6-f76660087cea@linaro.org>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

With match data split into general and power-management sections, let's
now do the same with runtime device data.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 .../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c    | 46 ++++++++++++----------
 1 file changed, 25 insertions(+), 21 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 1f00556bbad997e2ec76b521cffe2eb14fabb79e..09f122062dec87aa11804af2769ddff4964e6596 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -105,17 +105,21 @@ struct ethqos_emac_match_data {
 	const struct ethqos_emac_pm_data *pm_data;
 };
 
+struct ethqos_emac_pm_ctx {
+	struct clk *link_clk;
+	unsigned int link_clk_rate;
+	struct phy *serdes_phy;
+};
+
 struct qcom_ethqos {
 	struct platform_device *pdev;
 	void __iomem *rgmii_base;
 	void __iomem *mac_base;
 	int (*configure_func)(struct qcom_ethqos *ethqos, int speed);
 
-	unsigned int link_clk_rate;
-	struct clk *link_clk;
-	struct phy *serdes_phy;
-	int serdes_speed;
+	struct ethqos_emac_pm_ctx pm;
 	phy_interface_t phy_mode;
+	int serdes_speed;
 
 	const struct ethqos_emac_por *por;
 	unsigned int num_por;
@@ -181,9 +185,9 @@ ethqos_update_link_clk(struct qcom_ethqos *ethqos, int speed)
 
 	rate = rgmii_clock(speed);
 	if (rate > 0)
-		ethqos->link_clk_rate = rate * 2;
+		ethqos->pm.link_clk_rate = rate * 2;
 
-	clk_set_rate(ethqos->link_clk, ethqos->link_clk_rate);
+	clk_set_rate(ethqos->pm.link_clk, ethqos->pm.link_clk_rate);
 }
 
 static void
@@ -639,7 +643,7 @@ static int ethqos_configure_rgmii(struct qcom_ethqos *ethqos, int speed)
 static void ethqos_set_serdes_speed(struct qcom_ethqos *ethqos, int speed)
 {
 	if (ethqos->serdes_speed != speed) {
-		phy_set_speed(ethqos->serdes_phy, speed);
+		phy_set_speed(ethqos->pm.serdes_phy, speed);
 		ethqos->serdes_speed = speed;
 	}
 }
@@ -708,23 +712,23 @@ static int qcom_ethqos_serdes_powerup(struct net_device *ndev, void *priv)
 	struct qcom_ethqos *ethqos = priv;
 	int ret;
 
-	ret = phy_init(ethqos->serdes_phy);
+	ret = phy_init(ethqos->pm.serdes_phy);
 	if (ret)
 		return ret;
 
-	ret = phy_power_on(ethqos->serdes_phy);
+	ret = phy_power_on(ethqos->pm.serdes_phy);
 	if (ret)
 		return ret;
 
-	return phy_set_speed(ethqos->serdes_phy, ethqos->serdes_speed);
+	return phy_set_speed(ethqos->pm.serdes_phy, ethqos->serdes_speed);
 }
 
 static void qcom_ethqos_serdes_powerdown(struct net_device *ndev, void *priv)
 {
 	struct qcom_ethqos *ethqos = priv;
 
-	phy_power_off(ethqos->serdes_phy);
-	phy_exit(ethqos->serdes_phy);
+	phy_power_off(ethqos->pm.serdes_phy);
+	phy_exit(ethqos->pm.serdes_phy);
 }
 
 static int ethqos_clks_config(void *priv, bool enabled)
@@ -733,7 +737,7 @@ static int ethqos_clks_config(void *priv, bool enabled)
 	int ret = 0;
 
 	if (enabled) {
-		ret = clk_prepare_enable(ethqos->link_clk);
+		ret = clk_prepare_enable(ethqos->pm.link_clk);
 		if (ret) {
 			dev_err(&ethqos->pdev->dev, "link_clk enable failed\n");
 			return ret;
@@ -746,7 +750,7 @@ static int ethqos_clks_config(void *priv, bool enabled)
 		 */
 		ethqos_set_func_clk_en(ethqos);
 	} else {
-		clk_disable_unprepare(ethqos->link_clk);
+		clk_disable_unprepare(ethqos->pm.link_clk);
 	}
 
 	return ret;
@@ -843,9 +847,9 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 	ethqos->has_emac_ge_3 = drv_data->has_emac_ge_3;
 	ethqos->needs_sgmii_loopback = drv_data->needs_sgmii_loopback;
 
-	ethqos->link_clk = devm_clk_get(dev, clk_name);
-	if (IS_ERR(ethqos->link_clk))
-		return dev_err_probe(dev, PTR_ERR(ethqos->link_clk),
+	ethqos->pm.link_clk = devm_clk_get(dev, clk_name);
+	if (IS_ERR(ethqos->pm.link_clk))
+		return dev_err_probe(dev, PTR_ERR(ethqos->pm.link_clk),
 				     "Failed to get link_clk\n");
 
 	ret = ethqos_clks_config(ethqos, true);
@@ -856,9 +860,9 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	ethqos->serdes_phy = devm_phy_optional_get(dev, "serdes");
-	if (IS_ERR(ethqos->serdes_phy))
-		return dev_err_probe(dev, PTR_ERR(ethqos->serdes_phy),
+	ethqos->pm.serdes_phy = devm_phy_optional_get(dev, "serdes");
+	if (IS_ERR(ethqos->pm.serdes_phy))
+		return dev_err_probe(dev, PTR_ERR(ethqos->pm.serdes_phy),
 				     "Failed to get serdes phy\n");
 
 	ethqos->serdes_speed = SPEED_1000;
@@ -880,7 +884,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 	if (drv_data->dma_addr_width)
 		plat_dat->host_dma_width = drv_data->dma_addr_width;
 
-	if (ethqos->serdes_phy) {
+	if (ethqos->pm.serdes_phy) {
 		plat_dat->serdes_powerup = qcom_ethqos_serdes_powerup;
 		plat_dat->serdes_powerdown  = qcom_ethqos_serdes_powerdown;
 	}

-- 
2.51.0



From brgl at bgdev.pl  Tue Nov  4 05:08:58 2025
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Tue, 04 Nov 2025 14:08:58 +0100
Subject: [PATCH v4 7/8] net: stmmac: qcom-ethqos: define a callback for
 setting the serdes speed
In-Reply-To: <20251104-qcom-sa8255p-emac-v4-0-f76660087cea@linaro.org>
References: <20251104-qcom-sa8255p-emac-v4-0-f76660087cea@linaro.org>
Message-ID: <20251104-qcom-sa8255p-emac-v4-7-f76660087cea@linaro.org>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

Ahead of adding support for firmware driven power management, let's
allow different ways of setting the PHY speed. To that end create a
callback with a single implementation for now, that will be extended
later.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 09f122062dec87aa11804af2769ddff4964e6596..446f06b591a0b70992c7a431b56cf88c1b6718fd 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -120,6 +120,7 @@ struct qcom_ethqos {
 	struct ethqos_emac_pm_ctx pm;
 	phy_interface_t phy_mode;
 	int serdes_speed;
+	int (*set_serdes_speed)(struct qcom_ethqos *ethqos);
 
 	const struct ethqos_emac_por *por;
 	unsigned int num_por;
@@ -640,11 +641,16 @@ static int ethqos_configure_rgmii(struct qcom_ethqos *ethqos, int speed)
 	return 0;
 }
 
+static int ethqos_set_serdes_speed_phy(struct qcom_ethqos *ethqos)
+{
+	return phy_set_speed(ethqos->pm.serdes_phy, ethqos->serdes_speed);
+}
+
 static void ethqos_set_serdes_speed(struct qcom_ethqos *ethqos, int speed)
 {
 	if (ethqos->serdes_speed != speed) {
-		phy_set_speed(ethqos->pm.serdes_phy, speed);
 		ethqos->serdes_speed = speed;
+		ethqos->set_serdes_speed(ethqos);
 	}
 }
 
@@ -865,6 +871,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, PTR_ERR(ethqos->pm.serdes_phy),
 				     "Failed to get serdes phy\n");
 
+	ethqos->set_serdes_speed = ethqos_set_serdes_speed_phy;
 	ethqos->serdes_speed = SPEED_1000;
 	ethqos_update_link_clk(ethqos, SPEED_1000);
 	ethqos_set_func_clk_en(ethqos);

-- 
2.51.0



From brgl at bgdev.pl  Tue Nov  4 05:08:59 2025
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Tue, 04 Nov 2025 14:08:59 +0100
Subject: [PATCH v4 8/8] net: stmmac: qcom-ethqos: add support for sa8255p
In-Reply-To: <20251104-qcom-sa8255p-emac-v4-0-f76660087cea@linaro.org>
References: <20251104-qcom-sa8255p-emac-v4-0-f76660087cea@linaro.org>
Message-ID: <20251104-qcom-sa8255p-emac-v4-8-f76660087cea@linaro.org>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

Extend the driver to support a new model - sa8255p. Unlike the
previously supported variants, this one's power management is done in
the firmware using SCMI. This is modeled in linux using power domains so
add support for them.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 .../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c    | 230 ++++++++++++++++++---
 1 file changed, 201 insertions(+), 29 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 446f06b591a0b70992c7a431b56cf88c1b6718fd..d2922b4fb4bad1bb8dd77f1feaa7a260b97f0ae8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -7,6 +7,8 @@
 #include <linux/platform_device.h>
 #include <linux/phy.h>
 #include <linux/phy/phy.h>
+#include <linux/pm_opp.h>
+#include <linux/pm_domain.h>
 
 #include "stmmac.h"
 #include "stmmac_platform.h"
@@ -81,6 +83,13 @@
 
 #define SGMII_10M_RX_CLK_DVDR			0x31
 
+enum ethqos_pd_selector {
+	ETHQOS_PD_CORE = 0,
+	ETHQOS_PD_MDIO,
+	ETHQOS_PD_SERDES,
+	ETHQOS_NUM_PDS,
+};
+
 struct ethqos_emac_por {
 	unsigned int offset;
 	unsigned int value;
@@ -98,6 +107,9 @@ struct ethqos_emac_driver_data {
 
 struct ethqos_emac_pm_data {
 	const char *link_clk_name;
+	bool use_domains;
+	struct dev_pm_domain_attach_data pd;
+	unsigned int clk_ptp_rate;
 };
 
 struct ethqos_emac_match_data {
@@ -111,13 +123,20 @@ struct ethqos_emac_pm_ctx {
 	struct phy *serdes_phy;
 };
 
+struct ethqos_emac_pd_ctx {
+	struct dev_pm_domain_list *pd_list;
+};
+
 struct qcom_ethqos {
 	struct platform_device *pdev;
 	void __iomem *rgmii_base;
 	void __iomem *mac_base;
 	int (*configure_func)(struct qcom_ethqos *ethqos, int speed);
 
-	struct ethqos_emac_pm_ctx pm;
+	union {
+		struct ethqos_emac_pm_ctx pm;
+		struct ethqos_emac_pd_ctx pd;
+	};
 	phy_interface_t phy_mode;
 	int serdes_speed;
 	int (*set_serdes_speed)(struct qcom_ethqos *ethqos);
@@ -330,6 +349,25 @@ static const struct ethqos_emac_match_data emac_sa8775p_data = {
 	.pm_data = &emac_sa8775p_pm_data,
 };
 
+static const char * const emac_sa8255p_pd_names[] = {
+	"core", "mdio", "serdes"
+};
+
+static const struct ethqos_emac_pm_data emac_sa8255p_pm_data = {
+	.pd = {
+		.pd_flags = PD_FLAG_NO_DEV_LINK,
+		.pd_names = emac_sa8255p_pd_names,
+		.num_pd_names = ETHQOS_NUM_PDS,
+	},
+	.use_domains = true,
+	.clk_ptp_rate = 230400000,
+};
+
+static const struct ethqos_emac_match_data emac_sa8255p_data = {
+	.drv_data = &emac_v4_0_0_data,
+	.pm_data = &emac_sa8255p_pm_data,
+};
+
 static int ethqos_dll_configure(struct qcom_ethqos *ethqos)
 {
 	struct device *dev = &ethqos->pdev->dev;
@@ -411,6 +449,28 @@ static int ethqos_dll_configure(struct qcom_ethqos *ethqos)
 	return 0;
 }
 
+static int qcom_ethqos_domain_on(struct qcom_ethqos *ethqos,
+				 enum ethqos_pd_selector sel)
+{
+	struct device *dev = ethqos->pd.pd_list->pd_devs[sel];
+	int ret;
+
+	ret = pm_runtime_resume_and_get(dev);
+	if (ret < 0)
+		dev_err(&ethqos->pdev->dev,
+			"Failed to enable the power domain for %s\n",
+			dev_name(dev));
+	return ret;
+}
+
+static void qcom_ethqos_domain_off(struct qcom_ethqos *ethqos,
+				   enum ethqos_pd_selector sel)
+{
+	struct device *dev = ethqos->pd.pd_list->pd_devs[sel];
+
+	pm_runtime_put_sync(dev);
+}
+
 static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos, int speed)
 {
 	struct device *dev = &ethqos->pdev->dev;
@@ -646,6 +706,13 @@ static int ethqos_set_serdes_speed_phy(struct qcom_ethqos *ethqos)
 	return phy_set_speed(ethqos->pm.serdes_phy, ethqos->serdes_speed);
 }
 
+static int ethqos_set_serdes_speed_pd(struct qcom_ethqos *ethqos)
+{
+	struct device *dev = ethqos->pd.pd_list->pd_devs[ETHQOS_PD_SERDES];
+
+	return dev_pm_opp_set_level(dev, ethqos->serdes_speed);
+}
+
 static void ethqos_set_serdes_speed(struct qcom_ethqos *ethqos, int speed)
 {
 	if (ethqos->serdes_speed != speed) {
@@ -737,6 +804,27 @@ static void qcom_ethqos_serdes_powerdown(struct net_device *ndev, void *priv)
 	phy_exit(ethqos->pm.serdes_phy);
 }
 
+static int qcom_ethqos_pd_serdes_powerup(struct net_device *ndev, void *priv)
+{
+	struct qcom_ethqos *ethqos = priv;
+	struct device *dev = ethqos->pd.pd_list->pd_devs[ETHQOS_PD_SERDES];
+	int ret;
+
+	ret = qcom_ethqos_domain_on(ethqos, ETHQOS_PD_SERDES);
+	if (ret < 0)
+		return ret;
+
+	return dev_pm_opp_set_level(dev, ethqos->serdes_speed);
+}
+
+static void qcom_ethqos_pd_serdes_powerdown(struct net_device *ndev, void *priv)
+{
+	struct qcom_ethqos *ethqos = priv;
+
+	/* TODO set level */
+	qcom_ethqos_domain_off(ethqos, ETHQOS_PD_SERDES);
+}
+
 static int ethqos_clks_config(void *priv, bool enabled)
 {
 	struct qcom_ethqos *ethqos = priv;
@@ -769,6 +857,61 @@ static void ethqos_clks_disable(void *data)
 	ethqos_clks_config(ethqos, false);
 }
 
+static int ethqos_pd_clks_config(void *priv, bool enabled)
+{
+	struct qcom_ethqos *ethqos = priv;
+	int ret = 0;
+
+	if (enabled) {
+		ret = qcom_ethqos_domain_on(ethqos, ETHQOS_PD_MDIO);
+		if (ret < 0) {
+			dev_err(&ethqos->pdev->dev,
+				"Failed to enable the MDIO power domain\n");
+			return ret;
+		}
+
+		ethqos_set_func_clk_en(ethqos);
+	} else {
+		qcom_ethqos_domain_off(ethqos, ETHQOS_PD_MDIO);
+	}
+
+	return ret;
+}
+
+static int qcom_ethqos_pd_init(struct platform_device *pdev, void *priv)
+{
+	struct qcom_ethqos *ethqos = priv;
+	int ret;
+
+	/*
+	 * Enable functional clock to prevent DMA reset after timeout due
+	 * to no PHY clock being enabled after the hardware block has been
+	 * power cycled. The actual configuration will be adjusted once
+	 * ethqos_fix_mac_speed() is called.
+	 */
+	ethqos_set_func_clk_en(ethqos);
+
+	ret = qcom_ethqos_domain_on(ethqos, ETHQOS_PD_CORE);
+	if (ret)
+		return ret;
+
+	ret = qcom_ethqos_domain_on(ethqos, ETHQOS_PD_MDIO);
+	if (ret) {
+		qcom_ethqos_domain_off(ethqos, ETHQOS_PD_CORE);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void qcom_ethqos_pd_exit(struct platform_device *pdev, void *data)
+{
+	struct qcom_ethqos *ethqos = data;
+
+	qcom_ethqos_domain_off(ethqos, ETHQOS_PD_MDIO);
+	qcom_ethqos_domain_off(ethqos, ETHQOS_PD_CORE);
+}
+
 static void ethqos_ptp_clk_freq_config(struct stmmac_priv *priv)
 {
 	struct plat_stmmacenet_data *plat_dat = priv->plat;
@@ -809,8 +952,6 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 				     "dt configuration failed\n");
 	}
 
-	plat_dat->clks_config = ethqos_clks_config;
-
 	ethqos = devm_kzalloc(dev, sizeof(*ethqos), GFP_KERNEL);
 	if (!ethqos)
 		return -ENOMEM;
@@ -852,28 +993,63 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 	ethqos->rgmii_config_loopback_en = drv_data->rgmii_config_loopback_en;
 	ethqos->has_emac_ge_3 = drv_data->has_emac_ge_3;
 	ethqos->needs_sgmii_loopback = drv_data->needs_sgmii_loopback;
-
-	ethqos->pm.link_clk = devm_clk_get(dev, clk_name);
-	if (IS_ERR(ethqos->pm.link_clk))
-		return dev_err_probe(dev, PTR_ERR(ethqos->pm.link_clk),
-				     "Failed to get link_clk\n");
-
-	ret = ethqos_clks_config(ethqos, true);
-	if (ret)
-		return ret;
-
-	ret = devm_add_action_or_reset(dev, ethqos_clks_disable, ethqos);
-	if (ret)
-		return ret;
-
-	ethqos->pm.serdes_phy = devm_phy_optional_get(dev, "serdes");
-	if (IS_ERR(ethqos->pm.serdes_phy))
-		return dev_err_probe(dev, PTR_ERR(ethqos->pm.serdes_phy),
-				     "Failed to get serdes phy\n");
-
-	ethqos->set_serdes_speed = ethqos_set_serdes_speed_phy;
 	ethqos->serdes_speed = SPEED_1000;
-	ethqos_update_link_clk(ethqos, SPEED_1000);
+
+	if (pm_data && pm_data->use_domains) {
+		ethqos->set_serdes_speed = ethqos_set_serdes_speed_pd;
+
+		ret = devm_pm_domain_attach_list(dev, &pm_data->pd,
+						 &ethqos->pd.pd_list);
+		if (ret < 0)
+			return dev_err_probe(dev, ret, "Failed to attach power domains\n");
+
+		plat_dat->clks_config = ethqos_pd_clks_config;
+		plat_dat->serdes_powerup = qcom_ethqos_pd_serdes_powerup;
+		plat_dat->serdes_powerdown = qcom_ethqos_pd_serdes_powerdown;
+		plat_dat->exit = qcom_ethqos_pd_exit;
+		plat_dat->init = qcom_ethqos_pd_init;
+		plat_dat->clk_ptp_rate = pm_data->clk_ptp_rate;
+
+		ret = qcom_ethqos_pd_init(pdev, ethqos);
+		if (ret)
+			return ret;
+
+		ret = qcom_ethqos_domain_on(ethqos, ETHQOS_PD_SERDES);
+		if (ret)
+			return dev_err_probe(dev, ret,
+					     "Failed to enable the serdes power domain\n");
+	} else {
+		ethqos->set_serdes_speed = ethqos_set_serdes_speed_phy;
+
+		ethqos->pm.link_clk = devm_clk_get(dev, clk_name);
+		if (IS_ERR(ethqos->pm.link_clk))
+			return dev_err_probe(dev, PTR_ERR(ethqos->pm.link_clk),
+					     "Failed to get link_clk\n");
+
+		ret = ethqos_clks_config(ethqos, true);
+		if (ret)
+			return ret;
+
+		ret = devm_add_action_or_reset(dev, ethqos_clks_disable, ethqos);
+		if (ret)
+			return ret;
+
+		ethqos->pm.serdes_phy = devm_phy_optional_get(dev, "serdes");
+		if (IS_ERR(ethqos->pm.serdes_phy))
+			return dev_err_probe(dev, PTR_ERR(ethqos->pm.serdes_phy),
+					     "Failed to get serdes phy\n");
+
+		ethqos_update_link_clk(ethqos, SPEED_1000);
+
+		plat_dat->clks_config = ethqos_clks_config;
+		plat_dat->ptp_clk_freq_config = ethqos_ptp_clk_freq_config;
+
+		if (ethqos->pm.serdes_phy) {
+			plat_dat->serdes_powerup = qcom_ethqos_serdes_powerup;
+			plat_dat->serdes_powerdown  = qcom_ethqos_serdes_powerdown;
+		}
+	}
+
 	ethqos_set_func_clk_en(ethqos);
 
 	plat_dat->bsp_priv = ethqos;
@@ -891,11 +1067,6 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 	if (drv_data->dma_addr_width)
 		plat_dat->host_dma_width = drv_data->dma_addr_width;
 
-	if (ethqos->pm.serdes_phy) {
-		plat_dat->serdes_powerup = qcom_ethqos_serdes_powerup;
-		plat_dat->serdes_powerdown  = qcom_ethqos_serdes_powerdown;
-	}
-
 	/* Enable TSO on queue0 and enable TBS on rest of the queues */
 	for (i = 1; i < plat_dat->tx_queues_to_use; i++)
 		plat_dat->tx_queues_cfg[i].tbs_en = 1;
@@ -905,6 +1076,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 
 static const struct of_device_id qcom_ethqos_match[] = {
 	{ .compatible = "qcom,qcs404-ethqos", .data = &emac_qcs404_data},
+	{ .compatible = "qcom,sa8255p-ethqos", .data = &emac_sa8255p_data},
 	{ .compatible = "qcom,sa8775p-ethqos", .data = &emac_sa8775p_data},
 	{ .compatible = "qcom,sc8280xp-ethqos", .data = &emac_sc8280xp_data},
 	{ .compatible = "qcom,sm8150-ethqos", .data = &emac_sm8150_data},

-- 
2.51.0



From dsimic at manjaro.org  Tue Nov  4 06:15:10 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Tue, 04 Nov 2025 15:15:10 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= pwm-fan overlay for NanoPC-T6
Message-ID: <232be108-ea84-2808-77b9-ff46d2b8baf7@manjaro.org>

(Resending because the original message ended up on some spam lists,
seemingly as a result of some UTF-8 characters in the subject.)

Hello Hugh,

On Saturday, November 01, 2025 14:14 CET, Hugh Cole-Baker <sigmaris at gmail.com> wrote:
> On 01/11/2025 11:44, Heiko Stuebner wrote:
> > Personally, I'm more on the less complication side.
> > 
> > I.e. if there is an actual fan-connector on the board we should describe
> > it as such.
> > 
> > Overlays I see for things where you attach hats to generic pin headers
> > to create specific functionality on top of a generic interface.
> > 
> > But if the board itself has an actual fan header, it should be described
> > as such. Because that then _is_ the standard use of that.
> 
> The board does have a fan connector, just no fan by default. But anyway,
> since it sounds like the preferred approach I'll send a v2 which puts the
> fan into the base board .dts.
> 
> Dragan, you mentioned there's no need for more than 2 trip points - if
> I remove the trip points between "SoC is warm, start fan at slow speed"
> and "SoC is v. hot, run fan at full speed" is the OS/kernel expected to
> interpolate between those 2 trip points (if you have a link to docs or
> code about this it'd be interesting, I couldn't find anything in the
> dt-bindings)?

True, that isn't described in the bindings, because it basically
doesn't belong there.  Thus, the most specific description of the
associated cooling stuff, as provided by the bindings, is the
following excerpt from Documentation/devicetree/bindings/thermal/
thermal-zones.yaml:

  209 cooling-device:
  210   $ref: /schemas/types.yaml#/definitions/phandle-array
  211   description:
  212     A list of cooling device phandles along with the minimum
  213     and maximum cooling state specifiers for each cooling
  214     device. Using the THERMAL_NO_LIMIT (-1UL) constant in the
  215     cooling-device phandle limit specifier lets the framework
  216     use the minimum and maximum cooling state for that cooling
  217     device automatically.

That's where the cooling hardware description ends, so that's also
where the associated binding ends.  Everything else belongs to the
thermal governors, because they actually decide on how to best use
the available cooling features.

For example, the chain of events may look like this:

  (1) The rockchip_thermal_alarm_irq_thread() function, defined in
      drivers/thermal/rockchip_thermal.c, gets triggered by TSADC
      within the parameters of DT-defined "active" trip types

  (2) It calls the thermal_zone_device_update() function defined
      in drivers/thermal/thermal_core.c

  (3) This ends up calling the step_wise_manage() function that's
      defined in drivers/thermal/gov_step_wise.c, which handles
      the previously triggered "active" trip

  (4) This calls the drivers/thermal/gov_step_wise.c's locally
      defined thermal_zone_trip_update() and get_target_state()
      functions, which end up ramping the fan speed up and down
      as needed, while respecting the upper and lower limits
      defined through the "cooling-device" DT map properties,
      which correspond to the "cooling-levels" defined in the
      DT fan property

Here's also an excerpt from drivers/thermal/gov_step_wise.c, which
confirms all this and explains it a bit further:

  113  /*
  114   * Throttling Logic: Use the trend of the thermal zone to throttle.
  115   * If the thermal zone is 'heating up', throttle all of the cooling
  116   * devices associated with each trip point by one step. If the zone
  117   * is 'cooling down', it brings back the performance of the devices
  118   * by one step.
  119   */

With all that in mind, the fan will ramp its speed up and down
nicely, according to the current temperature, with no need for
having multiple manually defined steps.

The intended benefit of having the two usual, distinct "active"
thermal trips and cooling maps is to lower the fan-induced noise
a bit while not affecting the cooling much.  This is all visible
in rk3399-rockpro64.dtsi, for example.



From krzk at kernel.org  Wed Nov  5 00:33:27 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 5 Nov 2025 09:33:27 +0100
Subject: [PATCH v4 1/8] dt-bindings: net: qcom: document the ethqos
 device for SCMI-based systems
In-Reply-To: <20251104-qcom-sa8255p-emac-v4-1-f76660087cea@linaro.org>
References: <20251104-qcom-sa8255p-emac-v4-0-f76660087cea@linaro.org>
 <20251104-qcom-sa8255p-emac-v4-1-f76660087cea@linaro.org>
Message-ID: <20251105-fat-aromatic-nightingale-1ef8ac@kuoka>

On Tue, Nov 04, 2025 at 02:08:52PM +0100, Bartosz Golaszewski wrote:
> diff --git a/Documentation/devicetree/bindings/net/qcom,ethqos-scmi.yaml b/Documentation/devicetree/bindings/net/qcom,ethqos-scmi.yaml
> new file mode 100644
> index 0000000000000000000000000000000000000000..ff70d785d326f39a8fe5698759c56ab2cb7f7eef
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/qcom,ethqos-scmi.yaml
> @@ -0,0 +1,97 @@
> +# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/net/qcom,ethqos-scmi.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Qualcomm Ethernet ETHQOS device (firmware managed)
> +
> +maintainers:
> +  - Bjorn Andersson <andersson at kernel.org>
> +  - Konrad Dybcio <konradybcio at kernel.org>
> +  - Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> +
> +description:
> +  dwmmac based Qualcomm ethernet devices which support Gigabit
> +  ethernet (version v2.3.0 and onwards) with clocks, interconnects, etc.
> +  managed by firmware
> +
> +allOf:
> +  - $ref: snps,dwmac.yaml#
> +
> +properties:
> +  compatible:
> +    const: qcom,sa8255p-ethqos
> +
> +  reg:
> +    maxItems: 2
> +
> +  reg-names:
> +    items:
> +      - const: stmmaceth
> +      - const: rgmii
> +
> +  interrupts:
> +    items:
> +      - description: Combined signal for various interrupt events
> +      - description: The interrupt that occurs when HW safety error triggered
> +
> +  interrupt-names:
> +    items:
> +      - const: macirq
> +      - const: sfty
> +
> +  power-domains:
> +    minItems: 3

You should have here both constraints - min and maxItems. Current code
works fine, but usually we want it to be explicit.

I found two more nits which I did not notice earlier, so when fixing
above please also:

1. Please name the file following compatible, so:
qcom,sa8255p-ethqos.yaml
(unless this was already discussed...)

> +        snps,tso;
> +        snps,pbl = <32>;
> +        rx-fifo-depth = <16384>;
> +        tx-fifo-depth = <16384>;
> +
> +        phy-handle = <&ethernet_phy>;
> +        phy-mode = "2500base-x";
> +
> +        snps,mtl-rx-config = <&mtl_rx_setup1>;
> +        snps,mtl-tx-config = <&mtl_tx_setup1>;
> +
> +        power-domains = <&scmi8_pd 0>, <&scmi8_pd 1>, <&scmi8_dvfs 0>;
> +        power-domain-names = "core", "mdio","serdes";

2. Missing space after ,


Best regards,
Krzysztof



From conor at kernel.org  Thu Nov  6 09:27:12 2025
From: conor at kernel.org (Conor Dooley)
Date: Thu, 6 Nov 2025 17:27:12 +0000
Subject: [PATCH 2/9] dt-bindings: phy: rockchip-inno-dsidphy: Add
 compatible for rk3506
In-Reply-To: <20251106020632.92-3-kernel@airkyi.com>
References: <20251106020632.92-1-kernel@airkyi.com>
 <20251106020632.92-3-kernel@airkyi.com>
Message-ID: <20251106-litigate-cultivate-75a4aac333c7@spud>

Acked-by: Conor Dooley <conor.dooley at microchip.com>
pw-bot: not-applicable
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251106/07defd53/attachment-0001.sig>

From conor at kernel.org  Thu Nov  6 09:27:29 2025
From: conor at kernel.org (Conor Dooley)
Date: Thu, 6 Nov 2025 17:27:29 +0000
Subject: [PATCH 4/9] dt-bindings: display: rockchip,vop: Add compatible
 for rk3506
In-Reply-To: <20251106020632.92-5-kernel@airkyi.com>
References: <20251106020632.92-1-kernel@airkyi.com>
 <20251106020632.92-5-kernel@airkyi.com>
Message-ID: <20251106-handwrite-dragging-3b3412f31f73@spud>

Acked-by: Conor Dooley <conor.dooley at microchip.com>
pw-bot: not-applicable
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251106/0311a410/attachment.sig>

From conor at kernel.org  Thu Nov  6 09:27:58 2025
From: conor at kernel.org (Conor Dooley)
Date: Thu, 6 Nov 2025 17:27:58 +0000
Subject: [PATCH 3/9] dt-bindings: display: rockchip,dw-mipi-dsi: Add
 compatible for rk3506
In-Reply-To: <20251106020632.92-4-kernel@airkyi.com>
References: <20251106020632.92-1-kernel@airkyi.com>
 <20251106020632.92-4-kernel@airkyi.com>
Message-ID: <20251106-watch-confining-6a3800cf81eb@spud>

Acked-by: Conor Dooley <conor.dooley at microchip.com>
pw-bot: not-applicable
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251106/0e94444c/attachment.sig>

From conor at kernel.org  Thu Nov  6 09:28:21 2025
From: conor at kernel.org (Conor Dooley)
Date: Thu, 6 Nov 2025 17:28:21 +0000
Subject: [PATCH 1/9] dt-bindings: ili9881c: Add compatible string for
 Wanchanglong w552946aaa
In-Reply-To: <20251106020632.92-2-kernel@airkyi.com>
References: <20251106020632.92-1-kernel@airkyi.com>
 <20251106020632.92-2-kernel@airkyi.com>
Message-ID: <20251106-kung-lunacy-c5d7abc9208d@spud>

Acked-by: Conor Dooley <conor.dooley at microchip.com>
pw-bot: not-applicable
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251106/9b007885/attachment.sig>

From macroalpha82 at gmail.com  Thu Nov  6 10:09:11 2025
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Thu,  6 Nov 2025 12:09:11 -0600
Subject: [PATCH 0/3] Add HDMI for Gameforce Ace
Message-ID: <20251106180914.768502-1-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

Add support for the micro HDMI port for the Gameforce Ace. This port does
not have a HPD pin so it requires making changes to the HDMI controller
to support this configuration.

Chris Morgan (3):
  dt-bindings: display: rockchip: Add no-hpd for dw-hdmi-qp controller
  drm/bridge: dw-hdmi-qp: Add support for missing HPD
  arm64: dts: rockchip: Add HDMI to Gameforce Ace

 .../rockchip/rockchip,rk3588-dw-hdmi-qp.yaml  |  6 ++
 .../dts/rockchip/rk3588s-gameforce-ace.dts    | 63 +++++++++++++++++++
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c  | 35 +++++++++--
 3 files changed, 100 insertions(+), 4 deletions(-)

-- 
2.43.0



From macroalpha82 at gmail.com  Thu Nov  6 10:09:12 2025
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Thu,  6 Nov 2025 12:09:12 -0600
Subject: [PATCH 1/3] dt-bindings: display: rockchip: Add no-hpd for dw-hdmi-qp controller
In-Reply-To: <20251106180914.768502-1-macroalpha82@gmail.com>
References: <20251106180914.768502-1-macroalpha82@gmail.com>
Message-ID: <20251106180914.768502-2-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

Add an attribute of "no-hpd" for the Rockchip dw-hdmi-qp controller.
This is used to describe implementations where the HPD pin is not
connected or used for other purposes, such as in the RK3588S based
Gameforce Ace which repurposed the GPIO for an additional face
button.

The "no-hpd" option was chosen to be consistent with other devices
which already define this parameter for broken or missing hpd
functionality.

Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
---
 .../display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml        | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml
index 96b4b088eebe..07342838cd52 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml
@@ -69,6 +69,12 @@ properties:
       - const: main
       - const: hpd
 
+  no-hpd:
+    type: boolean
+    description:
+      The HPD pin is not present or used for another purpose, and the EDID
+      must be polled instead to determine if a device is attached.
+
   phys:
     maxItems: 1
     description: The HDMI/eDP PHY
-- 
2.43.0



From macroalpha82 at gmail.com  Thu Nov  6 10:09:13 2025
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Thu,  6 Nov 2025 12:09:13 -0600
Subject: [PATCH 2/3] drm/bridge: dw-hdmi-qp: Add support for missing HPD
In-Reply-To: <20251106180914.768502-1-macroalpha82@gmail.com>
References: <20251106180914.768502-1-macroalpha82@gmail.com>
Message-ID: <20251106180914.768502-3-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

Add support for the dw-hdmi-qp driver to handle devices with missing
HPD pins.

Since in this situation we are now polling for the EDID data via i2c
change the error message to a debug message when we are unable to
complete an i2c read, as a disconnected device would otherwise fill
dmesg with i2c read errors.

Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 35 +++++++++++++++++---
 1 file changed, 31 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
index 39332c57f2c5..b221f797de3d 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
@@ -145,6 +145,7 @@ struct dw_hdmi_qp {
 	struct regmap *regm;
 
 	unsigned long tmds_char_rate;
+	bool no_hpd;
 };
 
 static void dw_hdmi_qp_write(struct dw_hdmi_qp *hdmi, unsigned int val,
@@ -520,6 +521,11 @@ static int dw_hdmi_qp_i2c_read(struct dw_hdmi_qp *hdmi,
 		i2c->is_regaddr = true;
 	}
 
+	/*
+	 * Mark errors as debug messages when using no_hpd so no device
+	 * attached does not fill up dmesg.
+	 */
+
 	while (length--) {
 		reinit_completion(&i2c->cmp);
 
@@ -535,14 +541,20 @@ static int dw_hdmi_qp_i2c_read(struct dw_hdmi_qp *hdmi,
 
 		stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10);
 		if (!stat) {
-			dev_err(hdmi->dev, "i2c read timed out\n");
+			if (hdmi->no_hpd)
+				dev_dbg(hdmi->dev, "i2c read timed out\n");
+			else
+				dev_err(hdmi->dev, "i2c read timed out\n");
 			dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0);
 			return -EAGAIN;
 		}
 
 		/* Check for error condition on the bus */
 		if (i2c->stat & I2CM_NACK_RCVD_IRQ) {
-			dev_err(hdmi->dev, "i2c read error\n");
+			if (hdmi->no_hpd)
+				dev_dbg(hdmi->dev, "i2c read error\n");
+			else
+				dev_err(hdmi->dev, "i2c read error\n");
 			dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0);
 			return -EIO;
 		}
@@ -879,6 +891,15 @@ static enum drm_connector_status
 dw_hdmi_qp_bridge_detect(struct drm_bridge *bridge, struct drm_connector *connector)
 {
 	struct dw_hdmi_qp *hdmi = bridge->driver_private;
+	const struct drm_edid *drm_edid;
+
+	if (hdmi->no_hpd) {
+		drm_edid = drm_edid_read_ddc(connector, bridge->ddc);
+		if (drm_edid)
+			return connector_status_connected;
+		else
+			return connector_status_disconnected;
+	}
 
 	return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
 }
@@ -1074,12 +1095,18 @@ struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev,
 	if (ret)
 		return ERR_PTR(ret);
 
+	if (of_property_present(pdev->dev.of_node, "no-hpd"))
+		hdmi->no_hpd = 1;
+	else
+		hdmi->no_hpd = 0;
+
 	hdmi->bridge.driver_private = hdmi;
 	hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT |
 			   DRM_BRIDGE_OP_EDID |
 			   DRM_BRIDGE_OP_HDMI |
-			   DRM_BRIDGE_OP_HDMI_AUDIO |
-			   DRM_BRIDGE_OP_HPD;
+			   DRM_BRIDGE_OP_HDMI_AUDIO;
+	if (!hdmi->no_hpd)
+		hdmi->bridge.ops |= DRM_BRIDGE_OP_HPD;
 	hdmi->bridge.of_node = pdev->dev.of_node;
 	hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
 	hdmi->bridge.vendor = "Synopsys";
-- 
2.43.0



From macroalpha82 at gmail.com  Thu Nov  6 10:09:14 2025
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Thu,  6 Nov 2025 12:09:14 -0600
Subject: [PATCH 3/3] arm64: dts: rockchip: Add HDMI to Gameforce Ace
In-Reply-To: <20251106180914.768502-1-macroalpha82@gmail.com>
References: <20251106180914.768502-1-macroalpha82@gmail.com>
Message-ID: <20251106180914.768502-4-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

Add support for the HDMI port for the Gameforce Ace. The HDMI port
has no HPD pin present (the manufacturer's devicetree states the pin
is reused for an additional face button) so add the attribute of
no_hpd to poll for connected devices.

Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
---
 .../dts/rockchip/rk3588s-gameforce-ace.dts    | 63 +++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts b/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts
index f5894672fcbd..b98e1a3369dc 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts
@@ -300,6 +300,20 @@ amp_headphone: headphone-amplifier {
 		sound-name-prefix = "Headphones Amplifier";
 	};
 
+	hdmi0-con {
+		compatible = "hdmi-connector";
+		ddc-en-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_HIGH>;
+		pinctrl-0 = <&hdmi0_en>;
+		pinctrl-names = "default";
+		type = "d";
+
+		port {
+			hdmi0_con_in: endpoint {
+				remote-endpoint = <&hdmi0_out_con>;
+			};
+		};
+	};
+
 	pwm_fan: pwm-fan {
 		compatible = "pwm-fan";
 		#cooling-cells = <2>;
@@ -498,6 +512,34 @@ &gpu {
 	status = "okay";
 };
 
+&hdmi0 {
+	no-hpd;
+	pinctrl-0 = <&hdmim0_tx0_cec>, <&hdmim0_tx0_scl>,
+		    <&hdmim0_tx0_sda>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&hdmi0_in {
+	hdmi0_in_vp0: endpoint {
+		remote-endpoint = <&vp0_out_hdmi0>;
+	};
+};
+
+&hdmi0_out {
+	hdmi0_out_con: endpoint {
+		remote-endpoint = <&hdmi0_con_in>;
+	};
+};
+
+&hdmi0_sound {
+	status = "okay";
+};
+
+&hdptxphy0 {
+	status = "okay";
+};
+
 &i2c0 {
 	pinctrl-0 = <&i2c0m2_xfer>;
 	pinctrl-names = "default";
@@ -746,6 +788,10 @@ &i2s0_sdi0
 	status = "okay";
 };
 
+&i2s5_8ch {
+	status = "okay";
+};
+
 &mipidcphy0 {
 	status = "okay";
 };
@@ -842,6 +888,13 @@ charger_int_h: charger-int-h {
 		};
 	};
 
+	hdmi {
+		hdmi0_en: hdmi0-en {
+			rockchip,pins =
+				<4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
 	hym8563 {
 		hym8563_int: hym8563-int {
 			rockchip,pins =
@@ -1416,6 +1469,16 @@ &vop_mmu {
 	status = "okay";
 };
 
+&vp0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	vp0_out_hdmi0: endpoint at ROCKCHIP_VOP2_EP_HDMI0 {
+		reg = <ROCKCHIP_VOP2_EP_HDMI0>;
+		remote-endpoint = <&hdmi0_in_vp0>;
+	};
+};
+
 &vp3 {
 	#address-cells = <1>;
 	#size-cells = <0>;
-- 
2.43.0



From macroalpha82 at gmail.com  Thu Nov  6 10:24:36 2025
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Thu,  6 Nov 2025 12:24:36 -0600
Subject: [PATCH] arm64: dts: rockchip: enable NPU on Gameforce Ace
Message-ID: <20251106182436.771805-1-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

Enable the NPU on the Gameforce Ace.

Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
---
 .../dts/rockchip/rk3588s-gameforce-ace.dts    | 34 +++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts b/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts
index b98e1a3369dc..e8ad525ba3f9 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts
@@ -842,6 +842,10 @@ &pd_gpu {
 	domain-supply = <&vdd_gpu_s0>;
 };
 
+&pd_npu {
+	domain-supply = <&vdd_npu_s0>;
+};
+
 &pinctrl {
 	audio-amplifier {
 		headphone_amplifier_en: headphone-amplifier-en {
@@ -1032,6 +1036,36 @@ &pwm13 {
 	status = "okay";
 };
 
+&rknn_core_0 {
+	npu-supply = <&vdd_npu_s0>;
+	sram-supply = <&vdd_npu_s0>;
+	status = "okay";
+};
+
+&rknn_core_1 {
+	npu-supply = <&vdd_npu_s0>;
+	sram-supply = <&vdd_npu_s0>;
+	status = "okay";
+};
+
+&rknn_core_2 {
+	npu-supply = <&vdd_npu_s0>;
+	sram-supply = <&vdd_npu_s0>;
+	status = "okay";
+};
+
+&rknn_mmu_0 {
+	status = "okay";
+};
+
+&rknn_mmu_1 {
+	status = "okay";
+};
+
+&rknn_mmu_2 {
+	status = "okay";
+};
+
 &saradc {
 	vref-supply = <&vcc_1v8_s0>;
 	status = "okay";
-- 
2.43.0



From linux.amoon at gmail.com  Thu Nov  6 11:01:12 2025
From: linux.amoon at gmail.com (Anand Moon)
Date: Fri, 7 Nov 2025 00:31:12 +0530
Subject: [PATCH v4 0/9] PCI: dw-rockchip: add system suspend support
In-Reply-To: <cbvcjgcd7saxj42ifgqn3l6mwpgenlhbr4zuf5ibqbtj6rmzqh@yuc7flbwyi2y>
References: <20251029-rockchip-pcie-system-suspend-v4-0-ce2e1b0692d2@collabora.com>
 <cf6zumlp4iiltglu7bbrpdeysaznrkyvlemwl4lxwkfjkgux7a@wl37bxilsprx> <cbvcjgcd7saxj42ifgqn3l6mwpgenlhbr4zuf5ibqbtj6rmzqh@yuc7flbwyi2y>
Message-ID: <CANAwSgSvtc57kh-VJewk5=_MvfL3KVxNFU8C+tGh4iqJhnEVtw@mail.gmail.com>

Hi Sebastian,

On Tue, 4 Nov 2025 at 00:29, Sebastian Reichel
<sebastian.reichel at collabora.com> wrote:
>
> Hi,
>
> On Sat, Nov 01, 2025 at 07:29:41PM +0530, Manivannan Sadhasivam wrote:
> > On Wed, Oct 29, 2025 at 06:56:39PM +0100, Sebastian Reichel wrote:
> > > I've recently been working on fixing up at least basic system suspend
> > > support on the Rockchip RK3576 platform. Currently the biggest open
> > > issue is missing support in the PCIe driver. This series is a follow-up
> > > for Shawn Lin's series with feedback from Niklas Cassel and Manivannan
> > > Sadhasivam being handled as well as some of my own changes fixing up
> > > things I noticed.
> > >
> > > In opposite to Shawn Lin I did not test with different peripherals as my
> > > main goal is getting basic suspend to ram working in the first place.
> >
> > Wouldn't it break users who have connected endpoint devices and suspend their
> > platform? I don't want to have an untested feature that could potentially cause
> > regressions, just for the sake of getting basic system PM.
> >
> > But if your goal is to just add basic system PM operations for CI
> > testing, then I would suggest you to do something minimal in the
> > suspend/resume path that don't disrupt the operation of a device.
> >
> > But this also should be tested with some devices for sanity.
>
> My goal is proper system PM support, but I would like to go step by
> step. Right now system suspend on the Rockchip RK3576 EVB just hangs
> the board and it has to be power cycled afterwards. In parallel to
> this series I've send a bunch of fixes to get it working. It surely
> isn't perfect, but I fear things regressing again in other areas while
> the complex PCIe system sleep is being worked on - simply blocking system
> suspend is not very helpful, since it effectively hides suspend problems.
>
As per my understanding, the current DTS configuration is missing definitions
for critical PCIe power management GPIOs (clkreq-gpios, perst-gpios, wake-gpios)

clkreq-gpios, such as PCIE30x1_0_CLKREQn_M1_L (not sure if it is used ?)
perst-gpios such as PCIE30x1_0_PERSTn_M1_L
wake-gpios, such as PCIE30x1_0_WAKEn_M1_L.

However, the RK3588 TRM indicates that these power management functions
can be controlled programmatically using specific memory-mapped registers:

The PCIE_CLIENT_POWER_CON register at 0x002C provides comprehensive
power management controls, including link-state management, wake-up
event handling,
and clock management.

In PHY GRF, we have the PCIe3PHY_GRF_PHY0_LN0_CON0 register at 0x1000 allows
direct control over the PHY's power state (P-states like P1, P2),
enabling transitions into
deep suspend (L2/L3) via register writes
clkreq_n Clock request for lane X. This is a side-band signal that a
PIPE 4.2 controller needs
to enter and exit P1.CPM, P1.1, and P1.2 power states.

My thought is that using rockchip_pcie_phy_deinit() in the suspend
routine and rockchip_pcie_phy_init() in the resume routine are
incorrect; these functions
likely perform full resets or power cuts rather than managed power
state transitions,
thus disrupting the desired suspended state of the PCIe link

I tried a few things on my own, but I am not moving forward.

Thanks
-Anand


From heiko at sntech.de  Thu Nov  6 11:40:55 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Thu, 06 Nov 2025 20:40:55 +0100
Subject: [PATCH 2/3] drm/bridge: dw-hdmi-qp: Add support for missing HPD
In-Reply-To: <20251106180914.768502-3-macroalpha82@gmail.com>
References: <20251106180914.768502-1-macroalpha82@gmail.com>
 <20251106180914.768502-3-macroalpha82@gmail.com>
Message-ID: <2301926.irdbgypaU6@phil>

Am Donnerstag, 6. November 2025, 19:09:13 Mitteleurop?ische Normalzeit schrieb Chris Morgan:
> From: Chris Morgan <macromorgan at hotmail.com>
> 
> Add support for the dw-hdmi-qp driver to handle devices with missing
> HPD pins.
> 
> Since in this situation we are now polling for the EDID data via i2c
> change the error message to a debug message when we are unable to
> complete an i2c read, as a disconnected device would otherwise fill
> dmesg with i2c read errors.
> 
> Signed-off-by: Chris Morgan <macromorgan at hotmail.com>

> @@ -1074,12 +1095,18 @@ struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev,
>  	if (ret)
>  		return ERR_PTR(ret);
>  
> +	if (of_property_present(pdev->dev.of_node, "no-hpd"))
> +		hdmi->no_hpd = 1;
> +	else
> +		hdmi->no_hpd = 0;
> +

what is the argument against

hdmi->no_hpd = of_property_read_bool(pdev->dev.of_node, "no-hpd")); ?







From heiko at sntech.de  Thu Nov  6 11:45:33 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Thu, 06 Nov 2025 20:45:33 +0100
Subject: [PATCH 2/5] arm64: dts: rockchip: Add Additional pinctrl defs for
 Indiedroid Nova
In-Reply-To: <20251105205708.732125-3-macroalpha82@gmail.com>
References: <20251105205708.732125-1-macroalpha82@gmail.com>
 <20251105205708.732125-3-macroalpha82@gmail.com>
Message-ID: <3438819.aeNJFYEL58@phil>

Hi Chris,

Am Mittwoch, 5. November 2025, 21:57:05 Mitteleurop?ische Normalzeit schrieb Chris Morgan:
> From: Chris Morgan <macromorgan at hotmail.com>
> 
> Define the pinctrl nodes for the WiFi interrupts, correct the pinctrl
> for the ethernet according to the schematic, and add the clk32k_in
> control for the RTC. Add the correct regulator mapping for the PCIE
> too.

way too much completely different things to stuff into one patch.

- Adding the sdio wifi is one
- ethernet is next ... you're not fixing, but removing the pinctrl?
- pcie2 fixes is another one
- and the clkin32k as well


Heiko

> 
> Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
> ---
>  .../dts/rockchip/rk3588s-indiedroid-nova.dts  | 43 ++++++++++++-------
>  1 file changed, 28 insertions(+), 15 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
> index debab7732b71..f40782b6c7db 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
> @@ -406,7 +406,7 @@ rtc_hym8563: rtc at 51 {
>  		clock-output-names = "hym8563";
>  		interrupt-parent = <&gpio0>;
>  		interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>;
> -		pinctrl-0 = <&hym8563_int>;
> +		pinctrl-0 = <&hym8563_int>, <&clk32k_in>;
>  		pinctrl-names = "default";
>  		wakeup-source;
>  	};
> @@ -459,8 +459,11 @@ &i2s5_8ch {
>  };
>  
>  &pcie2x1l2 {
> -	pinctrl-0 = <&rtl8111_perstb>;
> +	pinctrl-0 = <&pcie20x1m0_perstn>, <&pcie20x1m0_clkreqn>,
> +		    <&pcie20x1m0_waken>;
>  	pinctrl-names = "default";
> +	reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
> +	vpcie3v3-supply = <&vcc_3v3_s3>;
>  	status = "okay";
>  };
>  
> @@ -486,12 +489,6 @@ bt_wake_host: bt-wake-host {
>  		};
>  	};
>  
> -	ethernet-pins {
> -		rtl8111_perstb: rtl8111-perstb {
> -			rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>;
> -		};
> -	};
> -
>  	hym8563 {
>  
>  		hym8563_int: hym8563-int {
> @@ -500,13 +497,6 @@ hym8563_int: hym8563-int {
>  		};
>  	};
>  
> -	sdio-pwrseq {
> -		wifi_enable_h: wifi-enable-h {
> -			rockchip,pins =
> -				<0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>;
> -		};
> -	};
> -
>  	usb-typec {
>  		usbc0_int: usbc0-int {
>  			rockchip,pins =
> @@ -518,6 +508,18 @@ typec5v_pwren: typec5v-pwren {
>  				<4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
>  		};
>  	};
> +
> +	wifi {
> +		wifi_enable_h: wifi-enable-h {
> +			rockchip,pins =
> +				<0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>;
> +		};
> +
> +		wifi_host_wake_irq: wifi-host-wake-irq {
> +			rockchip,pins =
> +				<0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_down>;
> +		};
> +	};
>  };
>  
>  &saradc {
> @@ -538,6 +540,7 @@ &sdhci {
>  };
>  
>  &sdio {
> +	#address-cells = <1>;
>  	bus-width = <4>;
>  	cap-sd-highspeed;
>  	cap-sdio-irq;
> @@ -549,9 +552,19 @@ &sdio {
>  	no-sd;
>  	non-removable;
>  	sd-uhs-sdr104;
> +	#size-cells = <0>;
>  	vmmc-supply = <&vcc_3v3_s3>;
>  	vqmmc-supply = <&vcc_1v8_s3>;
>  	status = "okay";
> +
> +	sdio_wifi: wifi at 1 {
> +		reg = <1>;
> +		interrupt-parent = <&gpio0>;
> +		interrupts = <RK_PA0 IRQ_TYPE_LEVEL_LOW>;
> +		interrupt-names = "host-wake";
> +		pinctrl-0 = <&wifi_host_wake_irq>;
> +		pinctrl-names = "default";
> +	};
>  };
>  
>  &sdmmc {
> 






From helgaas at kernel.org  Thu Nov  6 11:50:57 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Thu, 6 Nov 2025 13:50:57 -0600
Subject: [PATCH] PCI: Add ASPM quirk for Hi1105 PCIe Wi-Fi
In-Reply-To: <1762401119-232631-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <20251106195057.GA1965757@bhelgaas>

On Thu, Nov 06, 2025 at 11:51:59AM +0800, Shawn Lin wrote:
> This Wi-Fi advertises the L0s and L1 capabilities but actually
> it doesn't support them. This's comfirmed by Hisilicon team in
> actual productization.
> 
> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
> ---
> 
>  drivers/pci/quirks.c | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
> index 214ed06..67250d4 100644
> --- a/drivers/pci/quirks.c
> +++ b/drivers/pci/quirks.c
> @@ -2526,6 +2526,12 @@ static void quirk_disable_aspm_l0s_l1(struct pci_dev *dev)
>  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ASMEDIA, 0x1080, quirk_disable_aspm_l0s_l1);
>  
>  /*
> + * The Hi1105 PCIe Wi-Fi doesn't support L0s and L1 but advertise the capability.
> + * Disable both L0s and L1 for now.
> + */
> +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_HUAWEI, 0x1105, quirk_disable_aspm_l0s_l1);

PCI_VENDOR_ID_HUAWEI is 0x19e5.  Is there an upstream driver that
matches [19e5:1105]?  I didn't find anything.

I think quirk_disable_aspm_l0s_l1() might be a problem because the new
strategy is to enable ASPM early (in pcie_aspm_init_link_state(),
called from pci_scan_slot(), which happens before FINAL fixups are run
during pci_bus_add_device().

So I think we will enable L0s and L1 briefly before
quirk_disable_aspm_l0s_l1() runs, and it's possible we'd see a problem
then.

But if you apply this series:
  https://lore.kernel.org/r/20251106183643.1963801-1-helgaas at kernel.org

and then the patch below on top, I think we should avoid enabling L0s
and L1 at all:

diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 44e780718953..24c278857159 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -2536,6 +2536,7 @@ static void quirk_disable_aspm_l0s_l1_cap(struct pci_dev *dev)
 	pci_info(dev, "ASPM: L0s L1 removed from Link Capabilities to work around device defect\n");
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, 0x0451, quirk_disable_aspm_l0s_l1_cap);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_HUAWEI, 0x1105, quirk_disable_aspm_l0s_l1_cap);
 
 /*
  * Some Pericom PCIe-to-PCI bridges in reverse mode need the PCIe Retrain


From jgg at nvidia.com  Thu Nov  6 12:34:56 2025
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Thu,  6 Nov 2025 16:34:56 -0400
Subject: [PATCH v2 0/3] Cleanup around iommu_set_fault_handler()
Message-ID: <0-v2-25fc75484cab+ab-iommu_set_fault_jgg@nvidia.com>

report_iommu_fault() is an older API that has been superseded by
iommu_report_device_fault() which is capable to support PRI.

Only four external drivers consume this via iommu_set_fault_handler()
  drivers/remoteproc/omap_remoteproc.c
  drivers/remoteproc/qcom_q6v5_adsp.c
  drivers/gpu/drm/msm
  drivers/infiniband/hw/usnic

Remove the use in usnic as the iommu driver logging is good enough these
days.

Remove generation support from the AMD iommu driver since msm and two
remoteproc drivers are not used on AMD x86 CPUs.

Fail iommu_set_fault_handler() if the underlying iommu driver does not
support it.

v2:
 - Revise commit messages
 - Move report_iommu_fault_supported into the struct iommu_ops
 - Put back the pr_err in the AMD driver
v1: https://patch.msgid.link/r/0-v1-391058a85f30+14b-iommu_set_fault_jgg at nvidia.com

Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>

Jason Gunthorpe (3):
  RDMA/usnic: Remove iommu_set_fault_handler()
  iommu/amd: Don't call report_iommu_fault()
  iommu: Allow drivers to say if they use report_iommu_fault()

 drivers/infiniband/hw/usnic/usnic_uiom.c | 13 -------------
 drivers/iommu/amd/iommu.c                |  7 -------
 drivers/iommu/arm/arm-smmu/arm-smmu.c    |  1 +
 drivers/iommu/arm/arm-smmu/qcom_iommu.c  |  1 +
 drivers/iommu/iommu.c                    |  6 +++++-
 drivers/iommu/ipmmu-vmsa.c               |  1 +
 drivers/iommu/mtk_iommu.c                |  1 +
 drivers/iommu/mtk_iommu_v1.c             |  1 +
 drivers/iommu/omap-iommu.c               |  1 +
 drivers/iommu/rockchip-iommu.c           |  1 +
 drivers/iommu/sun50i-iommu.c             |  1 +
 include/linux/iommu.h                    |  3 +++
 12 files changed, 16 insertions(+), 21 deletions(-)


base-commit: 211ddde0823f1442e4ad052a2f30f050145ccada
-- 
2.43.0



From jgg at nvidia.com  Thu Nov  6 12:34:58 2025
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Thu,  6 Nov 2025 16:34:58 -0400
Subject: [PATCH v2 2/3] iommu/amd: Don't call report_iommu_fault()
In-Reply-To: <0-v2-25fc75484cab+ab-iommu_set_fault_jgg@nvidia.com>
Message-ID: <2-v2-25fc75484cab+ab-iommu_set_fault_jgg@nvidia.com>

This old style API is only used by drivers/gpu/drm/msm,
drivers/remoteproc/omap_remoteproc.c, and
drivers/remoteproc/qcom_q6v5_adsp.c none are used on x86 HW.

Remove the dead code to discourage new users.

Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 drivers/iommu/amd/iommu.c | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 2e1865daa1cee8..d4d9a5dbfa6333 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -854,13 +854,6 @@ static void amd_iommu_report_page_fault(struct amd_iommu *iommu,
 						   PCI_FUNC(devid), domain_id);
 				goto out;
 			}
-
-			if (!report_iommu_fault(&dev_data->domain->domain,
-						&pdev->dev, address,
-						IS_WRITE_REQUEST(flags) ?
-							IOMMU_FAULT_WRITE :
-							IOMMU_FAULT_READ))
-				goto out;
 		}
 
 		if (__ratelimit(&dev_data->rs)) {
-- 
2.43.0



From jgg at nvidia.com  Thu Nov  6 12:34:57 2025
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Thu,  6 Nov 2025 16:34:57 -0400
Subject: [PATCH v2 1/3] RDMA/usnic: Remove iommu_set_fault_handler()
In-Reply-To: <0-v2-25fc75484cab+ab-iommu_set_fault_jgg@nvidia.com>
Message-ID: <1-v2-25fc75484cab+ab-iommu_set_fault_jgg@nvidia.com>

The handler in usnic just prints a fault report message, the iommu drivers
all do a better job of that these days. Just remove the use of this old
API.

Acked-by: Jason Gunthorpe <jgg at nvidia.com>
Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 drivers/infiniband/hw/usnic/usnic_uiom.c | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/drivers/infiniband/hw/usnic/usnic_uiom.c b/drivers/infiniband/hw/usnic/usnic_uiom.c
index 3fbf99757b1148..f7fb6246c83aba 100644
--- a/drivers/infiniband/hw/usnic/usnic_uiom.c
+++ b/drivers/infiniband/hw/usnic/usnic_uiom.c
@@ -51,17 +51,6 @@
 	((void *) &((struct usnic_uiom_chunk *) 0)->page_list[1] -	\
 	(void *) &((struct usnic_uiom_chunk *) 0)->page_list[0]))
 
-static int usnic_uiom_dma_fault(struct iommu_domain *domain,
-				struct device *dev,
-				unsigned long iova, int flags,
-				void *token)
-{
-	usnic_err("Device %s iommu fault domain 0x%p va 0x%lx flags 0x%x\n",
-		dev_name(dev),
-		domain, iova, flags);
-	return -ENOSYS;
-}
-
 static void usnic_uiom_put_pages(struct list_head *chunk_list, int dirty)
 {
 	struct usnic_uiom_chunk *chunk, *tmp;
@@ -450,8 +439,6 @@ struct usnic_uiom_pd *usnic_uiom_alloc_pd(struct device *dev)
 		return ERR_CAST(domain);
 	}
 
-	iommu_set_fault_handler(pd->domain, usnic_uiom_dma_fault, NULL);
-
 	spin_lock_init(&pd->lock);
 	INIT_LIST_HEAD(&pd->devs);
 
-- 
2.43.0



From jgg at nvidia.com  Thu Nov  6 12:34:59 2025
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Thu,  6 Nov 2025 16:34:59 -0400
Subject: [PATCH v2 3/3] iommu: Allow drivers to say if they use report_iommu_fault()
In-Reply-To: <0-v2-25fc75484cab+ab-iommu_set_fault_jgg@nvidia.com>
Message-ID: <3-v2-25fc75484cab+ab-iommu_set_fault_jgg@nvidia.com>

report_iommu_fault() is an older API that has been superseded by
iommu_report_device_fault() which is capable to support PRI.

Only two external drivers consume this, drivers/remoteproc and
drivers/gpu/drm/msm. Ideally they would move over to the new APIs, but for
now protect against accidentally mix and matching the wrong components.

The iommu drivers support either the old iommu_set_fault_handler() via the
driver calling report_iommu_fault(), or they are newer server focused
drivers that call iommu_report_device_fault().

Include a flag in the iommu_ops if the driver calls report_iommu_fault()
and block iommu_set_fault_handler() for domain's of iommu drivers that
can't support it.

Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 drivers/iommu/arm/arm-smmu/arm-smmu.c   | 1 +
 drivers/iommu/arm/arm-smmu/qcom_iommu.c | 1 +
 drivers/iommu/iommu.c                   | 6 +++++-
 drivers/iommu/ipmmu-vmsa.c              | 1 +
 drivers/iommu/mtk_iommu.c               | 1 +
 drivers/iommu/mtk_iommu_v1.c            | 1 +
 drivers/iommu/omap-iommu.c              | 1 +
 drivers/iommu/rockchip-iommu.c          | 1 +
 drivers/iommu/sun50i-iommu.c            | 1 +
 include/linux/iommu.h                   | 3 +++
 10 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 4ced4b5bee4df3..f68a0576b9a3a6 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1643,6 +1643,7 @@ static const struct iommu_ops arm_smmu_ops = {
 	.get_resv_regions	= arm_smmu_get_resv_regions,
 	.def_domain_type	= arm_smmu_def_domain_type,
 	.owner			= THIS_MODULE,
+	.report_iommu_fault_supported = true,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
 		.attach_dev		= arm_smmu_attach_dev,
 		.map_pages		= arm_smmu_map_pages,
diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index c5be95e560317e..173d5957796790 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -597,6 +597,7 @@ static const struct iommu_ops qcom_iommu_ops = {
 	.probe_device	= qcom_iommu_probe_device,
 	.device_group	= generic_device_group,
 	.of_xlate	= qcom_iommu_of_xlate,
+	.report_iommu_fault_supported = true,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
 		.attach_dev	= qcom_iommu_attach_dev,
 		.map_pages	= qcom_iommu_map,
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 59244c744eabd2..8d9086a37671e1 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2005,6 +2005,9 @@ EXPORT_SYMBOL_GPL(iommu_group_has_isolated_msi);
  * This function should be used by IOMMU users which want to be notified
  * whenever an IOMMU fault happens.
  *
+ * This is a legacy API not supported by all drivers. New users should look
+ * to using domain->iopf_handler for the modern API.
+ *
  * The fault handler itself should return 0 on success, and an appropriate
  * error code otherwise.
  */
@@ -2012,7 +2015,8 @@ void iommu_set_fault_handler(struct iommu_domain *domain,
 					iommu_fault_handler_t handler,
 					void *token)
 {
-	if (WARN_ON(!domain || domain->cookie_type != IOMMU_COOKIE_NONE))
+	if (WARN_ON(!domain || domain->cookie_type != IOMMU_COOKIE_NONE ||
+		    !domain->owner->report_iommu_fault_supported))
 		return;
 
 	domain->cookie_type = IOMMU_COOKIE_FAULT_HANDLER;
diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
index ffa892f6571406..04a5836bf36000 100644
--- a/drivers/iommu/ipmmu-vmsa.c
+++ b/drivers/iommu/ipmmu-vmsa.c
@@ -884,6 +884,7 @@ static const struct iommu_ops ipmmu_ops = {
 	.device_group = IS_ENABLED(CONFIG_ARM) && !IS_ENABLED(CONFIG_IOMMU_DMA)
 			? generic_device_group : generic_single_device_group,
 	.of_xlate = ipmmu_of_xlate,
+	.report_iommu_fault_supported = true,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
 		.attach_dev	= ipmmu_attach_device,
 		.map_pages	= ipmmu_map,
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 0e0285348d2b8e..ccf6fdeb64a261 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -1018,6 +1018,7 @@ static const struct iommu_ops mtk_iommu_ops = {
 	.of_xlate	= mtk_iommu_of_xlate,
 	.get_resv_regions = mtk_iommu_get_resv_regions,
 	.owner		= THIS_MODULE,
+	.report_iommu_fault_supported = true,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
 		.attach_dev	= mtk_iommu_attach_device,
 		.map_pages	= mtk_iommu_map,
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index 10cc0b1197e801..3dd6222d210921 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -581,6 +581,7 @@ static const struct iommu_ops mtk_iommu_v1_ops = {
 	.release_device	= mtk_iommu_v1_release_device,
 	.device_group	= generic_device_group,
 	.owner          = THIS_MODULE,
+	.report_iommu_fault_supported = true,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
 		.attach_dev	= mtk_iommu_v1_attach_device,
 		.map_pages	= mtk_iommu_v1_map,
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index 5c6f5943f44b1f..7ba67600f32915 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -1723,6 +1723,7 @@ static const struct iommu_ops omap_iommu_ops = {
 	.release_device	= omap_iommu_release_device,
 	.device_group	= generic_single_device_group,
 	.of_xlate	= omap_iommu_of_xlate,
+	.report_iommu_fault_supported = true,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
 		.attach_dev	= omap_iommu_attach_dev,
 		.map_pages	= omap_iommu_map,
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 0861dd469bd866..932b5a62bac572 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -1173,6 +1173,7 @@ static const struct iommu_ops rk_iommu_ops = {
 	.release_device = rk_iommu_release_device,
 	.device_group = generic_single_device_group,
 	.of_xlate = rk_iommu_of_xlate,
+	.report_iommu_fault_supported = true,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
 		.attach_dev	= rk_iommu_attach_device,
 		.map_pages	= rk_iommu_map,
diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c
index de10b569d9a940..13c37b1be481d7 100644
--- a/drivers/iommu/sun50i-iommu.c
+++ b/drivers/iommu/sun50i-iommu.c
@@ -848,6 +848,7 @@ static const struct iommu_ops sun50i_iommu_ops = {
 	.domain_alloc_paging = sun50i_iommu_domain_alloc_paging,
 	.of_xlate	= sun50i_iommu_of_xlate,
 	.probe_device	= sun50i_iommu_probe_device,
+	.report_iommu_fault_supported = true,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
 		.attach_dev	= sun50i_iommu_attach_device,
 		.flush_iotlb_all = sun50i_iommu_flush_iotlb_all,
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index c30d12e16473df..941e4971b05fd3 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -659,6 +659,8 @@ __iommu_copy_struct_to_user(const struct iommu_user_data *dst_data,
  *                    no user domain for each PASID and the I/O page faults are
  *                    forwarded through the user domain attached to the device
  *                    RID.
+ * @report_iommu_fault_supported: True if the domain supports
+ *                                iommu_set_fault_handler()
  */
 struct iommu_ops {
 	bool (*capable)(struct device *dev, enum iommu_cap);
@@ -710,6 +712,7 @@ struct iommu_ops {
 	struct iommu_domain *release_domain;
 	struct iommu_domain *default_domain;
 	u8 user_pasid_table:1;
+	u8 report_iommu_fault_supported:1;
 };
 
 /**
-- 
2.43.0



From heiko at sntech.de  Thu Nov  6 14:51:40 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Thu, 06 Nov 2025 23:51:40 +0100
Subject: [PATCH v5 3/3] arm64: dts: rockchip: Add devicetree for the 9Tripod X3568
 v4
In-Reply-To: <20251103171702.1518730-4-coiaprant@gmail.com>
References: <20251103171702.1518730-1-coiaprant@gmail.com>
 <20251103171702.1518730-4-coiaprant@gmail.com>
Message-ID: <7930630.EvYhyI6sBW@phil>

Hi,

Am Montag, 3. November 2025, 18:17:02 Mitteleurop?ische Normalzeit schrieb Coia Prant:
> The 9Tripod X3568 v4 is an RK3568-based SBC, just like the RK3568-EVB.
> It always uses soldered connections between the X3568CV2/X3568CV3/X3568CV4 core board
> and the X3568bv4 I/O board.
> 
> The differences between the core boards
> - PCB size, layout
> - CPU (RKK3568B2/RK3568J)
> - Memory type (DDR4/LPDDR4/LPDDR4X) and size
> - eMMC size
> - DSI/EDP resistor values
> Although the components vary, they maintain full compatibility.
> 
> The X3568 board has multiple hardware revisions, and we currently support v4 (I/O board).

[...]

> Signed-off-by: Coia Prant <coiaprant at gmail.com>

I've dropped the camera overlay for the time being, when applying the
board, because there were a number of smallish issues with it.

So please submit it separately again. Also, how can you use the camera
yet, when the whole vicap work is still pending?

Details below

> ---
>  arch/arm64/boot/dts/rockchip/Makefile         |  11 +
>  .../rk3568-9tripod-x3568-v4-camera-demo.dtso  |  84 ++
>  .../rk3568-9tripod-x3568-v4-video-demo.dtso   | 154 +++
>  .../dts/rockchip/rk3568-9tripod-x3568-v4.dts  | 887 ++++++++++++++++++
>  4 files changed, 1136 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4-camera-demo.dtso
>  create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4-video-demo.dtso
>  create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4.dts
> 
> diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
> index ad684e383..959a806a2 100644
> --- a/arch/arm64/boot/dts/rockchip/Makefile
> +++ b/arch/arm64/boot/dts/rockchip/Makefile
> @@ -130,6 +130,9 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-lubancat-1.dtb
>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-nanopi-r3s.dtb
>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-bigtreetech-cb2-manta.dtb
>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-bigtreetech-pi2.dtb
> +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-9tripod-x3568-v4.dtb
> +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-9tripod-x3568-v4-camera-demo.dtbo
> +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-9tripod-x3568-v4-video-demo.dtbo
>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-bpi-r2-pro.dtb
>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-v10.dtb
>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-fastrhino-r66s.dtb
> @@ -252,6 +255,14 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-armsom-sige5-v1.2-wifibt.dtb
>  rk3576-armsom-sige5-v1.2-wifibt-dtbs := rk3576-armsom-sige5.dtb \
>  	rk3576-armsom-sige5-v1.2-wifibt.dtbo
>  
> +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-9tripod-x3568-v4-camera-demo.dtb
> +rk3568-9tripod-x3568-v4-camera-demo-dtbs := rk3568-9tripod-x3568-v4.dtb \
> +	rk3568-9tripod-x3568-v4-camera-demo.dtbo
> +
> +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-9tripod-x3568-v4-video-demo.dtb
> +rk3568-9tripod-x3568-v4-video-demo-dtbs := rk3568-9tripod-x3568-v4.dtb \
> +	rk3568-9tripod-x3568-v4-video-demo.dtbo
> +

when adding overlays, please sort them correctly,
rk3568-9tripod* should be above rk3568-wolfvision*


>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-edgeble-neu6a-wifi.dtb
>  rk3588-edgeble-neu6a-wifi-dtbs := rk3588-edgeble-neu6a-io.dtb \
>  	rk3588-edgeble-neu6a-wifi.dtbo
> diff --git a/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4-camera-demo.dtso b/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4-camera-demo.dtso
> new file mode 100644
> index 000000000..2b428ca71
> --- /dev/null
> +++ b/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4-camera-demo.dtso
> @@ -0,0 +1,84 @@

[...]

> +&csi_dphy {
> +	status = "okay";
> +
> +	ports {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		port at 0 {

../arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4-camera-demo.dtso:41.8-56.4: Warning (graph_child_address): /fragment at 2/__overlay__/ports: graph node has single child node 'port at 0', #address-cells/#size-cells are not necessary


> +			reg = <0>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			mipi_in_ucam: endpoint at 2 {
> +				reg = <2>;
> +				remote-endpoint = <&ucam_out>;
> +				data-lanes = <1 2 3 4>;
> +			};
> +		};
> +	};

/home/devel/hstuebner/00_git-repos/linux-rockchip/_build-arm64/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4-camera-demo.dtb: phy at fe870000 (rockchip,rk3568-csi-dphy): 'ports' does not match any of the regexes: '^pinctrl-[0-9]+$'
        from schema $id: http://devicetree.org/schemas/phy/rockchip-inno-csi-dphy.yaml#

not sure what is up with that.

> +};
> +
> +&i2c4 {
> +	#address-cells = <1>;
> +	#size-cells = <0>;
> +	status = "okay";
> +
> +	camera at 37 {
> +		compatible = "ovti,ov5695";
> +		reg = <0x37>;
> +		clocks = <&cru CLK_CIF_OUT>;
> +		clock-names = "xvclk";
> +		avdd-supply = <&vcc_cam>;
> +		dvdd-supply = <&vcc_cam>;
> +		dovdd-supply = <&vcc_cam>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&cif_clk>;
> +		reset-gpios = <&gpio3 RK_PB6 GPIO_ACTIVE_LOW>;
> +		pwdn-gpios = <&gpio4 RK_PB4 GPIO_ACTIVE_LOW>;
> +
> +		port {
> +			ucam_out: endpoint {
> +				remote-endpoint = <&mipi_in_ucam>;
> +				data-lanes = <1 2 3 4>;
> +			};
> +		};

/home/devel/hstuebner/00_git-repos/linux-rockchip/_build-arm64/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4-camera-demo.dtb: camera at 37 (ovti,ov5695): port:endpoint:data-lanes: [1, 2, 3, 4] is too long
        from schema $id: http://devicetree.org/schemas/media/i2c/ovti,ov5693.yaml#
/home/devel/hstuebner/00_git-repos/linux-rockchip/_build-arm64/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4-camera-demo.dtb: camera at 37 (ovti,ov5695): Unevaluated properties are not allowed ('port', 'pwdn-gpios' were unexpected)
        from schema $id: http://devicetree.org/schemas/media/i2c/ovti,ov5693.yaml#


> +	};
> +};



Heiko




From heiko at sntech.de  Thu Nov  6 14:54:45 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Thu, 06 Nov 2025 23:54:45 +0100
Subject: [PATCH v5 3/3] arm64: dts: rockchip: Add devicetree for the 9Tripod X3568
 v4
In-Reply-To: <20251103171702.1518730-4-coiaprant@gmail.com>
References: <20251103171702.1518730-1-coiaprant@gmail.com>
 <20251103171702.1518730-4-coiaprant@gmail.com>
Message-ID: <3719039.iIbC2pHGDl@phil>

Am Montag, 3. November 2025, 18:17:02 Mitteleurop?ische Normalzeit schrieb Coia Prant:
> The 9Tripod X3568 v4 is an RK3568-based SBC, just like the RK3568-EVB.
> It always uses soldered connections between the X3568CV2/X3568CV3/X3568CV4 core board
> and the X3568bv4 I/O board.
> 
> The differences between the core boards
> - PCB size, layout
> - CPU (RKK3568B2/RK3568J)
> - Memory type (DDR4/LPDDR4/LPDDR4X) and size
> - eMMC size
> - DSI/EDP resistor values
> Although the components vary, they maintain full compatibility.
> 
> The X3568 board has multiple hardware revisions, and we currently support v4 (I/O board).
> 
> Specification:
> - SoC: RockChip RK3568 ARM64 (4 cores)
> - eMMC: 16-128 GB
> - RAM: 2-16 GB
> - Power: DC 12V 2A
> - Ethernet: 2x YT8521SC RGMII (10/100/1000 Mbps)
> - Wireless radio: 802.11b/g/n/ac/ax dual-band
> - LED:
>   Power: AlwaysOn
>   User: GPIO
> - Button:
>   VOL+: SARADC/0 <35k ?V>
>   VOL-: SARADC/0 <450k ?V>
>   Power/Reset: PMIC RK809
> - CAN
>   CAN/1: 4-pin (PH 2.0)
> - PWM
>   PWM/4: Backlight DSI/0 DSI/1
>   PWM/7: IR Receiver [may not install]
> - UART:
>   UART/2: Debug TTL - 1500000 8N1 (1.25mm)
>   UART/3: TTL (PH 2.0)
>   UART/4: TTL (PH 2.0)
>   UART/8: AP6275S Bluetooth
>   UART/9: TTL (PH 2.0)
> - I2C:
>   I2C/0: PMIC RK809
>   I2C/1: Touchscreen DSI/0 DSI/1
>   I2C/4: Camera
>   I2C/5: RTC at 51 PCF8563
> - I2S:
>   I2S/0: miniHDMI Sound
>   I2S/1: RK809 Audio Codec
>   I2S/3: AP6275S Bluetooth Sound
> - SDMMC:
>   SDMMC/0: microSD (TF) slot
>   SDMMC/2: AP6275S SDIO WiFi card
> - Camera: 1x CSI
> - Video: miniHDMI / DSI0 (MIPI/LVDS) / DSI1 (MIPI/EDP)
> - Audio: miniHDMI / MIC on-board / Speaker / SPDIF / 3.5mm Headphones / AP6275S Bluetooth
> - USB:
>   USB 2.0 HOST x2
>   USB 2.0 HOST x3 (4-pin)
>   USB 2.0 OTG x1 (shared with USB 3.0 OTG/HOST) [slot may not install]
>   USB 3.0 HOST x1
>   USB 3.0 OTG/HOST x1
> - SATA: 1x SATA 3.0 with Power/4-pin [slot may not install]
> - PCIe: 1x PCIe 3.0 x2 (x4 connecter) [power/clock/slot may not install]
> 
> Link:
> - https://appletsapi.52solution.com/media/X3568V4%E5%BC%80%E5%8F%91%E6%9D%BF%E7%A1%AC%E4%BB%B6%E6%89%8B%E5%86%8C.pdf
> - https://blog.gov.cooking/archives/research-ninetripod-x3568-v4-and-flash.html
> 
> Signed-off-by: Coia Prant <coiaprant at gmail.com>

> diff --git a/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4-video-demo.dtso b/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4-video-demo.dtso
> new file mode 100644
> index 000000000..e7fa1ca48
> --- /dev/null
> +++ b/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4-video-demo.dtso
> @@ -0,0 +1,154 @@
> +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
> +
> +// This is a sample reference, due to lack of hardware can not be tested, at your own risk

and I've also dropped the 2nd overlay now.
Please only ever submit patches for stuff you have actually tested.

We don't really add stuff with "use at your own risk" caveats ;-)


Heiko




From heiko at sntech.de  Thu Nov  6 14:58:31 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Thu,  6 Nov 2025 23:58:31 +0100
Subject: [PATCH] arm64: dts: rockchip: Fix USB power enable pin for BTT CB2 and Pi2
In-Reply-To: <20251105210741.850031-1-andreil499@gmail.com>
References: <20251105210741.850031-1-andreil499@gmail.com>
Message-ID: <176246989731.210200.17367570635141107915.b4-ty@sntech.de>


On Wed, 05 Nov 2025 22:07:33 +0100, Andrey Leonchikov wrote:
>  Fix typo into regulator GPIO definition. With current
>  definition - USB powered off. Valid definition can be found on "pinctrl"
>  section:
>  		vcc5v0_usb2t_en: vcc5v0-usb2t-en {
>  				rockchip,pins = <3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
>  				 		};
> 
> [...]

Applied, thanks!

[1/1] arm64: dts: rockchip: Fix USB power enable pin for BTT CB2 and Pi2
      commit: a59e927ff46a967f84ddf94e89cbb045810e8974

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Thu Nov  6 14:58:34 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Thu,  6 Nov 2025 23:58:34 +0100
Subject: [PATCH] arm64: dts: rockchip: enable NPU on Gameforce Ace
In-Reply-To: <20251106182436.771805-1-macroalpha82@gmail.com>
References: <20251106182436.771805-1-macroalpha82@gmail.com>
Message-ID: <176246989726.210200.8690075173314380266.b4-ty@sntech.de>


On Thu, 06 Nov 2025 12:24:36 -0600, Chris Morgan wrote:
> Enable the NPU on the Gameforce Ace.
> 
> 

Applied, thanks!

[1/1] arm64: dts: rockchip: enable NPU on Gameforce Ace
      commit: 8a429c58354a59fa3cbd1fd964fa2e310c47af4a

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Thu Nov  6 14:58:33 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Thu,  6 Nov 2025 23:58:33 +0100
Subject: (subset) [PATCH 0/5] Indiedroid Nova Devicetree Updates
In-Reply-To: <20251105205708.732125-1-macroalpha82@gmail.com>
References: <20251105205708.732125-1-macroalpha82@gmail.com>
Message-ID: <176246989728.210200.8559295634693488639.b4-ty@sntech.de>


On Wed, 05 Nov 2025 14:57:03 -0600, Chris Morgan wrote:
> This series fixes up a few remaining issues with the devicetree for the
> Indiedroid Nova. Namely it adds or updates a few pinctrl definitions,
> it removes a few workarounds that no longer appear to be necessary for
> eMMC and bluetooth, it adds support for the NPU, and it sets the device
> type as embedded.
> 
> Chris Morgan (5):
>   arm64: dts: rockchip: Add device type for Indiedroid Nova.
>   arm64: dts: rockchip: Add Additional pinctrl defs for Indiedroid Nova
>   arm64: dts: rockchip: enable NPU on Indiedroid Nova
>   arm64: dts: rockchip: Enable HS400 for Indiedroid Nova
>   arm64: dts: rockchip: Fix DMA for Indiedroid Nova Bluetooth
> 
> [...]

Applied, thanks!

[1/5] arm64: dts: rockchip: Add device type for Indiedroid Nova.
      commit: 318bc4b5ad229435abbb7b9a7c8b1876fae311e7
[3/5] arm64: dts: rockchip: enable NPU on Indiedroid Nova
      commit: dfa4f7f5cb2c66fac5a17d63e5fcf1bf50ea7344
[4/5] arm64: dts: rockchip: Enable HS400 for Indiedroid Nova
      commit: cce837b7a3599dc83cd9c08afc07b076f127354b
[5/5] arm64: dts: rockchip: Fix DMA for Indiedroid Nova Bluetooth
      commit: c6c76445c30bb73fd4cfba8f4742e642dcfe90f5

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Thu Nov  6 14:58:32 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Thu,  6 Nov 2025 23:58:32 +0100
Subject: [PATCH v5 0/3] Add devicetree for the 9Tripod X3568 v4
In-Reply-To: <20251103171702.1518730-1-coiaprant@gmail.com>
References: <20251103171702.1518730-1-coiaprant@gmail.com>
Message-ID: <176246989738.210200.5023344118308147970.b4-ty@sntech.de>


On Tue, 04 Nov 2025 01:16:59 +0800, Coia Prant wrote:
> Change in v2:
> - Add vendor 'ninetripod' to board filename
>   > 'x3568_v4' => 'ninetripod_x3568_v4'
> 
> Change in v3:
> - Fix Makefile
> 
> [...]

Applied, thanks!

[1/3] dt-bindings: vendor-prefixes: Add 9Tripod
      commit: 25802f8d16374bcfc1e32d26fdee0d89ec82f865
[2/3] dt-bindings: arm: rockchip: Add 9Tripod X3568 series
      commit: a12838aab0cea1e4427d8d620906ce6a1a83a344
[3/3] arm64: dts: rockchip: Add devicetree for the 9Tripod X3568 v4
      commit: 156a530ed5ed012f35e8319c2ee5223dfc7195d3

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Thu Nov  6 14:58:35 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Thu,  6 Nov 2025 23:58:35 +0100
Subject: [PATCH v3] arm64: dts: rockchip: Fix USB Type-C host mode for Radxa ROCK 5B+/5T
In-Reply-To: <20251104085227.820-1-naoki@radxa.com>
References: <20251104085227.820-1-naoki@radxa.com>
Message-ID: <176246989735.210200.333917172984191028.b4-ty@sntech.de>


On Tue, 04 Nov 2025 08:52:27 +0000, FUKAUMI Naoki wrote:
> The Radxa ROCK 5B+/5T USB Type-C port supports Dual Role Data and
> should also act as a host. However, currently, when acting as a host,
> only self-powered devices work.
> 
> Since the ROCK 5B+ supports Dual Role Power, set the power-role
> property to "dual" and the try-power-role property to "sink". (along
> with related properties)
> 
> [...]

Applied, thanks!

[1/1] arm64: dts: rockchip: Fix USB Type-C host mode for Radxa ROCK 5B+/5T
      commit: fbf90d1b697faf61bb8b3ed72be6a8ebeb09de3d

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Thu Nov  6 15:02:15 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 07 Nov 2025 00:02:15 +0100
Subject: [PATCH] mmc: dw_mmc-rockchip: Fix wrong internal phase calculate
In-Reply-To: <1762228283-5025-1-git-send-email-shawn.lin@rock-chips.com>
References: <1762228283-5025-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <3369161.5fSG56mABF@phil>

Am Dienstag, 4. November 2025, 04:51:23 Mitteleurop?ische Normalzeit schrieb Shawn Lin:
> ciu clock is 2 times of io clock, but the sample clk used is
> derived from io clock provided to the card. So we should use
> io clock to calculate the phase.
> 
> Fixes: 59903441f5e4 ("mmc: dw_mmc-rockchip: Add internal phase support")
> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>

Acked-by: Heiko Stuebner <heiko at sntech.de>

> ---
> 
>  drivers/mmc/host/dw_mmc-rockchip.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c
> index 82dd906..6813549 100644
> --- a/drivers/mmc/host/dw_mmc-rockchip.c
> +++ b/drivers/mmc/host/dw_mmc-rockchip.c
> @@ -42,7 +42,7 @@ struct dw_mci_rockchip_priv_data {
>   */
>  static int rockchip_mmc_get_internal_phase(struct dw_mci *host, bool sample)
>  {
> -	unsigned long rate = clk_get_rate(host->ciu_clk);
> +	unsigned long rate = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
>  	u32 raw_value;
>  	u16 degrees;
>  	u32 delay_num = 0;
> @@ -85,7 +85,7 @@ static int rockchip_mmc_get_phase(struct dw_mci *host, bool sample)
>  
>  static int rockchip_mmc_set_internal_phase(struct dw_mci *host, bool sample, int degrees)
>  {
> -	unsigned long rate = clk_get_rate(host->ciu_clk);
> +	unsigned long rate = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
>  	u8 nineties, remainder;
>  	u8 delay_num;
>  	u32 raw_value;
> 






From bmasney at redhat.com  Thu Nov  6 15:25:46 2025
From: bmasney at redhat.com (Brian Masney)
Date: Thu, 06 Nov 2025 18:25:46 -0500
Subject: [PATCH RESEND v2 0/9] phy: convert from clk round_rate() to
 determine_rate()
Message-ID: <20251106-phy-clk-route-rate-v2-resend-v1-0-e2058963bfb1@redhat.com>

This is a resend of my previous v2 series since I haven't receieved any
feedback.

https://lore.kernel.org/linux-phy/20250810-phy-clk-round-rate-v2-0-9162470bb9f2 at redhat.com/T/

I'm hoping to get this merged for v6.19 so that I can remove the
round_rate() clk op from the clk core for v6.20. The clk maintainer
(Stephen) mentioned this work in his last pull to Linus:

https://lore.kernel.org/linux-clk/20251007051720.11386-1-sboyd at kernel.org/

The round_rate() clk ops is deprecated in the clk framework in favor
of the determine_rate() clk ops, so let's go ahead and convert the
drivers in the phy subsystem using the Coccinelle semantic patch
posted below. I did a few minor cosmetic cleanups of the code in a
few cases.

Changes since v2 RESEND:
- Collected up 3 Reviewed-by tags

Changes since v1:
- Patch 8 (phy-rockchip-samsung-hdptx): fix returning error code
  (Cristian)

Coccinelle semantic patch:

    virtual patch

    // Look up the current name of the round_rate function
    @ has_round_rate @
    identifier round_rate_name =~ ".*_round_rate";
    identifier hw_param, rate_param, parent_rate_param;
    @@

    long round_rate_name(struct clk_hw *hw_param, unsigned long rate_param,
                  unsigned long *parent_rate_param)
    {
    	...
    }

    // Rename the route_rate function name to determine_rate()
    @ script:python generate_name depends on has_round_rate @
    round_rate_name << has_round_rate.round_rate_name;
    new_name;
    @@

    coccinelle.new_name = round_rate_name.replace("_round_rate", "_determine_rate")

    // Change rate to req->rate; also change occurrences of 'return XXX'.
    @ chg_rate depends on generate_name @
    identifier has_round_rate.round_rate_name;
    identifier has_round_rate.hw_param;
    identifier has_round_rate.rate_param;
    identifier has_round_rate.parent_rate_param;
    identifier ERR =~ "E.*";
    expression E;
    @@

    long round_rate_name(struct clk_hw *hw_param, unsigned long rate_param,
                  unsigned long *parent_rate_param)
    {
    <...
    (
    -return -ERR;
    +return -ERR;
    |
    - return rate_param;
    + return 0;
    |
    - return E;
    + req->rate = E;
    +
    + return 0;
    |
    - rate_param
    + req->rate
    )
    ...>
    }

    // Coccinelle only transforms the first occurrence of the rate parameter
    // Run a second time. FIXME: Is there a better way to do this?
    @ chg_rate2 depends on generate_name @
    identifier has_round_rate.round_rate_name;
    identifier has_round_rate.hw_param;
    identifier has_round_rate.rate_param;
    identifier has_round_rate.parent_rate_param;
    @@

    long round_rate_name(struct clk_hw *hw_param, unsigned long rate_param,
                  unsigned long *parent_rate_param)
    {
    <...
    - rate_param
    + req->rate
    ...>
    }

    // Change parent_rate to req->best_parent_rate
    @ chg_parent_rate depends on generate_name @
    identifier has_round_rate.round_rate_name;
    identifier has_round_rate.hw_param;
    identifier has_round_rate.rate_param;
    identifier has_round_rate.parent_rate_param;
    @@

    long round_rate_name(struct clk_hw *hw_param, unsigned long rate_param,
                  unsigned long *parent_rate_param)
    {
    <...
    (
    - *parent_rate_param
    + req->best_parent_rate
    |
    - parent_rate_param
    + &req->best_parent_rate
    )
    ...>
    }

    // Convert the function definition from round_rate() to determine_rate()
    @ func_definition depends on chg_rate @
    identifier has_round_rate.round_rate_name;
    identifier has_round_rate.hw_param;
    identifier has_round_rate.rate_param;
    identifier has_round_rate.parent_rate_param;
    identifier generate_name.new_name;
    @@

    - long round_rate_name(struct clk_hw *hw_param, unsigned long rate_param,
    -               unsigned long *parent_rate_param)
    + int new_name(struct clk_hw *hw, struct clk_rate_request *req)
    {
        ...
    }

    // Update the ops from round_rate() to determine_rate()
    @ ops depends on func_definition @
    identifier has_round_rate.round_rate_name;
    identifier generate_name.new_name;
    @@

    {
        ...,
    -   .round_rate = round_rate_name,
    +   .determine_rate = new_name,
        ...,
    }

Note that I used coccinelle 1.2 instead of 1.3 since the newer version
adds unnecessary braces as described in this post.
https://lore.kernel.org/cocci/67642477-5f3e-4b2a-914d-579a54f48cbd at intel.com/

Signed-off-by: Brian Masney <bmasney at redhat.com>
---
Brian Masney (9):
      phy: freescale: phy-fsl-samsung-hdmi: convert from round_rate() to determine_rate()
      phy: mediatek: phy-mtk-hdmi-mt2701: convert from round_rate() to determine_rate()
      phy: mediatek: phy-mtk-hdmi-mt8173: convert from round_rate() to determine_rate()
      phy: mediatek: phy-mtk-hdmi-mt8195: convert from round_rate() to determine_rate()
      phy: mediatek: phy-mtk-mipi-dsi-mt8173: convert from round_rate() to determine_rate()
      phy: mediatek: phy-mtk-mipi-dsi-mt8183: convert from round_rate() to determine_rate()
      phy: rockchip: phy-rockchip-inno-hdmi: convert from round_rate() to determine_rate()
      phy: rockchip: phy-rockchip-samsung-hdptx: convert from round_rate() to determine_rate()
      phy: ti: phy-j721e-wiz: convert from round_rate() to determine_rate()

 drivers/phy/freescale/phy-fsl-samsung-hdmi.c      | 13 ++++++----
 drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c        |  8 +++---
 drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c        | 16 ++++++------
 drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c        | 10 ++++----
 drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c    | 10 +++++---
 drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c    | 10 +++++---
 drivers/phy/rockchip/phy-rockchip-inno-hdmi.c     | 30 ++++++++++++-----------
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 14 ++++++-----
 drivers/phy/ti/phy-j721e-wiz.c                    | 11 ++++++---
 9 files changed, 68 insertions(+), 54 deletions(-)
---
base-commit: df5d79720b152e7ff058f11ed7e88d5b5c8d2a0c
change-id: 20251106-phy-clk-route-rate-v2-resend-a86cb210196b

Best regards,
-- 
Brian Masney <bmasney at redhat.com>



From bmasney at redhat.com  Thu Nov  6 15:25:47 2025
From: bmasney at redhat.com (Brian Masney)
Date: Thu, 06 Nov 2025 18:25:47 -0500
Subject: [PATCH v2 RESEND 1/9] phy: freescale: phy-fsl-samsung-hdmi:
 convert from round_rate() to determine_rate()
In-Reply-To: <20251106-phy-clk-route-rate-v2-resend-v1-0-e2058963bfb1@redhat.com>
References: <20251106-phy-clk-route-rate-v2-resend-v1-0-e2058963bfb1@redhat.com>
Message-ID: <20251106-phy-clk-route-rate-v2-resend-v1-1-e2058963bfb1@redhat.com>

The round_rate() clk ops is deprecated, so migrate this driver from
round_rate() to determine_rate() using the Coccinelle semantic patch
on the cover letter of this series.

Signed-off-by: Brian Masney <bmasney at redhat.com>
---
 drivers/phy/freescale/phy-fsl-samsung-hdmi.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
index 191c282246d96e3f6c5a8d17abe078892882bf44..d010fec15671d33cc363af79e9f1c3f26ecb3464 100644
--- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
+++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c
@@ -570,17 +570,20 @@ const struct phy_config *fsl_samsung_hdmi_phy_find_settings(struct fsl_samsung_h
 	return fract_div_phy;
 }
 
-static long fsl_samsung_hdmi_phy_clk_round_rate(struct clk_hw *hw,
-						unsigned long rate, unsigned long *parent_rate)
+static int fsl_samsung_hdmi_phy_clk_determine_rate(struct clk_hw *hw,
+						   struct clk_rate_request *req)
 {
 	struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw);
-	const struct phy_config *target_settings = fsl_samsung_hdmi_phy_find_settings(phy, rate);
+	const struct phy_config *target_settings = fsl_samsung_hdmi_phy_find_settings(phy,
+										      req->rate);
 
 	if (target_settings == NULL)
 		return -EINVAL;
 
 	dev_dbg(phy->dev, "round_rate, closest rate = %u\n", target_settings->pixclk);
-	return target_settings->pixclk;
+	req->rate = target_settings->pixclk;
+
+	return 0;
 }
 
 static int fsl_samsung_hdmi_phy_clk_set_rate(struct clk_hw *hw,
@@ -599,7 +602,7 @@ static int fsl_samsung_hdmi_phy_clk_set_rate(struct clk_hw *hw,
 
 static const struct clk_ops phy_clk_ops = {
 	.recalc_rate = phy_clk_recalc_rate,
-	.round_rate = fsl_samsung_hdmi_phy_clk_round_rate,
+	.determine_rate = fsl_samsung_hdmi_phy_clk_determine_rate,
 	.set_rate = fsl_samsung_hdmi_phy_clk_set_rate,
 };
 

-- 
2.51.0



From bmasney at redhat.com  Thu Nov  6 15:25:48 2025
From: bmasney at redhat.com (Brian Masney)
Date: Thu, 06 Nov 2025 18:25:48 -0500
Subject: [PATCH v2 RESEND 2/9] phy: mediatek: phy-mtk-hdmi-mt2701: convert
 from round_rate() to determine_rate()
In-Reply-To: <20251106-phy-clk-route-rate-v2-resend-v1-0-e2058963bfb1@redhat.com>
References: <20251106-phy-clk-route-rate-v2-resend-v1-0-e2058963bfb1@redhat.com>
Message-ID: <20251106-phy-clk-route-rate-v2-resend-v1-2-e2058963bfb1@redhat.com>

The round_rate() clk ops is deprecated, so migrate this driver from
round_rate() to determine_rate() using the Coccinelle semantic patch
on the cover letter of this series.

Signed-off-by: Brian Masney <bmasney at redhat.com>
---
 drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c b/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c
index e51b2d13eab473dddace48c75c2a8d73c8c65635..b0b6497e7eedcb6867541b573d22156ded29a4d5 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c
+++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c
@@ -90,10 +90,10 @@ static void mtk_hdmi_pll_unprepare(struct clk_hw *hw)
 	usleep_range(80, 100);
 }
 
-static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
-				    unsigned long *parent_rate)
+static int mtk_hdmi_pll_determine_rate(struct clk_hw *hw,
+				       struct clk_rate_request *req)
 {
-	return rate;
+	return 0;
 }
 
 static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -170,7 +170,7 @@ static const struct clk_ops mtk_hdmi_phy_pll_ops = {
 	.prepare = mtk_hdmi_pll_prepare,
 	.unprepare = mtk_hdmi_pll_unprepare,
 	.set_rate = mtk_hdmi_pll_set_rate,
-	.round_rate = mtk_hdmi_pll_round_rate,
+	.determine_rate = mtk_hdmi_pll_determine_rate,
 	.recalc_rate = mtk_hdmi_pll_recalc_rate,
 };
 

-- 
2.51.0



From bmasney at redhat.com  Thu Nov  6 15:25:49 2025
From: bmasney at redhat.com (Brian Masney)
Date: Thu, 06 Nov 2025 18:25:49 -0500
Subject: [PATCH v2 RESEND 3/9] phy: mediatek: phy-mtk-hdmi-mt8173: convert
 from round_rate() to determine_rate()
In-Reply-To: <20251106-phy-clk-route-rate-v2-resend-v1-0-e2058963bfb1@redhat.com>
References: <20251106-phy-clk-route-rate-v2-resend-v1-0-e2058963bfb1@redhat.com>
Message-ID: <20251106-phy-clk-route-rate-v2-resend-v1-3-e2058963bfb1@redhat.com>

The round_rate() clk ops is deprecated, so migrate this driver from
round_rate() to determine_rate() using the Coccinelle semantic patch
on the cover letter of this series.

Signed-off-by: Brian Masney <bmasney at redhat.com>
---
 drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c b/drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c
index d04758396046363ab9edc584ae10bf31e9c5fb0f..58c6596c8c20bdacf96a97709b8f5709f447e85b 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c
+++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c
@@ -118,18 +118,18 @@ static void mtk_hdmi_pll_unprepare(struct clk_hw *hw)
 	usleep_range(100, 150);
 }
 
-static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
-				    unsigned long *parent_rate)
+static int mtk_hdmi_pll_determine_rate(struct clk_hw *hw,
+				       struct clk_rate_request *req)
 {
 	struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
 
-	hdmi_phy->pll_rate = rate;
-	if (rate <= 74250000)
-		*parent_rate = rate;
+	hdmi_phy->pll_rate = req->rate;
+	if (req->rate <= 74250000)
+		req->best_parent_rate = req->rate;
 	else
-		*parent_rate = rate / 2;
+		req->best_parent_rate = req->rate / 2;
 
-	return rate;
+	return 0;
 }
 
 static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -223,7 +223,7 @@ static const struct clk_ops mtk_hdmi_phy_pll_ops = {
 	.prepare = mtk_hdmi_pll_prepare,
 	.unprepare = mtk_hdmi_pll_unprepare,
 	.set_rate = mtk_hdmi_pll_set_rate,
-	.round_rate = mtk_hdmi_pll_round_rate,
+	.determine_rate = mtk_hdmi_pll_determine_rate,
 	.recalc_rate = mtk_hdmi_pll_recalc_rate,
 };
 

-- 
2.51.0



From bmasney at redhat.com  Thu Nov  6 15:25:50 2025
From: bmasney at redhat.com (Brian Masney)
Date: Thu, 06 Nov 2025 18:25:50 -0500
Subject: [PATCH v2 RESEND 4/9] phy: mediatek: phy-mtk-hdmi-mt8195: convert
 from round_rate() to determine_rate()
In-Reply-To: <20251106-phy-clk-route-rate-v2-resend-v1-0-e2058963bfb1@redhat.com>
References: <20251106-phy-clk-route-rate-v2-resend-v1-0-e2058963bfb1@redhat.com>
Message-ID: <20251106-phy-clk-route-rate-v2-resend-v1-4-e2058963bfb1@redhat.com>

The round_rate() clk ops is deprecated, so migrate this driver from
round_rate() to determine_rate() using the Coccinelle semantic patch
on the cover letter of this series.

Signed-off-by: Brian Masney <bmasney at redhat.com>
---
 drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
index b38f3ae26b3f3d8c9e73b43d86510acf6cedb471..1426a2db984d53b91125b18f7725738c44f19555 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
+++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
@@ -418,13 +418,13 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 	return mtk_hdmi_pll_calc(hdmi_phy, hw, rate, parent_rate);
 }
 
-static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
-				    unsigned long *parent_rate)
+static int mtk_hdmi_pll_determine_rate(struct clk_hw *hw,
+				       struct clk_rate_request *req)
 {
 	struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
 
-	hdmi_phy->pll_rate = rate;
-	return rate;
+	hdmi_phy->pll_rate = req->rate;
+	return 0;
 }
 
 static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
@@ -439,7 +439,7 @@ static const struct clk_ops mtk_hdmi_pll_ops = {
 	.prepare = mtk_hdmi_pll_prepare,
 	.unprepare = mtk_hdmi_pll_unprepare,
 	.set_rate = mtk_hdmi_pll_set_rate,
-	.round_rate = mtk_hdmi_pll_round_rate,
+	.determine_rate = mtk_hdmi_pll_determine_rate,
 	.recalc_rate = mtk_hdmi_pll_recalc_rate,
 };
 

-- 
2.51.0



From bmasney at redhat.com  Thu Nov  6 15:25:51 2025
From: bmasney at redhat.com (Brian Masney)
Date: Thu, 06 Nov 2025 18:25:51 -0500
Subject: [PATCH v2 RESEND 5/9] phy: mediatek: phy-mtk-mipi-dsi-mt8173:
 convert from round_rate() to determine_rate()
In-Reply-To: <20251106-phy-clk-route-rate-v2-resend-v1-0-e2058963bfb1@redhat.com>
References: <20251106-phy-clk-route-rate-v2-resend-v1-0-e2058963bfb1@redhat.com>
Message-ID: <20251106-phy-clk-route-rate-v2-resend-v1-5-e2058963bfb1@redhat.com>

The round_rate() clk ops is deprecated, so migrate this driver from
round_rate() to determine_rate() using the Coccinelle semantic patch
on the cover letter of this series.

Signed-off-by: Brian Masney <bmasney at redhat.com>
---
 drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c
index 673cb0f08959e0e4f2b1ade2ebaf796e8b76f8bc..438ff3605d90121b7bfe02b3ddca8194437ed9ba 100644
--- a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c
+++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c
@@ -237,16 +237,18 @@ static void mtk_mipi_tx_pll_unprepare(struct clk_hw *hw)
 	mtk_phy_clear_bits(base + MIPITX_DSI_PLL_CON0, RG_DSI_MPPLL_DIV_MSK);
 }
 
-static long mtk_mipi_tx_pll_round_rate(struct clk_hw *hw, unsigned long rate,
-				       unsigned long *prate)
+static int mtk_mipi_tx_pll_determine_rate(struct clk_hw *hw,
+					  struct clk_rate_request *req)
 {
-	return clamp_val(rate, 50000000, 1250000000);
+	req->rate = clamp_val(req->rate, 50000000, 1250000000);
+
+	return 0;
 }
 
 static const struct clk_ops mtk_mipi_tx_pll_ops = {
 	.prepare = mtk_mipi_tx_pll_prepare,
 	.unprepare = mtk_mipi_tx_pll_unprepare,
-	.round_rate = mtk_mipi_tx_pll_round_rate,
+	.determine_rate = mtk_mipi_tx_pll_determine_rate,
 	.set_rate = mtk_mipi_tx_pll_set_rate,
 	.recalc_rate = mtk_mipi_tx_pll_recalc_rate,
 };

-- 
2.51.0



From bmasney at redhat.com  Thu Nov  6 15:25:52 2025
From: bmasney at redhat.com (Brian Masney)
Date: Thu, 06 Nov 2025 18:25:52 -0500
Subject: [PATCH v2 RESEND 6/9] phy: mediatek: phy-mtk-mipi-dsi-mt8183:
 convert from round_rate() to determine_rate()
In-Reply-To: <20251106-phy-clk-route-rate-v2-resend-v1-0-e2058963bfb1@redhat.com>
References: <20251106-phy-clk-route-rate-v2-resend-v1-0-e2058963bfb1@redhat.com>
Message-ID: <20251106-phy-clk-route-rate-v2-resend-v1-6-e2058963bfb1@redhat.com>

The round_rate() clk ops is deprecated, so migrate this driver from
round_rate() to determine_rate() using the Coccinelle semantic patch
on the cover letter of this series.

Signed-off-by: Brian Masney <bmasney at redhat.com>
---
 drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
index 553725e1269c9d7ad88f89367dfa1cf367aaf1ce..a54d44ef70ab49937d210f04fdf42300e8e5f2de 100644
--- a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
+++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
@@ -97,16 +97,18 @@ static void mtk_mipi_tx_pll_disable(struct clk_hw *hw)
 	mtk_phy_clear_bits(base + MIPITX_PLL_PWR, AD_DSI_PLL_SDM_PWR_ON);
 }
 
-static long mtk_mipi_tx_pll_round_rate(struct clk_hw *hw, unsigned long rate,
-				       unsigned long *prate)
+static int mtk_mipi_tx_pll_determine_rate(struct clk_hw *hw,
+					  struct clk_rate_request *req)
 {
-	return clamp_val(rate, 125000000, 1600000000);
+	req->rate = clamp_val(req->rate, 125000000, 1600000000);
+
+	return 0;
 }
 
 static const struct clk_ops mtk_mipi_tx_pll_ops = {
 	.enable = mtk_mipi_tx_pll_enable,
 	.disable = mtk_mipi_tx_pll_disable,
-	.round_rate = mtk_mipi_tx_pll_round_rate,
+	.determine_rate = mtk_mipi_tx_pll_determine_rate,
 	.set_rate = mtk_mipi_tx_pll_set_rate,
 	.recalc_rate = mtk_mipi_tx_pll_recalc_rate,
 };

-- 
2.51.0



From bmasney at redhat.com  Thu Nov  6 15:25:53 2025
From: bmasney at redhat.com (Brian Masney)
Date: Thu, 06 Nov 2025 18:25:53 -0500
Subject: [PATCH v2 RESEND 7/9] phy: rockchip: phy-rockchip-inno-hdmi:
 convert from round_rate() to determine_rate()
In-Reply-To: <20251106-phy-clk-route-rate-v2-resend-v1-0-e2058963bfb1@redhat.com>
References: <20251106-phy-clk-route-rate-v2-resend-v1-0-e2058963bfb1@redhat.com>
Message-ID: <20251106-phy-clk-route-rate-v2-resend-v1-7-e2058963bfb1@redhat.com>

The round_rate() clk ops is deprecated, so migrate this driver from
round_rate() to determine_rate() using the Coccinelle semantic patch
on the cover letter of this series.

Reviewed-by: Heiko Stuebner <heiko at sntech.de>
Signed-off-by: Brian Masney <bmasney at redhat.com>
---
 drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 30 ++++++++++++++-------------
 1 file changed, 16 insertions(+), 14 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
index 8dcc2bb777b5455d21a10f06c5ad842b2ddbc834..1483907413faa5ce1dc8614db05e6e929410404d 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
@@ -749,22 +749,23 @@ unsigned long inno_hdmi_phy_rk3228_clk_recalc_rate(struct clk_hw *hw,
 	return vco;
 }
 
-static long inno_hdmi_phy_rk3228_clk_round_rate(struct clk_hw *hw,
-						unsigned long rate,
-						unsigned long *parent_rate)
+static int inno_hdmi_phy_rk3228_clk_determine_rate(struct clk_hw *hw,
+						   struct clk_rate_request *req)
 {
 	const struct pre_pll_config *cfg = pre_pll_cfg_table;
 
-	rate = (rate / 1000) * 1000;
+	req->rate = (req->rate / 1000) * 1000;
 
 	for (; cfg->pixclock != 0; cfg++)
-		if (cfg->pixclock == rate && !cfg->fracdiv)
+		if (cfg->pixclock == req->rate && !cfg->fracdiv)
 			break;
 
 	if (cfg->pixclock == 0)
 		return -EINVAL;
 
-	return cfg->pixclock;
+	req->rate = cfg->pixclock;
+
+	return 0;
 }
 
 static int inno_hdmi_phy_rk3228_clk_set_rate(struct clk_hw *hw,
@@ -835,7 +836,7 @@ static const struct clk_ops inno_hdmi_phy_rk3228_clk_ops = {
 	.unprepare = inno_hdmi_phy_rk3228_clk_unprepare,
 	.is_prepared = inno_hdmi_phy_rk3228_clk_is_prepared,
 	.recalc_rate = inno_hdmi_phy_rk3228_clk_recalc_rate,
-	.round_rate = inno_hdmi_phy_rk3228_clk_round_rate,
+	.determine_rate = inno_hdmi_phy_rk3228_clk_determine_rate,
 	.set_rate = inno_hdmi_phy_rk3228_clk_set_rate,
 };
 
@@ -906,22 +907,23 @@ unsigned long inno_hdmi_phy_rk3328_clk_recalc_rate(struct clk_hw *hw,
 	return inno->pixclock;
 }
 
-static long inno_hdmi_phy_rk3328_clk_round_rate(struct clk_hw *hw,
-						unsigned long rate,
-						unsigned long *parent_rate)
+static int inno_hdmi_phy_rk3328_clk_determine_rate(struct clk_hw *hw,
+						   struct clk_rate_request *req)
 {
 	const struct pre_pll_config *cfg = pre_pll_cfg_table;
 
-	rate = (rate / 1000) * 1000;
+	req->rate = (req->rate / 1000) * 1000;
 
 	for (; cfg->pixclock != 0; cfg++)
-		if (cfg->pixclock == rate)
+		if (cfg->pixclock == req->rate)
 			break;
 
 	if (cfg->pixclock == 0)
 		return -EINVAL;
 
-	return cfg->pixclock;
+	req->rate = cfg->pixclock;
+
+	return 0;
 }
 
 static int inno_hdmi_phy_rk3328_clk_set_rate(struct clk_hw *hw,
@@ -989,7 +991,7 @@ static const struct clk_ops inno_hdmi_phy_rk3328_clk_ops = {
 	.unprepare = inno_hdmi_phy_rk3328_clk_unprepare,
 	.is_prepared = inno_hdmi_phy_rk3328_clk_is_prepared,
 	.recalc_rate = inno_hdmi_phy_rk3328_clk_recalc_rate,
-	.round_rate = inno_hdmi_phy_rk3328_clk_round_rate,
+	.determine_rate = inno_hdmi_phy_rk3328_clk_determine_rate,
 	.set_rate = inno_hdmi_phy_rk3328_clk_set_rate,
 };
 

-- 
2.51.0



From bmasney at redhat.com  Thu Nov  6 15:25:54 2025
From: bmasney at redhat.com (Brian Masney)
Date: Thu, 06 Nov 2025 18:25:54 -0500
Subject: [PATCH v2 RESEND 8/9] phy: rockchip: phy-rockchip-samsung-hdptx:
 convert from round_rate() to determine_rate()
In-Reply-To: <20251106-phy-clk-route-rate-v2-resend-v1-0-e2058963bfb1@redhat.com>
References: <20251106-phy-clk-route-rate-v2-resend-v1-0-e2058963bfb1@redhat.com>
Message-ID: <20251106-phy-clk-route-rate-v2-resend-v1-8-e2058963bfb1@redhat.com>

The round_rate() clk ops is deprecated, so migrate this driver from
round_rate() to determine_rate() using the Coccinelle semantic patch
on the cover letter of this series.

Reviewed-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
Reviewed-by: Heiko Stuebner <heiko at sntech.de>
Signed-off-by: Brian Masney <bmasney at redhat.com>
---
 drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
index 01bbf668e05ef94e24a3fa11f96f219c4f942451..e5436c99a3c435715358a07da73b4d10d78ef1fc 100644
--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
+++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
@@ -1868,8 +1868,8 @@ static unsigned long rk_hdptx_phy_clk_recalc_rate(struct clk_hw *hw,
 	return hdptx->hw_rate;
 }
 
-static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
-					unsigned long *parent_rate)
+static int rk_hdptx_phy_clk_determine_rate(struct clk_hw *hw,
+					   struct clk_rate_request *req)
 {
 	struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);
 
@@ -1878,9 +1878,9 @@ static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
 	 * To be dropped as soon as the RK DW HDMI QP bridge driver
 	 * switches to make use of phy_configure().
 	 */
-	if (!hdptx->restrict_rate_change && rate != hdptx->hdmi_cfg.tmds_char_rate) {
+	if (!hdptx->restrict_rate_change && req->rate != hdptx->hdmi_cfg.tmds_char_rate) {
 		struct phy_configure_opts_hdmi hdmi = {
-			.tmds_char_rate = rate,
+			.tmds_char_rate = req->rate,
 		};
 		int ret = rk_hdptx_phy_verify_hdmi_config(hdptx, &hdmi);
 
@@ -1895,7 +1895,9 @@ static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate,
 	 * hence ensure rk_hdptx_phy_clk_set_rate() won't be invoked with
 	 * a different rate argument.
 	 */
-	return hdptx->hdmi_cfg.tmds_char_rate;
+	req->rate = hdptx->hdmi_cfg.tmds_char_rate;
+
+	return 0;
 }
 
 static int rk_hdptx_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -1924,7 +1926,7 @@ static const struct clk_ops hdptx_phy_clk_ops = {
 	.prepare = rk_hdptx_phy_clk_prepare,
 	.unprepare = rk_hdptx_phy_clk_unprepare,
 	.recalc_rate = rk_hdptx_phy_clk_recalc_rate,
-	.round_rate = rk_hdptx_phy_clk_round_rate,
+	.determine_rate = rk_hdptx_phy_clk_determine_rate,
 	.set_rate = rk_hdptx_phy_clk_set_rate,
 };
 

-- 
2.51.0



From bmasney at redhat.com  Thu Nov  6 15:25:55 2025
From: bmasney at redhat.com (Brian Masney)
Date: Thu, 06 Nov 2025 18:25:55 -0500
Subject: [PATCH v2 RESEND 9/9] phy: ti: phy-j721e-wiz: convert from
 round_rate() to determine_rate()
In-Reply-To: <20251106-phy-clk-route-rate-v2-resend-v1-0-e2058963bfb1@redhat.com>
References: <20251106-phy-clk-route-rate-v2-resend-v1-0-e2058963bfb1@redhat.com>
Message-ID: <20251106-phy-clk-route-rate-v2-resend-v1-9-e2058963bfb1@redhat.com>

The round_rate() clk ops is deprecated, so migrate this driver from
round_rate() to determine_rate() using the Coccinelle semantic patch
on the cover letter of this series.

Signed-off-by: Brian Masney <bmasney at redhat.com>
---
 drivers/phy/ti/phy-j721e-wiz.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c
index a8b440c6c46bb0c754845655f9c2c0ba6b435b8d..cbc98d4dec74560e6403fb899ebe2bb916440f45 100644
--- a/drivers/phy/ti/phy-j721e-wiz.c
+++ b/drivers/phy/ti/phy-j721e-wiz.c
@@ -934,12 +934,15 @@ static unsigned long wiz_clk_div_recalc_rate(struct clk_hw *hw,
 	return divider_recalc_rate(hw, parent_rate, val, div->table, 0x0, 2);
 }
 
-static long wiz_clk_div_round_rate(struct clk_hw *hw, unsigned long rate,
-				   unsigned long *prate)
+static int wiz_clk_div_determine_rate(struct clk_hw *hw,
+				      struct clk_rate_request *req)
 {
 	struct wiz_clk_divider *div = to_wiz_clk_div(hw);
 
-	return divider_round_rate(hw, rate, prate, div->table, 2, 0x0);
+	req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate,
+				       div->table, 2, 0x0);
+
+	return 0;
 }
 
 static int wiz_clk_div_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -958,7 +961,7 @@ static int wiz_clk_div_set_rate(struct clk_hw *hw, unsigned long rate,
 
 static const struct clk_ops wiz_clk_div_ops = {
 	.recalc_rate = wiz_clk_div_recalc_rate,
-	.round_rate = wiz_clk_div_round_rate,
+	.determine_rate = wiz_clk_div_determine_rate,
 	.set_rate = wiz_clk_div_set_rate,
 };
 

-- 
2.51.0



From macromorgan at hotmail.com  Thu Nov  6 15:45:07 2025
From: macromorgan at hotmail.com (Chris Morgan)
Date: Thu, 6 Nov 2025 17:45:07 -0600
Subject: [PATCH 2/5] arm64: dts: rockchip: Add Additional pinctrl defs
 for Indiedroid Nova
In-Reply-To: <3438819.aeNJFYEL58@phil>
References: <20251105205708.732125-1-macroalpha82@gmail.com>
 <20251105205708.732125-3-macroalpha82@gmail.com>
 <3438819.aeNJFYEL58@phil>
Message-ID: <SN6PR1901MB4654BD4EBF84CCA3DF4FD902A5C2A@SN6PR1901MB4654.namprd19.prod.outlook.com>

On Thu, Nov 06, 2025 at 08:45:33PM +0100, Heiko Stuebner wrote:
> Hi Chris,
> 
> Am Mittwoch, 5. November 2025, 21:57:05 Mitteleurop?ische Normalzeit schrieb Chris Morgan:
> > From: Chris Morgan <macromorgan at hotmail.com>
> > 
> > Define the pinctrl nodes for the WiFi interrupts, correct the pinctrl
> > for the ethernet according to the schematic, and add the clk32k_in
> > control for the RTC. Add the correct regulator mapping for the PCIE
> > too.
> 
> way too much completely different things to stuff into one patch.

Sorry, to me this seemed like a few tiny fixes that, excluding the pcie
regulator addition, all related to correcting pinctrl definitions. I'll
be happy to split it up if need be. The SDIO wifi is really just adding
the interrupt pin... there was just a bit of stuff to add on top so I
could define it correctly; for ethernet I'm replacing the reset pin with
the PCIE port reset pin and adding other PCIE pins defined in the
schematic, and the clk32k_in is just adding another pin to note that the
RTC output is connected to that pin.

Thank you,
Chris

> 
> - Adding the sdio wifi is one
> - ethernet is next ... you're not fixing, but removing the pinctrl?
> - pcie2 fixes is another one
> - and the clkin32k as well
> 
> 
> Heiko
> 
> > 
> > Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
> > ---
> >  .../dts/rockchip/rk3588s-indiedroid-nova.dts  | 43 ++++++++++++-------
> >  1 file changed, 28 insertions(+), 15 deletions(-)
> > 
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
> > index debab7732b71..f40782b6c7db 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
> > +++ b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
> > @@ -406,7 +406,7 @@ rtc_hym8563: rtc at 51 {
> >  		clock-output-names = "hym8563";
> >  		interrupt-parent = <&gpio0>;
> >  		interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>;
> > -		pinctrl-0 = <&hym8563_int>;
> > +		pinctrl-0 = <&hym8563_int>, <&clk32k_in>;
> >  		pinctrl-names = "default";
> >  		wakeup-source;
> >  	};
> > @@ -459,8 +459,11 @@ &i2s5_8ch {
> >  };
> >  
> >  &pcie2x1l2 {
> > -	pinctrl-0 = <&rtl8111_perstb>;
> > +	pinctrl-0 = <&pcie20x1m0_perstn>, <&pcie20x1m0_clkreqn>,
> > +		    <&pcie20x1m0_waken>;
> >  	pinctrl-names = "default";
> > +	reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
> > +	vpcie3v3-supply = <&vcc_3v3_s3>;
> >  	status = "okay";
> >  };
> >  
> > @@ -486,12 +489,6 @@ bt_wake_host: bt-wake-host {
> >  		};
> >  	};
> >  
> > -	ethernet-pins {
> > -		rtl8111_perstb: rtl8111-perstb {
> > -			rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>;
> > -		};
> > -	};
> > -
> >  	hym8563 {
> >  
> >  		hym8563_int: hym8563-int {
> > @@ -500,13 +497,6 @@ hym8563_int: hym8563-int {
> >  		};
> >  	};
> >  
> > -	sdio-pwrseq {
> > -		wifi_enable_h: wifi-enable-h {
> > -			rockchip,pins =
> > -				<0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>;
> > -		};
> > -	};
> > -
> >  	usb-typec {
> >  		usbc0_int: usbc0-int {
> >  			rockchip,pins =
> > @@ -518,6 +508,18 @@ typec5v_pwren: typec5v-pwren {
> >  				<4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
> >  		};
> >  	};
> > +
> > +	wifi {
> > +		wifi_enable_h: wifi-enable-h {
> > +			rockchip,pins =
> > +				<0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>;
> > +		};
> > +
> > +		wifi_host_wake_irq: wifi-host-wake-irq {
> > +			rockchip,pins =
> > +				<0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_down>;
> > +		};
> > +	};
> >  };
> >  
> >  &saradc {
> > @@ -538,6 +540,7 @@ &sdhci {
> >  };
> >  
> >  &sdio {
> > +	#address-cells = <1>;
> >  	bus-width = <4>;
> >  	cap-sd-highspeed;
> >  	cap-sdio-irq;
> > @@ -549,9 +552,19 @@ &sdio {
> >  	no-sd;
> >  	non-removable;
> >  	sd-uhs-sdr104;
> > +	#size-cells = <0>;
> >  	vmmc-supply = <&vcc_3v3_s3>;
> >  	vqmmc-supply = <&vcc_1v8_s3>;
> >  	status = "okay";
> > +
> > +	sdio_wifi: wifi at 1 {
> > +		reg = <1>;
> > +		interrupt-parent = <&gpio0>;
> > +		interrupts = <RK_PA0 IRQ_TYPE_LEVEL_LOW>;
> > +		interrupt-names = "host-wake";
> > +		pinctrl-0 = <&wifi_host_wake_irq>;
> > +		pinctrl-names = "default";
> > +	};
> >  };
> >  
> >  &sdmmc {
> > 
> 
> 
> 
> 


From macromorgan at hotmail.com  Thu Nov  6 15:46:27 2025
From: macromorgan at hotmail.com (Chris Morgan)
Date: Thu, 6 Nov 2025 17:46:27 -0600
Subject: [PATCH 2/3] drm/bridge: dw-hdmi-qp: Add support for missing HPD
In-Reply-To: <2301926.irdbgypaU6@phil>
References: <20251106180914.768502-1-macroalpha82@gmail.com>
 <20251106180914.768502-3-macroalpha82@gmail.com>
 <2301926.irdbgypaU6@phil>
Message-ID: <SN6PR1901MB4654F4B7C67C04A00559C7C7A5C2A@SN6PR1901MB4654.namprd19.prod.outlook.com>

On Thu, Nov 06, 2025 at 08:40:55PM +0100, Heiko Stuebner wrote:
> Am Donnerstag, 6. November 2025, 19:09:13 Mitteleurop?ische Normalzeit schrieb Chris Morgan:
> > From: Chris Morgan <macromorgan at hotmail.com>
> > 
> > Add support for the dw-hdmi-qp driver to handle devices with missing
> > HPD pins.
> > 
> > Since in this situation we are now polling for the EDID data via i2c
> > change the error message to a debug message when we are unable to
> > complete an i2c read, as a disconnected device would otherwise fill
> > dmesg with i2c read errors.
> > 
> > Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
> 
> > @@ -1074,12 +1095,18 @@ struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev,
> >  	if (ret)
> >  		return ERR_PTR(ret);
> >  
> > +	if (of_property_present(pdev->dev.of_node, "no-hpd"))
> > +		hdmi->no_hpd = 1;
> > +	else
> > +		hdmi->no_hpd = 0;
> > +
> 
> what is the argument against
> 
> hdmi->no_hpd = of_property_read_bool(pdev->dev.of_node, "no-hpd")); ?
> 

I'm a self taught and not always that efficient? :-p
I'll make the change for the next version.

Thank you,
Chris

> 
> 
> 
> 


From shawn.lin at rock-chips.com  Thu Nov  6 16:34:29 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Fri, 7 Nov 2025 08:34:29 +0800
Subject: [PATCH] PCI: Add ASPM quirk for Hi1105 PCIe Wi-Fi
In-Reply-To: <20251106195057.GA1965757@bhelgaas>
References: <20251106195057.GA1965757@bhelgaas>
Message-ID: <9b83595d-ba79-404d-a7ff-ed07f524966f@rock-chips.com>

? 2025/11/07 ??? 3:50, Bjorn Helgaas ??:
> On Thu, Nov 06, 2025 at 11:51:59AM +0800, Shawn Lin wrote:
>> This Wi-Fi advertises the L0s and L1 capabilities but actually
>> it doesn't support them. This's comfirmed by Hisilicon team in
>> actual productization.
>>
>> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
>> ---
>>
>>   drivers/pci/quirks.c | 6 ++++++
>>   1 file changed, 6 insertions(+)
>>
>> diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
>> index 214ed06..67250d4 100644
>> --- a/drivers/pci/quirks.c
>> +++ b/drivers/pci/quirks.c
>> @@ -2526,6 +2526,12 @@ static void quirk_disable_aspm_l0s_l1(struct pci_dev *dev)
>>   DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ASMEDIA, 0x1080, quirk_disable_aspm_l0s_l1);
>>   
>>   /*
>> + * The Hi1105 PCIe Wi-Fi doesn't support L0s and L1 but advertise the capability.
>> + * Disable both L0s and L1 for now.
>> + */
>> +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_HUAWEI, 0x1105, quirk_disable_aspm_l0s_l1);
> 
> PCI_VENDOR_ID_HUAWEI is 0x19e5.  Is there an upstream driver that
> matches [19e5:1105]?  I didn't find anything.

Yes, like plenty of other wireless drivers, Hi1105 driver is also out of
tree.

> 
> I think quirk_disable_aspm_l0s_l1() might be a problem because the new
> strategy is to enable ASPM early (in pcie_aspm_init_link_state(),
> called from pci_scan_slot(), which happens before FINAL fixups are run
> during pci_bus_add_device().
> 

Oh, I missed this.

> So I think we will enable L0s and L1 briefly before
> quirk_disable_aspm_l0s_l1() runs, and it's possible we'd see a problem
> then.
> 
> But if you apply this series:
>    https://lore.kernel.org/r/20251106183643.1963801-1-helgaas at kernel.org
> 
> and then the patch below on top, I think we should avoid enabling L0s
> and L1 at all:
> 

The patch below looks good to me. I will fix it.
Thanks.

> diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
> index 44e780718953..24c278857159 100644
> --- a/drivers/pci/quirks.c
> +++ b/drivers/pci/quirks.c
> @@ -2536,6 +2536,7 @@ static void quirk_disable_aspm_l0s_l1_cap(struct pci_dev *dev)
>   	pci_info(dev, "ASPM: L0s L1 removed from Link Capabilities to work around device defect\n");
>   }
>   DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, 0x0451, quirk_disable_aspm_l0s_l1_cap);
> +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_HUAWEI, 0x1105, quirk_disable_aspm_l0s_l1_cap);
>   
>   /*
>    * Some Pericom PCIe-to-PCI bridges in reverse mode need the PCIe Retrain
> 



From zhangqing at rock-chips.com  Thu Nov  6 17:24:57 2025
From: zhangqing at rock-chips.com (zhangqing)
Date: Fri, 7 Nov 2025 09:24:57 +0800
Subject: [PATCH v5 6/7] dt-bindings: clock: rockchip: Add RK3506 clock and
 reset unit
In-Reply-To: <241e4a1d-039c-4738-b492-6325ad354b2e@kwiboo.se>
References: <20251027084147.4148739-1-zhangqing@rock-chips.com>
 <20251027084147.4148739-7-zhangqing@rock-chips.com>
 <241e4a1d-039c-4738-b492-6325ad354b2e@kwiboo.se>
Message-ID: <f39d34b3-5e52-4490-99d8-db9b32f1324e@rock-chips.com>


? 2025/10/30 21:55, Jonas Karlman ??:
> Hi Elaine,
>
> On 10/27/2025 9:41 AM, Elaine Zhang wrote:
>> From: Finley Xiao <finley.xiao at rock-chips.com>
>>
>> Add device tree bindings for clock and reset unit on RK3506 SoC.
>> Add clock and reset IDs for RK3506 SoC.
>>
>> Signed-off-by: Finley Xiao <finley.xiao at rock-chips.com>
>> ---
>>   .../bindings/clock/rockchip,rk3506-cru.yaml   |  51 ++++
>>   .../dt-bindings/clock/rockchip,rk3506-cru.h   | 285 ++++++++++++++++++
>>   .../dt-bindings/reset/rockchip,rk3506-cru.h   | 211 +++++++++++++
>>   3 files changed, 547 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
>>   create mode 100644 include/dt-bindings/clock/rockchip,rk3506-cru.h
>>   create mode 100644 include/dt-bindings/reset/rockchip,rk3506-cru.h
> [snip]
>
>> diff --git a/include/dt-bindings/reset/rockchip,rk3506-cru.h b/include/dt-bindings/reset/rockchip,rk3506-cru.h
>> new file mode 100644
>> index 000000000000..f38cc066009b
>> --- /dev/null
>> +++ b/include/dt-bindings/reset/rockchip,rk3506-cru.h
>> @@ -0,0 +1,211 @@
>> +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
>> +/*
>> + * Copyright (c) 2023-2025 Rockchip Electronics Co., Ltd.
>> + * Author: Finley Xiao <finley.xiao at rock-chips.com>
>> + */
>> +
>> +#ifndef _DT_BINDINGS_REST_ROCKCHIP_RK3506_H
>> +#define _DT_BINDINGS_REST_ROCKCHIP_RK3506_H
>> +
>> +/* CRU-->SOFTRST_CON00 */
>> +#define SRST_NCOREPORESET0_AC		0
>> +#define SRST_NCOREPORESET1_AC		1
>> +#define SRST_NCOREPORESET2_AC		2
>> +#define SRST_NCORESET0_AC		3
>> +#define SRST_NCORESET1_AC		4
>> +#define SRST_NCORESET2_AC		5
>> +#define SRST_NL2RESET_AC		6
>> +#define SRST_ARESETN_CORE_BIU_AC	7
>> +#define SRST_HRESETN_M0_AC		8
>> +
>> +/* CRU-->SOFTRST_CON02 */
>> +#define SRST_NDBGRESET			9
>> +#define SRST_PRESETN_CORE_BIU		10
>> +#define SRST_RESETN_PMU			11
>> +
>> +/* CRU-->SOFTRST_CON03 */
>> +#define SRST_PRESETN_DBG		12
>> +#define SRST_POTRESETN_DBG		13
>> +#define SRST_PRESETN_CORE_GRF		14
>> +#define SRST_RESETN_CORE_EMA_DETECT	15
>> +#define SRST_RESETN_REF_PVTPLL_CORE	16
>> +#define SRST_PRESETN_GPIO1		17
>> +#define SRST_DBRESETN_GPIO1		18
>> +
>> +/* CRU-->SOFTRST_CON04 */
>> +#define SRST_ARESETN_CORE_PERI_BIU	19
>> +#define SRST_ARESETN_DSMC		20
>> +#define SRST_PRESETN_DSMC		21
>> +#define SRST_RESETN_FLEXBUS		22
>> +#define SRST_ARESETN_FLEXBUS		23
>> +#define SRST_HRESETN_FLEXBUS		24
>> +#define SRST_ARESETN_DSMC_SLV		25
>> +#define SRST_HRESETN_DSMC_SLV		26
>> +#define SRST_RESETN_DSMC_SLV		27
>> +
>> +/* CRU-->SOFTRST_CON05 */
>> +#define SRST_ARESETN_BUS_BIU		28
>> +#define SRST_HRESETN_BUS_BIU		29
>> +#define SRST_PRESETN_BUS_BIU		30
>> +#define SRST_ARESETN_SYSRAM		31
>> +#define SRST_HRESETN_SYSRAM		32
>> +#define SRST_ARESETN_DMAC0		33
>> +#define SRST_ARESETN_DMAC1		34
>> +#define SRST_HRESETN_M0			35
>> +#define SRST_RESETN_M0_JTAG		36
>> +#define SRST_HRESETN_CRYPTO		37
> Is there a reason why this (and the RV1126B) reset names now include the
> RESETN name in all reset constant?
>
> For RK3528 and prior mainline SoCs the RESETN part of the name has been
> striped from the constant, suggest we also strip the RESETN part for
> RK3506 and RV1126B for consistency with other RK SoCs.

The current practice is to separate the reset id from the clk id.

Follow with others RK socs(RK3528?RK3588?RK3576.....)
>
> Regards,
> Jonas
>
> [snip]
>
-- 
??
???????????
Rockchip Electronics Co.,Ltd
????????????????89????A?21??
Add:No.21 Building, A District, No.89 Software Boulevard Fuzhou, Fujian 350003, P.R.China
Tel:+86-0591-83991906-8601
???350003
E-mail:elaine.zhang at rock-chips.com
****************************************************************************
??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

IMPORTANT NOTICE: This email is from Fuzhou Rockchip Electronics Co., Ltd .The contents of this email and any attachments may contain information that is privileged, confidential and/or exempt from disclosure under applicable law and relevant NDA. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution, or use of the information is STRICTLY PROHIBITED. Please immediately contact the sender as soon as possible and destroy the material in its entirety in any format. Thank you.

****************************************************************************



From zhangqing at rock-chips.com  Thu Nov  6 17:37:57 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Fri,  7 Nov 2025 09:37:57 +0800
Subject: [RESEND PATCH v6 4/5] dt-bindings: clock: rockchip: Add RK3506 clock and reset unit
Message-ID: <20251107013757.5013-1-zhangqing@rock-chips.com>

From: Finley Xiao <finley.xiao at rock-chips.com>

Add device tree bindings for clock and reset unit on RK3506 SoC.
Add clock and reset IDs for RK3506 SoC.

Signed-off-by: Finley Xiao <finley.xiao at rock-chips.com>
Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
---
 .../bindings/clock/rockchip,rk3506-cru.yaml   |  51 ++++
 .../dt-bindings/clock/rockchip,rk3506-cru.h   | 285 ++++++++++++++++++
 .../dt-bindings/reset/rockchip,rk3506-cru.h   | 211 +++++++++++++
 3 files changed, 547 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
 create mode 100644 include/dt-bindings/clock/rockchip,rk3506-cru.h
 create mode 100644 include/dt-bindings/reset/rockchip,rk3506-cru.h

diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml b/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
new file mode 100644
index 000000000000..ecb5fa497747
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/rockchip,rk3506-cru.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip RK3506 Clock and Reset Unit (CRU)
+
+maintainers:
+  - Finley Xiao <finley.xiao at rock-chips.com>
+  - Heiko Stuebner <heiko at sntech.de>
+
+description: |
+  The RK3506 CRU generates the clock and also implements reset for SoC
+  peripherals.
+
+properties:
+  compatible:
+    const: rockchip,rk3506-cru
+
+  reg:
+    maxItems: 1
+
+  "#clock-cells":
+    const: 1
+
+  "#reset-cells":
+    const: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    const: xin24m
+
+required:
+  - compatible
+  - reg
+  - "#clock-cells"
+  - "#reset-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller at ff9a0000 {
+      compatible = "rockchip,rk3506-cru";
+      reg = <0xff9a0000 0x20000>;
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+    };
diff --git a/include/dt-bindings/clock/rockchip,rk3506-cru.h b/include/dt-bindings/clock/rockchip,rk3506-cru.h
new file mode 100644
index 000000000000..71d7dda23cc9
--- /dev/null
+++ b/include/dt-bindings/clock/rockchip,rk3506-cru.h
@@ -0,0 +1,285 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2023-2025 Rockchip Electronics Co., Ltd.
+ * Author: Finley Xiao <finley.xiao at rock-chips.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3506_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_RK3506_H
+
+/* cru plls */
+#define PLL_GPLL			0
+#define PLL_V0PLL			1
+#define PLL_V1PLL			2
+
+/* cru-clocks indices */
+#define ARMCLK				3
+#define CLK_DDR				4
+#define XIN24M_GATE			5
+#define CLK_GPLL_GATE			6
+#define CLK_V0PLL_GATE			7
+#define CLK_V1PLL_GATE			8
+#define CLK_GPLL_DIV			9
+#define CLK_GPLL_DIV_100M		10
+#define CLK_V0PLL_DIV			11
+#define CLK_V1PLL_DIV			12
+#define CLK_INT_VOICE_MATRIX0		13
+#define CLK_INT_VOICE_MATRIX1		14
+#define CLK_INT_VOICE_MATRIX2		15
+#define CLK_FRAC_UART_MATRIX0_MUX	16
+#define CLK_FRAC_UART_MATRIX1_MUX	17
+#define CLK_FRAC_VOICE_MATRIX0_MUX	18
+#define CLK_FRAC_VOICE_MATRIX1_MUX	19
+#define CLK_FRAC_COMMON_MATRIX0_MUX	20
+#define CLK_FRAC_COMMON_MATRIX1_MUX	21
+#define CLK_FRAC_COMMON_MATRIX2_MUX	22
+#define CLK_FRAC_UART_MATRIX0		23
+#define CLK_FRAC_UART_MATRIX1		24
+#define CLK_FRAC_VOICE_MATRIX0		25
+#define CLK_FRAC_VOICE_MATRIX1		26
+#define CLK_FRAC_COMMON_MATRIX0		27
+#define CLK_FRAC_COMMON_MATRIX1		28
+#define CLK_FRAC_COMMON_MATRIX2		29
+#define CLK_REF_USBPHY_TOP		30
+#define CLK_REF_DPHY_TOP		31
+#define ACLK_CORE_ROOT			32
+#define PCLK_CORE_ROOT			33
+#define PCLK_DBG			34
+#define PCLK_CORE_GRF			35
+#define PCLK_CORE_CRU			36
+#define CLK_CORE_EMA_DETECT		37
+#define CLK_REF_PVTPLL_CORE		38
+#define PCLK_GPIO1			39
+#define DBCLK_GPIO1			40
+#define ACLK_CORE_PERI_ROOT		41
+#define HCLK_CORE_PERI_ROOT		42
+#define PCLK_CORE_PERI_ROOT		43
+#define CLK_DSMC			44
+#define ACLK_DSMC			45
+#define PCLK_DSMC			46
+#define CLK_FLEXBUS_TX			47
+#define CLK_FLEXBUS_RX			48
+#define ACLK_FLEXBUS			49
+#define HCLK_FLEXBUS			50
+#define ACLK_DSMC_SLV			51
+#define HCLK_DSMC_SLV			52
+#define ACLK_BUS_ROOT			53
+#define HCLK_BUS_ROOT			54
+#define PCLK_BUS_ROOT			55
+#define ACLK_SYSRAM			56
+#define HCLK_SYSRAM			57
+#define ACLK_DMAC0			58
+#define ACLK_DMAC1			59
+#define HCLK_M0				60
+#define PCLK_BUS_GRF			61
+#define PCLK_TIMER			62
+#define CLK_TIMER0_CH0			63
+#define CLK_TIMER0_CH1			64
+#define CLK_TIMER0_CH2			65
+#define CLK_TIMER0_CH3			66
+#define CLK_TIMER0_CH4			67
+#define CLK_TIMER0_CH5			68
+#define PCLK_WDT0			69
+#define TCLK_WDT0			70
+#define PCLK_WDT1			71
+#define TCLK_WDT1			72
+#define PCLK_MAILBOX			73
+#define PCLK_INTMUX			74
+#define PCLK_SPINLOCK			75
+#define PCLK_DDRC			76
+#define HCLK_DDRPHY			77
+#define PCLK_DDRMON			78
+#define CLK_DDRMON_OSC			79
+#define PCLK_STDBY			80
+#define HCLK_USBOTG0			81
+#define HCLK_USBOTG0_PMU		82
+#define CLK_USBOTG0_ADP			83
+#define HCLK_USBOTG1			84
+#define HCLK_USBOTG1_PMU		85
+#define CLK_USBOTG1_ADP			86
+#define PCLK_USBPHY			87
+#define ACLK_DMA2DDR			88
+#define PCLK_DMA2DDR			89
+#define STCLK_M0			90
+#define CLK_DDRPHY			91
+#define CLK_DDRC_SRC			92
+#define ACLK_DDRC_0			93
+#define ACLK_DDRC_1			94
+#define CLK_DDRC			95
+#define CLK_DDRMON			96
+#define HCLK_LSPERI_ROOT		97
+#define PCLK_LSPERI_ROOT		98
+#define PCLK_UART0			99
+#define PCLK_UART1			100
+#define PCLK_UART2			101
+#define PCLK_UART3			102
+#define PCLK_UART4			103
+#define SCLK_UART0			104
+#define SCLK_UART1			105
+#define SCLK_UART2			106
+#define SCLK_UART3			107
+#define SCLK_UART4			108
+#define PCLK_I2C0			109
+#define CLK_I2C0			110
+#define PCLK_I2C1			111
+#define CLK_I2C1			112
+#define PCLK_I2C2			113
+#define CLK_I2C2			114
+#define PCLK_PWM1			115
+#define CLK_PWM1			116
+#define CLK_OSC_PWM1			117
+#define CLK_RC_PWM1			118
+#define CLK_FREQ_PWM1			119
+#define CLK_COUNTER_PWM1		120
+#define PCLK_SPI0			121
+#define CLK_SPI0			122
+#define PCLK_SPI1			123
+#define CLK_SPI1			124
+#define PCLK_GPIO2			125
+#define DBCLK_GPIO2			126
+#define PCLK_GPIO3			127
+#define DBCLK_GPIO3			128
+#define PCLK_GPIO4			129
+#define DBCLK_GPIO4			130
+#define HCLK_CAN0			131
+#define CLK_CAN0			132
+#define HCLK_CAN1			133
+#define CLK_CAN1			134
+#define HCLK_PDM			135
+#define MCLK_PDM			136
+#define CLKOUT_PDM			137
+#define MCLK_SPDIFTX			138
+#define HCLK_SPDIFTX			139
+#define HCLK_SPDIFRX			140
+#define MCLK_SPDIFRX			141
+#define MCLK_SAI0			142
+#define HCLK_SAI0			143
+#define MCLK_OUT_SAI0			144
+#define MCLK_SAI1			145
+#define HCLK_SAI1			146
+#define MCLK_OUT_SAI1			147
+#define HCLK_ASRC0			148
+#define CLK_ASRC0			149
+#define HCLK_ASRC1			150
+#define CLK_ASRC1			151
+#define PCLK_CRU			152
+#define PCLK_PMU_ROOT			153
+#define MCLK_ASRC0			154
+#define MCLK_ASRC1			155
+#define MCLK_ASRC2			156
+#define MCLK_ASRC3			157
+#define LRCK_ASRC0_SRC			158
+#define LRCK_ASRC0_DST			159
+#define LRCK_ASRC1_SRC			160
+#define LRCK_ASRC1_DST			161
+#define ACLK_HSPERI_ROOT		162
+#define HCLK_HSPERI_ROOT		163
+#define PCLK_HSPERI_ROOT		164
+#define CCLK_SRC_SDMMC			165
+#define HCLK_SDMMC			166
+#define HCLK_FSPI			167
+#define SCLK_FSPI			168
+#define PCLK_SPI2			169
+#define ACLK_MAC0			170
+#define ACLK_MAC1			171
+#define PCLK_MAC0			172
+#define PCLK_MAC1			173
+#define CLK_MAC_ROOT			174
+#define CLK_MAC0			175
+#define CLK_MAC1			176
+#define MCLK_SAI2			177
+#define HCLK_SAI2			178
+#define MCLK_OUT_SAI2			179
+#define MCLK_SAI3_SRC			180
+#define HCLK_SAI3			181
+#define MCLK_SAI3			182
+#define MCLK_OUT_SAI3			183
+#define MCLK_SAI4_SRC			184
+#define HCLK_SAI4			185
+#define MCLK_SAI4			186
+#define HCLK_DSM			187
+#define MCLK_DSM			188
+#define PCLK_AUDIO_ADC			189
+#define MCLK_AUDIO_ADC			190
+#define MCLK_AUDIO_ADC_DIV4		191
+#define PCLK_SARADC			192
+#define CLK_SARADC			193
+#define PCLK_OTPC_NS			194
+#define CLK_SBPI_OTPC_NS		195
+#define CLK_USER_OTPC_NS		196
+#define PCLK_UART5			197
+#define SCLK_UART5			198
+#define PCLK_GPIO234_IOC		199
+#define CLK_MAC_PTP_ROOT		200
+#define CLK_MAC0_PTP			201
+#define CLK_MAC1_PTP			202
+#define CLK_SPI2			203
+#define ACLK_VIO_ROOT			204
+#define HCLK_VIO_ROOT			205
+#define PCLK_VIO_ROOT			206
+#define HCLK_RGA			207
+#define ACLK_RGA			208
+#define CLK_CORE_RGA			209
+#define ACLK_VOP			210
+#define HCLK_VOP			211
+#define DCLK_VOP			212
+#define PCLK_DPHY			213
+#define PCLK_DSI_HOST			214
+#define PCLK_TSADC			215
+#define CLK_TSADC			216
+#define CLK_TSADC_TSEN			217
+#define PCLK_GPIO1_IOC			218
+#define PCLK_OTPC_S			219
+#define CLK_SBPI_OTPC_S			220
+#define CLK_USER_OTPC_S			221
+#define PCLK_OTP_MASK			222
+#define PCLK_KEYREADER			223
+#define HCLK_BOOTROM			224
+#define PCLK_DDR_SERVICE		225
+#define HCLK_CRYPTO_S			226
+#define HCLK_KEYLAD			227
+#define CLK_CORE_CRYPTO			228
+#define CLK_PKA_CRYPTO			229
+#define CLK_CORE_CRYPTO_S		230
+#define CLK_PKA_CRYPTO_S		231
+#define ACLK_CRYPTO_S			232
+#define HCLK_RNG_S			233
+#define CLK_CORE_CRYPTO_NS		234
+#define CLK_PKA_CRYPTO_NS		235
+#define ACLK_CRYPTO_NS			236
+#define HCLK_CRYPTO_NS			237
+#define HCLK_RNG			238
+#define CLK_PMU				239
+#define PCLK_PMU			240
+#define CLK_PMU_32K			241
+#define PCLK_PMU_CRU			242
+#define PCLK_PMU_GRF			243
+#define PCLK_GPIO0_IOC			244
+#define PCLK_GPIO0			245
+#define DBCLK_GPIO0			246
+#define PCLK_GPIO1_SHADOW		247
+#define DBCLK_GPIO1_SHADOW		248
+#define PCLK_PMU_HP_TIMER		249
+#define CLK_PMU_HP_TIMER		250
+#define CLK_PMU_HP_TIMER_32K		251
+#define PCLK_PWM0			252
+#define CLK_PWM0			253
+#define CLK_OSC_PWM0			254
+#define CLK_RC_PWM0			255
+#define CLK_MAC_OUT			256
+#define CLK_REF_OUT0			257
+#define CLK_REF_OUT1			258
+#define CLK_32K_FRAC			259
+#define CLK_32K_RC			260
+#define CLK_32K				261
+#define CLK_32K_PMU			262
+#define PCLK_TOUCH_KEY			263
+#define CLK_TOUCH_KEY			264
+#define CLK_REF_PHY_PLL			265
+#define CLK_REF_PHY_PMU_MUX		266
+#define CLK_WIFI_OUT			267
+#define CLK_V0PLL_REF			268
+#define CLK_V1PLL_REF			269
+#define CLK_32K_FRAC_MUX		270
+
+#endif
diff --git a/include/dt-bindings/reset/rockchip,rk3506-cru.h b/include/dt-bindings/reset/rockchip,rk3506-cru.h
new file mode 100644
index 000000000000..f38cc066009b
--- /dev/null
+++ b/include/dt-bindings/reset/rockchip,rk3506-cru.h
@@ -0,0 +1,211 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2023-2025 Rockchip Electronics Co., Ltd.
+ * Author: Finley Xiao <finley.xiao at rock-chips.com>
+ */
+
+#ifndef _DT_BINDINGS_REST_ROCKCHIP_RK3506_H
+#define _DT_BINDINGS_REST_ROCKCHIP_RK3506_H
+
+/* CRU-->SOFTRST_CON00 */
+#define SRST_NCOREPORESET0_AC		0
+#define SRST_NCOREPORESET1_AC		1
+#define SRST_NCOREPORESET2_AC		2
+#define SRST_NCORESET0_AC		3
+#define SRST_NCORESET1_AC		4
+#define SRST_NCORESET2_AC		5
+#define SRST_NL2RESET_AC		6
+#define SRST_ARESETN_CORE_BIU_AC	7
+#define SRST_HRESETN_M0_AC		8
+
+/* CRU-->SOFTRST_CON02 */
+#define SRST_NDBGRESET			9
+#define SRST_PRESETN_CORE_BIU		10
+#define SRST_RESETN_PMU			11
+
+/* CRU-->SOFTRST_CON03 */
+#define SRST_PRESETN_DBG		12
+#define SRST_POTRESETN_DBG		13
+#define SRST_PRESETN_CORE_GRF		14
+#define SRST_RESETN_CORE_EMA_DETECT	15
+#define SRST_RESETN_REF_PVTPLL_CORE	16
+#define SRST_PRESETN_GPIO1		17
+#define SRST_DBRESETN_GPIO1		18
+
+/* CRU-->SOFTRST_CON04 */
+#define SRST_ARESETN_CORE_PERI_BIU	19
+#define SRST_ARESETN_DSMC		20
+#define SRST_PRESETN_DSMC		21
+#define SRST_RESETN_FLEXBUS		22
+#define SRST_ARESETN_FLEXBUS		23
+#define SRST_HRESETN_FLEXBUS		24
+#define SRST_ARESETN_DSMC_SLV		25
+#define SRST_HRESETN_DSMC_SLV		26
+#define SRST_RESETN_DSMC_SLV		27
+
+/* CRU-->SOFTRST_CON05 */
+#define SRST_ARESETN_BUS_BIU		28
+#define SRST_HRESETN_BUS_BIU		29
+#define SRST_PRESETN_BUS_BIU		30
+#define SRST_ARESETN_SYSRAM		31
+#define SRST_HRESETN_SYSRAM		32
+#define SRST_ARESETN_DMAC0		33
+#define SRST_ARESETN_DMAC1		34
+#define SRST_HRESETN_M0			35
+#define SRST_RESETN_M0_JTAG		36
+#define SRST_HRESETN_CRYPTO		37
+
+/* CRU-->SOFTRST_CON06 */
+#define SRST_HRESETN_RNG		38
+#define SRST_PRESETN_BUS_GRF		39
+#define SRST_PRESETN_TIMER0		40
+#define SRST_RESETN_TIMER0_CH0		41
+#define SRST_RESETN_TIMER0_CH1		42
+#define SRST_RESETN_TIMER0_CH2		43
+#define SRST_RESETN_TIMER0_CH3		44
+#define SRST_RESETN_TIMER0_CH4		45
+#define SRST_RESETN_TIMER0_CH5		46
+#define SRST_PRESETN_WDT0		47
+#define SRST_TRESETN_WDT0		48
+#define SRST_PRESETN_WDT1		49
+#define SRST_TRESETN_WDT1		50
+#define SRST_PRESETN_MAILBOX		51
+#define SRST_PRESETN_INTMUX		52
+#define SRST_PRESETN_SPINLOCK		53
+
+/* CRU-->SOFTRST_CON07 */
+#define SRST_PRESETN_DDRC		54
+#define SRST_HRESETN_DDRPHY		55
+#define SRST_PRESETN_DDRMON		56
+#define SRST_RESETN_DDRMON_OSC		57
+#define SRST_PRESETN_DDR_LPC		58
+#define SRST_HRESETN_USBOTG0		59
+#define SRST_RESETN_USBOTG0_ADP		60
+#define SRST_HRESETN_USBOTG1		61
+#define SRST_RESETN_USBOTG1_ADP		62
+#define SRST_PRESETN_USBPHY		63
+#define SRST_RESETN_USBPHY_POR		64
+#define SRST_RESETN_USBPHY_OTG0		65
+#define SRST_RESETN_USBPHY_OTG1		66
+
+/* CRU-->SOFTRST_CON08 */
+#define SRST_ARESETN_DMA2DDR		67
+#define SRST_PRESETN_DMA2DDR		68
+
+/* CRU-->SOFTRST_CON09 */
+#define SRST_RESETN_USBOTG0_UTMI	69
+#define SRST_RESETN_USBOTG1_UTMI	70
+
+/* CRU-->SOFTRST_CON10 */
+#define SRST_ARESETN_DDRC_0		71
+#define SRST_ARESETN_DDRC_1		72
+#define SRST_ARESETN_DDR_BIU		73
+#define SRST_RESETN_DDRC		74
+#define SRST_RESETN_DDRMON		75
+
+/* CRU-->SOFTRST_CON11 */
+#define SRST_HRESETN_LSPERI_BIU		76
+#define SRST_PRESETN_UART0		77
+#define SRST_PRESETN_UART1		78
+#define SRST_PRESETN_UART2		79
+#define SRST_PRESETN_UART3		80
+#define SRST_PRESETN_UART4		81
+#define SRST_RESETN_UART0		82
+#define SRST_RESETN_UART1		83
+#define SRST_RESETN_UART2		84
+#define SRST_RESETN_UART3		85
+#define SRST_RESETN_UART4		86
+#define SRST_PRESETN_I2C0		87
+#define SRST_RESETN_I2C0		88
+
+/* CRU-->SOFTRST_CON12 */
+#define SRST_PRESETN_I2C1		89
+#define SRST_RESETN_I2C1		90
+#define SRST_PRESETN_I2C2		91
+#define SRST_RESETN_I2C2		92
+#define SRST_PRESETN_PWM1		93
+#define SRST_RESETN_PWM1		94
+#define SRST_PRESETN_SPI0		95
+#define SRST_RESETN_SPI0		96
+#define SRST_PRESETN_SPI1		97
+#define SRST_RESETN_SPI1		98
+#define SRST_PRESETN_GPIO2		99
+#define SRST_DBRESETN_GPIO2		100
+
+/* CRU-->SOFTRST_CON13 */
+#define SRST_PRESETN_GPIO3		101
+#define SRST_DBRESETN_GPIO3		102
+#define SRST_PRESETN_GPIO4		103
+#define SRST_DBRESETN_GPIO4		104
+#define SRST_HRESETN_CAN0		105
+#define SRST_RESETN_CAN0		106
+#define SRST_HRESETN_CAN1		107
+#define SRST_RESETN_CAN1		108
+#define SRST_HRESETN_PDM		109
+#define SRST_MRESETN_PDM		110
+#define SRST_RESETN_PDM			111
+#define SRST_RESETN_SPDIFTX		112
+#define SRST_HRESETN_SPDIFTX		113
+#define SRST_HRESETN_SPDIFRX		114
+#define SRST_RESETN_SPDIFRX		115
+#define SRST_MRESETN_SAI0		116
+
+/* CRU-->SOFTRST_CON14 */
+#define SRST_HRESETN_SAI0		117
+#define SRST_MRESETN_SAI1		118
+#define SRST_HRESETN_SAI1		119
+#define SRST_HRESETN_ASRC0		120
+#define SRST_RESETN_ASRC0		121
+#define SRST_HRESETN_ASRC1		122
+#define SRST_RESETN_ASRC1		123
+
+/* CRU-->SOFTRST_CON17 */
+#define SRST_HRESETN_HSPERI_BIU		124
+#define SRST_HRESETN_SDMMC		125
+#define SRST_HRESETN_FSPI		126
+#define SRST_SRESETN_FSPI		127
+#define SRST_PRESETN_SPI2		128
+#define SRST_ARESETN_MAC0		129
+#define SRST_ARESETN_MAC1		130
+
+/* CRU-->SOFTRST_CON18 */
+#define SRST_MRESETN_SAI2		131
+#define SRST_HRESETN_SAI2		132
+#define SRST_HRESETN_SAI3		133
+#define SRST_MRESETN_SAI3		134
+#define SRST_HRESETN_SAI4		135
+#define SRST_MRESETN_SAI4		136
+#define SRST_HRESETN_DSM		137
+#define SRST_MRESETN_DSM		138
+#define SRST_PRESETN_AUDIO_ADC		139
+#define SRST_MRESETN_AUDIO_ADC		140
+
+/* CRU-->SOFTRST_CON19 */
+#define SRST_PRESETN_SARADC		141
+#define SRST_RESETN_SARADC		142
+#define SRST_RESETN_SARADC_PHY		143
+#define SRST_PRESETN_OTPC_NS		144
+#define SRST_RESETN_SBPI_OTPC_NS	145
+#define SRST_RESETN_USER_OTPC_NS	146
+#define SRST_PRESETN_UART5		147
+#define SRST_RESETN_UART5		148
+#define SRST_PRESETN_GPIO234_IOC	149
+
+/* CRU-->SOFTRST_CON21 */
+#define SRST_ARESETN_VIO_BIU		150
+#define SRST_HRESETN_VIO_BIU		151
+#define SRST_HRESETN_RGA		152
+#define SRST_ARESETN_RGA		153
+#define SRST_RESETN_CORE_RGA		154
+#define SRST_ARESETN_VOP		155
+#define SRST_HRESETN_VOP		156
+#define SRST_RESETN_VOP			157
+#define SRST_PRESETN_DPHY		158
+#define SRST_PRESETN_DSI_HOST		159
+#define SRST_PRESETN_TSADC		160
+#define SRST_RESETN_TSADC		161
+
+/* CRU-->SOFTRST_CON22 */
+#define SRST_PRESETN_GPIO1_IOC		162
+
+#endif
-- 
2.34.1



From zhangqing at rock-chips.com  Thu Nov  6 17:38:12 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Fri,  7 Nov 2025 09:38:12 +0800
Subject: [RESEND PATCH v6 5/5] clk: rockchip: Add clock and reset driver for RK3506
Message-ID: <20251107013812.5030-1-zhangqing@rock-chips.com>

Add the clock and reset tree definitions for the new
RK3506 SoC.

Signed-off-by: Finley Xiao <finley.xiao at rock-chips.com>
Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
---
 drivers/clk/rockchip/Kconfig      |   7 +
 drivers/clk/rockchip/Makefile     |   1 +
 drivers/clk/rockchip/clk-rk3506.c | 869 ++++++++++++++++++++++++++++++
 drivers/clk/rockchip/clk.h        |  13 +
 drivers/clk/rockchip/rst-rk3506.c | 226 ++++++++
 5 files changed, 1116 insertions(+)
 create mode 100644 drivers/clk/rockchip/clk-rk3506.c
 create mode 100644 drivers/clk/rockchip/rst-rk3506.c

diff --git a/drivers/clk/rockchip/Kconfig b/drivers/clk/rockchip/Kconfig
index e1ea0a098ca9..5cf1e0fd6fb3 100644
--- a/drivers/clk/rockchip/Kconfig
+++ b/drivers/clk/rockchip/Kconfig
@@ -100,6 +100,13 @@ config CLK_RK3399
 	help
 	  Build the driver for RK3399 Clock Driver.
 
+config CLK_RK3506
+	bool "Rockchip RK3506 clock controller support"
+	depends on ARM || COMPILE_TEST
+	default y
+	help
+	  Build the driver for RK3506 Clock Driver.
+
 config CLK_RK3528
 	bool "Rockchip RK3528 clock controller support"
 	depends on ARM64 || COMPILE_TEST
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index 82b4b29ad036..4d8cbb2044c7 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_CLK_RK3308)        += clk-rk3308.o
 obj-$(CONFIG_CLK_RK3328)        += clk-rk3328.o
 obj-$(CONFIG_CLK_RK3368)        += clk-rk3368.o
 obj-$(CONFIG_CLK_RK3399)        += clk-rk3399.o
+obj-$(CONFIG_CLK_RK3506)	+= clk-rk3506.o rst-rk3506.o
 obj-$(CONFIG_CLK_RK3528)	+= clk-rk3528.o rst-rk3528.o
 obj-$(CONFIG_CLK_RK3562)	+= clk-rk3562.o rst-rk3562.o
 obj-$(CONFIG_CLK_RK3568)	+= clk-rk3568.o
diff --git a/drivers/clk/rockchip/clk-rk3506.c b/drivers/clk/rockchip/clk-rk3506.c
new file mode 100644
index 000000000000..dd59bd60382e
--- /dev/null
+++ b/drivers/clk/rockchip/clk-rk3506.c
@@ -0,0 +1,869 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023-2025 Rockchip Electronics Co., Ltd.
+ * Author: Finley Xiao <finley.xiao at rock-chips.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/syscore_ops.h>
+#include <dt-bindings/clock/rockchip,rk3506-cru.h>
+#include "clk.h"
+
+#define PVTPLL_SRC_SEL_PVTPLL		(BIT(7) | BIT(23))
+
+enum rk3506_plls {
+	gpll, v0pll, v1pll,
+};
+
+/*
+ * [FRAC PLL]: GPLL, V0PLL, V1PLL
+ *   - VCO Frequency: 950MHz to 3800MHZ
+ *   - Output Frequency: 19MHz to 3800MHZ
+ *   - refdiv: 1 to 63 (Int Mode), 1 to 2 (Frac Mode)
+ *   - fbdiv: 16 to 3800 (Int Mode), 20 to 380 (Frac Mode)
+ *   - post1div: 1 to 7
+ *   - post2div: 1 to 7
+ */
+static struct rockchip_pll_rate_table rk3506_pll_rates[] = {
+	/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
+	RK3036_PLL_RATE(1896000000, 1, 79, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1800000000, 1, 75, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1704000000, 1, 71, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1512000000, 1, 63, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1350000000, 4, 225, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1179648000, 1, 49, 1, 1, 0, 2550137),
+	RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1000000000, 3, 125, 1, 1, 1, 0),
+	RK3036_PLL_RATE(993484800, 1, 41, 1, 1, 0, 6630355),
+	RK3036_PLL_RATE(983040000, 1, 40, 1, 1, 0, 16106127),
+	RK3036_PLL_RATE(960000000, 1, 80, 2, 1, 1, 0),
+	RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0),
+	RK3036_PLL_RATE(903168000, 1, 75, 2, 1, 0, 4429185),
+	RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
+	RK3036_PLL_RATE(800000000, 3, 200, 2, 1, 1, 0),
+	RK3036_PLL_RATE(600000000, 1, 50, 2, 1, 1, 0),
+	RK3036_PLL_RATE(594000000, 2, 99, 2, 1, 1, 0),
+	RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0),
+	RK3036_PLL_RATE(312000000, 1, 78, 6, 1, 1, 0),
+	RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0),
+	RK3036_PLL_RATE(96000000, 1, 48, 6, 2, 1, 0),
+	{ /* sentinel */ },
+};
+
+#define RK3506_DIV_ACLK_CORE_MASK	0xf
+#define RK3506_DIV_ACLK_CORE_SHIFT	9
+#define RK3506_DIV_PCLK_CORE_MASK	0xf
+#define RK3506_DIV_PCLK_CORE_SHIFT	0
+
+#define RK3506_CLKSEL15(_aclk_core_div)					\
+{									\
+	.reg = RK3506_CLKSEL_CON(15),					\
+	.val = HIWORD_UPDATE(_aclk_core_div, RK3506_DIV_ACLK_CORE_MASK,	\
+			     RK3506_DIV_ACLK_CORE_SHIFT),		\
+}
+
+#define RK3506_CLKSEL16(_pclk_core_div)					\
+{									\
+	.reg = RK3506_CLKSEL_CON(16),					\
+	.val = HIWORD_UPDATE(_pclk_core_div, RK3506_DIV_PCLK_CORE_MASK,	\
+			     RK3506_DIV_PCLK_CORE_SHIFT),		\
+}
+
+/* SIGN-OFF: aclk_core: 500M, pclk_core: 125M, */
+#define RK3506_CPUCLK_RATE(_prate, _aclk_core_div, _pclk_core_div)	\
+{									\
+	.prate = _prate,						\
+	.divs = {							\
+		RK3506_CLKSEL15(_aclk_core_div),			\
+		RK3506_CLKSEL16(_pclk_core_div),			\
+	},								\
+}
+
+static struct rockchip_cpuclk_rate_table rk3506_cpuclk_rates[] __initdata = {
+	RK3506_CPUCLK_RATE(1608000000, 3, 12),
+	RK3506_CPUCLK_RATE(1512000000, 3, 12),
+	RK3506_CPUCLK_RATE(1416000000, 2, 11),
+	RK3506_CPUCLK_RATE(1296000000, 2, 10),
+	RK3506_CPUCLK_RATE(1200000000, 2, 9),
+	RK3506_CPUCLK_RATE(1179648000, 2, 9),
+	RK3506_CPUCLK_RATE(1008000000, 1, 7),
+	RK3506_CPUCLK_RATE(903168000, 1, 7),
+	RK3506_CPUCLK_RATE(800000000, 1, 6),
+	RK3506_CPUCLK_RATE(750000000, 1, 5),
+	RK3506_CPUCLK_RATE(589824000, 1, 4),
+	RK3506_CPUCLK_RATE(400000000, 1, 3),
+	RK3506_CPUCLK_RATE(200000000, 1, 1),
+};
+
+PNAME(mux_pll_p)				= { "xin24m" };
+PNAME(gpll_v0pll_v1pll_parents_p)		= { "gpll", "v0pll", "v1pll" };
+PNAME(gpll_v0pll_v1pll_g_parents_p)		= { "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate" };
+PNAME(gpll_v0pll_v1pll_div_parents_p)		= { "clk_gpll_div", "clk_v0pll_div", "clk_v1pll_div" };
+PNAME(xin24m_gpll_v0pll_v1pll_g_parents_p)	= { "xin24m", "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate" };
+PNAME(xin24m_g_gpll_v0pll_v1pll_g_parents_p)	= { "xin24m_gate", "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate" };
+PNAME(xin24m_g_gpll_v0pll_v1pll_div_parents_p)	= { "xin24m_gate", "clk_gpll_div", "clk_v0pll_div", "clk_v1pll_div" };
+PNAME(xin24m_400k_32k_parents_p)		= { "xin24m", "clk_rc", "clk_32k" };
+PNAME(clk_frac_uart_matrix0_mux_parents_p)	= { "xin24m", "gpll", "clk_v0pll_gate", "clk_v1pll_gate" };
+PNAME(clk_timer0_parents_p)			= { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai0_mclk_in", "sai0_sclk_in" };
+PNAME(clk_timer1_parents_p)			= { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai1_mclk_in", "sai1_sclk_in" };
+PNAME(clk_timer2_parents_p)			= { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai2_mclk_in", "sai2_sclk_in" };
+PNAME(clk_timer3_parents_p)			= { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai3_mclk_in", "sai3_sclk_in" };
+PNAME(clk_timer4_parents_p)			= { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "mclk_asrc0" };
+PNAME(clk_timer5_parents_p)			= { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "mclk_asrc1" };
+PNAME(sclk_uart_parents_p)			= { "xin24m", "clk_gpll_gate", "clk_v0pll_gate", "clk_frac_uart_matrix0", "clk_frac_uart_matrix1",
+						    "clk_frac_common_matrix0", "clk_frac_common_matrix1", "clk_frac_common_matrix2" };
+PNAME(clk_mac_ptp_root_parents_p)		= { "gpll", "v0pll", "v1pll" };
+PNAME(clk_pwm_parents_p)			= { "clk_rc", "sai0_mclk_in", "sai1_mclk_in", "sai2_mclk_in", "sai3_mclk_in", "sai0_sclk_in", "sai1_sclk_in",
+						    "sai2_sclk_in", "sai3_sclk_in", "mclk_asrc0", "mclk_asrc1" };
+PNAME(clk_can_parents_p)			= { "xin24m", "gpll", "clk_v0pll_gate", "clk_v1pll_gate", "clk_frac_voice_matrix1",
+						    "clk_frac_common_matrix0", "clk_frac_common_matrix1", "clk_frac_common_matrix2" };
+PNAME(clk_pdm_parents_p)			= { "xin24m_gate", "clk_int_voice_matrix0", "clk_int_voice_matrix1", "clk_int_voice_matrix2",
+						    "clk_frac_voice_matrix0", "clk_frac_voice_matrix1", "clk_frac_common_matrix0", "clk_frac_common_matrix1",
+						    "clk_frac_common_matrix2", "sai0_mclk_in", "sai1_mclk_in", "sai2_mclk_in", "sai3_mclk_in", "clk_gpll_div" };
+PNAME(mclk_sai_asrc_parents_p)			= { "xin24m_gate", "clk_int_voice_matrix0", "clk_int_voice_matrix1", "clk_int_voice_matrix2",
+						    "clk_frac_voice_matrix0", "clk_frac_voice_matrix1", "clk_frac_common_matrix0", "clk_frac_common_matrix1",
+						    "clk_frac_common_matrix2", "sai0_mclk_in", "sai1_mclk_in", "sai2_mclk_in", "sai3_mclk_in" };
+PNAME(lrck_asrc_parents_p)			= { "mclk_asrc0", "mclk_asrc1", "mclk_asrc2", "mclk_asrc3", "mclk_spdiftx", "clk_spdifrx_to_asrc", "clkout_pdm",
+						    "sai0_fs", "sai1_fs", "sai2_fs", "sai3_fs", "sai4_fs" };
+PNAME(cclk_src_sdmmc_parents_p)			= { "xin24m_gate", "gpll", "clk_v0pll_gate", "clk_v1pll_gate" };
+PNAME(dclk_vop_parents_p)			= { "xin24m_gate", "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate", "dummy_vop_dclk",
+						    "dummy_vop_dclk", "dummy_vop_dclk", "dummy_vop_dclk" };
+PNAME(dbclk_gpio0_parents_p)			= { "xin24m", "clk_rc", "clk_32k_pmu" };
+PNAME(clk_pmu_hp_timer_parents_p)		= { "xin24m", "gpll_div_100m", "clk_core_pvtpll" };
+PNAME(clk_ref_out_parents_p)			= { "xin24m", "gpll", "v0pll", "v1pll" };
+PNAME(clk_32k_frac_parents_p)			= { "xin24m", "v0pll", "v1pll", "clk_rc" };
+PNAME(clk_32k_parents_p)			= { "xin32k", "clk_32k_rc", "clk_32k_frac" };
+PNAME(clk_ref_phy_pmu_mux_parents_p)		= { "xin24m", "clk_ref_phy_pll" };
+PNAME(clk_vpll_ref_parents_p)			= { "xin24m", "clk_pll_ref_io" };
+PNAME(mux_armclk_p)				= { "armclk_pll", "clk_core_pvtpll" };
+
+#define MFLAGS CLK_MUX_HIWORD_MASK
+#define DFLAGS CLK_DIVIDER_HIWORD_MASK
+#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
+
+static struct rockchip_pll_clock rk3506_pll_clks[] __initdata = {
+	[gpll] = PLL(pll_rk3328, PLL_GPLL, "gpll", mux_pll_p,
+		     CLK_IS_CRITICAL, RK3506_PLL_CON(0),
+		     RK3506_MODE_CON, 0, 2, 0, rk3506_pll_rates),
+	[v0pll] = PLL(pll_rk3328, PLL_V0PLL, "v0pll", mux_pll_p,
+		     CLK_IS_CRITICAL, RK3506_PLL_CON(8),
+		     RK3506_MODE_CON, 2, 0, 0, rk3506_pll_rates),
+	[v1pll] = PLL(pll_rk3328, PLL_V1PLL, "v1pll", mux_pll_p,
+		     CLK_IS_CRITICAL, RK3506_PLL_CON(16),
+		     RK3506_MODE_CON, 4, 1, 0, rk3506_pll_rates),
+};
+
+static struct rockchip_clk_branch rk3506_armclk __initdata =
+	MUX(ARMCLK, "armclk", mux_armclk_p, CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
+			RK3506_CLKSEL_CON(15), 8, 1, MFLAGS);
+
+static struct rockchip_clk_branch rk3506_clk_branches[] __initdata = {
+	/*
+	 * CRU Clock-Architecture
+	 */
+	/* top */
+	GATE(XIN24M_GATE, "xin24m_gate", "xin24m", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(0), 1, GFLAGS),
+	GATE(CLK_GPLL_GATE, "clk_gpll_gate", "gpll", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(0), 2, GFLAGS),
+	GATE(CLK_V0PLL_GATE, "clk_v0pll_gate", "v0pll", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(0), 3, GFLAGS),
+	GATE(CLK_V1PLL_GATE, "clk_v1pll_gate", "v1pll", 0,
+			RK3506_CLKGATE_CON(0), 4, GFLAGS),
+	COMPOSITE_NOMUX(CLK_GPLL_DIV, "clk_gpll_div", "clk_gpll_gate", CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(0), 6, 4, DFLAGS,
+			RK3506_CLKGATE_CON(0), 5, GFLAGS),
+	COMPOSITE_NOMUX(CLK_GPLL_DIV_100M, "clk_gpll_div_100m", "clk_gpll_div", 0,
+			RK3506_CLKSEL_CON(0), 10, 4, DFLAGS,
+			RK3506_CLKGATE_CON(0), 6, GFLAGS),
+	COMPOSITE_NOMUX(CLK_V0PLL_DIV, "clk_v0pll_div", "clk_v0pll_gate", CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(1), 0, 4, DFLAGS,
+			RK3506_CLKGATE_CON(0), 7, GFLAGS),
+	COMPOSITE_NOMUX(CLK_V1PLL_DIV, "clk_v1pll_div", "clk_v1pll_gate", 0,
+			RK3506_CLKSEL_CON(1), 4, 4, DFLAGS,
+			RK3506_CLKGATE_CON(0), 8, GFLAGS),
+	COMPOSITE_NOMUX(CLK_INT_VOICE_MATRIX0, "clk_int_voice_matrix0", "clk_v0pll_gate", 0,
+			RK3506_CLKSEL_CON(1), 8, 5, DFLAGS,
+			RK3506_CLKGATE_CON(0), 9, GFLAGS),
+	COMPOSITE_NOMUX(CLK_INT_VOICE_MATRIX1, "clk_int_voice_matrix1", "clk_v1pll_gate", 0,
+			RK3506_CLKSEL_CON(2), 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(0), 10, GFLAGS),
+	COMPOSITE_NOMUX(CLK_INT_VOICE_MATRIX2, "clk_int_voice_matrix2", "clk_v0pll_gate", 0,
+			RK3506_CLKSEL_CON(2), 5, 5, DFLAGS,
+			RK3506_CLKGATE_CON(0), 11, GFLAGS),
+	MUX(CLK_FRAC_UART_MATRIX0_MUX, "clk_frac_uart_matrix0_mux", clk_frac_uart_matrix0_mux_parents_p, 0,
+			RK3506_CLKSEL_CON(3), 9, 2, MFLAGS),
+	MUX(CLK_FRAC_UART_MATRIX1_MUX, "clk_frac_uart_matrix1_mux", xin24m_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(3), 11, 2, MFLAGS),
+	MUX(CLK_FRAC_VOICE_MATRIX0_MUX, "clk_frac_voice_matrix0_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(3), 13, 2, MFLAGS),
+	MUX(CLK_FRAC_VOICE_MATRIX1_MUX, "clk_frac_voice_matrix1_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(4), 0, 2, MFLAGS),
+	MUX(CLK_FRAC_COMMON_MATRIX0_MUX, "clk_frac_common_matrix0_mux", xin24m_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(4), 2, 2, MFLAGS),
+	MUX(CLK_FRAC_COMMON_MATRIX1_MUX, "clk_frac_common_matrix1_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(4), 4, 2, MFLAGS),
+	MUX(CLK_FRAC_COMMON_MATRIX2_MUX, "clk_frac_common_matrix2_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(4), 6, 2, MFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_UART_MATRIX0, "clk_frac_uart_matrix0", "clk_frac_uart_matrix0_mux", 0,
+			RK3506_CLKSEL_CON(5), 0,
+			RK3506_CLKGATE_CON(0), 13, GFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_UART_MATRIX1, "clk_frac_uart_matrix1", "clk_frac_uart_matrix1_mux", 0,
+			RK3506_CLKSEL_CON(6), 0,
+			RK3506_CLKGATE_CON(0), 14, GFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_VOICE_MATRIX0, "clk_frac_voice_matrix0", "clk_frac_voice_matrix0_mux", 0,
+			RK3506_CLKSEL_CON(7), 0,
+			RK3506_CLKGATE_CON(0), 15, GFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_VOICE_MATRIX1, "clk_frac_voice_matrix1", "clk_frac_voice_matrix1_mux", 0,
+			RK3506_CLKSEL_CON(9), 0,
+			RK3506_CLKGATE_CON(1), 0, GFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_COMMON_MATRIX0, "clk_frac_common_matrix0", "clk_frac_common_matrix0_mux", 0,
+			RK3506_CLKSEL_CON(11), 0,
+			RK3506_CLKGATE_CON(1), 1, GFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_COMMON_MATRIX1, "clk_frac_common_matrix1", "clk_frac_common_matrix1_mux", 0,
+			RK3506_CLKSEL_CON(12), 0,
+			RK3506_CLKGATE_CON(1), 2, GFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_COMMON_MATRIX2, "clk_frac_common_matrix2", "clk_frac_common_matrix2_mux", 0,
+			RK3506_CLKSEL_CON(13), 0,
+			RK3506_CLKGATE_CON(1), 3, GFLAGS),
+	GATE(CLK_REF_USBPHY_TOP, "clk_ref_usbphy_top", "xin24m", 0,
+			RK3506_CLKGATE_CON(1), 4, GFLAGS),
+	GATE(CLK_REF_DPHY_TOP, "clk_ref_dphy_top", "xin24m", 0,
+			RK3506_CLKGATE_CON(1), 5, GFLAGS),
+
+	/* core */
+	COMPOSITE_NOGATE(0, "armclk_pll", gpll_v0pll_v1pll_parents_p, CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(15), 5, 2, MFLAGS, 0, 5, DFLAGS),
+	COMPOSITE_NOMUX(ACLK_CORE_ROOT, "aclk_core_root", "armclk", CLK_IGNORE_UNUSED,
+			RK3506_CLKSEL_CON(15), 9, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
+			RK3506_CLKGATE_CON(2), 11, GFLAGS),
+	COMPOSITE_NOMUX(PCLK_CORE_ROOT, "pclk_core_root", "armclk", CLK_IGNORE_UNUSED,
+			RK3506_CLKSEL_CON(16), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
+			RK3506_CLKGATE_CON(2), 12, GFLAGS),
+	GATE(PCLK_DBG, "pclk_dbg", "pclk_core_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(3), 1, GFLAGS),
+	GATE(PCLK_CORE_GRF, "pclk_core_grf", "pclk_core_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(3), 4, GFLAGS),
+	GATE(PCLK_CORE_CRU, "pclk_core_cru", "pclk_core_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(3), 5, GFLAGS),
+	GATE(CLK_CORE_EMA_DETECT, "clk_core_ema_detect", "xin24m_gate", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(3), 6, GFLAGS),
+	GATE(PCLK_GPIO1, "pclk_gpio1", "aclk_core_root", 0,
+			RK3506_CLKGATE_CON(3), 8, GFLAGS),
+	GATE(DBCLK_GPIO1, "dbclk_gpio1", "xin24m_gate", 0,
+			RK3506_CLKGATE_CON(3), 9, GFLAGS),
+
+	/* core peri */
+	COMPOSITE(ACLK_CORE_PERI_ROOT, "aclk_core_peri_root", gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(18), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(4), 0, GFLAGS),
+	GATE(HCLK_CORE_PERI_ROOT, "hclk_core_peri_root", "aclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 1, GFLAGS),
+	GATE(PCLK_CORE_PERI_ROOT, "pclk_core_peri_root", "aclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 2, GFLAGS),
+	COMPOSITE(CLK_DSMC, "clk_dsmc", xin24m_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(18), 12, 2, MFLAGS, 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(4), 4, GFLAGS),
+	GATE(ACLK_DSMC, "aclk_dsmc", "aclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 5, GFLAGS),
+	GATE(PCLK_DSMC, "pclk_dsmc", "pclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 6, GFLAGS),
+	COMPOSITE(CLK_FLEXBUS_TX, "clk_flexbus_tx", xin24m_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(19), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(4), 7, GFLAGS),
+	COMPOSITE(CLK_FLEXBUS_RX, "clk_flexbus_rx", xin24m_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(19), 12, 2, MFLAGS, 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(4), 8, GFLAGS),
+	GATE(ACLK_FLEXBUS, "aclk_flexbus", "aclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 9, GFLAGS),
+	GATE(HCLK_FLEXBUS, "hclk_flexbus", "hclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 10, GFLAGS),
+	GATE(ACLK_DSMC_SLV, "aclk_dsmc_slv", "aclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 11, GFLAGS),
+	GATE(HCLK_DSMC_SLV, "hclk_dsmc_slv", "hclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 12, GFLAGS),
+
+	/* bus */
+	COMPOSITE(ACLK_BUS_ROOT, "aclk_bus_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(21), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(5), 0, GFLAGS),
+	COMPOSITE(HCLK_BUS_ROOT, "hclk_bus_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(21), 12, 2, MFLAGS, 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(5), 1, GFLAGS),
+	COMPOSITE(PCLK_BUS_ROOT, "pclk_bus_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(22), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(5), 2, GFLAGS),
+	GATE(ACLK_SYSRAM, "aclk_sysram", "aclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(5), 6, GFLAGS),
+	GATE(HCLK_SYSRAM, "hclk_sysram", "aclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(5), 7, GFLAGS),
+	GATE(ACLK_DMAC0, "aclk_dmac0", "aclk_bus_root", 0,
+			RK3506_CLKGATE_CON(5), 8, GFLAGS),
+	GATE(ACLK_DMAC1, "aclk_dmac1", "aclk_bus_root", 0,
+			RK3506_CLKGATE_CON(5), 9, GFLAGS),
+	GATE(HCLK_M0, "hclk_m0", "aclk_bus_root", 0,
+			RK3506_CLKGATE_CON(5), 10, GFLAGS),
+	GATE(ACLK_CRYPTO_NS, "aclk_crypto_ns", "aclk_bus_root", 0,
+			RK3506_CLKGATE_CON(5), 14, GFLAGS),
+	GATE(HCLK_CRYPTO_NS, "hclk_crypto_ns", "hclk_bus_root", 0,
+			RK3506_CLKGATE_CON(5), 15, GFLAGS),
+	GATE(HCLK_RNG, "hclk_rng", "hclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 0, GFLAGS),
+	GATE(PCLK_BUS_GRF, "pclk_bus_grf", "pclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(6), 1, GFLAGS),
+	GATE(PCLK_TIMER, "pclk_timer", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 2, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0_CH0, "clk_timer0_ch0", clk_timer0_parents_p, 0,
+			RK3506_CLKSEL_CON(22), 7, 3, MFLAGS,
+			RK3506_CLKGATE_CON(6), 3, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0_CH1, "clk_timer0_ch1", clk_timer1_parents_p, 0,
+			RK3506_CLKSEL_CON(22), 10, 3, MFLAGS,
+			RK3506_CLKGATE_CON(6), 4, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0_CH2, "clk_timer0_ch2", clk_timer2_parents_p, 0,
+			RK3506_CLKSEL_CON(22), 13, 3, MFLAGS,
+			RK3506_CLKGATE_CON(6), 5, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0_CH3, "clk_timer0_ch3", clk_timer3_parents_p, 0,
+			RK3506_CLKSEL_CON(23), 0, 3, MFLAGS,
+			RK3506_CLKGATE_CON(6), 6, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0_CH4, "clk_timer0_ch4", clk_timer4_parents_p, 0,
+			RK3506_CLKSEL_CON(23), 3, 3, MFLAGS,
+			RK3506_CLKGATE_CON(6), 7, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0_CH5, "clk_timer0_ch5", clk_timer5_parents_p, 0,
+			RK3506_CLKSEL_CON(23), 6, 3, MFLAGS,
+			RK3506_CLKGATE_CON(6), 8, GFLAGS),
+	GATE(PCLK_WDT0, "pclk_wdt0", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 9, GFLAGS),
+	GATE(TCLK_WDT0, "tclk_wdt0", "xin24m_gate", 0,
+			RK3506_CLKGATE_CON(6), 10, GFLAGS),
+	GATE(PCLK_WDT1, "pclk_wdt1", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 11, GFLAGS),
+	GATE(TCLK_WDT1, "tclk_wdt1", "xin24m_gate", 0,
+			RK3506_CLKGATE_CON(6), 12, GFLAGS),
+	GATE(PCLK_MAILBOX, "pclk_mailbox", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 13, GFLAGS),
+	GATE(PCLK_INTMUX, "pclk_intmux", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 14, GFLAGS),
+	GATE(PCLK_SPINLOCK, "pclk_spinlock", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 15, GFLAGS),
+	GATE(PCLK_DDRC, "pclk_ddrc", "pclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(7), 0, GFLAGS),
+	GATE(HCLK_DDRPHY, "hclk_ddrphy", "hclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(7), 1, GFLAGS),
+	GATE(PCLK_DDRMON, "pclk_ddrmon", "pclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(7), 2, GFLAGS),
+	GATE(CLK_DDRMON_OSC, "clk_ddrmon_osc", "xin24m_gate", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(7), 3, GFLAGS),
+	GATE(PCLK_STDBY, "pclk_stdby", "pclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(7), 4, GFLAGS),
+	GATE(HCLK_USBOTG0, "hclk_usbotg0", "hclk_bus_root", 0,
+			RK3506_CLKGATE_CON(7), 5, GFLAGS),
+	GATE(HCLK_USBOTG0_PMU, "hclk_usbotg0_pmu", "hclk_bus_root", 0,
+			RK3506_CLKGATE_CON(7), 6, GFLAGS),
+	GATE(CLK_USBOTG0_ADP, "clk_usbotg0_adp", "clk_32k", 0,
+			RK3506_CLKGATE_CON(7), 7, GFLAGS),
+	GATE(HCLK_USBOTG1, "hclk_usbotg1", "hclk_bus_root", 0,
+			RK3506_CLKGATE_CON(7), 8, GFLAGS),
+	GATE(HCLK_USBOTG1_PMU, "hclk_usbotg1_pmu", "hclk_bus_root", 0,
+			RK3506_CLKGATE_CON(7), 9, GFLAGS),
+	GATE(CLK_USBOTG1_ADP, "clk_usbotg1_adp", "clk_32k", 0,
+			RK3506_CLKGATE_CON(7), 10, GFLAGS),
+	GATE(PCLK_USBPHY, "pclk_usbphy", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(7), 11, GFLAGS),
+	GATE(ACLK_DMA2DDR, "aclk_dma2ddr", "aclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(8), 0, GFLAGS),
+	GATE(PCLK_DMA2DDR, "pclk_dma2ddr", "pclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(8), 1, GFLAGS),
+	COMPOSITE_NOMUX(STCLK_M0, "stclk_m0", "xin24m_gate", 0,
+			RK3506_CLKSEL_CON(23), 9, 6, DFLAGS,
+			RK3506_CLKGATE_CON(8), 2, GFLAGS),
+	COMPOSITE(CLK_DDRPHY, "clk_ddrphy", gpll_v0pll_v1pll_parents_p, CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKSEL_CON(4), 4, 2, MFLAGS, 0, 4, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 10, GFLAGS),
+	FACTOR(CLK_DDRC_SRC, "clk_ddrc_src", "clk_ddrphy", 0, 1, 4),
+	GATE(ACLK_DDRC_0, "aclk_ddrc_0", "clk_ddrc_src", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(10), 0, GFLAGS),
+	GATE(ACLK_DDRC_1, "aclk_ddrc_1", "clk_ddrc_src", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(10), 1, GFLAGS),
+	GATE(CLK_DDRC, "clk_ddrc", "clk_ddrc_src", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(10), 3, GFLAGS),
+	GATE(CLK_DDRMON, "clk_ddrmon", "clk_ddrc_src", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(10), 4, GFLAGS),
+
+	/* ls peri */
+	COMPOSITE(HCLK_LSPERI_ROOT, "hclk_lsperi_root", gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(29), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(11), 0, GFLAGS),
+	GATE(PCLK_LSPERI_ROOT, "pclk_lsperi_root", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 1, GFLAGS),
+	GATE(PCLK_UART0, "pclk_uart0", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 4, GFLAGS),
+	GATE(PCLK_UART1, "pclk_uart1", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 5, GFLAGS),
+	GATE(PCLK_UART2, "pclk_uart2", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 6, GFLAGS),
+	GATE(PCLK_UART3, "pclk_uart3", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 7, GFLAGS),
+	GATE(PCLK_UART4, "pclk_uart4", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 8, GFLAGS),
+	COMPOSITE(SCLK_UART0, "sclk_uart0", sclk_uart_parents_p, 0,
+			RK3506_CLKSEL_CON(29), 12, 3, MFLAGS, 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(11), 9, GFLAGS),
+	COMPOSITE(SCLK_UART1, "sclk_uart1", sclk_uart_parents_p, 0,
+			RK3506_CLKSEL_CON(30), 5, 3, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(11), 10, GFLAGS),
+	COMPOSITE(SCLK_UART2, "sclk_uart2", sclk_uart_parents_p, 0,
+			RK3506_CLKSEL_CON(30), 13, 3, MFLAGS, 8, 5, DFLAGS,
+			RK3506_CLKGATE_CON(11), 11, GFLAGS),
+	COMPOSITE(SCLK_UART3, "sclk_uart3", sclk_uart_parents_p, 0,
+			RK3506_CLKSEL_CON(31), 5, 3, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(11), 12, GFLAGS),
+	COMPOSITE(SCLK_UART4, "sclk_uart4", sclk_uart_parents_p, 0,
+			RK3506_CLKSEL_CON(31), 13, 3, MFLAGS, 8, 5, DFLAGS,
+			RK3506_CLKGATE_CON(11), 13, GFLAGS),
+	GATE(PCLK_I2C0, "pclk_i2c0", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 14, GFLAGS),
+	COMPOSITE(CLK_I2C0, "clk_i2c0", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(32), 4, 2, MFLAGS, 0, 4, DFLAGS,
+			RK3506_CLKGATE_CON(11), 15, GFLAGS),
+	GATE(PCLK_I2C1, "pclk_i2c1", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(12), 0, GFLAGS),
+	COMPOSITE(CLK_I2C1, "clk_i2c1", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(32), 10, 2, MFLAGS, 6, 4, DFLAGS,
+			RK3506_CLKGATE_CON(12), 1, GFLAGS),
+	GATE(PCLK_I2C2, "pclk_i2c2", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(12), 2, GFLAGS),
+	COMPOSITE(CLK_I2C2, "clk_i2c2", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(33), 4, 2, MFLAGS, 0, 4, DFLAGS,
+			RK3506_CLKGATE_CON(12), 3, GFLAGS),
+	GATE(PCLK_PWM1, "pclk_pwm1", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(12), 4, GFLAGS),
+	COMPOSITE(CLK_PWM1, "clk_pwm1", gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(33), 10, 2, MFLAGS, 6, 4, DFLAGS,
+			RK3506_CLKGATE_CON(12), 5, GFLAGS),
+	GATE(CLK_OSC_PWM1, "clk_osc_pwm1", "xin24m", 0,
+			RK3506_CLKGATE_CON(12), 6, GFLAGS),
+	GATE(CLK_RC_PWM1, "clk_rc_pwm1", "clk_rc", 0,
+			RK3506_CLKGATE_CON(12), 7, GFLAGS),
+	COMPOSITE_NODIV(CLK_FREQ_PWM1, "clk_freq_pwm1", clk_pwm_parents_p, 0,
+			RK3506_CLKSEL_CON(33), 12, 4, MFLAGS,
+			RK3506_CLKGATE_CON(12), 8, GFLAGS),
+	COMPOSITE_NODIV(CLK_COUNTER_PWM1, "clk_counter_pwm1", clk_pwm_parents_p, 0,
+			RK3506_CLKSEL_CON(34), 0, 4, MFLAGS,
+			RK3506_CLKGATE_CON(12), 9, GFLAGS),
+	GATE(PCLK_SPI0, "pclk_spi0", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(12), 10, GFLAGS),
+	COMPOSITE(CLK_SPI0, "clk_spi0", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(34), 8, 2, MFLAGS, 4, 4, DFLAGS,
+			RK3506_CLKGATE_CON(12), 11, GFLAGS),
+	GATE(PCLK_SPI1, "pclk_spi1", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(12), 12, GFLAGS),
+	COMPOSITE(CLK_SPI1, "clk_spi1", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(34), 14, 2, MFLAGS, 10, 4, DFLAGS,
+			RK3506_CLKGATE_CON(12), 13, GFLAGS),
+	GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(12), 14, GFLAGS),
+	COMPOSITE_NODIV(DBCLK_GPIO2, "dbclk_gpio2", xin24m_400k_32k_parents_p, 0,
+			RK3506_CLKSEL_CON(35), 0, 2, MFLAGS,
+			RK3506_CLKGATE_CON(12), 15, GFLAGS),
+	GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 0, GFLAGS),
+	COMPOSITE_NODIV(DBCLK_GPIO3, "dbclk_gpio3", xin24m_400k_32k_parents_p, 0,
+			RK3506_CLKSEL_CON(35), 2, 2, MFLAGS,
+			RK3506_CLKGATE_CON(13), 1, GFLAGS),
+	GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 2, GFLAGS),
+	COMPOSITE_NODIV(DBCLK_GPIO4, "dbclk_gpio4", xin24m_400k_32k_parents_p, 0,
+			RK3506_CLKSEL_CON(35), 4, 2, MFLAGS,
+			RK3506_CLKGATE_CON(13), 3, GFLAGS),
+	GATE(HCLK_CAN0, "hclk_can0", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 4, GFLAGS),
+	COMPOSITE(CLK_CAN0, "clk_can0", clk_can_parents_p, 0,
+			RK3506_CLKSEL_CON(35), 11, 3, MFLAGS, 6, 5, DFLAGS,
+			RK3506_CLKGATE_CON(13), 5, GFLAGS),
+	GATE(HCLK_CAN1, "hclk_can1", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 6, GFLAGS),
+	COMPOSITE(CLK_CAN1, "clk_can1", clk_can_parents_p, 0,
+			RK3506_CLKSEL_CON(36), 5, 3, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(13), 7, GFLAGS),
+	GATE(HCLK_PDM, "hclk_pdm", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 8, GFLAGS),
+	COMPOSITE(MCLK_PDM, "mclk_pdm", clk_pdm_parents_p, 0,
+			RK3506_CLKSEL_CON(37), 5, 4, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(13), 9, GFLAGS),
+	COMPOSITE(CLKOUT_PDM, "clkout_pdm", clk_pdm_parents_p, 0,
+			RK3506_CLKSEL_CON(38), 10, 4, MFLAGS, 0, 10, DFLAGS,
+			RK3506_CLKGATE_CON(13), 10, GFLAGS),
+	COMPOSITE(MCLK_SPDIFTX, "mclk_spdiftx", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(39), 5, 4, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(13), 11, GFLAGS),
+	GATE(HCLK_SPDIFTX, "hclk_spdiftx", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 12, GFLAGS),
+	GATE(HCLK_SPDIFRX, "hclk_spdifrx", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 13, GFLAGS),
+	COMPOSITE(MCLK_SPDIFRX, "mclk_spdifrx", gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(39), 14, 2, MFLAGS, 9, 5, DFLAGS,
+			RK3506_CLKGATE_CON(13), 14, GFLAGS),
+	COMPOSITE(MCLK_SAI0, "mclk_sai0", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(40), 8, 4, MFLAGS, 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(13), 15, GFLAGS),
+	GATE(HCLK_SAI0, "hclk_sai0", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(14), 0, GFLAGS),
+	GATE(MCLK_OUT_SAI0, "mclk_out_sai0", "mclk_sai0", 0,
+			RK3506_CLKGATE_CON(14), 1, GFLAGS),
+	COMPOSITE(MCLK_SAI1, "mclk_sai1", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(41), 8, 4, MFLAGS, 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(14), 2, GFLAGS),
+	GATE(HCLK_SAI1, "hclk_sai1", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(14), 3, GFLAGS),
+	GATE(MCLK_OUT_SAI1, "mclk_out_sai1", "mclk_sai1", 0,
+			RK3506_CLKGATE_CON(14), 4, GFLAGS),
+	GATE(HCLK_ASRC0, "hclk_asrc0", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(14), 5, GFLAGS),
+	COMPOSITE(CLK_ASRC0, "clk_asrc0", gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(42), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(14), 6, GFLAGS),
+	GATE(HCLK_ASRC1, "hclk_asrc1", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(14), 7, GFLAGS),
+	COMPOSITE(CLK_ASRC1, "clk_asrc1", gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(42), 12, 2, MFLAGS, 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(14), 8, GFLAGS),
+	GATE(PCLK_CRU, "pclk_cru", "pclk_lsperi_root", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(14), 9, GFLAGS),
+	GATE(PCLK_PMU_ROOT, "pclk_pmu_root", "pclk_lsperi_root", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(14), 10, GFLAGS),
+	COMPOSITE_NODIV(MCLK_ASRC0, "mclk_asrc0", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(46), 0, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 0, GFLAGS),
+	COMPOSITE_NODIV(MCLK_ASRC1, "mclk_asrc1", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(46), 4, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 1, GFLAGS),
+	COMPOSITE_NODIV(MCLK_ASRC2, "mclk_asrc2", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(46), 8, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 2, GFLAGS),
+	COMPOSITE_NODIV(MCLK_ASRC3, "mclk_asrc3", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(46), 12, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 3, GFLAGS),
+	COMPOSITE_NODIV(LRCK_ASRC0_SRC, "lrck_asrc0_src", lrck_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(47), 0, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 4, GFLAGS),
+	COMPOSITE_NODIV(LRCK_ASRC0_DST, "lrck_asrc0_dst", lrck_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(47), 4, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 5, GFLAGS),
+	COMPOSITE_NODIV(LRCK_ASRC1_SRC, "lrck_asrc1_src", lrck_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(47), 8, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 6, GFLAGS),
+	COMPOSITE_NODIV(LRCK_ASRC1_DST, "lrck_asrc1_dst", lrck_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(47), 12, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 7, GFLAGS),
+
+	/* hs peri */
+	COMPOSITE(ACLK_HSPERI_ROOT, "aclk_hsperi_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(49), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(17), 0, GFLAGS),
+	GATE(HCLK_HSPERI_ROOT, "hclk_hsperi_root", "aclk_hsperi_root", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(17), 1, GFLAGS),
+	GATE(PCLK_HSPERI_ROOT, "pclk_hsperi_root", "hclk_hsperi_root", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(17), 2, GFLAGS),
+	COMPOSITE(CCLK_SRC_SDMMC, "cclk_src_sdmmc", cclk_src_sdmmc_parents_p, 0,
+			RK3506_CLKSEL_CON(49), 13, 2, MFLAGS, 7, 6, DFLAGS,
+			RK3506_CLKGATE_CON(17), 6, GFLAGS),
+	GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 7, GFLAGS),
+	GATE(HCLK_FSPI, "hclk_fspi", "hclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 8, GFLAGS),
+	COMPOSITE(SCLK_FSPI, "sclk_fspi", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(50), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(17), 9, GFLAGS),
+	GATE(PCLK_SPI2, "pclk_spi2", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 10, GFLAGS),
+	GATE(ACLK_MAC0, "aclk_mac0", "aclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 11, GFLAGS),
+	GATE(ACLK_MAC1, "aclk_mac1", "aclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 12, GFLAGS),
+	GATE(PCLK_MAC0, "pclk_mac0", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 13, GFLAGS),
+	GATE(PCLK_MAC1, "pclk_mac1", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 14, GFLAGS),
+	COMPOSITE_NOMUX(CLK_MAC_ROOT, "clk_mac_root", "gpll", 0,
+			RK3506_CLKSEL_CON(50), 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(17), 15, GFLAGS),
+	GATE(CLK_MAC0, "clk_mac0", "clk_mac_root", 0,
+			RK3506_CLKGATE_CON(18), 0, GFLAGS),
+	GATE(CLK_MAC1, "clk_mac1", "clk_mac_root", 0,
+			RK3506_CLKGATE_CON(18), 1, GFLAGS),
+	COMPOSITE(MCLK_SAI2, "mclk_sai2", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(51), 8, 4, MFLAGS, 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(18), 2, GFLAGS),
+	GATE(HCLK_SAI2, "hclk_sai2", "hclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(18), 3, GFLAGS),
+	GATE(MCLK_OUT_SAI2, "mclk_out_sai2", "mclk_sai2", 0,
+			RK3506_CLKGATE_CON(18), 4, GFLAGS),
+	COMPOSITE(MCLK_SAI3_SRC, "mclk_sai3_src", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(52), 8, 4, MFLAGS, 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(18), 5, GFLAGS),
+	GATE(HCLK_SAI3, "hclk_sai3", "hclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(18), 6, GFLAGS),
+	GATE(MCLK_SAI3, "mclk_sai3", "mclk_sai3_src", 0,
+			RK3506_CLKGATE_CON(18), 7, GFLAGS),
+	GATE(MCLK_OUT_SAI3, "mclk_out_sai3", "mclk_sai3_src", 0,
+			RK3506_CLKGATE_CON(18), 8, GFLAGS),
+	COMPOSITE(MCLK_SAI4_SRC, "mclk_sai4_src", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(53), 8, 4, MFLAGS, 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(18), 9, GFLAGS),
+	GATE(HCLK_SAI4, "hclk_sai4", "hclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(18), 10, GFLAGS),
+	GATE(MCLK_SAI4, "mclk_sai4", "mclk_sai4_src", 0,
+			RK3506_CLKGATE_CON(18), 11, GFLAGS),
+	GATE(HCLK_DSM, "hclk_dsm", "hclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(18), 12, GFLAGS),
+	GATE(MCLK_DSM, "mclk_dsm", "mclk_sai3_src", 0,
+			RK3506_CLKGATE_CON(18), 13, GFLAGS),
+	GATE(PCLK_AUDIO_ADC, "pclk_audio_adc", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(18), 14, GFLAGS),
+	GATE(MCLK_AUDIO_ADC, "mclk_audio_adc", "mclk_sai4_src", 0,
+			RK3506_CLKGATE_CON(18), 15, GFLAGS),
+	FACTOR(MCLK_AUDIO_ADC_DIV4, "mclk_audio_adc_div4", "mclk_audio_adc", 0, 1, 4),
+	GATE(PCLK_SARADC, "pclk_saradc", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(19), 0, GFLAGS),
+	COMPOSITE(CLK_SARADC, "clk_saradc", xin24m_400k_32k_parents_p, 0,
+			RK3506_CLKSEL_CON(54), 4, 2, MFLAGS, 0, 4, DFLAGS,
+			RK3506_CLKGATE_CON(19), 1, GFLAGS),
+	GATE(PCLK_OTPC_NS, "pclk_otpc_ns", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(19), 3, GFLAGS),
+	GATE(CLK_SBPI_OTPC_NS, "clk_sbpi_otpc_ns", "xin24m_gate", 0,
+			RK3506_CLKGATE_CON(19), 4, GFLAGS),
+	FACTOR(CLK_USER_OTPC_NS, "clk_user_otpc_ns", "clk_sbpi_otpc_ns", 0, 1, 2),
+	GATE(PCLK_UART5, "pclk_uart5", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(19), 6, GFLAGS),
+	COMPOSITE(SCLK_UART5, "sclk_uart5", sclk_uart_parents_p, 0,
+			RK3506_CLKSEL_CON(54), 11, 3, MFLAGS, 6, 5, DFLAGS,
+			RK3506_CLKGATE_CON(19), 7, GFLAGS),
+	GATE(PCLK_GPIO234_IOC, "pclk_gpio234_ioc", "pclk_hsperi_root", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(19), 8, GFLAGS),
+	COMPOSITE(CLK_MAC_PTP_ROOT, "clk_mac_ptp_root", clk_mac_ptp_root_parents_p, 0,
+			RK3506_CLKSEL_CON(55), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(19), 9, GFLAGS),
+	GATE(CLK_MAC0_PTP, "clk_mac0_ptp", "clk_mac_ptp_root", 0,
+			RK3506_CLKGATE_CON(19), 10, GFLAGS),
+	GATE(CLK_MAC1_PTP, "clk_mac1_ptp", "clk_mac_ptp_root", 0,
+			RK3506_CLKGATE_CON(19), 11, GFLAGS),
+	COMPOSITE(ACLK_VIO_ROOT, "aclk_vio_root", gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(58), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(21), 0, GFLAGS),
+	COMPOSITE(HCLK_VIO_ROOT, "hclk_vio_root", gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(58), 12, 2, MFLAGS, 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(21), 1, GFLAGS),
+	GATE(PCLK_VIO_ROOT, "pclk_vio_root", "hclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 2, GFLAGS),
+	GATE(HCLK_RGA, "hclk_rga", "hclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 6, GFLAGS),
+	GATE(ACLK_RGA, "aclk_rga", "aclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 7, GFLAGS),
+	COMPOSITE(CLK_CORE_RGA, "clk_core_rga", gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(59), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(21), 8, GFLAGS),
+	GATE(ACLK_VOP, "aclk_vop", "aclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 9, GFLAGS),
+	GATE(HCLK_VOP, "hclk_vop", "hclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 10, GFLAGS),
+	COMPOSITE(DCLK_VOP, "dclk_vop", dclk_vop_parents_p, 0,
+			RK3506_CLKSEL_CON(60), 8, 3, MFLAGS, 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(21), 11, GFLAGS),
+	GATE(PCLK_DPHY, "pclk_dphy", "pclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 12, GFLAGS),
+	GATE(PCLK_DSI_HOST, "pclk_dsi_host", "pclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 13, GFLAGS),
+	GATE(PCLK_TSADC, "pclk_tsadc", "pclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 14, GFLAGS),
+	COMPOSITE_NOMUX(CLK_TSADC, "clk_tsadc", "xin24m_gate", 0,
+			RK3506_CLKSEL_CON(61), 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(21), 15, GFLAGS),
+	COMPOSITE_NOMUX(CLK_TSADC_TSEN, "clk_tsadc_tsen", "xin24m_gate", 0,
+			RK3506_CLKSEL_CON(61), 8, 3, DFLAGS,
+			RK3506_CLKGATE_CON(22), 0, GFLAGS),
+	GATE(PCLK_GPIO1_IOC, "pclk_gpio1_ioc", "pclk_vio_root", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(22), 1, GFLAGS),
+
+	/* pmu */
+	GATE(CLK_PMU, "clk_pmu", "xin24m", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 1, GFLAGS),
+	GATE(PCLK_PMU, "pclk_pmu", "pclk_pmu_root", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 2, GFLAGS),
+	GATE(PCLK_PMU_CRU, "pclk_pmu_cru", "pclk_pmu_root", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 4, GFLAGS),
+	GATE(PCLK_PMU_GRF, "pclk_pmu_grf", "pclk_pmu_root", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 5, GFLAGS),
+	GATE(PCLK_GPIO0_IOC, "pclk_gpio0_ioc", "pclk_pmu_root", CLK_IS_CRITICAL,
+			RK3506_PMU_CLKGATE_CON(0), 7, GFLAGS),
+	GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pmu_root", 0,
+			RK3506_PMU_CLKGATE_CON(0), 8, GFLAGS),
+	COMPOSITE_NODIV(DBCLK_GPIO0, "dbclk_gpio0", dbclk_gpio0_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(0), 0, 2, MFLAGS,
+			RK3506_PMU_CLKGATE_CON(0), 9, GFLAGS),
+	GATE(PCLK_GPIO1_SHADOW, "pclk_gpio1_shadow", "pclk_pmu_root", 0,
+			RK3506_PMU_CLKGATE_CON(0), 10, GFLAGS),
+	COMPOSITE_NODIV(DBCLK_GPIO1_SHADOW, "dbclk_gpio1_shadow", dbclk_gpio0_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(0), 2, 2, MFLAGS,
+			RK3506_PMU_CLKGATE_CON(0), 11, GFLAGS),
+	GATE(PCLK_PMU_HP_TIMER, "pclk_pmu_hp_timer", "pclk_pmu_root", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 12, GFLAGS),
+	MUX(CLK_PMU_HP_TIMER, "clk_pmu_hp_timer", clk_pmu_hp_timer_parents_p, CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKSEL_CON(0), 4, 2, MFLAGS),
+	GATE(PCLK_PWM0, "pclk_pwm0", "pclk_pmu_root", 0,
+			RK3506_PMU_CLKGATE_CON(0), 15, GFLAGS),
+	COMPOSITE_NOMUX(CLK_PWM0, "clk_pwm0", "clk_gpll_div_100m", 0,
+			RK3506_PMU_CLKSEL_CON(0), 6, 4, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 0, GFLAGS),
+	GATE(CLK_OSC_PWM0, "clk_osc_pwm0", "xin24m", 0,
+			RK3506_PMU_CLKGATE_CON(1), 1, GFLAGS),
+	GATE(CLK_RC_PWM0, "clk_rc_pwm0", "clk_rc", 0,
+			RK3506_PMU_CLKGATE_CON(1), 2, GFLAGS),
+	COMPOSITE_NOMUX(CLK_MAC_OUT, "clk_mac_out", "gpll", 0,
+			RK3506_PMU_CLKSEL_CON(0), 10, 6, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 3, GFLAGS),
+	COMPOSITE(CLK_REF_OUT0, "clk_ref_out0", clk_ref_out_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(1), 6, 2, MFLAGS, 0, 6, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 4, GFLAGS),
+	COMPOSITE(CLK_REF_OUT1, "clk_ref_out1", clk_ref_out_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(1), 14, 2, MFLAGS, 8, 6, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 5, GFLAGS),
+	MUX(CLK_32K_FRAC_MUX, "clk_32k_frac_mux", clk_32k_frac_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(3), 0, 2, MFLAGS),
+	COMPOSITE_FRAC(CLK_32K_FRAC, "clk_32k_frac", "clk_32k_frac_mux", 0,
+			RK3506_PMU_CLKSEL_CON(2), 0,
+			RK3506_PMU_CLKGATE_CON(1), 6, GFLAGS),
+	COMPOSITE_NOMUX(CLK_32K_RC, "clk_32k_rc", "clk_rc", CLK_IS_CRITICAL,
+			RK3506_PMU_CLKSEL_CON(3), 2, 5, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 7, GFLAGS),
+	COMPOSITE_NODIV(CLK_32K, "clk_32k", clk_32k_parents_p, CLK_IS_CRITICAL,
+			RK3506_PMU_CLKSEL_CON(3), 7, 2, MFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 8, GFLAGS),
+	COMPOSITE_NODIV(CLK_32K_PMU, "clk_32k_pmu", clk_32k_parents_p, CLK_IS_CRITICAL,
+			RK3506_PMU_CLKSEL_CON(3), 9, 2, MFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 9, GFLAGS),
+	GATE(CLK_PMU_32K, "clk_pmu_32k", "clk_32k_pmu", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 3, GFLAGS),
+	GATE(CLK_PMU_HP_TIMER_32K, "clk_pmu_hp_timer_32k", "clk_32k_pmu", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 14, GFLAGS),
+	GATE(PCLK_TOUCH_KEY, "pclk_touch_key", "pclk_pmu_root", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(1), 12, GFLAGS),
+	GATE(CLK_TOUCH_KEY, "clk_touch_key", "xin24m", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(1), 13, GFLAGS),
+	COMPOSITE(CLK_REF_PHY_PLL, "clk_ref_phy_pll", gpll_v0pll_v1pll_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(4), 13, 2, MFLAGS, 6, 7, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 14, GFLAGS),
+	MUX(CLK_REF_PHY_PMU_MUX, "clk_ref_phy_pmu_mux", clk_ref_phy_pmu_mux_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(4), 15, 1, MFLAGS),
+	GATE(CLK_WIFI_OUT, "clk_wifi_out", "xin24m", 0,
+			RK3506_PMU_CLKGATE_CON(2), 0, GFLAGS),
+	MUX(CLK_V0PLL_REF, "clk_v0pll_ref", clk_vpll_ref_parents_p, CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKSEL_CON(6), 0, 1, MFLAGS),
+	MUX(CLK_V1PLL_REF, "clk_v1pll_ref", clk_vpll_ref_parents_p, CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKSEL_CON(6), 1, 1, MFLAGS),
+
+	/* secure ns */
+	GATE(CLK_CORE_CRYPTO_NS, "clk_core_crypto_ns", "clk_core_crypto", 0,
+			RK3506_CLKGATE_CON(5), 12, GFLAGS),
+	GATE(CLK_PKA_CRYPTO_NS, "clk_pka_crypto_ns", "clk_pka_crypto", 0,
+			RK3506_CLKGATE_CON(5), 13, GFLAGS),
+
+	/* io */
+	GATE(CLK_SPI2, "clk_spi2", "clk_spi2_io", 0,
+			RK3506_CLKGATE_CON(20), 0, GFLAGS),
+};
+
+static void __init rk3506_clk_init(struct device_node *np)
+{
+	struct rockchip_clk_provider *ctx;
+	unsigned long clk_nr_clks;
+	void __iomem *reg_base;
+
+	clk_nr_clks = rockchip_clk_find_max_clk_id(rk3506_clk_branches,
+						   ARRAY_SIZE(rk3506_clk_branches)) + 1;
+
+	reg_base = of_iomap(np, 0);
+	if (!reg_base) {
+		pr_err("%s: could not map cru region\n", __func__);
+		return;
+	}
+
+	ctx = rockchip_clk_init(np, reg_base, clk_nr_clks);
+	if (IS_ERR(ctx)) {
+		pr_err("%s: rockchip clk init failed\n", __func__);
+		iounmap(reg_base);
+		return;
+	}
+
+	rockchip_clk_register_plls(ctx, rk3506_pll_clks,
+				   ARRAY_SIZE(rk3506_pll_clks),
+				   0);
+
+	rockchip_clk_register_armclk_multi_pll(ctx, &rk3506_armclk,
+					       rk3506_cpuclk_rates,
+					       ARRAY_SIZE(rk3506_cpuclk_rates));
+
+	rockchip_clk_register_branches(ctx, rk3506_clk_branches,
+				       ARRAY_SIZE(rk3506_clk_branches));
+
+	rk3506_rst_init(np, reg_base);
+
+	rockchip_register_restart_notifier(ctx, RK3506_GLB_SRST_FST, NULL);
+
+	rockchip_clk_of_add_provider(np, ctx);
+
+	/* pvtpll src init */
+	writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RK3506_CLKSEL_CON(15));
+}
+
+CLK_OF_DECLARE(rk3506_cru, "rockchip,rk3506-cru", rk3506_clk_init);
+
+struct clk_rk3506_inits {
+	void (*inits)(struct device_node *np);
+};
+
+static const struct clk_rk3506_inits clk_rk3506_cru_init = {
+	.inits = rk3506_clk_init,
+};
+
+static const struct of_device_id clk_rk3506_match_table[] = {
+	{
+		.compatible = "rockchip,rk3506-cru",
+		.data = &clk_rk3506_cru_init,
+	},
+	{ }
+};
+
+static int clk_rk3506_probe(struct platform_device *pdev)
+{
+	const struct clk_rk3506_inits *init_data;
+	struct device *dev = &pdev->dev;
+
+	init_data = device_get_match_data(dev);
+	if (!init_data)
+		return -EINVAL;
+
+	if (init_data->inits)
+		init_data->inits(dev->of_node);
+
+	return 0;
+}
+
+static struct platform_driver clk_rk3506_driver = {
+	.probe		= clk_rk3506_probe,
+	.driver		= {
+		.name	= "clk-rk3506",
+		.of_match_table = clk_rk3506_match_table,
+		.suppress_bind_attrs = true,
+	},
+};
+builtin_platform_driver_probe(clk_rk3506_driver, clk_rk3506_probe);
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index 87f09320b942..b2fff1d13a4a 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -275,6 +275,18 @@ struct clk;
 #define RK3399_PMU_CLKGATE_CON(x)	((x) * 0x4 + 0x100)
 #define RK3399_PMU_SOFTRST_CON(x)	((x) * 0x4 + 0x110)
 
+#define RK3506_PMU_CRU_BASE		0x10000
+#define RK3506_PLL_CON(x)		((x) * 0x4 + RK3506_PMU_CRU_BASE)
+#define RK3506_CLKSEL_CON(x)		((x) * 0x4 + 0x300)
+#define RK3506_CLKGATE_CON(x)		((x) * 0x4 + 0x800)
+#define RK3506_SOFTRST_CON(x)		((x) * 0x4 + 0xa00)
+#define RK3506_PMU_CLKSEL_CON(x)	((x) * 0x4 + 0x300 + RK3506_PMU_CRU_BASE)
+#define RK3506_PMU_CLKGATE_CON(x)	((x) * 0x4 + 0x800 + RK3506_PMU_CRU_BASE)
+#define RK3506_MODE_CON			0x280
+#define RK3506_GLB_CNT_TH		0xc00
+#define RK3506_GLB_SRST_FST		0xc08
+#define RK3506_GLB_SRST_SND		0xc0c
+
 #define RK3528_PMU_CRU_BASE		0x10000
 #define RK3528_PCIE_CRU_BASE		0x20000
 #define RK3528_DDRPHY_CRU_BASE		0x28000
@@ -1329,6 +1341,7 @@ static inline void rockchip_register_softrst(struct device_node *np,
 }
 
 void rv1126b_rst_init(struct device_node *np, void __iomem *reg_base);
+void rk3506_rst_init(struct device_node *np, void __iomem *reg_base);
 void rk3528_rst_init(struct device_node *np, void __iomem *reg_base);
 void rk3562_rst_init(struct device_node *np, void __iomem *reg_base);
 void rk3576_rst_init(struct device_node *np, void __iomem *reg_base);
diff --git a/drivers/clk/rockchip/rst-rk3506.c b/drivers/clk/rockchip/rst-rk3506.c
new file mode 100644
index 000000000000..f6a833ee2f5c
--- /dev/null
+++ b/drivers/clk/rockchip/rst-rk3506.c
@@ -0,0 +1,226 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2025 Rockchip Electronics Co., Ltd.
+ * Author: Finley Xiao <finley.xiao at rock-chips.com>
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <dt-bindings/reset/rockchip,rk3506-cru.h>
+#include "clk.h"
+
+/* 0xFF9A0000 + 0x0A00 */
+#define RK3506_CRU_RESET_OFFSET(id, reg, bit) [id] = (0 + reg * 16 + bit)
+
+/* mapping table for reset ID to register offset */
+static const int rk3506_register_offset[] = {
+	/* CRU-->SOFTRST_CON00 */
+	RK3506_CRU_RESET_OFFSET(SRST_NCOREPORESET0_AC, 0, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_NCOREPORESET1_AC, 0, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_NCOREPORESET2_AC, 0, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_NCORESET0_AC, 0, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_NCORESET1_AC, 0, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_NCORESET2_AC, 0, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_NL2RESET_AC, 0, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_CORE_BIU_AC, 0, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_M0_AC, 0, 10),
+
+	/* CRU-->SOFTRST_CON02 */
+	RK3506_CRU_RESET_OFFSET(SRST_NDBGRESET, 2, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_CORE_BIU, 2, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_PMU, 2, 15),
+
+	/* CRU-->SOFTRST_CON03 */
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_DBG, 3, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_POTRESETN_DBG, 3, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_CORE_GRF, 3, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_CORE_EMA_DETECT, 3, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_REF_PVTPLL_CORE, 3, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_GPIO1, 3, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_DBRESETN_GPIO1, 3, 9),
+
+	/* CRU-->SOFTRST_CON04 */
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_CORE_PERI_BIU, 4, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_DSMC, 4, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_DSMC, 4, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_FLEXBUS, 4, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_FLEXBUS, 4, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_FLEXBUS, 4, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_DSMC_SLV, 4, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_DSMC_SLV, 4, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_DSMC_SLV, 4, 13),
+
+	/* CRU-->SOFTRST_CON05 */
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_BUS_BIU, 5, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_BUS_BIU, 5, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_BUS_BIU, 5, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_SYSRAM, 5, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_SYSRAM, 5, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_DMAC0, 5, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_DMAC1, 5, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_M0, 5, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_M0_JTAG, 5, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_CRYPTO, 5, 15),
+
+	/* CRU-->SOFTRST_CON06 */
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_RNG, 6, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_BUS_GRF, 6, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_TIMER0, 6, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_TIMER0_CH0, 6, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_TIMER0_CH1, 6, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_TIMER0_CH2, 6, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_TIMER0_CH3, 6, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_TIMER0_CH4, 6, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_TIMER0_CH5, 6, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_WDT0, 6, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_TRESETN_WDT0, 6, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_WDT1, 6, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_TRESETN_WDT1, 6, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_MAILBOX, 6, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_INTMUX, 6, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_SPINLOCK, 6, 15),
+
+	/* CRU-->SOFTRST_CON07 */
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_DDRC, 7, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_DDRPHY, 7, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_DDRMON, 7, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_DDRMON_OSC, 7, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_DDR_LPC, 7, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_USBOTG0, 7, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_USBOTG0_ADP, 7, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_USBOTG1, 7, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_USBOTG1_ADP, 7, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_USBPHY, 7, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_USBPHY_POR, 7, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_USBPHY_OTG0, 7, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_USBPHY_OTG1, 7, 14),
+
+	/* CRU-->SOFTRST_CON08 */
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_DMA2DDR, 8, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_DMA2DDR, 8, 1),
+
+	/* CRU-->SOFTRST_CON09 */
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_USBOTG0_UTMI, 9, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_USBOTG1_UTMI, 9, 1),
+
+	/* CRU-->SOFTRST_CON10 */
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_DDRC_0, 10, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_DDRC_1, 10, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_DDR_BIU, 10, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_DDRC, 10, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_DDRMON, 10, 4),
+
+	/* CRU-->SOFTRST_CON11 */
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_LSPERI_BIU, 11, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_UART0, 11, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_UART1, 11, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_UART2, 11, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_UART3, 11, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_UART4, 11, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_UART0, 11, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_UART1, 11, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_UART2, 11, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_UART3, 11, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_UART4, 11, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_I2C0, 11, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_I2C0, 11, 15),
+
+	/* CRU-->SOFTRST_CON12 */
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_I2C1, 12, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_I2C1, 12, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_I2C2, 12, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_I2C2, 12, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_PWM1, 12, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_PWM1, 12, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_SPI0, 12, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_SPI0, 12, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_SPI1, 12, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_SPI1, 12, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_GPIO2, 12, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_DBRESETN_GPIO2, 12, 15),
+
+	/* CRU-->SOFTRST_CON13 */
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_GPIO3, 13, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_DBRESETN_GPIO3, 13, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_GPIO4, 13, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_DBRESETN_GPIO4, 13, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_CAN0, 13, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_CAN0, 13, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_CAN1, 13, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_CAN1, 13, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_PDM, 13, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_MRESETN_PDM, 13, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_PDM, 13, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_SPDIFTX, 13, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_SPDIFTX, 13, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_SPDIFRX, 13, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_SPDIFRX, 13, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_MRESETN_SAI0, 13, 15),
+
+	/* CRU-->SOFTRST_CON14 */
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_SAI0, 14, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_MRESETN_SAI1, 14, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_SAI1, 14, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_ASRC0, 14, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_ASRC0, 14, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_ASRC1, 14, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_ASRC1, 14, 8),
+
+	/* CRU-->SOFTRST_CON17 */
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_HSPERI_BIU, 17, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_SDMMC, 17, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_FSPI, 17, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_SRESETN_FSPI, 17, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_SPI2, 17, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_MAC0, 17, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_MAC1, 17, 12),
+
+	/* CRU-->SOFTRST_CON18 */
+	RK3506_CRU_RESET_OFFSET(SRST_MRESETN_SAI2, 18, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_SAI2, 18, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_SAI3, 18, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_MRESETN_SAI3, 18, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_SAI4, 18, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_MRESETN_SAI4, 18, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_DSM, 18, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_MRESETN_DSM, 18, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_AUDIO_ADC, 18, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_MRESETN_AUDIO_ADC, 18, 15),
+
+	/* CRU-->SOFTRST_CON19 */
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_SARADC, 19, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_SARADC, 19, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_SARADC_PHY, 19, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_OTPC_NS, 19, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_SBPI_OTPC_NS, 19, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_USER_OTPC_NS, 19, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_UART5, 19, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_UART5, 19, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_GPIO234_IOC, 19, 8),
+
+	/* CRU-->SOFTRST_CON21 */
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_VIO_BIU, 21, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_VIO_BIU, 21, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_RGA, 21, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_RGA, 21, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_CORE_RGA, 21, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_ARESETN_VOP, 21, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_HRESETN_VOP, 21, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_VOP, 21, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_DPHY, 21, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_DSI_HOST, 21, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_TSADC, 21, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_RESETN_TSADC, 21, 15),
+
+	/* CRU-->SOFTRST_CON22 */
+	RK3506_CRU_RESET_OFFSET(SRST_PRESETN_GPIO1_IOC, 22, 1),
+};
+
+void rk3506_rst_init(struct device_node *np, void __iomem *reg_base)
+{
+	rockchip_register_softrst_lut(np,
+				      rk3506_register_offset,
+				      ARRAY_SIZE(rk3506_register_offset),
+				      reg_base + RK3506_SOFTRST_CON(0),
+				      ROCKCHIP_SOFTRST_HIWORD_MASK);
+}
-- 
2.34.1



From zhangqing at rock-chips.com  Thu Nov  6 17:44:23 2025
From: zhangqing at rock-chips.com (zhangqing)
Date: Fri, 7 Nov 2025 09:44:23 +0800
Subject: [PATCH v5 6/7] dt-bindings: clock: rockchip: Add RK3506 clock and
 reset unit
In-Reply-To: <241e4a1d-039c-4738-b492-6325ad354b2e@kwiboo.se>
References: <20251027084147.4148739-1-zhangqing@rock-chips.com>
 <20251027084147.4148739-7-zhangqing@rock-chips.com>
 <241e4a1d-039c-4738-b492-6325ad354b2e@kwiboo.se>
Message-ID: <3477bbf7-bfca-44d8-8fe1-5dadcfd59428@rock-chips.com>


? 2025/10/30 21:55, Jonas Karlman ??:
> Hi Elaine,
>
> On 10/27/2025 9:41 AM, Elaine Zhang wrote:
>> From: Finley Xiao <finley.xiao at rock-chips.com>
>>
>> Add device tree bindings for clock and reset unit on RK3506 SoC.
>> Add clock and reset IDs for RK3506 SoC.
>>
>> Signed-off-by: Finley Xiao <finley.xiao at rock-chips.com>
>> ---
>>   .../bindings/clock/rockchip,rk3506-cru.yaml   |  51 ++++
>>   .../dt-bindings/clock/rockchip,rk3506-cru.h   | 285 ++++++++++++++++++
>>   .../dt-bindings/reset/rockchip,rk3506-cru.h   | 211 +++++++++++++
>>   3 files changed, 547 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
>>   create mode 100644 include/dt-bindings/clock/rockchip,rk3506-cru.h
>>   create mode 100644 include/dt-bindings/reset/rockchip,rk3506-cru.h
> [snip]
>
>> diff --git a/include/dt-bindings/reset/rockchip,rk3506-cru.h b/include/dt-bindings/reset/rockchip,rk3506-cru.h
>> new file mode 100644
>> index 000000000000..f38cc066009b
>> --- /dev/null
>> +++ b/include/dt-bindings/reset/rockchip,rk3506-cru.h
>> @@ -0,0 +1,211 @@
>> +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
>> +/*
>> + * Copyright (c) 2023-2025 Rockchip Electronics Co., Ltd.
>> + * Author: Finley Xiao <finley.xiao at rock-chips.com>
>> + */
>> +
>> +#ifndef _DT_BINDINGS_REST_ROCKCHIP_RK3506_H
>> +#define _DT_BINDINGS_REST_ROCKCHIP_RK3506_H
>> +
>> +/* CRU-->SOFTRST_CON00 */
>> +#define SRST_NCOREPORESET0_AC		0
>> +#define SRST_NCOREPORESET1_AC		1
>> +#define SRST_NCOREPORESET2_AC		2
>> +#define SRST_NCORESET0_AC		3
>> +#define SRST_NCORESET1_AC		4
>> +#define SRST_NCORESET2_AC		5
>> +#define SRST_NL2RESET_AC		6
>> +#define SRST_ARESETN_CORE_BIU_AC	7
>> +#define SRST_HRESETN_M0_AC		8
>> +
>> +/* CRU-->SOFTRST_CON02 */
>> +#define SRST_NDBGRESET			9
>> +#define SRST_PRESETN_CORE_BIU		10
>> +#define SRST_RESETN_PMU			11
>> +
>> +/* CRU-->SOFTRST_CON03 */
>> +#define SRST_PRESETN_DBG		12
>> +#define SRST_POTRESETN_DBG		13
>> +#define SRST_PRESETN_CORE_GRF		14
>> +#define SRST_RESETN_CORE_EMA_DETECT	15
>> +#define SRST_RESETN_REF_PVTPLL_CORE	16
>> +#define SRST_PRESETN_GPIO1		17
>> +#define SRST_DBRESETN_GPIO1		18
>> +
>> +/* CRU-->SOFTRST_CON04 */
>> +#define SRST_ARESETN_CORE_PERI_BIU	19
>> +#define SRST_ARESETN_DSMC		20
>> +#define SRST_PRESETN_DSMC		21
>> +#define SRST_RESETN_FLEXBUS		22
>> +#define SRST_ARESETN_FLEXBUS		23
>> +#define SRST_HRESETN_FLEXBUS		24
>> +#define SRST_ARESETN_DSMC_SLV		25
>> +#define SRST_HRESETN_DSMC_SLV		26
>> +#define SRST_RESETN_DSMC_SLV		27
>> +
>> +/* CRU-->SOFTRST_CON05 */
>> +#define SRST_ARESETN_BUS_BIU		28
>> +#define SRST_HRESETN_BUS_BIU		29
>> +#define SRST_PRESETN_BUS_BIU		30
>> +#define SRST_ARESETN_SYSRAM		31
>> +#define SRST_HRESETN_SYSRAM		32
>> +#define SRST_ARESETN_DMAC0		33
>> +#define SRST_ARESETN_DMAC1		34
>> +#define SRST_HRESETN_M0			35
>> +#define SRST_RESETN_M0_JTAG		36
>> +#define SRST_HRESETN_CRYPTO		37
> Is there a reason why this (and the RV1126B) reset names now include the
> RESETN name in all reset constant?
>
> For RK3528 and prior mainline SoCs the RESETN part of the name has been
> striped from the constant, suggest we also strip the RESETN part for
> RK3506 and RV1126B for consistency with other RK SoCs.
The reset id and rst-rk3506.c were automatically generated from our trm 
using tools, while some of the previous chips were filled in manually.

It is not recommended to manually modify the content generated by the 
tool to avoid unnecessary errors.

It is not necessary to change SRST_HRESETN_CRYPTO to SRST_H_CRYPTO.

>
> Regards,
> Jonas
>
> [snip]
>
-- 
??
???????????
Rockchip Electronics Co.,Ltd
????????????????89????A?21??
Add:No.21 Building, A District, No.89 Software Boulevard Fuzhou, Fujian 350003, P.R.China
Tel:+86-0591-83991906-8601
???350003
E-mail:elaine.zhang at rock-chips.com
****************************************************************************
??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

IMPORTANT NOTICE: This email is from Fuzhou Rockchip Electronics Co., Ltd .The contents of this email and any attachments may contain information that is privileged, confidential and/or exempt from disclosure under applicable law and relevant NDA. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution, or use of the information is STRICTLY PROHIBITED. Please immediately contact the sender as soon as possible and destroy the material in its entirety in any format. Thank you.

****************************************************************************



From geraldogabriel at gmail.com  Thu Nov  6 18:43:57 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Thu, 6 Nov 2025 23:43:57 -0300
Subject: [PATCH] arm64: dts: rockchip: align bindings to PCIe spec
In-Reply-To: <67b605b0-7046-448a-bc9b-d3ac56333809@rock-chips.com>
References: <4b5ffcccfef2a61838aa563521672a171acb27b2.1762321976.git.geraldogabriel@gmail.com>
 <ba120577-42da-424d-8102-9d085c1494c8@rock-chips.com>
 <aQsIXcQzeYop6a0B@geday>
 <67b605b0-7046-448a-bc9b-d3ac56333809@rock-chips.com>
Message-ID: <aQ1c7ZDycxiOIy8Y@geday>

On Wed, Nov 05, 2025 at 04:56:36PM +0800, Shawn Lin wrote:
> ? 2025/11/05 ??? 16:18, Geraldo Nascimento ??:
> > Hi Shawn, glad to hear from you.
> > 
> > Perhaps the following change is better? It resolves the issue
> > without the added complication of open drain. After you questioned
> > if open drain is actually part of the spec, I remembered that
> > GPIO_OPEN_DRAIN is actually (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_DRAIN)
> > so I decided to test with just GPIO_SINGLE_ENDED and it works.

Shawn,

I quote from the PCIe Mini Card Electromechanical Specification Rev 1.2

"3.4.1. Logic Signal Requirements

The 3.3V card logic levels for single-ended digital signals (WAKE#,
CLKREQ#, PERST#, and W_DISABLE#) are given in Table 3-7. [...]"

So while you are correct that PERST# is most definitely not Open Drain,
there's evidence on the spec that defines this signal as Single-Ended.

Thanks,
Geraldo Nascimento


From shawn.lin at rock-chips.com  Thu Nov  6 19:01:04 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Fri, 7 Nov 2025 11:01:04 +0800
Subject: [PATCH] arm64: dts: rockchip: align bindings to PCIe spec
In-Reply-To: <aQ1c7ZDycxiOIy8Y@geday>
References: <4b5ffcccfef2a61838aa563521672a171acb27b2.1762321976.git.geraldogabriel@gmail.com>
 <ba120577-42da-424d-8102-9d085c1494c8@rock-chips.com>
 <aQsIXcQzeYop6a0B@geday>
 <67b605b0-7046-448a-bc9b-d3ac56333809@rock-chips.com>
 <aQ1c7ZDycxiOIy8Y@geday>
Message-ID: <d9e257bd-806c-48b4-bb22-f1342e9fc15a@rock-chips.com>

+ Ye Zhang

? 2025/11/07 ??? 10:43, Geraldo Nascimento ??:
> On Wed, Nov 05, 2025 at 04:56:36PM +0800, Shawn Lin wrote:
>> ? 2025/11/05 ??? 16:18, Geraldo Nascimento ??:
>>> Hi Shawn, glad to hear from you.
>>>
>>> Perhaps the following change is better? It resolves the issue
>>> without the added complication of open drain. After you questioned
>>> if open drain is actually part of the spec, I remembered that
>>> GPIO_OPEN_DRAIN is actually (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_DRAIN)
>>> so I decided to test with just GPIO_SINGLE_ENDED and it works.
> 
> Shawn,
> 
> I quote from the PCIe Mini Card Electromechanical Specification Rev 1.2
> 
> "3.4.1. Logic Signal Requirements
> 
> The 3.3V card logic levels for single-ended digital signals (WAKE#,
> CLKREQ#, PERST#, and W_DISABLE#) are given in Table 3-7. [...]"
> 
> So while you are correct that PERST# is most definitely not Open Drain,
> there's evidence on the spec that defines this signal as Single-Ended.
> 

This's true. But I couldn't find any user in dts using either
GPIO_SINGLE_ENDED or GPIO_OPEN_DRAIN for PCIe PERST#. I'm curious
how these two flags affect actual behavior of chips. Ye, could you
please help check it?

> Thanks,
> Geraldo Nascimento
> 



From coiaprant at gmail.com  Thu Nov  6 21:45:10 2025
From: coiaprant at gmail.com (Coia Prant)
Date: Fri, 07 Nov 2025 13:45:10 +0800
Subject: =?US-ASCII?Q?Re=3A_=5BPATCH_v5_3/3=5D_arm64=3A_dts=3A_rockchip=3A?=
 =?US-ASCII?Q?_Add_devicetree_for_the_9Tripod_X3568_v4?=
In-Reply-To: <3719039.iIbC2pHGDl@phil>
References: <20251103171702.1518730-1-coiaprant@gmail.com> <20251103171702.1518730-4-coiaprant@gmail.com> <3719039.iIbC2pHGDl@phil>
Message-ID: <8AD7010C-A0E9-4CF5-B66D-1E1A01CF0B43@gmail.com>

On November 7, 2025 6:54:45 AM GMT+08:00, Heiko Stuebner <heiko at sntech.de> wrote:
>Am Montag, 3. November 2025, 18:17:02 Mitteleurop?ische Normalzeit schrieb Coia Prant:
>> The 9Tripod X3568 v4 is an RK3568-based SBC, just like the RK3568-EVB.
>> It always uses soldered connections between the X3568CV2/X3568CV3/X3568CV4 core board
>> and the X3568bv4 I/O board.
>> 
>> The differences between the core boards
>> - PCB size, layout
>> - CPU (RKK3568B2/RK3568J)
>> - Memory type (DDR4/LPDDR4/LPDDR4X) and size
>> - eMMC size
>> - DSI/EDP resistor values
>> Although the components vary, they maintain full compatibility.
>> 
>> The X3568 board has multiple hardware revisions, and we currently support v4 (I/O board).
>> 
>> Specification:
>> - SoC: RockChip RK3568 ARM64 (4 cores)
>> - eMMC: 16-128 GB
>> - RAM: 2-16 GB
>> - Power: DC 12V 2A
>> - Ethernet: 2x YT8521SC RGMII (10/100/1000 Mbps)
>> - Wireless radio: 802.11b/g/n/ac/ax dual-band
>> - LED:
>>   Power: AlwaysOn
>>   User: GPIO
>> - Button:
>>   VOL+: SARADC/0 <35k ?V>
>>   VOL-: SARADC/0 <450k ?V>
>>   Power/Reset: PMIC RK809
>> - CAN
>>   CAN/1: 4-pin (PH 2.0)
>> - PWM
>>   PWM/4: Backlight DSI/0 DSI/1
>>   PWM/7: IR Receiver [may not install]
>> - UART:
>>   UART/2: Debug TTL - 1500000 8N1 (1.25mm)
>>   UART/3: TTL (PH 2.0)
>>   UART/4: TTL (PH 2.0)
>>   UART/8: AP6275S Bluetooth
>>   UART/9: TTL (PH 2.0)
>> - I2C:
>>   I2C/0: PMIC RK809
>>   I2C/1: Touchscreen DSI/0 DSI/1
>>   I2C/4: Camera
>>   I2C/5: RTC at 51 PCF8563
>> - I2S:
>>   I2S/0: miniHDMI Sound
>>   I2S/1: RK809 Audio Codec
>>   I2S/3: AP6275S Bluetooth Sound
>> - SDMMC:
>>   SDMMC/0: microSD (TF) slot
>>   SDMMC/2: AP6275S SDIO WiFi card
>> - Camera: 1x CSI
>> - Video: miniHDMI / DSI0 (MIPI/LVDS) / DSI1 (MIPI/EDP)
>> - Audio: miniHDMI / MIC on-board / Speaker / SPDIF / 3.5mm Headphones / AP6275S Bluetooth
>> - USB:
>>   USB 2.0 HOST x2
>>   USB 2.0 HOST x3 (4-pin)
>>   USB 2.0 OTG x1 (shared with USB 3.0 OTG/HOST) [slot may not install]
>>   USB 3.0 HOST x1
>>   USB 3.0 OTG/HOST x1
>> - SATA: 1x SATA 3.0 with Power/4-pin [slot may not install]
>> - PCIe: 1x PCIe 3.0 x2 (x4 connecter) [power/clock/slot may not install]
>> 
>> Link:
>> - https://appletsapi.52solution.com/media/X3568V4%E5%BC%80%E5%8F%91%E6%9D%BF%E7%A1%AC%E4%BB%B6%E6%89%8B%E5%86%8C.pdf
>> - https://blog.gov.cooking/archives/research-ninetripod-x3568-v4-and-flash.html
>> 
>> Signed-off-by: Coia Prant <coiaprant at gmail.com>
>
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4-video-demo.dtso b/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4-video-demo.dtso
>> new file mode 100644
>> index 000000000..e7fa1ca48
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4-video-demo.dtso
>> @@ -0,0 +1,154 @@
>> +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
>> +
>> +// This is a sample reference, due to lack of hardware can not be tested, at your own risk
>
>and I've also dropped the 2nd overlay now.
>Please only ever submit patches for stuff you have actually tested.
>
>We don't really add stuff with "use at your own risk" caveats ;-)
>
>
>Heiko
>
>

Okay.

I'll ask if anyone has a camera and a screen.
This part is extracted from the original equipment tree, and has been corrected by reference to other board.

If I can find a test, I will submit a new patch.

Thanks!
Wish have a good day.


From krzysztof.kozlowski at linaro.org  Thu Nov  6 23:39:02 2025
From: krzysztof.kozlowski at linaro.org (Krzysztof Kozlowski)
Date: Fri, 7 Nov 2025 08:39:02 +0100
Subject: [RESEND PATCH v6 4/5] dt-bindings: clock: rockchip: Add RK3506
 clock and reset unit
In-Reply-To: <20251107013757.5013-1-zhangqing@rock-chips.com>
References: <20251107013757.5013-1-zhangqing@rock-chips.com>
Message-ID: <e9a3e213-5dfd-4486-be0b-e50e79970374@linaro.org>

On 07/11/2025 02:37, Elaine Zhang wrote:
> From: Finley Xiao <finley.xiao at rock-chips.com>
> 
> Add device tree bindings for clock and reset unit on RK3506 SoC.
> Add clock and reset IDs for RK3506 SoC.
> 
> Signed-off-by: Finley Xiao <finley.xiao at rock-chips.com>
> Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>


You CC-ed an address, which suggests you do not work on mainline kernel
or you do not use get_maintainers.pl/b4/patman. Please rebase and always
work on mainline or start using mentioned tools, so correct addresses
will be used.

> ---
>  .../bindings/clock/rockchip,rk3506-cru.yaml   |  51 ++++
>  .../dt-bindings/clock/rockchip,rk3506-cru.h   | 285 ++++++++++++++++++
>  .../dt-bindings/reset/rockchip,rk3506-cru.h   | 211 +++++++++++++
>  3 files changed, 547 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
>  create mode 100644 include/dt-bindings/clock/rockchip,rk3506-cru.h
>  create mode 100644 include/dt-bindings/reset/rockchip,rk3506-cru.h
> 
> diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml b/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
> new file mode 100644
> index 000000000000..ecb5fa497747
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
> @@ -0,0 +1,51 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/rockchip,rk3506-cru.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Rockchip RK3506 Clock and Reset Unit (CRU)
> +
> +maintainers:
> +  - Finley Xiao <finley.xiao at rock-chips.com>
> +  - Heiko Stuebner <heiko at sntech.de>
> +
> +description: |

You got already review. Month or so ago. Implement it.

Best regards,
Krzysztof


From sebastian.reichel at collabora.com  Fri Nov  7 02:08:47 2025
From: sebastian.reichel at collabora.com (Sebastian Reichel)
Date: Fri, 7 Nov 2025 11:08:47 +0100
Subject: [PATCH 2/3] drm/bridge: dw-hdmi-qp: Add support for missing HPD
In-Reply-To: <2301926.irdbgypaU6@phil>
References: <20251106180914.768502-1-macroalpha82@gmail.com>
 <20251106180914.768502-3-macroalpha82@gmail.com>
 <2301926.irdbgypaU6@phil>
Message-ID: <z3qwk6o5exump4c6ot4wkh7sn4ihlu6gzeknoqbaop3ftvs5wc@hl7svwf25mvw>

Hi,

On Thu, Nov 06, 2025 at 08:40:55PM +0100, Heiko Stuebner wrote:
> Am Donnerstag, 6. November 2025, 19:09:13 Mitteleurop?ische Normalzeit schrieb Chris Morgan:
> > From: Chris Morgan <macromorgan at hotmail.com>
> > 
> > Add support for the dw-hdmi-qp driver to handle devices with missing
> > HPD pins.
> > 
> > Since in this situation we are now polling for the EDID data via i2c
> > change the error message to a debug message when we are unable to
> > complete an i2c read, as a disconnected device would otherwise fill
> > dmesg with i2c read errors.
> > 
> > Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
> 
> > @@ -1074,12 +1095,18 @@ struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev,
> >  	if (ret)
> >  		return ERR_PTR(ret);
> >  
> > +	if (of_property_present(pdev->dev.of_node, "no-hpd"))
> > +		hdmi->no_hpd = 1;
> > +	else
> > +		hdmi->no_hpd = 0;
> > +
> 
> what is the argument against
> 
> hdmi->no_hpd = of_property_read_bool(pdev->dev.of_node, "no-hpd")); ?

Would be even better to use this, which avoids adding DT specific
code to the bridge driver:

hdmi->no_hpd = device_property_read_bool(pdev->dev, "no-hpd");

Greetings,

-- Sebastian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251107/8bce544d/attachment.sig>

From diederik at cknow-tech.com  Fri Nov  7 02:27:45 2025
From: diederik at cknow-tech.com (Diederik de Haas)
Date: Fri, 07 Nov 2025 11:27:45 +0100
Subject: [RFC PATCH 2/2] PCI: rockchip-host: drop wait on PERST# toggle
In-Reply-To: <aQu_-JDy7qqeviUm@geday>
References: <d3d0c3a387ff461e62bbd66a0bde654a9a17761e.1762150971.git.geraldogabriel@gmail.com> <20251103181038.GA1814635@bhelgaas> <aQrKtFT0ldc70gKj@geday> <DE0N4LA8MOJD.236O12UZ3I3C4@cknow-tech.com> <aQu_-JDy7qqeviUm@geday>
Message-ID: <DE2E3LND1O81.25N3JM01890FT@cknow-tech.com>

Hi Geraldo,

On Wed Nov 5, 2025 at 10:22 PM CET, Geraldo Nascimento wrote:
> On Wed, Nov 05, 2025 at 10:06:53AM +0100, Diederik de Haas wrote:
>> I have a Samsung PM981 (without the 'a') and AFAICT it works fine.
>> I had noticed that the PERST# (pinctrl) was missing, but 'ep-gpios'
>> was/is new to me and I hadn't had time to research that properly yet.
>> Good to see you already found it yourself :-)
>
> Would you mind testing the following DT change to make sure your PM981
> continues to work fine?

I just learned the the PCIe system on rk3399 is indeed different from
the systems where I use it with (rk3568 & rk3588). And 'ep-gpios' is
only used with rk3399 based devices (in the Rockchip dts tree), which
explains why I hadn't seen that before.
Which in turn means I can't test your proposed change.

I guess I was triggered by RFC patch 2 which said 'a known quirky
device' while my Samsung PM981's are working fine ... but with DW based
IP. You did specify in your cover letter the connection with Rockchip
PCI IP, which apparently can make a (lot of?) difference.
Me finding the PERST# pinctrl in a few minutes and we finding
improvements in RockPro64's PCI 'config' recently, indicated to me that
a new look into the dts definition may be warranted, before changing
``drivers/pci/controller/pcie-rockchip-host.c`` for everyone.

Cheers,
  Diederik

> Thank you,
> Geraldo Nascimento
>
> ---
>
> diff --git a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
> index aa70776e898a..b3d19dce539f 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
> @@ -383,7 +383,7 @@ &pcie_phy {
>  };
>  
>  &pcie0 {
> -	ep-gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>;
> +	ep-gpios = <&gpio0 RK_PB4 (GPIO_ACTIVE_HIGH | GPIO_SINGLE_ENDED)>;
>  	num-lanes = <4>;
>  	pinctrl-0 = <&pcie_clkreqnb_cpm>;
>  	pinctrl-names = "default";



From amadeus at jmu.edu.cn  Fri Nov  7 03:00:20 2025
From: amadeus at jmu.edu.cn (Chukun Pan)
Date: Fri,  7 Nov 2025 19:00:20 +0800
Subject: [PATCH v5 3/3] arm64: dts: rockchip: Add devicetree for the 9Tripod X3568 v4
In-Reply-To: <20251103171702.1518730-4-coiaprant@gmail.com>
References: <20251103171702.1518730-4-coiaprant@gmail.com>
Message-ID: <20251107110020.226562-1-amadeus@jmu.edu.cn>

Hi,

> +++ b/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4-camera-demo.dtso
> @@ -0,0 +1,84 @@
> +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
> +
> +// This is a sample reference, due to lack of hardware can not be tested, at your own risk

> +++ b/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4-video-demo.dtso
> @@ -0,0 +1,154 @@
> +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
> +
> +// This is a sample reference, due to lack of hardware can not be tested, at your own risk

Why are these demo DT Overlays needed? Are these optional accessories?
These untested DT Overlays should be removed.

> +	vcc3v3_pcie: regulator-vcc3v3-pcie {
> +		compatible = "regulator-gpio";

This should use regulator-fixed.

> +		regulator-name = "vcc3v3_pcie";
> +		regulator-min-microvolt = <100000>;
> +		regulator-max-microvolt = <3300000>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&vcc3v3_pcie_en_pin>;

Is this the name from the schematic?

> +	pinctrl-names = "default";
> +	pinctrl-0 = <&gmac0_miim
> +			&gmac0_tx_bus2
> +			&gmac0_rx_bus2
> +			&gmac0_rgmii_clk
> +			&gmac0_rgmii_bus
> +			&gmac0_clkinout>;

> +	pinctrl-names = "default";
> +	pinctrl-0 = <&gmac1m1_miim
> +			&gmac1m1_tx_bus2
> +			&gmac1m1_rx_bus2
> +			&gmac1m1_rgmii_clk
> +			&gmac1m1_rgmii_bus
> +			&gmac1m1_clkinout>;

Align Indentation.

> +		codec {
> +			rockchip,mic-in-differential;
> +		};

Is it confirmed to be differential signaling?

> +	pmic {
> +		pmic_int: pmic_int {
> +			rockchip,pins =
> +				<0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;

No line break is needed here.

> +/* Required remotectl for IR receiver */
> +&pwm7 {
> +	status = "disabled";
> +};

This should be replaced with gpio-ir-receiver.

> +&sdmmc2 {
> +	bus-width = <4>;
> +	disable-wp;

The disable-wp property does not apply to SDIO cards.

> +	sd-uhs-sdr12;
> +	sd-uhs-sdr25;
> +	sd-uhs-sdr50;
> +	sd-uhs-sdr104;

Just declare the highest supported speed.


From coiaprant at gmail.com  Fri Nov  7 03:36:58 2025
From: coiaprant at gmail.com (Coia Prant)
Date: Fri, 07 Nov 2025 19:36:58 +0800
Subject: =?US-ASCII?Q?Re=3A_=5BPATCH_v5_3/3=5D_arm64=3A_dts=3A_rockchip=3A?=
 =?US-ASCII?Q?_Add_devicetree_for_the_9Tripod_X3568_v4?=
In-Reply-To: <20251107110020.226562-1-amadeus@jmu.edu.cn>
References: <20251103171702.1518730-4-coiaprant@gmail.com> <20251107110020.226562-1-amadeus@jmu.edu.cn>
Message-ID: <6F2972A5-047F-48A5-B409-C3F3E71643AD@gmail.com>

On November 7, 2025 7:00:20 PM GMT+08:00, Chukun Pan <amadeus at jmu.edu.cn> wrote:
>Hi,
>
>> +++ b/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4-camera-demo.dtso
>> @@ -0,0 +1,84 @@
>> +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
>> +
>> +// This is a sample reference, due to lack of hardware can not be tested, at your own risk
>
>> +++ b/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4-video-demo.dtso
>> @@ -0,0 +1,154 @@
>> +// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
>> +
>> +// This is a sample reference, due to lack of hardware can not be tested, at your own risk
>
>Why are these demo DT Overlays needed? Are these optional accessories?
>These untested DT Overlays should be removed.
>
>> +	vcc3v3_pcie: regulator-vcc3v3-pcie {
>> +		compatible = "regulator-gpio";
>
>This should use regulator-fixed.
>
>> +		regulator-name = "vcc3v3_pcie";
>> +		regulator-min-microvolt = <100000>;
>> +		regulator-max-microvolt = <3300000>;
>> +		pinctrl-names = "default";
>> +		pinctrl-0 = <&vcc3v3_pcie_en_pin>;
>
>Is this the name from the schematic?
>
>> +	pinctrl-names = "default";
>> +	pinctrl-0 = <&gmac0_miim
>> +			&gmac0_tx_bus2
>> +			&gmac0_rx_bus2
>> +			&gmac0_rgmii_clk
>> +			&gmac0_rgmii_bus
>> +			&gmac0_clkinout>;
>
>> +	pinctrl-names = "default";
>> +	pinctrl-0 = <&gmac1m1_miim
>> +			&gmac1m1_tx_bus2
>> +			&gmac1m1_rx_bus2
>> +			&gmac1m1_rgmii_clk
>> +			&gmac1m1_rgmii_bus
>> +			&gmac1m1_clkinout>;
>
>Align Indentation.
>
>> +		codec {
>> +			rockchip,mic-in-differential;
>> +		};
>
>Is it confirmed to be differential signaling?
>
>> +	pmic {
>> +		pmic_int: pmic_int {
>> +			rockchip,pins =
>> +				<0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
>
>No line break is needed here.
>
>> +/* Required remotectl for IR receiver */
>> +&pwm7 {
>> +	status = "disabled";
>> +};
>
>This should be replaced with gpio-ir-receiver.
>
>> +&sdmmc2 {
>> +	bus-width = <4>;
>> +	disable-wp;
>
>The disable-wp property does not apply to SDIO cards.
>
>> +	sd-uhs-sdr12;
>> +	sd-uhs-sdr25;
>> +	sd-uhs-sdr50;
>> +	sd-uhs-sdr104;
>
>Just declare the highest supported speed.

PCIe and MIC picked from OEM source codes.

PMIC picked from RK3568-EVB.

Since parts of the OEM source code are not available in mainline, I refer to other boards (e.g. RK3568-EVB or RK3568-ROC-PC), but I don't have a camera or screen to test, so I mark them as demo.

Do I need to release a new set of patches?


Thanks


From coiaprant at gmail.com  Fri Nov  7 05:38:38 2025
From: coiaprant at gmail.com (Coia Prant)
Date: Fri,  7 Nov 2025 21:38:38 +0800
Subject: [PATCH] arm64: dts: rockchip: clean up devicetree for 9Tripod X3568 v4
Message-ID: <20251107133839.300252-1-coiaprant@gmail.com>

Fix indentation, remove unused SDIO properties, and drop the GMAC clock
that was used for input direction. The board uses the clock as
output, so the input clock is not needed.

Signed-off-by: Coia Prant <coiaprant at gmail.com>
---
 .../dts/rockchip/rk3568-9tripod-x3568-v4.dts  | 25 +++++++------------
 1 file changed, 9 insertions(+), 16 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4.dts b/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4.dts
index 443ed7d4b..ad4d62060 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4.dts
@@ -273,11 +273,10 @@ &gmac0 {
 	clock_in_out = "output";
 	pinctrl-names = "default";
 	pinctrl-0 = <&gmac0_miim
-			&gmac0_tx_bus2
-			&gmac0_rx_bus2
-			&gmac0_rgmii_clk
-			&gmac0_rgmii_bus
-			&gmac0_clkinout>;
+		     &gmac0_tx_bus2
+		     &gmac0_rx_bus2
+		     &gmac0_rgmii_clk
+		     &gmac0_rgmii_bus>;
 	phy-handle = <&rgmii_phy0>;
 	phy-mode = "rgmii-id";
 	status = "okay";
@@ -290,11 +289,10 @@ &gmac1 {
 	clock_in_out = "output";
 	pinctrl-names = "default";
 	pinctrl-0 = <&gmac1m1_miim
-			&gmac1m1_tx_bus2
-			&gmac1m1_rx_bus2
-			&gmac1m1_rgmii_clk
-			&gmac1m1_rgmii_bus
-			&gmac1m1_clkinout>;
+		     &gmac1m1_tx_bus2
+		     &gmac1m1_rx_bus2
+		     &gmac1m1_rgmii_clk
+		     &gmac1m1_rgmii_bus>;
 	phy-handle = <&rgmii_phy1>;
 	phy-mode = "rgmii-id";
 	status = "okay";
@@ -674,8 +672,7 @@ led_work_en: led_work_en {
 
 	pmic {
 		pmic_int: pmic_int {
-			rockchip,pins =
-				<0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
 		};
 	};
 
@@ -763,7 +760,6 @@ &sdmmc0 {
 /* used for AP6275S WiFi */
 &sdmmc2 {
 	bus-width = <4>;
-	disable-wp;
 	cap-sd-highspeed;
 	cap-sdio-irq;
 	keep-power-in-suspend;
@@ -771,9 +767,6 @@ &sdmmc2 {
 	non-removable;
 	pinctrl-names = "default";
 	pinctrl-0 = <&sdmmc2m0_bus4 &sdmmc2m0_cmd &sdmmc2m0_clk>;
-	sd-uhs-sdr12;
-	sd-uhs-sdr25;
-	sd-uhs-sdr50;
 	sd-uhs-sdr104;
 	vmmc-supply = <&vcc3v3_sys>;
 	vqmmc-supply = <&vcc_1v8>;
-- 
2.47.3



From jonas at kwiboo.se  Fri Nov  7 06:31:02 2025
From: jonas at kwiboo.se (Jonas Karlman)
Date: Fri, 7 Nov 2025 15:31:02 +0100
Subject: [PATCH v6 2/5] dt-bindings: clock, reset: Add support for rv1126b
In-Reply-To: <20251104030633.2721038-3-zhangqing@rock-chips.com>
References: <20251104030633.2721038-1-zhangqing@rock-chips.com>
 <20251104030633.2721038-3-zhangqing@rock-chips.com>
Message-ID: <3be7a6e4-4025-42b4-a73f-a9d05e64191d@kwiboo.se>

Hi Elaine,

On 11/4/2025 4:06 AM, Elaine Zhang wrote:
> Add clock and reset ID defines for rv1126b.
> Also add documentation for the rv1126b CRU core.
> 
> Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
> Acked-by: Conor Dooley <conor.dooley at microchip.com>
> ---
>  .../bindings/clock/rockchip,rv1126b-cru.yaml  |  52 +++
>  .../dt-bindings/clock/rockchip,rv1126b-cru.h  | 392 +++++++++++++++++
>  .../dt-bindings/reset/rockchip,rv1126b-cru.h  | 405 ++++++++++++++++++
>  3 files changed, 849 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rv1126b-cru.yaml
>  create mode 100644 include/dt-bindings/clock/rockchip,rv1126b-cru.h
>  create mode 100644 include/dt-bindings/reset/rockchip,rv1126b-cru.h

[snip]

> diff --git a/include/dt-bindings/clock/rockchip,rv1126b-cru.h b/include/dt-bindings/clock/rockchip,rv1126b-cru.h
> new file mode 100644
> index 000000000000..d6040058c21f
> --- /dev/null
> +++ b/include/dt-bindings/clock/rockchip,rv1126b-cru.h
> @@ -0,0 +1,392 @@
> +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
> +/*
> + * Copyright (c) 2025 Rockchip Electronics Co., Ltd.
> + * Author: Elaine Zhang <zhangqing at rock-chips.com>
> + */
> +
> +#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RV1126B_H
> +#define _DT_BINDINGS_CLK_ROCKCHIP_RV1126B_H
> +
> +/* pll clocks */
> +#define PLL_GPLL				1

The clock indices should typically start at 0 not 1.

[snip]

> +#define HCLK_RKRNG_NS				362
> +#define HCLK_RKRNG_S_NS				363
> +#define CLK_AISP_PLL_SRC			364
> +
> +/* secure clks */
> +#define CLK_USER_OTPC_S				400

And the indices should typically not contain any jumps in numbers.

Regards,
Jonas

> +#define CLK_SBPI_OTPC_S				401
> +#define PCLK_OTPC_S				402
> +#define PCLK_KEY_READER_S			403
> +#define HCLK_KL_RKCE_S				404
> +#define HCLK_RKCE_S				405
> +#define PCLK_WDT_S				406
> +#define TCLK_WDT_S				407
> +#define CLK_STIMER0				408
> +#define CLK_STIMER1				409
> +#define PLK_STIMER				410
> +#define HCLK_RKRNG_S				411
> +#define CLK_PKA_RKCE_S				412
> +#define ACLK_RKCE_S				413
> +
> +#endif

[snip]


From jonas at kwiboo.se  Fri Nov  7 06:59:12 2025
From: jonas at kwiboo.se (Jonas Karlman)
Date: Fri, 7 Nov 2025 15:59:12 +0100
Subject: [RESEND PATCH v6 4/5] dt-bindings: clock: rockchip: Add RK3506
 clock and reset unit
In-Reply-To: <20251107013757.5013-1-zhangqing@rock-chips.com>
References: <20251107013757.5013-1-zhangqing@rock-chips.com>
Message-ID: <48108089-775a-428c-8dd1-a75344823ace@kwiboo.se>

Hi Elaine,

On 11/7/2025 2:37 AM, Elaine Zhang wrote:
> From: Finley Xiao <finley.xiao at rock-chips.com>
> 
> Add device tree bindings for clock and reset unit on RK3506 SoC.
> Add clock and reset IDs for RK3506 SoC.
> 
> Signed-off-by: Finley Xiao <finley.xiao at rock-chips.com>
> Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
> ---
>  .../bindings/clock/rockchip,rk3506-cru.yaml   |  51 ++++
>  .../dt-bindings/clock/rockchip,rk3506-cru.h   | 285 ++++++++++++++++++
>  .../dt-bindings/reset/rockchip,rk3506-cru.h   | 211 +++++++++++++
>  3 files changed, 547 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
>  create mode 100644 include/dt-bindings/clock/rockchip,rk3506-cru.h
>  create mode 100644 include/dt-bindings/reset/rockchip,rk3506-cru.h

[snip]

> diff --git a/include/dt-bindings/reset/rockchip,rk3506-cru.h b/include/dt-bindings/reset/rockchip,rk3506-cru.h
> new file mode 100644
> index 000000000000..f38cc066009b
> --- /dev/null
> +++ b/include/dt-bindings/reset/rockchip,rk3506-cru.h
> @@ -0,0 +1,211 @@
> +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
> +/*
> + * Copyright (c) 2023-2025 Rockchip Electronics Co., Ltd.
> + * Author: Finley Xiao <finley.xiao at rock-chips.com>
> + */
> +
> +#ifndef _DT_BINDINGS_REST_ROCKCHIP_RK3506_H
> +#define _DT_BINDINGS_REST_ROCKCHIP_RK3506_H
> +
> +/* CRU-->SOFTRST_CON00 */
> +#define SRST_NCOREPORESET0_AC		0
> +#define SRST_NCOREPORESET1_AC		1
> +#define SRST_NCOREPORESET2_AC		2
> +#define SRST_NCORESET0_AC		3
> +#define SRST_NCORESET1_AC		4
> +#define SRST_NCORESET2_AC		5
> +#define SRST_NL2RESET_AC		6
> +#define SRST_ARESETN_CORE_BIU_AC	7
> +#define SRST_HRESETN_M0_AC		8
> +
> +/* CRU-->SOFTRST_CON02 */
> +#define SRST_NDBGRESET			9
> +#define SRST_PRESETN_CORE_BIU		10
> +#define SRST_RESETN_PMU			11
> +
> +/* CRU-->SOFTRST_CON03 */
> +#define SRST_PRESETN_DBG		12
> +#define SRST_POTRESETN_DBG		13
> +#define SRST_PRESETN_CORE_GRF		14
> +#define SRST_RESETN_CORE_EMA_DETECT	15
> +#define SRST_RESETN_REF_PVTPLL_CORE	16
> +#define SRST_PRESETN_GPIO1		17
> +#define SRST_DBRESETN_GPIO1		18
> +
> +/* CRU-->SOFTRST_CON04 */
> +#define SRST_ARESETN_CORE_PERI_BIU	19
> +#define SRST_ARESETN_DSMC		20
> +#define SRST_PRESETN_DSMC		21
> +#define SRST_RESETN_FLEXBUS		22
> +#define SRST_ARESETN_FLEXBUS		23
> +#define SRST_HRESETN_FLEXBUS		24
> +#define SRST_ARESETN_DSMC_SLV		25
> +#define SRST_HRESETN_DSMC_SLV		26
> +#define SRST_RESETN_DSMC_SLV		27
> +
> +/* CRU-->SOFTRST_CON05 */
> +#define SRST_ARESETN_BUS_BIU		28
> +#define SRST_HRESETN_BUS_BIU		29
> +#define SRST_PRESETN_BUS_BIU		30
> +#define SRST_ARESETN_SYSRAM		31
> +#define SRST_HRESETN_SYSRAM		32
> +#define SRST_ARESETN_DMAC0		33
> +#define SRST_ARESETN_DMAC1		34
> +#define SRST_HRESETN_M0			35
> +#define SRST_RESETN_M0_JTAG		36
> +#define SRST_HRESETN_CRYPTO		37

My original question and your reply from v5 follow below.

On 11/7/2025 2:24 AM, zhangqing wrote:
>> Is there a reason why this (and the RV1126B) reset names now include the
>> RESETN name in all reset constant?
>>
>> For RK3528 and prior mainline SoCs the RESETN part of the name has been
>> striped from the constant, suggest we also strip the RESETN part for
>> RK3506 and RV1126B for consistency with other RK SoCs.
>>
> The current practice is to separate the reset id from the clk id.
> 
> Follow with others RK socs(RK3528?RK3588?RK3576.....)

and

On 11/7/2025 2:44 AM, zhangqing wrote:
> The reset id and rst-rk3506.c were automatically generated from our trm 
> using tools, while some of the previous chips were filled in manually.
> 
> It is not recommended to manually modify the content generated by the 
> tool to avoid unnecessary errors.
> 
> It is not necessary to change SRST_HRESETN_CRYPTO to SRST_H_CRYPTO.

Why do we now need to have two part of the indices name to represent it
is a reset, i.e. the SRST_ prefix and the RESETN in middle of the name.

	resets = <&cru SRST_ARESETN_MAC1>;

The example above seem unnecessary verbose with 3x reset:
- resets as prop name
- SRST_ prefix (software? reset) in the indices name
- RESETN in the indices name

Maybe the SRST_ prefix could be dropped if we now have RESETN as part of
the indices name?

Your tool could be updated to strip the verbose naming. For RK3528 I
used a small script/tool to strip away the RESETN name and to generate
the macros used in rst driver.

Regards,
Jonas

[snip]


From conor at kernel.org  Fri Nov  7 09:26:15 2025
From: conor at kernel.org (Conor Dooley)
Date: Fri, 7 Nov 2025 17:26:15 +0000
Subject: [PATCH 1/3] dt-bindings: display: rockchip: Add no-hpd for
 dw-hdmi-qp controller
In-Reply-To: <20251106180914.768502-2-macroalpha82@gmail.com>
References: <20251106180914.768502-1-macroalpha82@gmail.com>
 <20251106180914.768502-2-macroalpha82@gmail.com>
Message-ID: <20251107-salutary-flatbed-0a9d343ea233@spud>

On Thu, Nov 06, 2025 at 12:09:12PM -0600, Chris Morgan wrote:
> From: Chris Morgan <macromorgan at hotmail.com>
> 
> Add an attribute of "no-hpd" for the Rockchip dw-hdmi-qp controller.
> This is used to describe implementations where the HPD pin is not
> connected or used for other purposes, such as in the RK3588S based
> Gameforce Ace which repurposed the GPIO for an additional face
> button.
> 
> The "no-hpd" option was chosen to be consistent with other devices
> which already define this parameter for broken or missing hpd
> functionality.

Glad you mentioned this, so we could avoid the "why have you no vendor
prefix" conversation :)

Acked-by: Conor Dooley <conor.dooley at microchip.com>
pw-bot: not-applicable
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251107/c62e0968/attachment.sig>

From sakari.ailus at linux.intel.com  Fri Nov  7 09:32:22 2025
From: sakari.ailus at linux.intel.com (Sakari Ailus)
Date: Fri, 7 Nov 2025 19:32:22 +0200
Subject: [PATCH v14 00/18] media: rockchip: add a driver for the rockchip
 camera interface
In-Reply-To: <20240220-rk3568-vicap-v14-0-b38b6da0fc80@collabora.com>
References: <20240220-rk3568-vicap-v14-0-b38b6da0fc80@collabora.com>
Message-ID: <aQ4tJg8r_j4NyKhv@kekkonen.localdomain>

Hi Michael,

On Fri, Oct 24, 2025 at 02:51:29PM +0200, Michael Riesch via B4 Relay wrote:
> Habidere,
> 
> This series introduces support for the Rockchip Camera Interface (CIF),
> which is featured in many Rockchip SoCs in different variations.
> For example, the PX30 Video Input Processor (VIP) is able to receive
> video data via the Digital Video Port (DVP, a parallel data interface)
> and transfer it into system memory using a double-buffering mechanism
> called ping-pong mode.
> The RK3568 Video Capture (VICAP) unit, on the other hand, features a
> DVP and a MIPI CSI-2 receiver that can receive video data independently
> (both using the ping-pong scheme).
> The different variants may have additional features, such as scaling
> and/or cropping.
> Finally, the RK3588 VICAP unit constitutes an essential piece of the
> camera interface with one DVP, six MIPI CSI-2 receivers, scale/crop
> units, and a data path multiplexer (to scaler units, to ISP, ...).

I understand both RK3568 and RK3588 include an ISP. Do you have insight on
how would this work, should the support for the ISP be added later on?

-- 
Kind regards,

Sakari Ailus


From michael.riesch at collabora.com  Fri Nov  7 10:41:59 2025
From: michael.riesch at collabora.com (Michael Riesch)
Date: Fri, 7 Nov 2025 19:41:59 +0100
Subject: [PATCH v14 00/18] media: rockchip: add a driver for the rockchip
 camera interface
In-Reply-To: <aQ4tJg8r_j4NyKhv@kekkonen.localdomain>
References: <20240220-rk3568-vicap-v14-0-b38b6da0fc80@collabora.com>
 <aQ4tJg8r_j4NyKhv@kekkonen.localdomain>
Message-ID: <074cd08e-0412-49f9-8dd9-b1f96eb11717@collabora.com>

Hi Sakari,

On 11/7/25 18:32, Sakari Ailus wrote:
> Hi Michael,
> 
> On Fri, Oct 24, 2025 at 02:51:29PM +0200, Michael Riesch via B4 Relay wrote:
>> Habidere,
>>
>> This series introduces support for the Rockchip Camera Interface (CIF),
>> which is featured in many Rockchip SoCs in different variations.
>> For example, the PX30 Video Input Processor (VIP) is able to receive
>> video data via the Digital Video Port (DVP, a parallel data interface)
>> and transfer it into system memory using a double-buffering mechanism
>> called ping-pong mode.
>> The RK3568 Video Capture (VICAP) unit, on the other hand, features a
>> DVP and a MIPI CSI-2 receiver that can receive video data independently
>> (both using the ping-pong scheme).
>> The different variants may have additional features, such as scaling
>> and/or cropping.
>> Finally, the RK3588 VICAP unit constitutes an essential piece of the
>> camera interface with one DVP, six MIPI CSI-2 receivers, scale/crop
>> units, and a data path multiplexer (to scaler units, to ISP, ...).
> 
> I understand both RK3568 and RK3588 include an ISP. Do you have insight on
> how would this work, should the support for the ISP be added later on?
> 

Short answer: Yes and yes.

Long answer:

The patch series at hand adds support for the PX30 VIP and the RK3568
VICAP. I cannot really say something about the PX30, but on the RK3568
VICAP and ISP are orthogonal (the ISP features its own MIPI CSI-2
receiver, different from that introduced in this series). Thus, ISP
support can be introduced anytime (whenever someone is motivated ;-)).

Once this patch series is merged, I'll push out changes that introduce
support for the RK3588 VICAP. We can discuss the integration of any
RK3588 ISP in this scope then -- and there may be some things to discuss
as there the VICAP and the ISP(s) are directly connected by means of a
MUX unit in the VICAP.

Alright?

Best regards,
Michael



From jgg at nvidia.com  Fri Nov  7 10:54:09 2025
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Fri, 7 Nov 2025 14:54:09 -0400
Subject: [PATCH v1 02/20] iommu: Introduce a test_dev domain op and an
 internal helper
In-Reply-To: <aQuU2dic75VkSyjr@Asurada-Nvidia>
References: <cover.1760312725.git.nicolinc@nvidia.com>
 <32ce256a2ece5d63e99d5858f953586859818ffc.1760312725.git.nicolinc@nvidia.com>
 <BN9PR11MB5276D10BD480FE66881870B08CFBA@BN9PR11MB5276.namprd11.prod.outlook.com>
 <aQO//+6/B/WbdK2h@Asurada-Nvidia>
 <20251103185400.GA1537560@nvidia.com>
 <BN9PR11MB527638C0E43E8AA000410B878CC5A@BN9PR11MB5276.namprd11.prod.outlook.com>
 <aQuU2dic75VkSyjr@Asurada-Nvidia>
Message-ID: <20251107185409.GA1932966@nvidia.com>

On Wed, Nov 05, 2025 at 10:18:01AM -0800, Nicolin Chen wrote:
> On Wed, Nov 05, 2025 at 06:57:31AM +0000, Tian, Kevin wrote:
> > > From: Jason Gunthorpe <jgg at nvidia.com>
> > > Sent: Tuesday, November 4, 2025 2:54 AM
> > > 
> > > On Thu, Oct 30, 2025 at 12:43:59PM -0700, Nicolin Chen wrote:
> > > 
> > > > FWIW, I am thinking of another design based on Jason's remarks:
> > > > https://lore.kernel.org/linux-iommu/aQBopHFub8wyQh5C at Asurada-
> > > Nvidia/
> > > >
> > > > So, instead of core initiating the round trip between the blocking
> > > > domain and group->domain, it forwards dev_reset_prepare/done to the
> > > > driver where it does a low-level attachment that wouldn't fail:
> > > >   For SMMUv3, it's an STE update.
> > > >   For intel_iommu, it seems to be the context table update?
> > > 
> > > Kevin, how bad do you think the UAPI issue is if we ignore it?
> > > 
> > 
> > yeah probably better to leave it. I didn't see a clean way and the
> > value didn't justify the complexity.
> > 
> > Regarding to PF reset, it's a devastating operation while the vf user
> > is operating the vf w/o any awareness. there must be certain
> > coordination in userspace. otherwise nobody can recover the
> > registers. Comparing to that, solving the domain attach problem
> > is less important...
> 
> If I capture these correctly, we should go with a -EBUSY version:
>  - Reject concurrent attachments during a device reset
>  - Skip reset for devices having sibling group devices
>  - Allow PF to stop IOMMU, ignoring VFs
> ?
> 
> That sounds pretty much like this v4:
> https://lore.kernel.org/linux-iommu/0f6021b500c74db33af8118210dd7a2b2fd31b3c.1756682135.git.nicolinc at nvidia.com/
> by dropping the SRIOV concern.

It seems like the simplest answer..

I'd ignore the VFs, I think it is already really weird/dangerous to be
resetting the PF while VFs have drivers bound.. Not sure there is
anything we can do to make this work better.

Jason


From laurent.pinchart at ideasonboard.com  Fri Nov  7 10:54:41 2025
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Fri, 7 Nov 2025 20:54:41 +0200
Subject: [PATCH v14 00/18] media: rockchip: add a driver for the rockchip
 camera interface
In-Reply-To: <074cd08e-0412-49f9-8dd9-b1f96eb11717@collabora.com>
References: <20240220-rk3568-vicap-v14-0-b38b6da0fc80@collabora.com>
 <aQ4tJg8r_j4NyKhv@kekkonen.localdomain>
 <074cd08e-0412-49f9-8dd9-b1f96eb11717@collabora.com>
Message-ID: <20251107185441.GG5558@pendragon.ideasonboard.com>

On Fri, Nov 07, 2025 at 07:41:59PM +0100, Michael Riesch wrote:
> On 11/7/25 18:32, Sakari Ailus wrote:
> > On Fri, Oct 24, 2025 at 02:51:29PM +0200, Michael Riesch via B4 Relay wrote:
> >> Habidere,
> >>
> >> This series introduces support for the Rockchip Camera Interface (CIF),
> >> which is featured in many Rockchip SoCs in different variations.
> >> For example, the PX30 Video Input Processor (VIP) is able to receive
> >> video data via the Digital Video Port (DVP, a parallel data interface)
> >> and transfer it into system memory using a double-buffering mechanism
> >> called ping-pong mode.
> >> The RK3568 Video Capture (VICAP) unit, on the other hand, features a
> >> DVP and a MIPI CSI-2 receiver that can receive video data independently
> >> (both using the ping-pong scheme).
> >> The different variants may have additional features, such as scaling
> >> and/or cropping.
> >> Finally, the RK3588 VICAP unit constitutes an essential piece of the
> >> camera interface with one DVP, six MIPI CSI-2 receivers, scale/crop
> >> units, and a data path multiplexer (to scaler units, to ISP, ...).
> > 
> > I understand both RK3568 and RK3588 include an ISP. Do you have insight on
> > how would this work, should the support for the ISP be added later on?
> 
> Short answer: Yes and yes.
> 
> Long answer:
> 
> The patch series at hand adds support for the PX30 VIP and the RK3568
> VICAP. I cannot really say something about the PX30, but on the RK3568
> VICAP and ISP are orthogonal (the ISP features its own MIPI CSI-2
> receiver, different from that introduced in this series). Thus, ISP
> support can be introduced anytime (whenever someone is motivated ;-)).

Won't they both be connected to the same sensor though, and probably the
same D-PHY in the SoC ? They don't seem entirely separate to me.

A block diagram that shows connections between the CSI-2 pins, D-PHY,
CSI-2 receivers, VICAP and ISP could help.

> Once this patch series is merged, I'll push out changes that introduce
> support for the RK3588 VICAP. We can discuss the integration of any
> RK3588 ISP in this scope then -- and there may be some things to discuss
> as there the VICAP and the ISP(s) are directly connected by means of a
> MUX unit in the VICAP.
> 
> Alright?

-- 
Regards,

Laurent Pinchart


From nicolinc at nvidia.com  Fri Nov  7 10:58:56 2025
From: nicolinc at nvidia.com (Nicolin Chen)
Date: Fri, 7 Nov 2025 10:58:56 -0800
Subject: [PATCH v1 02/20] iommu: Introduce a test_dev domain op and an
 internal helper
In-Reply-To: <20251107185409.GA1932966@nvidia.com>
References: <cover.1760312725.git.nicolinc@nvidia.com>
 <32ce256a2ece5d63e99d5858f953586859818ffc.1760312725.git.nicolinc@nvidia.com>
 <BN9PR11MB5276D10BD480FE66881870B08CFBA@BN9PR11MB5276.namprd11.prod.outlook.com>
 <aQO//+6/B/WbdK2h@Asurada-Nvidia>
 <20251103185400.GA1537560@nvidia.com>
 <BN9PR11MB527638C0E43E8AA000410B878CC5A@BN9PR11MB5276.namprd11.prod.outlook.com>
 <aQuU2dic75VkSyjr@Asurada-Nvidia>
 <20251107185409.GA1932966@nvidia.com>
Message-ID: <aQ5BcKLR1YzRggGo@Asurada-Nvidia>

On Fri, Nov 07, 2025 at 02:54:09PM -0400, Jason Gunthorpe wrote:
> On Wed, Nov 05, 2025 at 10:18:01AM -0800, Nicolin Chen wrote:
> > On Wed, Nov 05, 2025 at 06:57:31AM +0000, Tian, Kevin wrote:
> > > > From: Jason Gunthorpe <jgg at nvidia.com>
> > > > Sent: Tuesday, November 4, 2025 2:54 AM
> > > > 
> > > > On Thu, Oct 30, 2025 at 12:43:59PM -0700, Nicolin Chen wrote:
> > > > 
> > > > > FWIW, I am thinking of another design based on Jason's remarks:
> > > > > https://lore.kernel.org/linux-iommu/aQBopHFub8wyQh5C at Asurada-
> > > > Nvidia/
> > > > >
> > > > > So, instead of core initiating the round trip between the blocking
> > > > > domain and group->domain, it forwards dev_reset_prepare/done to the
> > > > > driver where it does a low-level attachment that wouldn't fail:
> > > > >   For SMMUv3, it's an STE update.
> > > > >   For intel_iommu, it seems to be the context table update?
> > > > 
> > > > Kevin, how bad do you think the UAPI issue is if we ignore it?
> > > > 
> > > 
> > > yeah probably better to leave it. I didn't see a clean way and the
> > > value didn't justify the complexity.
> > > 
> > > Regarding to PF reset, it's a devastating operation while the vf user
> > > is operating the vf w/o any awareness. there must be certain
> > > coordination in userspace. otherwise nobody can recover the
> > > registers. Comparing to that, solving the domain attach problem
> > > is less important...
> > 
> > If I capture these correctly, we should go with a -EBUSY version:
> >  - Reject concurrent attachments during a device reset
> >  - Skip reset for devices having sibling group devices
> >  - Allow PF to stop IOMMU, ignoring VFs
> > ?
> > 
> > That sounds pretty much like this v4:
> > https://lore.kernel.org/linux-iommu/0f6021b500c74db33af8118210dd7a2b2fd31b3c.1756682135.git.nicolinc at nvidia.com/
> > by dropping the SRIOV concern.
> 
> It seems like the simplest answer..
> 
> I'd ignore the VFs, I think it is already really weird/dangerous to be
> resetting the PF while VFs have drivers bound.. Not sure there is
> anything we can do to make this work better.

Ack. I've rebased that and will do some cleanup and run sanity tests
before sending.

Thanks
Nicolin


From michael.riesch at collabora.com  Fri Nov  7 12:51:37 2025
From: michael.riesch at collabora.com (Michael Riesch)
Date: Fri, 7 Nov 2025 21:51:37 +0100
Subject: [PATCH v14 00/18] media: rockchip: add a driver for the rockchip
 camera interface
In-Reply-To: <20251107185441.GG5558@pendragon.ideasonboard.com>
References: <20240220-rk3568-vicap-v14-0-b38b6da0fc80@collabora.com>
 <aQ4tJg8r_j4NyKhv@kekkonen.localdomain>
 <074cd08e-0412-49f9-8dd9-b1f96eb11717@collabora.com>
 <20251107185441.GG5558@pendragon.ideasonboard.com>
Message-ID: <13c43edb-9592-4779-a39a-7856bb0f964d@collabora.com>

Hi Laurent,

On 11/7/25 19:54, Laurent Pinchart wrote:
> On Fri, Nov 07, 2025 at 07:41:59PM +0100, Michael Riesch wrote:
>> On 11/7/25 18:32, Sakari Ailus wrote:
>>> On Fri, Oct 24, 2025 at 02:51:29PM +0200, Michael Riesch via B4 Relay wrote:
>>>> Habidere,
>>>>
>>>> This series introduces support for the Rockchip Camera Interface (CIF),
>>>> which is featured in many Rockchip SoCs in different variations.
>>>> For example, the PX30 Video Input Processor (VIP) is able to receive
>>>> video data via the Digital Video Port (DVP, a parallel data interface)
>>>> and transfer it into system memory using a double-buffering mechanism
>>>> called ping-pong mode.
>>>> The RK3568 Video Capture (VICAP) unit, on the other hand, features a
>>>> DVP and a MIPI CSI-2 receiver that can receive video data independently
>>>> (both using the ping-pong scheme).
>>>> The different variants may have additional features, such as scaling
>>>> and/or cropping.
>>>> Finally, the RK3588 VICAP unit constitutes an essential piece of the
>>>> camera interface with one DVP, six MIPI CSI-2 receivers, scale/crop
>>>> units, and a data path multiplexer (to scaler units, to ISP, ...).
>>>
>>> I understand both RK3568 and RK3588 include an ISP. Do you have insight on
>>> how would this work, should the support for the ISP be added later on?
>>
>> Short answer: Yes and yes.
>>
>> Long answer:
>>
>> The patch series at hand adds support for the PX30 VIP and the RK3568
>> VICAP. I cannot really say something about the PX30, but on the RK3568
>> VICAP and ISP are orthogonal (the ISP features its own MIPI CSI-2
>> receiver, different from that introduced in this series). Thus, ISP
>> support can be introduced anytime (whenever someone is motivated ;-)).
> 
> Won't they both be connected to the same sensor though, and probably the
> same D-PHY in the SoC ? They don't seem entirely separate to me.

The MIPI CSI-2 DPHY is shared, indeed. Thus, they *maybe technically
could be* connected to the same sensor, but I don't know whether that
works and fail to see why anyone would to such a thing (if it is about
raw capture, the MIPI CSI-2 receiver in the ISP can do that on its own).

The DPHY can be operated in split mode, with two lanes for VICAP and two
lanes for ISP. This is not implemented yet, but can be done at a later
stage on PHY level (not media related). In this case, ISP and VICAP can
receive data from different subdevices via CSI-2.

BTW the ISP is able to process the data captured by VICAP, but
apparently this includes a RAM round trip (VICAP captures to memory, ISP
operates in mem2mem mode).

> A block diagram that shows connections between the CSI-2 pins, D-PHY,
> CSI-2 receivers, VICAP and ISP could help.
> 
>> Once this patch series is merged, I'll push out changes that introduce
>> support for the RK3588 VICAP. We can discuss the integration of any
>> RK3588 ISP in this scope then -- and there may be some things to discuss
>> as there the VICAP and the ISP(s) are directly connected by means of a
>> MUX unit in the VICAP.
>>
>> Alright?
> 

Best regards,
Michael




From macroalpha82 at gmail.com  Fri Nov  7 13:47:24 2025
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Fri,  7 Nov 2025 15:47:24 -0600
Subject: [PATCH] arm64: dts: rockchip: Enable USB-C DP Alt for Indiedroid Nova
Message-ID: <20251107214724.878955-1-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

Enable the Display Port alt-mode for the USB-C port on the Indiedroid
Nova.

Note that while ROCKCHIP_VOP2_EP_DP0 is defined as 10 we need to
set the address to "a" or else we receive a dtc warning.

Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
---
 .../dts/rockchip/rk3588s-indiedroid-nova.dts  | 80 ++++++++++++++++---
 1 file changed, 67 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
index dee053afc6b6..174d299cc6bb 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
@@ -190,6 +190,22 @@ &cpu_b3 {
 	cpu-supply = <&vdd_cpu_big1_s0>;
 };
 
+&dp0 {
+	status = "okay";
+};
+
+&dp0_in {
+	dp0_in_vp1: endpoint {
+		remote-endpoint = <&vp1_out_dp0>;
+	};
+};
+
+&dp0_out {
+	dp0_out_con: endpoint {
+		remote-endpoint = <&usbdp_phy0_dp_in>;
+	};
+};
+
 /*
  * Add labels for each GPIO pin exposed on the 40 pin header. Note that
  * voltage of each GPIO pin could be either 3.3v or 1.8v (as noted by
@@ -371,28 +387,36 @@ usb_con: connector {
 			sink-pdos = <PDO_FIXED(5000, 1000, PDO_FIXED_USB_COMM)>;
 			op-sink-microwatt = <1000000>;
 
+			altmodes {
+				displayport {
+					svid = /bits/ 16 <0xff01>;
+					vdo = <0xffffffff>;
+				};
+			};
+
+
 			ports {
 				#address-cells = <1>;
 				#size-cells = <0>;
 
 				port at 0 {
 					reg = <0>;
-					usbc0_orien_sw: endpoint {
-						remote-endpoint = <&usbdp_phy0_orientation_switch>;
+					usbc0_hs: endpoint {
+						remote-endpoint = <&usb_host0_xhci_hs>;
 					};
 				};
 
 				port at 1 {
 					reg = <1>;
-					usbc0_role_sw: endpoint {
-						remote-endpoint = <&dwc3_0_role_switch>;
+					usbc0_ss: endpoint {
+						remote-endpoint = <&usbdp_phy0_ss_out>;
 					};
 				};
 
 				port at 2 {
 					reg = <2>;
-					dp_altmode_mux: endpoint {
-						remote-endpoint = <&usbdp_phy0_dp_altmode_mux>;
+					usbc0_sbu: endpoint {
+						remote-endpoint = <&usbdp_phy0_dp_out>;
 					};
 				};
 			};
@@ -973,9 +997,22 @@ &usb_host0_xhci {
 	usb-role-switch;
 	status = "okay";
 
-	port {
-		dwc3_0_role_switch: endpoint {
-			remote-endpoint = <&usbc0_role_sw>;
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port at 0 {
+			reg = <0>;
+			usb_host0_xhci_hs: endpoint {
+				remote-endpoint = <&usbc0_hs>;
+			};
+		};
+
+		port at 1 {
+			reg = <1>;
+			usb_host0_xhci_ss: endpoint {
+				remote-endpoint = <&usbdp_phy0_ss_in>;
+			};
 		};
 	};
 };
@@ -1004,14 +1041,24 @@ port {
 		#address-cells = <1>;
 		#size-cells = <0>;
 
-		usbdp_phy0_orientation_switch: endpoint at 0 {
+		usbdp_phy0_ss_out: endpoint at 0 {
 			reg = <0>;
-			remote-endpoint = <&usbc0_orien_sw>;
+			remote-endpoint = <&usbc0_ss>;
 		};
 
-		usbdp_phy0_dp_altmode_mux: endpoint at 1 {
+		usbdp_phy0_ss_in: endpoint at 1 {
 			reg = <1>;
-			remote-endpoint = <&dp_altmode_mux>;
+			remote-endpoint = <&usb_host0_xhci_ss>;
+		};
+
+		usbdp_phy0_dp_in: endpoint at 2 {
+			reg = <2>;
+			remote-endpoint = <&dp0_out_con>;
+		};
+
+		usbdp_phy0_dp_out: endpoint at 3 {
+			reg = <3>;
+			remote-endpoint = <&usbc0_sbu>;
 		};
 	};
 };
@@ -1030,3 +1077,10 @@ vp0_out_hdmi0: endpoint at ROCKCHIP_VOP2_EP_HDMI0 {
 		remote-endpoint = <&hdmi0_in_vp0>;
 	};
 };
+
+&vp1 {
+	vp1_out_dp0: endpoint at a {
+		reg = <ROCKCHIP_VOP2_EP_DP0>;
+		remote-endpoint = <&dp0_in_vp1>;
+	};
+};
-- 
2.43.0



From laurent.pinchart at ideasonboard.com  Fri Nov  7 15:18:18 2025
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Sat, 8 Nov 2025 01:18:18 +0200
Subject: [PATCH v8 6/8] media: rkisp1: Use v4l2-isp for validation
In-Reply-To: <20251020-extensible-parameters-validation-v8-6-afba4ba7b42d@ideasonboard.com>
References: <20251020-extensible-parameters-validation-v8-0-afba4ba7b42d@ideasonboard.com>
 <20251020-extensible-parameters-validation-v8-6-afba4ba7b42d@ideasonboard.com>
Message-ID: <20251107231818.GH5558@pendragon.ideasonboard.com>

Hi Jacopo,

Thank you for the patch.

On Mon, Oct 20, 2025 at 10:24:52AM +0200, Jacopo Mondi wrote:
> Convert rkisp1-params.c to use the helpers defined in v4l2-isp.h
> to perform validation of a ISP parameters buffer.
> 
> Reviewed-by: Daniel Scally <dan.scally at ideasonboard.com>
> Acked-by: Sakari Ailus <sakari.ailus at linux.intel.com>
> Signed-off-by: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
> ---
>  drivers/media/platform/rockchip/rkisp1/Kconfig     |   1 +
>  .../media/platform/rockchip/rkisp1/rkisp1-params.c | 183 +++++++++------------
>  2 files changed, 77 insertions(+), 107 deletions(-)
> 
> diff --git a/drivers/media/platform/rockchip/rkisp1/Kconfig b/drivers/media/platform/rockchip/rkisp1/Kconfig
> index 731c9acbf6efa33188617204d441fb0ea59adebc..f53eb1f3f3e7003d8e02c9236aeabb5ae8844f7b 100644
> --- a/drivers/media/platform/rockchip/rkisp1/Kconfig
> +++ b/drivers/media/platform/rockchip/rkisp1/Kconfig
> @@ -10,6 +10,7 @@ config VIDEO_ROCKCHIP_ISP1
>  	select VIDEOBUF2_VMALLOC
>  	select V4L2_FWNODE
>  	select GENERIC_PHY_MIPI_DPHY
> +	select V4L2_ISP
>  	default n
>  	help
>  	  Enable this to support the Image Signal Processing (ISP) module
> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
> index f1585f8fa0f478304f74317fd9dd09199c94ec82..a880a46d2eefefc6474b36dc5aa69b4f3dce51d1 100644
> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
> @@ -12,6 +12,7 @@
>  #include <media/v4l2-common.h>
>  #include <media/v4l2-event.h>
>  #include <media/v4l2-ioctl.h>
> +#include <media/v4l2-isp.h>
>  #include <media/videobuf2-core.h>
>  #include <media/videobuf2-vmalloc.h>	/* for ISP params */
>  
> @@ -2097,122 +2098,166 @@ typedef void (*rkisp1_block_handler)(struct rkisp1_params *params,
>  			     const union rkisp1_ext_params_config *config);
>  
>  static const struct rkisp1_ext_params_handler {
> -	size_t size;
>  	rkisp1_block_handler handler;
>  	unsigned int group;
>  	unsigned int features;
>  } rkisp1_ext_params_handlers[] = {
>  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_BLS] = {
> -		.size		= sizeof(struct rkisp1_ext_params_bls_config),
>  		.handler	= rkisp1_ext_params_bls,
>  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
>  		.features       = RKISP1_FEATURE_BLS,
>  	},
>  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_DPCC] = {
> -		.size		= sizeof(struct rkisp1_ext_params_dpcc_config),
>  		.handler	= rkisp1_ext_params_dpcc,
>  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
>  	},
>  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_SDG] = {
> -		.size		= sizeof(struct rkisp1_ext_params_sdg_config),
>  		.handler	= rkisp1_ext_params_sdg,
>  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
>  	},
>  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_GAIN] = {
> -		.size		= sizeof(struct rkisp1_ext_params_awb_gain_config),
>  		.handler	= rkisp1_ext_params_awbg,
>  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
>  	},
>  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_FLT] = {
> -		.size		= sizeof(struct rkisp1_ext_params_flt_config),
>  		.handler	= rkisp1_ext_params_flt,
>  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
>  	},
>  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_BDM] = {
> -		.size		= sizeof(struct rkisp1_ext_params_bdm_config),
>  		.handler	= rkisp1_ext_params_bdm,
>  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
>  	},
>  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_CTK] = {
> -		.size		= sizeof(struct rkisp1_ext_params_ctk_config),
>  		.handler	= rkisp1_ext_params_ctk,
>  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
>  	},
>  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_GOC] = {
> -		.size		= sizeof(struct rkisp1_ext_params_goc_config),
>  		.handler	= rkisp1_ext_params_goc,
>  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
>  	},
>  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF] = {
> -		.size		= sizeof(struct rkisp1_ext_params_dpf_config),
>  		.handler	= rkisp1_ext_params_dpf,
>  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
>  	},
>  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF_STRENGTH] = {
> -		.size		= sizeof(struct rkisp1_ext_params_dpf_strength_config),
>  		.handler	= rkisp1_ext_params_dpfs,
>  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
>  	},
>  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_CPROC] = {
> -		.size		= sizeof(struct rkisp1_ext_params_cproc_config),
>  		.handler	= rkisp1_ext_params_cproc,
>  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
>  	},
>  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_IE] = {
> -		.size		= sizeof(struct rkisp1_ext_params_ie_config),
>  		.handler	= rkisp1_ext_params_ie,
>  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
>  	},
>  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_LSC] = {
> -		.size		= sizeof(struct rkisp1_ext_params_lsc_config),
>  		.handler	= rkisp1_ext_params_lsc,
>  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_LSC,
>  	},
>  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_MEAS] = {
> -		.size		= sizeof(struct rkisp1_ext_params_awb_meas_config),
>  		.handler	= rkisp1_ext_params_awbm,
>  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
>  	},
>  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_HST_MEAS] = {
> -		.size		= sizeof(struct rkisp1_ext_params_hst_config),
>  		.handler	= rkisp1_ext_params_hstm,
>  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
>  	},
>  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_AEC_MEAS] = {
> -		.size		= sizeof(struct rkisp1_ext_params_aec_config),
>  		.handler	= rkisp1_ext_params_aecm,
>  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
>  	},
>  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_AFC_MEAS] = {
> -		.size		= sizeof(struct rkisp1_ext_params_afc_config),
>  		.handler	= rkisp1_ext_params_afcm,
>  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
>  	},
>  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_BLS] = {
> -		.size		= sizeof(struct rkisp1_ext_params_compand_bls_config),
>  		.handler	= rkisp1_ext_params_compand_bls,
>  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
>  		.features	= RKISP1_FEATURE_COMPAND,
>  	},
>  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_EXPAND] = {
> -		.size		= sizeof(struct rkisp1_ext_params_compand_curve_config),
>  		.handler	= rkisp1_ext_params_compand_expand,
>  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
>  		.features	= RKISP1_FEATURE_COMPAND,
>  	},
>  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_COMPRESS] = {
> -		.size		= sizeof(struct rkisp1_ext_params_compand_curve_config),
>  		.handler	= rkisp1_ext_params_compand_compress,
>  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
>  		.features	= RKISP1_FEATURE_COMPAND,
>  	},
>  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_WDR] = {
> -		.size		= sizeof(struct rkisp1_ext_params_wdr_config),
>  		.handler	= rkisp1_ext_params_wdr,
>  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
>  	},
>  };
>  
> +static const struct v4l2_isp_params_block_info rkisp1_ext_params_blocks_info[] = {
> +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_BLS] = {
> +		.size		= sizeof(struct rkisp1_ext_params_bls_config),
> +	},
> +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_DPCC] = {
> +		.size		= sizeof(struct rkisp1_ext_params_dpcc_config),
> +	},
> +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_SDG] = {
> +		.size		= sizeof(struct rkisp1_ext_params_sdg_config),
> +	},
> +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_GAIN] = {
> +		.size		= sizeof(struct rkisp1_ext_params_awb_gain_config),
> +	},
> +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_FLT] = {
> +		.size		= sizeof(struct rkisp1_ext_params_flt_config),
> +	},
> +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_BDM] = {
> +		.size		= sizeof(struct rkisp1_ext_params_bdm_config),
> +	},
> +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_CTK] = {
> +		.size		= sizeof(struct rkisp1_ext_params_ctk_config),
> +	},
> +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_GOC] = {
> +		.size		= sizeof(struct rkisp1_ext_params_goc_config),
> +	},
> +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF] = {
> +		.size		= sizeof(struct rkisp1_ext_params_dpf_config),
> +	},
> +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF_STRENGTH] = {
> +		.size		= sizeof(struct rkisp1_ext_params_dpf_strength_config),
> +	},
> +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_CPROC] = {
> +		.size		= sizeof(struct rkisp1_ext_params_cproc_config),
> +	},
> +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_IE] = {
> +		.size		= sizeof(struct rkisp1_ext_params_ie_config),
> +	},
> +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_LSC] = {
> +		.size		= sizeof(struct rkisp1_ext_params_lsc_config),
> +	},
> +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_MEAS] = {
> +		.size		= sizeof(struct rkisp1_ext_params_awb_meas_config),
> +	},
> +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_HST_MEAS] = {
> +		.size		= sizeof(struct rkisp1_ext_params_hst_config),
> +	},
> +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_AEC_MEAS] = {
> +		.size		= sizeof(struct rkisp1_ext_params_aec_config),
> +	},
> +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_AFC_MEAS] = {
> +		.size		= sizeof(struct rkisp1_ext_params_afc_config),
> +	},
> +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_BLS] = {
> +		.size		= sizeof(struct rkisp1_ext_params_compand_bls_config),
> +	},
> +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_EXPAND] = {
> +		.size		= sizeof(struct rkisp1_ext_params_compand_curve_config),
> +	},
> +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_COMPRESS] = {
> +		.size		= sizeof(struct rkisp1_ext_params_compand_curve_config),
> +	},
> +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_WDR] = {
> +		.size		= sizeof(struct rkisp1_ext_params_wdr_config),
> +	},

We could make this more compact with

#define RKISP1_PARAMS_BLOCK_INFO(block, data) \
	[RKISP1_EXT_PARAMS_BLOCK_TYPE_ ## block] = { \
		.size = sizeof(struct rkisp1_ext_params_ ## data ## _config), \
	}

	RKISP1_PARAMS_BLOCK_INFO(BLS, bls),
	RKISP1_PARAMS_BLOCK_INFO(DPCC, dpcc),
	RKISP1_PARAMS_BLOCK_INFO(SDG, sdg),
	RKISP1_PARAMS_BLOCK_INFO(AWB_GAIN, awb_gain),
	RKISP1_PARAMS_BLOCK_INFO(FLT, flt),
	RKISP1_PARAMS_BLOCK_INFO(BDM, bdm),
	RKISP1_PARAMS_BLOCK_INFO(CTK, ctk),
	RKISP1_PARAMS_BLOCK_INFO(GOC, goc),
	RKISP1_PARAMS_BLOCK_INFO(DPF, dpf),
	RKISP1_PARAMS_BLOCK_INFO(DPF_STRENGTH, dpf_strength),
	RKISP1_PARAMS_BLOCK_INFO(CPROC, cproc),
	RKISP1_PARAMS_BLOCK_INFO(IE, ie),
	RKISP1_PARAMS_BLOCK_INFO(LSC, lsc),
	RKISP1_PARAMS_BLOCK_INFO(AWB_MEAS, awb_meas),
	RKISP1_PARAMS_BLOCK_INFO(HST_MEAS, hst),
	RKISP1_PARAMS_BLOCK_INFO(AEC_MEAS, aec),
	RKISP1_PARAMS_BLOCK_INFO(AFC_MEAS, afc),
	RKISP1_PARAMS_BLOCK_INFO(COMPAND_BLS, compand_bls),
	RKISP1_PARAMS_BLOCK_INFO(COMPAND_EXPAND, compand_curve),
	RKISP1_PARAMS_BLOCK_INFO(COMPAND_COMPRESS, compand_curve),
	RKISP1_PARAMS_BLOCK_INFO(WDR, wdr),

It helped me quickly visualize that the block types and data types
matched, so I think it could help reviews when adding new blocks.

This can also be done in a patch on top. Same for the c3-isp driver.

Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

> +};
> +
>  static void rkisp1_ext_params_config(struct rkisp1_params *params,
>  				     struct rkisp1_ext_params_cfg *cfg,
>  				     u32 block_group_mask)
> @@ -2646,31 +2691,16 @@ static int rkisp1_params_prepare_ext_params(struct rkisp1_params *params,
>  {
>  	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
>  	struct rkisp1_params_buffer *params_buf = to_rkisp1_params_buffer(vbuf);
> -	size_t header_size = offsetof(struct rkisp1_ext_params_cfg, data);
>  	struct rkisp1_ext_params_cfg *cfg = params_buf->cfg;
>  	size_t payload_size = vb2_get_plane_payload(vb, 0);
>  	struct rkisp1_ext_params_cfg *usr_cfg =
>  		vb2_plane_vaddr(&vbuf->vb2_buf, 0);
> -	size_t block_offset = 0;
> -	size_t cfg_size;
> -
> -	/*
> -	 * Validate the buffer payload size before copying the parameters. The
> -	 * payload has to be smaller than the destination buffer size and larger
> -	 * than the header size.
> -	 */
> -	if (payload_size > params->metafmt->buffersize) {
> -		dev_dbg(params->rkisp1->dev,
> -			"Too large buffer payload size %zu\n", payload_size);
> -		return -EINVAL;
> -	}
> +	int ret;
>  
> -	if (payload_size < header_size) {
> -		dev_dbg(params->rkisp1->dev,
> -			"Buffer payload %zu smaller than header size %zu\n",
> -			payload_size, header_size);
> -		return -EINVAL;
> -	}
> +	ret = v4l2_isp_params_validate_buffer_size(params->rkisp1->dev, vb,
> +						   params->metafmt->buffersize);
> +	if (ret)
> +		return ret;
>  
>  	/*
>  	 * Copy the parameters buffer to the internal scratch buffer to avoid
> @@ -2678,71 +2708,10 @@ static int rkisp1_params_prepare_ext_params(struct rkisp1_params *params,
>  	 */
>  	memcpy(cfg, usr_cfg, payload_size);
>  
> -	/* Only v1 is supported at the moment. */
> -	if (cfg->version != RKISP1_EXT_PARAM_BUFFER_V1) {
> -		dev_dbg(params->rkisp1->dev,
> -			"Unsupported extensible format version: %u\n",
> -			cfg->version);
> -		return -EINVAL;
> -	}
> -
> -	/* Validate the size reported in the parameters buffer header. */
> -	cfg_size = header_size + cfg->data_size;
> -	if (cfg_size != payload_size) {
> -		dev_dbg(params->rkisp1->dev,
> -			"Data size %zu different than buffer payload size %zu\n",
> -			cfg_size, payload_size);
> -		return -EINVAL;
> -	}
> -
> -	/* Walk the list of parameter blocks and validate them. */
> -	cfg_size = cfg->data_size;
> -	while (cfg_size >= sizeof(struct rkisp1_ext_params_block_header)) {
> -		const struct rkisp1_ext_params_block_header *block;
> -		const struct rkisp1_ext_params_handler *handler;
> -
> -		block = (const struct rkisp1_ext_params_block_header *)
> -			&cfg->data[block_offset];
> -
> -		if (block->type >= ARRAY_SIZE(rkisp1_ext_params_handlers)) {
> -			dev_dbg(params->rkisp1->dev,
> -				"Invalid parameters block type\n");
> -			return -EINVAL;
> -		}
> -
> -		if (block->size > cfg_size) {
> -			dev_dbg(params->rkisp1->dev,
> -				"Premature end of parameters data\n");
> -			return -EINVAL;
> -		}
> -
> -		if ((block->flags & (RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE |
> -				     RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE)) ==
> -		   (RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE |
> -		    RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE)) {
> -			dev_dbg(params->rkisp1->dev,
> -				"Invalid parameters block flags\n");
> -			return -EINVAL;
> -		}
> -
> -		handler = &rkisp1_ext_params_handlers[block->type];
> -		if (block->size != handler->size) {
> -			dev_dbg(params->rkisp1->dev,
> -				"Invalid parameters block size\n");
> -			return -EINVAL;
> -		}
> -
> -		block_offset += block->size;
> -		cfg_size -= block->size;
> -	}
> -
> -	if (cfg_size) {
> -		dev_dbg(params->rkisp1->dev,
> -			"Unexpected data after the parameters buffer end\n");
> -		return -EINVAL;
> -	}
> -
> -	return 0;
> +	return v4l2_isp_params_validate_buffer(params->rkisp1->dev, vb,
> +				(struct v4l2_isp_params_buffer *)cfg,
> +				rkisp1_ext_params_blocks_info,
> +				ARRAY_SIZE(rkisp1_ext_params_blocks_info));
>  }
>  
>  static int rkisp1_params_vb2_buf_prepare(struct vb2_buffer *vb)

-- 
Regards,

Laurent Pinchart


From laurent.pinchart at ideasonboard.com  Fri Nov  7 15:28:02 2025
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Sat, 8 Nov 2025 01:28:02 +0200
Subject: [PATCH v8 7/8] media: amlogic-c3: Use v4l2-isp for validation
In-Reply-To: <20251020-extensible-parameters-validation-v8-7-afba4ba7b42d@ideasonboard.com>
References: <20251020-extensible-parameters-validation-v8-0-afba4ba7b42d@ideasonboard.com>
 <20251020-extensible-parameters-validation-v8-7-afba4ba7b42d@ideasonboard.com>
Message-ID: <20251107232802.GJ5558@pendragon.ideasonboard.com>

Hi Jacopo,

Thank you for the patch.

On Mon, Oct 20, 2025 at 10:24:53AM +0200, Jacopo Mondi wrote:
> Convert c3-isp-params.c to use the helpers defined in v4l2-isp.h
> to perform validation of a ISP parameters buffer.

s/a ISP/an ISP/

> 
> Reviewed-by: Keke Li <keke.li at amlogic.com>
> Reviewed-by: Daniel Scally <dan.scally at ideasonboard.com>
> Acked-by: Sakari Ailus <sakari.ailus at linux.intel.com>
> Signed-off-by: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
> ---
>  drivers/media/platform/amlogic/c3/isp/Kconfig      |   1 +
>  .../media/platform/amlogic/c3/isp/c3-isp-params.c  | 124 +++++----------------
>  2 files changed, 27 insertions(+), 98 deletions(-)
> 
> diff --git a/drivers/media/platform/amlogic/c3/isp/Kconfig b/drivers/media/platform/amlogic/c3/isp/Kconfig
> index 02c62a50a5e88eac665e27abf163e5d654faed3f..809208cd7e3aa7ca0821cb07366ec73a47edb278 100644
> --- a/drivers/media/platform/amlogic/c3/isp/Kconfig
> +++ b/drivers/media/platform/amlogic/c3/isp/Kconfig
> @@ -10,6 +10,7 @@ config VIDEO_C3_ISP
>  	select VIDEO_V4L2_SUBDEV_API
>  	select VIDEOBUF2_DMA_CONTIG
>  	select VIDEOBUF2_VMALLOC
> +	select V4L2_ISP
>  	help
>  	  Video4Linux2 driver for Amlogic C3 ISP pipeline.
>  	  The C3 ISP is used for processing raw images and
> diff --git a/drivers/media/platform/amlogic/c3/isp/c3-isp-params.c b/drivers/media/platform/amlogic/c3/isp/c3-isp-params.c
> index c80667dd766210d2b2e1ee60c8254a5814b9d81b..0e031d64de312cfdf0a52a46f70edbaf07563359 100644
> --- a/drivers/media/platform/amlogic/c3/isp/c3-isp-params.c
> +++ b/drivers/media/platform/amlogic/c3/isp/c3-isp-params.c
> @@ -8,6 +8,7 @@
>  #include <linux/pm_runtime.h>
>  
>  #include <media/v4l2-ioctl.h>
> +#include <media/v4l2-isp.h>
>  #include <media/v4l2-mc.h>
>  #include <media/videobuf2-vmalloc.h>
>  
> @@ -51,11 +52,6 @@ union c3_isp_params_block {
>  typedef void (*c3_isp_block_handler)(struct c3_isp_device *isp,
>  				     const union c3_isp_params_block *block);
>  
> -struct c3_isp_params_handler {
> -	size_t size;
> -	c3_isp_block_handler handler;
> -};
> -
>  #define to_c3_isp_params_buffer(vbuf) \
>  	container_of(vbuf, struct c3_isp_params_buffer, vb)
>  
> @@ -523,38 +519,41 @@ static void c3_isp_params_cfg_blc(struct c3_isp_device *isp,
>  				   ISP_TOP_BEO_CTRL_BLC_EN);
>  }
>  
> -static const struct c3_isp_params_handler c3_isp_params_handlers[] = {
> +static const c3_isp_block_handler c3_isp_params_handlers[] = {
> +	[C3_ISP_PARAMS_BLOCK_AWB_GAINS] = c3_isp_params_cfg_awb_gains,
> +	[C3_ISP_PARAMS_BLOCK_AWB_CONFIG] = c3_isp_params_cfg_awb_config,
> +	[C3_ISP_PARAMS_BLOCK_AE_CONFIG] = c3_isp_params_cfg_ae_config,
> +	[C3_ISP_PARAMS_BLOCK_AF_CONFIG] = c3_isp_params_cfg_af_config,
> +	[C3_ISP_PARAMS_BLOCK_PST_GAMMA] = c3_isp_params_cfg_pst_gamma,
> +	[C3_ISP_PARAMS_BLOCK_CCM] = c3_isp_params_cfg_ccm,
> +	[C3_ISP_PARAMS_BLOCK_CSC] = c3_isp_params_cfg_csc,
> +	[C3_ISP_PARAMS_BLOCK_BLC] = c3_isp_params_cfg_blc,
> +};
> +
> +static const struct v4l2_isp_params_block_info c3_isp_params_blocks_info[] = {
>  	[C3_ISP_PARAMS_BLOCK_AWB_GAINS] = {
>  		.size = sizeof(struct c3_isp_params_awb_gains),
> -		.handler = c3_isp_params_cfg_awb_gains,
>  	},
>  	[C3_ISP_PARAMS_BLOCK_AWB_CONFIG] = {
>  		.size = sizeof(struct c3_isp_params_awb_config),
> -		.handler = c3_isp_params_cfg_awb_config,
>  	},
>  	[C3_ISP_PARAMS_BLOCK_AE_CONFIG] = {
>  		.size = sizeof(struct c3_isp_params_ae_config),
> -		.handler = c3_isp_params_cfg_ae_config,
>  	},
>  	[C3_ISP_PARAMS_BLOCK_AF_CONFIG] = {
>  		.size = sizeof(struct c3_isp_params_af_config),
> -		.handler = c3_isp_params_cfg_af_config,
>  	},
>  	[C3_ISP_PARAMS_BLOCK_PST_GAMMA] = {
>  		.size = sizeof(struct c3_isp_params_pst_gamma),
> -		.handler = c3_isp_params_cfg_pst_gamma,
>  	},
>  	[C3_ISP_PARAMS_BLOCK_CCM] = {
>  		.size = sizeof(struct c3_isp_params_ccm),
> -		.handler = c3_isp_params_cfg_ccm,
>  	},
>  	[C3_ISP_PARAMS_BLOCK_CSC] = {
>  		.size = sizeof(struct c3_isp_params_csc),
> -		.handler = c3_isp_params_cfg_csc,
>  	},
>  	[C3_ISP_PARAMS_BLOCK_BLC] = {
>  		.size = sizeof(struct c3_isp_params_blc),
> -		.handler = c3_isp_params_cfg_blc,
>  	},
>  };

Same comment as with 6/8.

Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas at ideasonboard.com>

>  
> @@ -568,14 +567,14 @@ static void c3_isp_params_cfg_blocks(struct c3_isp_params *params)
>  
>  	/* Walk the list of parameter blocks and process them */
>  	while (block_offset < config->data_size) {
> -		const struct c3_isp_params_handler *block_handler;
>  		const union c3_isp_params_block *block;
> +		c3_isp_block_handler block_handler;
>  
>  		block = (const union c3_isp_params_block *)
>  			 &config->data[block_offset];
>  
> -		block_handler = &c3_isp_params_handlers[block->header.type];
> -		block_handler->handler(params->isp, block);
> +		block_handler = c3_isp_params_handlers[block->header.type];
> +		block_handler(params->isp, block);
>  
>  		block_offset += block->header.size;
>  	}
> @@ -771,26 +770,15 @@ static int c3_isp_params_vb2_buf_prepare(struct vb2_buffer *vb)
>  	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
>  	struct c3_isp_params_buffer *buf = to_c3_isp_params_buffer(vbuf);
>  	struct c3_isp_params *params = vb2_get_drv_priv(vb->vb2_queue);
> -	struct c3_isp_params_cfg *cfg = buf->cfg;
>  	struct c3_isp_params_cfg *usr_cfg = vb2_plane_vaddr(vb, 0);
>  	size_t payload_size = vb2_get_plane_payload(vb, 0);
> -	size_t header_size = offsetof(struct c3_isp_params_cfg, data);
> -	size_t block_offset = 0;
> -	size_t cfg_size;
> -
> -	/* Payload size can't be greater than the destination buffer size */
> -	if (payload_size > params->vfmt.fmt.meta.buffersize) {
> -		dev_dbg(params->isp->dev,
> -			"Payload size is too large: %zu\n", payload_size);
> -		return -EINVAL;
> -	}
> +	struct c3_isp_params_cfg *cfg = buf->cfg;
> +	int ret;
>  
> -	/* Payload size can't be smaller than the header size */
> -	if (payload_size < header_size) {
> -		dev_dbg(params->isp->dev,
> -			"Payload size is too small: %zu\n", payload_size);
> -		return -EINVAL;
> -	}
> +	ret = v4l2_isp_params_validate_buffer_size(params->isp->dev, vb,
> +						   params->vfmt.fmt.meta.buffersize);
> +	if (ret)
> +		return ret;
>  
>  	/*
>  	 * Use the internal scratch buffer to avoid userspace modifying
> @@ -798,70 +786,10 @@ static int c3_isp_params_vb2_buf_prepare(struct vb2_buffer *vb)
>  	 */
>  	memcpy(cfg, usr_cfg, payload_size);
>  
> -	/* Only v0 is supported at the moment */
> -	if (cfg->version != C3_ISP_PARAMS_BUFFER_V0) {
> -		dev_dbg(params->isp->dev,
> -			"Invalid params buffer version: %u\n", cfg->version);
> -		return -EINVAL;
> -	}
> -
> -	/* Validate the size reported in the parameter buffer header */
> -	cfg_size = header_size + cfg->data_size;
> -	if (cfg_size != payload_size) {
> -		dev_dbg(params->isp->dev,
> -			"Data size %zu and payload size %zu are different\n",
> -			cfg_size, payload_size);
> -		return -EINVAL;
> -	}
> -
> -	/* Walk the list of parameter blocks and validate them */
> -	cfg_size = cfg->data_size;
> -	while (cfg_size >= sizeof(struct c3_isp_params_block_header)) {
> -		const struct c3_isp_params_block_header *block;
> -		const struct c3_isp_params_handler *handler;
> -
> -		block = (struct c3_isp_params_block_header *)
> -			&cfg->data[block_offset];
> -
> -		if (block->type >= ARRAY_SIZE(c3_isp_params_handlers)) {
> -			dev_dbg(params->isp->dev,
> -				"Invalid params block type\n");
> -			return -EINVAL;
> -		}
> -
> -		if (block->size > cfg_size) {
> -			dev_dbg(params->isp->dev,
> -				"Block size is greater than cfg size\n");
> -			return -EINVAL;
> -		}
> -
> -		if ((block->flags & (C3_ISP_PARAMS_BLOCK_FL_ENABLE |
> -				     C3_ISP_PARAMS_BLOCK_FL_DISABLE)) ==
> -		    (C3_ISP_PARAMS_BLOCK_FL_ENABLE |
> -		     C3_ISP_PARAMS_BLOCK_FL_DISABLE)) {
> -			dev_dbg(params->isp->dev,
> -				"Invalid parameters block flags\n");
> -			return -EINVAL;
> -		}
> -
> -		handler = &c3_isp_params_handlers[block->type];
> -		if (block->size != handler->size) {
> -			dev_dbg(params->isp->dev,
> -				"Invalid params block size\n");
> -			return -EINVAL;
> -		}
> -
> -		block_offset += block->size;
> -		cfg_size -= block->size;
> -	}
> -
> -	if (cfg_size) {
> -		dev_dbg(params->isp->dev,
> -			"Unexpected data after the params buffer end\n");
> -		return -EINVAL;
> -	}
> -
> -	return 0;
> +	return v4l2_isp_params_validate_buffer(params->isp->dev, vb,
> +					(struct v4l2_isp_params_buffer *)cfg,
> +					c3_isp_params_blocks_info,
> +					ARRAY_SIZE(c3_isp_params_blocks_info));
>  }
>  
>  static int c3_isp_params_vb2_buf_init(struct vb2_buffer *vb)

-- 
Regards,

Laurent Pinchart


From laurent.pinchart at ideasonboard.com  Fri Nov  7 15:34:15 2025
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Sat, 8 Nov 2025 01:34:15 +0200
Subject: [PATCH v8 8/8] media: Documentation: kapi: Add v4l2 generic ISP
 support
In-Reply-To: <20251020-extensible-parameters-validation-v8-8-afba4ba7b42d@ideasonboard.com>
References: <20251020-extensible-parameters-validation-v8-0-afba4ba7b42d@ideasonboard.com>
 <20251020-extensible-parameters-validation-v8-8-afba4ba7b42d@ideasonboard.com>
Message-ID: <20251107233415.GK5558@pendragon.ideasonboard.com>

Hi Jacopo,

Thank you for the patch.

On Mon, Oct 20, 2025 at 10:24:54AM +0200, Jacopo Mondi wrote:
> Add to the driver-api documentation the v4l2-isp.h types and
> helpers documentation.
> 
> Reviewed-by: Daniel Scally <dan.scally at ideasonboard.com>
> Reviewed-by: Michael Riesch <michael.riesch at collabora.com>
> Acked-by: Sakari Ailus <sakari.ailus at linux.intel.com>
> Signed-off-by: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
> ---
>  Documentation/driver-api/media/v4l2-core.rst |  1 +
>  Documentation/driver-api/media/v4l2-isp.rst  | 49 ++++++++++++++++++++++++++++
>  MAINTAINERS                                  |  1 +
>  3 files changed, 51 insertions(+)
> 
> diff --git a/Documentation/driver-api/media/v4l2-core.rst b/Documentation/driver-api/media/v4l2-core.rst
> index ad987c34ad2a8460bb95e97adc4d850d624e0b81..a5f5102c64cca57b57b54ab95882b26286fb27de 100644
> --- a/Documentation/driver-api/media/v4l2-core.rst
> +++ b/Documentation/driver-api/media/v4l2-core.rst
> @@ -27,3 +27,4 @@ Video4Linux devices
>      v4l2-common
>      v4l2-tveeprom
>      v4l2-jpeg
> +    v4l2-isp
> diff --git a/Documentation/driver-api/media/v4l2-isp.rst b/Documentation/driver-api/media/v4l2-isp.rst
> new file mode 100644
> index 0000000000000000000000000000000000000000..150ba39b257b23e6a8ca1a348047f5b55588fbf7
> --- /dev/null
> +++ b/Documentation/driver-api/media/v4l2-isp.rst
> @@ -0,0 +1,49 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +V4L2 generic ISP parameters and statistics support
> +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> +
> +Design rationale
> +================
> +
> +ISP configuration parameters and statistics are processed and collected by
> +drivers and exchanged with userspace through data types that usually
> +reflect the ISP peripheral registers layout.
> +
> +Each ISP driver defines its own metadata output format for parameters and
> +a metadata capture format for statistics. The buffer layout is realized by a
> +set of C structures that reflects the registers layout. The number and types
> +of C structures is fixed by the format definition and becomes part of the Linux
> +kernel uAPI/uABI interface.
> +
> +Because of the hard requirement of backward compatibility when extending the
> +user API/ABI interface, modifying an ISP driver capture or output metadata
> +format after it has been accepted by mainline is very hard if not impossible.
> +
> +It generally happens, in fact, that after the first accepted revision of an ISP
> +driver the buffers layout need to be modified, either to support new hardware
> +blocks, to fix bugs or to support different revisions of the hardware.
> +
> +Each of these situations would require defining a new metadata format, making it
> +really hard to maintain and extend drivers and requiring userspace to use
> +the correct format depending on the kernel revision in use.
> +
> +V4L2 ISP configuration parameters
> +=================================
> +
> +For these reasons, Video4Linux2 defines generic types for ISP configuration
> +parameters and statistics. Drivers are still expected to define their own
> +formats for their metadata output and capture nodes, but the buffers layout can
> +be defined using the extensible and versioned types defined by
> +include/uapi/linux/media/v4l2-isp.h.
> +
> +Drivers are expected to provide the definitions of their supported ISP blocks,
> +the control flags and the expected maximum size of a buffer.

What are the control flags here ? Is it a leftover from a previous
version ?

With this addressed,

Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas at ideasonboard.com>

> +
> +For driver developers a set of helper functions to assist them with validation
> +of the buffer received from userspace is available in
> +drivers/media/v4l2-core/v4l2-isp.c
> +
> +V4L2 ISP support driver documentation
> +=====================================
> +.. kernel-doc:: include/media/v4l2-isp.h
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 5833f82caa7f2f734bb0e1be144ade2109b23988..cd1137c7754538d02bd72521fec6c89e082246d2 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -26856,6 +26856,7 @@ V4L2 GENERIC ISP PARAMETERS AND STATISTIC FORMATS
>  M:	Jacopo Mondi <jacopo.mondi at ideasonboard.com>
>  L:	linux-media at vger.kernel.org
>  S:	Maintained
> +F:	Documentation/driver-api/media/v4l2-isp.rst
>  F:	Documentation/userspace-api/media/v4l/v4l2-isp.rst
>  F:	drivers/media/v4l2-core/v4l2-isp.c
>  F:	include/media/v4l2-isp.h

-- 
Regards,

Laurent Pinchart


From laurent.pinchart at ideasonboard.com  Fri Nov  7 16:17:13 2025
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Sat, 8 Nov 2025 02:17:13 +0200
Subject: [PATCH v8 4/8] media: Documentation: uapi: Add V4L2 ISP
 documentation
In-Reply-To: <20251020-extensible-parameters-validation-v8-4-afba4ba7b42d@ideasonboard.com>
References: <20251020-extensible-parameters-validation-v8-0-afba4ba7b42d@ideasonboard.com>
 <20251020-extensible-parameters-validation-v8-4-afba4ba7b42d@ideasonboard.com>
Message-ID: <20251108001713.GL5558@pendragon.ideasonboard.com>

Hi Jacopo,

Thank you for the patch.

On Mon, Oct 20, 2025 at 10:24:50AM +0200, Jacopo Mondi wrote:
> Add userspace documentation for V4L2 ISP generic parameters and
> statistics formats.
> 
> Reviewed-by: Daniel Scally <dan.scally at ideasonboard.com>
> Reviewed-by: Michael Riesch <michael.riesch at collabora.com>
> Acked-by: Sakari Ailus <sakari.ailus at linux.intel.com>
> Signed-off-by: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
> ---
>  .../userspace-api/media/v4l/meta-formats.rst       |   1 +
>  Documentation/userspace-api/media/v4l/v4l2-isp.rst | 120 +++++++++++++++++++++
>  MAINTAINERS                                        |   1 +
>  3 files changed, 122 insertions(+)
> 
> diff --git a/Documentation/userspace-api/media/v4l/meta-formats.rst b/Documentation/userspace-api/media/v4l/meta-formats.rst
> index d9868ee88a0717c1acaa4ee477eaed96a6411f73..7b758ea9eb4ac3c4b354bf8e2f319985ed9e2b37 100644
> --- a/Documentation/userspace-api/media/v4l/meta-formats.rst
> +++ b/Documentation/userspace-api/media/v4l/meta-formats.rst
> @@ -25,3 +25,4 @@ These formats are used for the :ref:`metadata` interface only.
>      metafmt-vivid
>      metafmt-vsp1-hgo
>      metafmt-vsp1-hgt
> +    v4l2-isp
> diff --git a/Documentation/userspace-api/media/v4l/v4l2-isp.rst b/Documentation/userspace-api/media/v4l/v4l2-isp.rst
> new file mode 100644
> index 0000000000000000000000000000000000000000..b53df722ed29117c3827314e844fc4de61343f40
> --- /dev/null
> +++ b/Documentation/userspace-api/media/v4l/v4l2-isp.rst
> @@ -0,0 +1,120 @@
> +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
> +
> +.. _v4l2-isp:
> +
> +************************
> +Generic V4L2 ISP formats
> +************************
> +
> +ISP configuration and statistics: theory of operations
> +======================================================
> +
> +ISP configuration parameters are computed by userspace and programmed into a
> +*parameters buffer* which is queued to the ISP driver on a per-frame basis.
> +
> +ISP statistics are collected at a specific time point and drivers use them to
> +populate a *statistics buffer* which is then returned to userspace.
> +
> +The parameters and statistics buffers are organized in a driver-specific
> +way, and their data layout differs between one driver and another.
> +
> +ISP drivers generally exchange parameters and statistics with userspace through
> +a metadata output and capture node respectively, implementing the
> +:c:type:`v4l2_meta_format` interface. Each ISP driver defines one metadata
> +capture format and one metadata output format to be used on those video nodes,
> +and the buffer content layout and organization is fixed by the format definition.
> +
> +The uAPI/ABI problem
> +--------------------
> +
> +By upstreaming the metadata formats that describe the parameters and statistics
> +buffers layout, driver developers make them part of the Linux kernel ABI. As for
> +most peripherals, ISP driver development in Linux is often an iterative process,
> +in which not all of the hardware features are supported in the first version.
> +
> +The support for new features and/or bug fixes may land in the kernel at a later
> +stage and require changes to the metadata formats definition. This is
> +considered an ABI breakage that is strictly forbidden by the Linux kernel
> +policies. For this reason, any change in the ISP parameters and statistics
> +buffer layout would require defining a new metadata format.
> +
> +For these reasons Video4Linux2 has introduced support for generic ISP parameters
> +and statistics data types, designed with the goal of being:
> +
> +- Extensible: new features can be added later on without breaking the existing
> +  interface
> +- Versioned: different versions of the format can be defined without
> +  breaking the existing interface
> +
> +ISP configuration
> +=================
> +
> +Before the introduction of generic formats
> +------------------------------------------
> +
> +Metadata output formats that describe ISP configuration parameters were
> +typically realized by defining C structures that reflect the ISP registers
> +layout and get populated by userspace before queueing the buffer to the ISP.
> +Each C structure usually corresponds to one ISP *processing block*, with each
> +block implementing one of the ISP supported features.
> +
> +The number of supported ISP blocks, the layout of their configuration data are
> +fixed by the format definition, incurring in the above described uAPI/uABI
> +problem.
> +
> +Generic ISP parameters
> +----------------------
> +

Most of the text above is a design rationale that in my opinion doesn't
belong to the UAPI documentation. You already include a design rationale
in the kernel documentation, in patch 8/8. If some of the text above
contains a more verbose explanation, it could be moved there.

I would shorten all this to

************************
Generic V4L2 ISP formats
************************

Generic ISP formats are metadata formats that define a mechanism to pass ISP
parameters and statistics between userspace and drivers in V4L2 buffers. They
are designed to allow extending the data in a backward-compatible way.

ISP configuration
=================

> +The generic ISP configuration parameters format is realized by a defining a
> +single C structure that contains a header, followed by a binary buffer where
> +userspace programs a variable number of ISP configuration data block, one for
> +each supported ISP feature.
> +
> +The :c:type:`v4l2_isp_params_buffer` structure defines the parameters buffer
> +header which is followed by a binary buffer of ISP configuration parameters.
> +Userspace shall correctly populate the buffer header with the versioning

s/versioning information/extensible parameters format version/

> +information and with the size (in bytes) of the binary data buffer where it will
> +store the ISP blocks configuration.
> +
> +Each *ISP configuration block* is preceded by an header implemented by the
> +:c:type:`v4l2_isp_params_block_header` structure, followed by the configuration
> +parameters for that specific block, defined by the ISP driver specific data
> +types.
> +
> +Userspace applications are responsible for correctly populating each block's
> +header fields (type, flags and size) and the block-specific parameters.
> +
> +ISP Block enabling, disabling and configuration
> +-----------------------------------------------
> +
> +When userspace wants to configure and enable an ISP block it shall fully
> +populate the block configuration and set the V4L2_ISP_PARAMS_FL_BLOCK_ENABLE
> +bit in the block header's `flags` field.
> +
> +When userspace simply wants to disable an ISP block the
> +V4L2_ISP_PARAMS_FL_BLOCK_DISABLE bit should be set in block header's `flags`
> +field. Drivers accept a configuration parameters block with no additional
> +data after the header in this case.
> +
> +If the configuration of an already active ISP block has to be updated,
> +userspace shall fully populate the ISP block parameters and omit setting the
> +V4L2_ISP_PARAMS_FL_BLOCK_ENABLE and V4L2_ISP_PARAMS_FL_BLOCK_DISABLE bits in the
> +header's `flags` field.
> +
> +Setting both the V4L2_ISP_PARAMS_FL_BLOCK_ENABLE and
> +V4L2_ISP_PARAMS_FL_BLOCK_DISABLE bits in the flags field is not allowed and not
> +accepted.

s/and not accepted/and returns an error/

> +
> +Any further extension to the parameters layout that happens after the ISP driver

s/Any further extension/Extensions/

> +has been merged in Linux can be implemented by adding new blocks definition

s/after the ISP driver has been merged in Linux //

Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas at ideasonboard.com>

> +without invalidating the existing ones.
> +
> +ISP statistics
> +==============
> +
> +Support for generic statistics format is not yet implemented in Video4Linux2.
> +
> +V4L2 ISP uAPI data types
> +========================
> +
> +.. kernel-doc:: include/uapi/linux/media/v4l2-isp.h
> diff --git a/MAINTAINERS b/MAINTAINERS
> index d925745077f21e5a1388a30217a24beeb4fff3b5..f52237d57710cadff78b297d2b4610b508f55092 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -26856,6 +26856,7 @@ V4L2 GENERIC ISP PARAMETERS AND STATISTIC FORMATS
>  M:	Jacopo Mondi <jacopo.mondi at ideasonboard.com>
>  L:	linux-media at vger.kernel.org
>  S:	Maintained
> +F:	Documentation/userspace-api/media/v4l/v4l2-isp.rst
>  F:	include/uapi/linux/media/v4l2-isp.h
>  
>  VF610 NAND DRIVER

-- 
Regards,

Laurent Pinchart


From jacopo.mondi at ideasonboard.com  Sat Nov  8 00:46:10 2025
From: jacopo.mondi at ideasonboard.com (Jacopo Mondi)
Date: Sat, 8 Nov 2025 09:46:10 +0100
Subject: [PATCH v8 6/8] media: rkisp1: Use v4l2-isp for validation
In-Reply-To: <20251107231818.GH5558@pendragon.ideasonboard.com>
References: <20251020-extensible-parameters-validation-v8-0-afba4ba7b42d@ideasonboard.com>
 <20251020-extensible-parameters-validation-v8-6-afba4ba7b42d@ideasonboard.com>
 <20251107231818.GH5558@pendragon.ideasonboard.com>
Message-ID: <tkgroszon7wi43jvmte5vylbxdn7oafm665weecztkfguqhu6c@mw24ipqvwxou>

Hi Laurent

On Sat, Nov 08, 2025 at 01:18:18AM +0200, Laurent Pinchart wrote:
> Hi Jacopo,
>
> Thank you for the patch.
>
> On Mon, Oct 20, 2025 at 10:24:52AM +0200, Jacopo Mondi wrote:
> > Convert rkisp1-params.c to use the helpers defined in v4l2-isp.h
> > to perform validation of a ISP parameters buffer.
> >
> > Reviewed-by: Daniel Scally <dan.scally at ideasonboard.com>
> > Acked-by: Sakari Ailus <sakari.ailus at linux.intel.com>
> > Signed-off-by: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
> > ---
> >  drivers/media/platform/rockchip/rkisp1/Kconfig     |   1 +
> >  .../media/platform/rockchip/rkisp1/rkisp1-params.c | 183 +++++++++------------
> >  2 files changed, 77 insertions(+), 107 deletions(-)
> >
> > diff --git a/drivers/media/platform/rockchip/rkisp1/Kconfig b/drivers/media/platform/rockchip/rkisp1/Kconfig
> > index 731c9acbf6efa33188617204d441fb0ea59adebc..f53eb1f3f3e7003d8e02c9236aeabb5ae8844f7b 100644
> > --- a/drivers/media/platform/rockchip/rkisp1/Kconfig
> > +++ b/drivers/media/platform/rockchip/rkisp1/Kconfig
> > @@ -10,6 +10,7 @@ config VIDEO_ROCKCHIP_ISP1
> >  	select VIDEOBUF2_VMALLOC
> >  	select V4L2_FWNODE
> >  	select GENERIC_PHY_MIPI_DPHY
> > +	select V4L2_ISP
> >  	default n
> >  	help
> >  	  Enable this to support the Image Signal Processing (ISP) module
> > diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
> > index f1585f8fa0f478304f74317fd9dd09199c94ec82..a880a46d2eefefc6474b36dc5aa69b4f3dce51d1 100644
> > --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
> > +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
> > @@ -12,6 +12,7 @@
> >  #include <media/v4l2-common.h>
> >  #include <media/v4l2-event.h>
> >  #include <media/v4l2-ioctl.h>
> > +#include <media/v4l2-isp.h>
> >  #include <media/videobuf2-core.h>
> >  #include <media/videobuf2-vmalloc.h>	/* for ISP params */
> >
> > @@ -2097,122 +2098,166 @@ typedef void (*rkisp1_block_handler)(struct rkisp1_params *params,
> >  			     const union rkisp1_ext_params_config *config);
> >
> >  static const struct rkisp1_ext_params_handler {
> > -	size_t size;
> >  	rkisp1_block_handler handler;
> >  	unsigned int group;
> >  	unsigned int features;
> >  } rkisp1_ext_params_handlers[] = {
> >  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_BLS] = {
> > -		.size		= sizeof(struct rkisp1_ext_params_bls_config),
> >  		.handler	= rkisp1_ext_params_bls,
> >  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
> >  		.features       = RKISP1_FEATURE_BLS,
> >  	},
> >  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_DPCC] = {
> > -		.size		= sizeof(struct rkisp1_ext_params_dpcc_config),
> >  		.handler	= rkisp1_ext_params_dpcc,
> >  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
> >  	},
> >  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_SDG] = {
> > -		.size		= sizeof(struct rkisp1_ext_params_sdg_config),
> >  		.handler	= rkisp1_ext_params_sdg,
> >  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
> >  	},
> >  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_GAIN] = {
> > -		.size		= sizeof(struct rkisp1_ext_params_awb_gain_config),
> >  		.handler	= rkisp1_ext_params_awbg,
> >  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
> >  	},
> >  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_FLT] = {
> > -		.size		= sizeof(struct rkisp1_ext_params_flt_config),
> >  		.handler	= rkisp1_ext_params_flt,
> >  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
> >  	},
> >  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_BDM] = {
> > -		.size		= sizeof(struct rkisp1_ext_params_bdm_config),
> >  		.handler	= rkisp1_ext_params_bdm,
> >  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
> >  	},
> >  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_CTK] = {
> > -		.size		= sizeof(struct rkisp1_ext_params_ctk_config),
> >  		.handler	= rkisp1_ext_params_ctk,
> >  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
> >  	},
> >  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_GOC] = {
> > -		.size		= sizeof(struct rkisp1_ext_params_goc_config),
> >  		.handler	= rkisp1_ext_params_goc,
> >  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
> >  	},
> >  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF] = {
> > -		.size		= sizeof(struct rkisp1_ext_params_dpf_config),
> >  		.handler	= rkisp1_ext_params_dpf,
> >  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
> >  	},
> >  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF_STRENGTH] = {
> > -		.size		= sizeof(struct rkisp1_ext_params_dpf_strength_config),
> >  		.handler	= rkisp1_ext_params_dpfs,
> >  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
> >  	},
> >  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_CPROC] = {
> > -		.size		= sizeof(struct rkisp1_ext_params_cproc_config),
> >  		.handler	= rkisp1_ext_params_cproc,
> >  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
> >  	},
> >  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_IE] = {
> > -		.size		= sizeof(struct rkisp1_ext_params_ie_config),
> >  		.handler	= rkisp1_ext_params_ie,
> >  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
> >  	},
> >  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_LSC] = {
> > -		.size		= sizeof(struct rkisp1_ext_params_lsc_config),
> >  		.handler	= rkisp1_ext_params_lsc,
> >  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_LSC,
> >  	},
> >  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_MEAS] = {
> > -		.size		= sizeof(struct rkisp1_ext_params_awb_meas_config),
> >  		.handler	= rkisp1_ext_params_awbm,
> >  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
> >  	},
> >  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_HST_MEAS] = {
> > -		.size		= sizeof(struct rkisp1_ext_params_hst_config),
> >  		.handler	= rkisp1_ext_params_hstm,
> >  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
> >  	},
> >  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_AEC_MEAS] = {
> > -		.size		= sizeof(struct rkisp1_ext_params_aec_config),
> >  		.handler	= rkisp1_ext_params_aecm,
> >  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
> >  	},
> >  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_AFC_MEAS] = {
> > -		.size		= sizeof(struct rkisp1_ext_params_afc_config),
> >  		.handler	= rkisp1_ext_params_afcm,
> >  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
> >  	},
> >  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_BLS] = {
> > -		.size		= sizeof(struct rkisp1_ext_params_compand_bls_config),
> >  		.handler	= rkisp1_ext_params_compand_bls,
> >  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
> >  		.features	= RKISP1_FEATURE_COMPAND,
> >  	},
> >  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_EXPAND] = {
> > -		.size		= sizeof(struct rkisp1_ext_params_compand_curve_config),
> >  		.handler	= rkisp1_ext_params_compand_expand,
> >  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
> >  		.features	= RKISP1_FEATURE_COMPAND,
> >  	},
> >  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_COMPRESS] = {
> > -		.size		= sizeof(struct rkisp1_ext_params_compand_curve_config),
> >  		.handler	= rkisp1_ext_params_compand_compress,
> >  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
> >  		.features	= RKISP1_FEATURE_COMPAND,
> >  	},
> >  	[RKISP1_EXT_PARAMS_BLOCK_TYPE_WDR] = {
> > -		.size		= sizeof(struct rkisp1_ext_params_wdr_config),
> >  		.handler	= rkisp1_ext_params_wdr,
> >  		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
> >  	},
> >  };
> >
> > +static const struct v4l2_isp_params_block_info rkisp1_ext_params_blocks_info[] = {
> > +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_BLS] = {
> > +		.size		= sizeof(struct rkisp1_ext_params_bls_config),
> > +	},
> > +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_DPCC] = {
> > +		.size		= sizeof(struct rkisp1_ext_params_dpcc_config),
> > +	},
> > +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_SDG] = {
> > +		.size		= sizeof(struct rkisp1_ext_params_sdg_config),
> > +	},
> > +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_GAIN] = {
> > +		.size		= sizeof(struct rkisp1_ext_params_awb_gain_config),
> > +	},
> > +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_FLT] = {
> > +		.size		= sizeof(struct rkisp1_ext_params_flt_config),
> > +	},
> > +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_BDM] = {
> > +		.size		= sizeof(struct rkisp1_ext_params_bdm_config),
> > +	},
> > +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_CTK] = {
> > +		.size		= sizeof(struct rkisp1_ext_params_ctk_config),
> > +	},
> > +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_GOC] = {
> > +		.size		= sizeof(struct rkisp1_ext_params_goc_config),
> > +	},
> > +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF] = {
> > +		.size		= sizeof(struct rkisp1_ext_params_dpf_config),
> > +	},
> > +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF_STRENGTH] = {
> > +		.size		= sizeof(struct rkisp1_ext_params_dpf_strength_config),
> > +	},
> > +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_CPROC] = {
> > +		.size		= sizeof(struct rkisp1_ext_params_cproc_config),
> > +	},
> > +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_IE] = {
> > +		.size		= sizeof(struct rkisp1_ext_params_ie_config),
> > +	},
> > +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_LSC] = {
> > +		.size		= sizeof(struct rkisp1_ext_params_lsc_config),
> > +	},
> > +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_MEAS] = {
> > +		.size		= sizeof(struct rkisp1_ext_params_awb_meas_config),
> > +	},
> > +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_HST_MEAS] = {
> > +		.size		= sizeof(struct rkisp1_ext_params_hst_config),
> > +	},
> > +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_AEC_MEAS] = {
> > +		.size		= sizeof(struct rkisp1_ext_params_aec_config),
> > +	},
> > +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_AFC_MEAS] = {
> > +		.size		= sizeof(struct rkisp1_ext_params_afc_config),
> > +	},
> > +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_BLS] = {
> > +		.size		= sizeof(struct rkisp1_ext_params_compand_bls_config),
> > +	},
> > +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_EXPAND] = {
> > +		.size		= sizeof(struct rkisp1_ext_params_compand_curve_config),
> > +	},
> > +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_COMPRESS] = {
> > +		.size		= sizeof(struct rkisp1_ext_params_compand_curve_config),
> > +	},
> > +	[RKISP1_EXT_PARAMS_BLOCK_TYPE_WDR] = {
> > +		.size		= sizeof(struct rkisp1_ext_params_wdr_config),
> > +	},
>
> We could make this more compact with
>
> #define RKISP1_PARAMS_BLOCK_INFO(block, data) \
> 	[RKISP1_EXT_PARAMS_BLOCK_TYPE_ ## block] = { \
> 		.size = sizeof(struct rkisp1_ext_params_ ## data ## _config), \
> 	}
>
> 	RKISP1_PARAMS_BLOCK_INFO(BLS, bls),
> 	RKISP1_PARAMS_BLOCK_INFO(DPCC, dpcc),
> 	RKISP1_PARAMS_BLOCK_INFO(SDG, sdg),
> 	RKISP1_PARAMS_BLOCK_INFO(AWB_GAIN, awb_gain),
> 	RKISP1_PARAMS_BLOCK_INFO(FLT, flt),
> 	RKISP1_PARAMS_BLOCK_INFO(BDM, bdm),
> 	RKISP1_PARAMS_BLOCK_INFO(CTK, ctk),
> 	RKISP1_PARAMS_BLOCK_INFO(GOC, goc),
> 	RKISP1_PARAMS_BLOCK_INFO(DPF, dpf),
> 	RKISP1_PARAMS_BLOCK_INFO(DPF_STRENGTH, dpf_strength),
> 	RKISP1_PARAMS_BLOCK_INFO(CPROC, cproc),
> 	RKISP1_PARAMS_BLOCK_INFO(IE, ie),
> 	RKISP1_PARAMS_BLOCK_INFO(LSC, lsc),
> 	RKISP1_PARAMS_BLOCK_INFO(AWB_MEAS, awb_meas),
> 	RKISP1_PARAMS_BLOCK_INFO(HST_MEAS, hst),
> 	RKISP1_PARAMS_BLOCK_INFO(AEC_MEAS, aec),
> 	RKISP1_PARAMS_BLOCK_INFO(AFC_MEAS, afc),
> 	RKISP1_PARAMS_BLOCK_INFO(COMPAND_BLS, compand_bls),
> 	RKISP1_PARAMS_BLOCK_INFO(COMPAND_EXPAND, compand_curve),
> 	RKISP1_PARAMS_BLOCK_INFO(COMPAND_COMPRESS, compand_curve),
> 	RKISP1_PARAMS_BLOCK_INFO(WDR, wdr),
>
> It helped me quickly visualize that the block types and data types
> matched, so I think it could help reviews when adding new blocks.
>
> This can also be done in a patch on top. Same for the c3-isp driver.
>
> Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

Nicer, thanks.

I've also added (here and in the C3 driver)

static_assert(ARRAY_SIZE(rkisp1_ext_params_handlers) ==
              ARRAY_SIZE(rkisp1_ext_params_blocks_info));

>
> > +};
> > +
> >  static void rkisp1_ext_params_config(struct rkisp1_params *params,
> >  				     struct rkisp1_ext_params_cfg *cfg,
> >  				     u32 block_group_mask)
> > @@ -2646,31 +2691,16 @@ static int rkisp1_params_prepare_ext_params(struct rkisp1_params *params,
> >  {
> >  	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
> >  	struct rkisp1_params_buffer *params_buf = to_rkisp1_params_buffer(vbuf);
> > -	size_t header_size = offsetof(struct rkisp1_ext_params_cfg, data);
> >  	struct rkisp1_ext_params_cfg *cfg = params_buf->cfg;
> >  	size_t payload_size = vb2_get_plane_payload(vb, 0);
> >  	struct rkisp1_ext_params_cfg *usr_cfg =
> >  		vb2_plane_vaddr(&vbuf->vb2_buf, 0);
> > -	size_t block_offset = 0;
> > -	size_t cfg_size;
> > -
> > -	/*
> > -	 * Validate the buffer payload size before copying the parameters. The
> > -	 * payload has to be smaller than the destination buffer size and larger
> > -	 * than the header size.
> > -	 */
> > -	if (payload_size > params->metafmt->buffersize) {
> > -		dev_dbg(params->rkisp1->dev,
> > -			"Too large buffer payload size %zu\n", payload_size);
> > -		return -EINVAL;
> > -	}
> > +	int ret;
> >
> > -	if (payload_size < header_size) {
> > -		dev_dbg(params->rkisp1->dev,
> > -			"Buffer payload %zu smaller than header size %zu\n",
> > -			payload_size, header_size);
> > -		return -EINVAL;
> > -	}
> > +	ret = v4l2_isp_params_validate_buffer_size(params->rkisp1->dev, vb,
> > +						   params->metafmt->buffersize);
> > +	if (ret)
> > +		return ret;
> >
> >  	/*
> >  	 * Copy the parameters buffer to the internal scratch buffer to avoid
> > @@ -2678,71 +2708,10 @@ static int rkisp1_params_prepare_ext_params(struct rkisp1_params *params,
> >  	 */
> >  	memcpy(cfg, usr_cfg, payload_size);
> >
> > -	/* Only v1 is supported at the moment. */
> > -	if (cfg->version != RKISP1_EXT_PARAM_BUFFER_V1) {
> > -		dev_dbg(params->rkisp1->dev,
> > -			"Unsupported extensible format version: %u\n",
> > -			cfg->version);
> > -		return -EINVAL;
> > -	}
> > -
> > -	/* Validate the size reported in the parameters buffer header. */
> > -	cfg_size = header_size + cfg->data_size;
> > -	if (cfg_size != payload_size) {
> > -		dev_dbg(params->rkisp1->dev,
> > -			"Data size %zu different than buffer payload size %zu\n",
> > -			cfg_size, payload_size);
> > -		return -EINVAL;
> > -	}
> > -
> > -	/* Walk the list of parameter blocks and validate them. */
> > -	cfg_size = cfg->data_size;
> > -	while (cfg_size >= sizeof(struct rkisp1_ext_params_block_header)) {
> > -		const struct rkisp1_ext_params_block_header *block;
> > -		const struct rkisp1_ext_params_handler *handler;
> > -
> > -		block = (const struct rkisp1_ext_params_block_header *)
> > -			&cfg->data[block_offset];
> > -
> > -		if (block->type >= ARRAY_SIZE(rkisp1_ext_params_handlers)) {
> > -			dev_dbg(params->rkisp1->dev,
> > -				"Invalid parameters block type\n");
> > -			return -EINVAL;
> > -		}
> > -
> > -		if (block->size > cfg_size) {
> > -			dev_dbg(params->rkisp1->dev,
> > -				"Premature end of parameters data\n");
> > -			return -EINVAL;
> > -		}
> > -
> > -		if ((block->flags & (RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE |
> > -				     RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE)) ==
> > -		   (RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE |
> > -		    RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE)) {
> > -			dev_dbg(params->rkisp1->dev,
> > -				"Invalid parameters block flags\n");
> > -			return -EINVAL;
> > -		}
> > -
> > -		handler = &rkisp1_ext_params_handlers[block->type];
> > -		if (block->size != handler->size) {
> > -			dev_dbg(params->rkisp1->dev,
> > -				"Invalid parameters block size\n");
> > -			return -EINVAL;
> > -		}
> > -
> > -		block_offset += block->size;
> > -		cfg_size -= block->size;
> > -	}
> > -
> > -	if (cfg_size) {
> > -		dev_dbg(params->rkisp1->dev,
> > -			"Unexpected data after the parameters buffer end\n");
> > -		return -EINVAL;
> > -	}
> > -
> > -	return 0;
> > +	return v4l2_isp_params_validate_buffer(params->rkisp1->dev, vb,
> > +				(struct v4l2_isp_params_buffer *)cfg,
> > +				rkisp1_ext_params_blocks_info,
> > +				ARRAY_SIZE(rkisp1_ext_params_blocks_info));
> >  }
> >
> >  static int rkisp1_params_vb2_buf_prepare(struct vb2_buffer *vb)
>
> --
> Regards,
>
> Laurent Pinchart


From jacopo.mondi at ideasonboard.com  Sat Nov  8 00:59:51 2025
From: jacopo.mondi at ideasonboard.com (Jacopo Mondi)
Date: Sat, 8 Nov 2025 09:59:51 +0100
Subject: [PATCH v8 4/8] media: Documentation: uapi: Add V4L2 ISP
 documentation
In-Reply-To: <20251108001713.GL5558@pendragon.ideasonboard.com>
References: <20251020-extensible-parameters-validation-v8-0-afba4ba7b42d@ideasonboard.com>
 <20251020-extensible-parameters-validation-v8-4-afba4ba7b42d@ideasonboard.com>
 <20251108001713.GL5558@pendragon.ideasonboard.com>
Message-ID: <ochkz2axakkaqv6ygqwfackxh37nmelcu45d3g6cpmh3dxxjmf@mg6jlfyb62iv>

Hi Laurent

On Sat, Nov 08, 2025 at 02:17:13AM +0200, Laurent Pinchart wrote:
> Hi Jacopo,
>
> Thank you for the patch.
>
> On Mon, Oct 20, 2025 at 10:24:50AM +0200, Jacopo Mondi wrote:
> > Add userspace documentation for V4L2 ISP generic parameters and
> > statistics formats.
> >
> > Reviewed-by: Daniel Scally <dan.scally at ideasonboard.com>
> > Reviewed-by: Michael Riesch <michael.riesch at collabora.com>
> > Acked-by: Sakari Ailus <sakari.ailus at linux.intel.com>
> > Signed-off-by: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
> > ---
> >  .../userspace-api/media/v4l/meta-formats.rst       |   1 +
> >  Documentation/userspace-api/media/v4l/v4l2-isp.rst | 120 +++++++++++++++++++++
> >  MAINTAINERS                                        |   1 +
> >  3 files changed, 122 insertions(+)
> >
> > diff --git a/Documentation/userspace-api/media/v4l/meta-formats.rst b/Documentation/userspace-api/media/v4l/meta-formats.rst
> > index d9868ee88a0717c1acaa4ee477eaed96a6411f73..7b758ea9eb4ac3c4b354bf8e2f319985ed9e2b37 100644
> > --- a/Documentation/userspace-api/media/v4l/meta-formats.rst
> > +++ b/Documentation/userspace-api/media/v4l/meta-formats.rst
> > @@ -25,3 +25,4 @@ These formats are used for the :ref:`metadata` interface only.
> >      metafmt-vivid
> >      metafmt-vsp1-hgo
> >      metafmt-vsp1-hgt
> > +    v4l2-isp
> > diff --git a/Documentation/userspace-api/media/v4l/v4l2-isp.rst b/Documentation/userspace-api/media/v4l/v4l2-isp.rst
> > new file mode 100644
> > index 0000000000000000000000000000000000000000..b53df722ed29117c3827314e844fc4de61343f40
> > --- /dev/null
> > +++ b/Documentation/userspace-api/media/v4l/v4l2-isp.rst
> > @@ -0,0 +1,120 @@
> > +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
> > +
> > +.. _v4l2-isp:
> > +
> > +************************
> > +Generic V4L2 ISP formats
> > +************************
> > +
> > +ISP configuration and statistics: theory of operations
> > +======================================================
> > +
> > +ISP configuration parameters are computed by userspace and programmed into a
> > +*parameters buffer* which is queued to the ISP driver on a per-frame basis.
> > +
> > +ISP statistics are collected at a specific time point and drivers use them to
> > +populate a *statistics buffer* which is then returned to userspace.
> > +
> > +The parameters and statistics buffers are organized in a driver-specific
> > +way, and their data layout differs between one driver and another.
> > +
> > +ISP drivers generally exchange parameters and statistics with userspace through
> > +a metadata output and capture node respectively, implementing the
> > +:c:type:`v4l2_meta_format` interface. Each ISP driver defines one metadata
> > +capture format and one metadata output format to be used on those video nodes,
> > +and the buffer content layout and organization is fixed by the format definition.
> > +
> > +The uAPI/ABI problem
> > +--------------------
> > +
> > +By upstreaming the metadata formats that describe the parameters and statistics
> > +buffers layout, driver developers make them part of the Linux kernel ABI. As for
> > +most peripherals, ISP driver development in Linux is often an iterative process,
> > +in which not all of the hardware features are supported in the first version.
> > +
> > +The support for new features and/or bug fixes may land in the kernel at a later
> > +stage and require changes to the metadata formats definition. This is
> > +considered an ABI breakage that is strictly forbidden by the Linux kernel
> > +policies. For this reason, any change in the ISP parameters and statistics
> > +buffer layout would require defining a new metadata format.
> > +
> > +For these reasons Video4Linux2 has introduced support for generic ISP parameters
> > +and statistics data types, designed with the goal of being:
> > +
> > +- Extensible: new features can be added later on without breaking the existing
> > +  interface
> > +- Versioned: different versions of the format can be defined without
> > +  breaking the existing interface
> > +
> > +ISP configuration
> > +=================
> > +
> > +Before the introduction of generic formats
> > +------------------------------------------
> > +
> > +Metadata output formats that describe ISP configuration parameters were
> > +typically realized by defining C structures that reflect the ISP registers
> > +layout and get populated by userspace before queueing the buffer to the ISP.
> > +Each C structure usually corresponds to one ISP *processing block*, with each
> > +block implementing one of the ISP supported features.
> > +
> > +The number of supported ISP blocks, the layout of their configuration data are
> > +fixed by the format definition, incurring in the above described uAPI/uABI
> > +problem.
> > +
> > +Generic ISP parameters
> > +----------------------
> > +
>
> Most of the text above is a design rationale that in my opinion doesn't
> belong to the UAPI documentation. You already include a design rationale

mm, you're right, I'll drop it

> in the kernel documentation, in patch 8/8. If some of the text above
> contains a more verbose explanation, it could be moved there.

I think it's fine

>
> I would shorten all this to
>
> ************************
> Generic V4L2 ISP formats
> ************************
>
> Generic ISP formats are metadata formats that define a mechanism to pass ISP
> parameters and statistics between userspace and drivers in V4L2 buffers. They
> are designed to allow extending the data in a backward-compatible way.
>
> ISP configuration
> =================

Now re-organized as

************************
Generic V4L2 ISP formats
************************

ISP parameters
=================

ISP Block enabling, disabling and configuration
-----------------------------------------------

ISP statistics
==============

V4L2 ISP uAPI data types
========================

>
> > +The generic ISP configuration parameters format is realized by a defining a
> > +single C structure that contains a header, followed by a binary buffer where
> > +userspace programs a variable number of ISP configuration data block, one for
> > +each supported ISP feature.
> > +
> > +The :c:type:`v4l2_isp_params_buffer` structure defines the parameters buffer
> > +header which is followed by a binary buffer of ISP configuration parameters.
> > +Userspace shall correctly populate the buffer header with the versioning
>
> s/versioning information/extensible parameters format version/


Thanks, I tried in the last versions to avoid the term "extensible"
and I've used "generic" everywhere I could.

I have reworded this as it follows to avoid repeating 'parameters' 3
times in a single paragraph:

The :c:type:`v4l2_isp_params_buffer` structure defines the buffer header which
is followed by a binary buffer of ISP configuration data. Userspace shall
correctly populate the buffer header with the generic parameters format version
and with the size (in bytes) of the binary data buffer where it will store the
ISP blocks configuration.

>
> > +information and with the size (in bytes) of the binary data buffer where it will
> > +store the ISP blocks configuration.
> > +
> > +Each *ISP configuration block* is preceded by an header implemented by the
> > +:c:type:`v4l2_isp_params_block_header` structure, followed by the configuration
> > +parameters for that specific block, defined by the ISP driver specific data
> > +types.
> > +
> > +Userspace applications are responsible for correctly populating each block's
> > +header fields (type, flags and size) and the block-specific parameters.
> > +
> > +ISP Block enabling, disabling and configuration
> > +-----------------------------------------------
> > +
> > +When userspace wants to configure and enable an ISP block it shall fully
> > +populate the block configuration and set the V4L2_ISP_PARAMS_FL_BLOCK_ENABLE
> > +bit in the block header's `flags` field.
> > +
> > +When userspace simply wants to disable an ISP block the
> > +V4L2_ISP_PARAMS_FL_BLOCK_DISABLE bit should be set in block header's `flags`
> > +field. Drivers accept a configuration parameters block with no additional
> > +data after the header in this case.
> > +
> > +If the configuration of an already active ISP block has to be updated,
> > +userspace shall fully populate the ISP block parameters and omit setting the
> > +V4L2_ISP_PARAMS_FL_BLOCK_ENABLE and V4L2_ISP_PARAMS_FL_BLOCK_DISABLE bits in the
> > +header's `flags` field.
> > +
> > +Setting both the V4L2_ISP_PARAMS_FL_BLOCK_ENABLE and
> > +V4L2_ISP_PARAMS_FL_BLOCK_DISABLE bits in the flags field is not allowed and not
> > +accepted.
>
> s/and not accepted/and returns an error/
>
> > +
> > +Any further extension to the parameters layout that happens after the ISP driver
>
> s/Any further extension/Extensions/
>
> > +has been merged in Linux can be implemented by adding new blocks definition
>
> s/after the ISP driver has been merged in Linux //

Reworded as

Extension to the parameters format can be implemented by adding new blocks
definition without invalidating the existing ones.

>
> Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas at ideasonboard.com>

Thanks
  j

>
> > +without invalidating the existing ones.
> > +
> > +ISP statistics
> > +==============
> > +
> > +Support for generic statistics format is not yet implemented in Video4Linux2.
> > +
> > +V4L2 ISP uAPI data types
> > +========================
> > +
> > +.. kernel-doc:: include/uapi/linux/media/v4l2-isp.h
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index d925745077f21e5a1388a30217a24beeb4fff3b5..f52237d57710cadff78b297d2b4610b508f55092 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -26856,6 +26856,7 @@ V4L2 GENERIC ISP PARAMETERS AND STATISTIC FORMATS
> >  M:	Jacopo Mondi <jacopo.mondi at ideasonboard.com>
> >  L:	linux-media at vger.kernel.org
> >  S:	Maintained
> > +F:	Documentation/userspace-api/media/v4l/v4l2-isp.rst
> >  F:	include/uapi/linux/media/v4l2-isp.h
> >
> >  VF610 NAND DRIVER
>
> --
> Regards,
>
> Laurent Pinchart


From jacopo.mondi at ideasonboard.com  Sat Nov  8 01:36:21 2025
From: jacopo.mondi at ideasonboard.com (Jacopo Mondi)
Date: Sat, 08 Nov 2025 10:36:21 +0100
Subject: [PATCH v9 0/8] media: Introduce V4L2 generic ISP support
Message-ID: <20251108-extensible-parameters-validation-v9-0-6a7e22aa57d0@ideasonboard.com>

Extensible parameters meta formats have been introduced in the Linux
kernel v6.12 initially to support different revision of the RkISP1 ISP
implemented in different SoC. In order to avoid breaking userspace
everytime an ISP configuration block is added or modified in the uAPI
these new formats, which are versionated and extensible by their
definition have been introduced.

See for reference:
e9d05e9d5db1 ("media: uapi: rkisp1-config: Add extensible params format")
6c53a7b68c5d ("media: rkisp1: Implement extensible params support")

The Amlogic C3 ISP driver followed shortly, introducing an extensible
format for the ISP configuration:

6d406187ebc0 ("media: uapi: Add stats info and parameters buffer for C3 ISP")

with a very similar, if not identical, implementation of the routines to
validate and handle the ISP configuration in the ISP driver in the
c3-isp-params.c file.

fb2e135208f3 ("media: platform: Add C3 ISP driver")

With the recent upstreaming attempt of the Mali C55 ISP driver from Dan,
a third user of extensible parameters is going to be itroduced in the
kernel, duplicating again in the driver the procedure for validating and
handling the ISP configuration blocks

https://patchwork.linuxtv.org/project/linux-media/patch/20250624-c55-v10-15-54f3d4196990 at ideasonboard.com/

To avoid duplicating again the validation routines and common types
definition, this series introduces v4l2-isp.c/.h for the kAPI
and v4l2-isp.h for the uAPI and re-organize the RkISP1
and Amlogic C3 drivers to use the common types and the helper validation
routines.

The v4l2-isp abstraction will be augmented to support statistcs as well.

If the here proposed approach is accepted, I propose to rebase the Mali
C55 driver on top of this series, to use the new common types and
helpers.

Tested on Mali C55 and RkISP1 with camshark

Thanks
  j

Signed-off-by: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
---
Changes in v9:
- Modify the RkISP1 and C3 params drivers to enumerate their block info
  with macros (and static_assert they're of the correct size)
- Modify documentation according to Laurent's suggestion
- Link to v8: https://lore.kernel.org/r/20251020-extensible-parameters-validation-v8-0-afba4ba7b42d at ideasonboard.com

Changes in v8:
- Address Michael comments and reword documentation
- Use the correct "metadata capture" for stats and "metadata output" for
  parameters. I mixed up the two in the previous revisions.
- Link to v7: https://lore.kernel.org/r/20251014-extensible-parameters-validation-v7-0-6628bed5ca98 at ideasonboard.com

Changes in v7:
- Moved version to the v4l2-isp uAPI
- Moved version check to the v4l2-isp.c helpers
- Link to v6: https://lore.kernel.org/r/20251007-extensible-parameters-validation-v6-0-5f719d9f39e5 at ideasonboard.com

Changes in v6:
- Rename all symbols to v4l2_isp
- Changed the interface of the two buffer validation functions
- Reworked the rkisp1 and c3 porting accordingly
- Updated documentation
- I have moved v4l2_params_buffer_size() from uAPI because it was
  convenient for linux but not required in userspace
- Link to v5: https://lore.kernel.org/r/20250915-extensible-parameters-validation-v5-0-e6db94468af3 at ideasonboard.com

Changes in v5:
- Move everything to v4l2-isp prefix except from format documentation
  which still is about 'extensible-parameters' (to be paired in future
  with extensbile-stats)
- Simplify documentation and move it part to the driver-api
  Documentation
- Remove 'group' and 'features' from the generic handlers definition and
  adjust rkisp1 accordingly
- Link to v4: https://lore.kernel.org/r/20250820-extensible-parameters-validation-v4-0-30fe5a99cb1f at ideasonboard.com

Changes in v4:
- Fix the definition of V4L2_PARAMS_FL_PLATFORM_FLAGS
- Add __counted_by() attribute to the data[] flexible-array member of
  v4l2_params_buffer
- Minor style change
- Link to v3: https://lore.kernel.org/r/20250819-extensible-parameters-validation-v3-0-9dc008348b30 at ideasonboard.com

Changes in v3:
- Rebased on latest media-committers/next
- Take in Dan's suggestion in block size validation
- Documentation minor spelling fixes
- Link to v2: https://lore.kernel.org/r/20250710-extensible-parameters-validation-v2-0-7ec8918ec443 at ideasonboard.com

Changes in v2:
- Make v4l2_params_buffer directly usable
- Centralize ENABLE/DISABLE flags definition and validation
- Take in Dan's v4l2_params_buffer_size()
- Allow blocks to only contain the header if they're going to be
  disabled
- Documentation fixes as reported by Nicolas
- Link to v1: https://lore.kernel.org/r/20250708-extensible-parameters-validation-v1-0-9fc27c9c728c at ideasonboard.com

---
Jacopo Mondi (8):
      media: uapi: Introduce V4L2 generic ISP types
      media: uapi: Convert RkISP1 to V4L2 extensible params
      media: uapi: Convert Amlogic C3 to V4L2 extensible params
      media: Documentation: uapi: Add V4L2 ISP documentation
      media: v4l2-core: Introduce v4l2-isp.c
      media: rkisp1: Use v4l2-isp for validation
      media: amlogic-c3: Use v4l2-isp for validation
      media: Documentation: kapi: Add v4l2 generic ISP support

 Documentation/driver-api/media/v4l2-core.rst       |   1 +
 Documentation/driver-api/media/v4l2-isp.rst        |  49 ++++++
 .../userspace-api/media/v4l/meta-formats.rst       |   1 +
 Documentation/userspace-api/media/v4l/v4l2-isp.rst |  67 +++++++++
 MAINTAINERS                                        |  10 ++
 drivers/media/platform/amlogic/c3/isp/Kconfig      |   1 +
 .../media/platform/amlogic/c3/isp/c3-isp-params.c  | 165 ++++++---------------
 drivers/media/platform/rockchip/rkisp1/Kconfig     |   1 +
 .../media/platform/rockchip/rkisp1/rkisp1-params.c | 150 ++++++-------------
 drivers/media/v4l2-core/Kconfig                    |   4 +
 drivers/media/v4l2-core/Makefile                   |   1 +
 drivers/media/v4l2-core/v4l2-isp.c                 | 128 ++++++++++++++++
 include/media/v4l2-isp.h                           |  91 ++++++++++++
 include/uapi/linux/media/amlogic/c3-isp-config.h   |  92 +++---------
 include/uapi/linux/media/v4l2-isp.h                | 102 +++++++++++++
 include/uapi/linux/rkisp1-config.h                 | 107 +++----------
 16 files changed, 590 insertions(+), 380 deletions(-)
---
base-commit: b4fbb13db86adb0bae1d7f968b61ea8dc9635e33
change-id: 20250701-extensible-parameters-validation-c831f7f5cc0b

Best regards,
-- 
Jacopo Mondi <jacopo.mondi at ideasonboard.com>



From jacopo.mondi at ideasonboard.com  Sat Nov  8 01:36:22 2025
From: jacopo.mondi at ideasonboard.com (Jacopo Mondi)
Date: Sat, 08 Nov 2025 10:36:22 +0100
Subject: [PATCH v9 1/8] media: uapi: Introduce V4L2 generic ISP types
In-Reply-To: <20251108-extensible-parameters-validation-v9-0-6a7e22aa57d0@ideasonboard.com>
References: <20251108-extensible-parameters-validation-v9-0-6a7e22aa57d0@ideasonboard.com>
Message-ID: <20251108-extensible-parameters-validation-v9-1-6a7e22aa57d0@ideasonboard.com>

Introduce v4l2-isp.h in the Linux kernel uAPI.

The header includes types for generic ISP configuration parameters
and will be extended in the future with support for generic ISP statistics
formats.

Generic ISP parameters support is provided by introducing two new
types that represent an extensible and versioned buffer of ISP
configuration parameters.

The v4l2_params_buffer represents the container for the ISP
configuration data block. The generic type is defined with a 0-sized
data member that the ISP driver implementations shall properly size
according to their capabilities. The v4l2_params_block_header structure
represents the header to be prepend to each ISP configuration block.

Signed-off-by: Daniel Scally <dan.scally at ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally at ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas at ideasonboard.com>
Reviewed-by: Michael Riesch <michael.riesch at collabora.com>
Acked-by: Sakari Ailus <sakari.ailus at linux.intel.com>
Tested-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
---
 MAINTAINERS                         |   6 +++
 include/uapi/linux/media/v4l2-isp.h | 102 ++++++++++++++++++++++++++++++++++++
 2 files changed, 108 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 8aec054a6ac7280d11356737787d4b63a4bd5584..8989e7e00d86d0c13c4c0b7e5c7eb9481b65861f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -26855,6 +26855,12 @@ F:	drivers/media/i2c/vd55g1.c
 F:	drivers/media/i2c/vd56g3.c
 F:	drivers/media/i2c/vgxy61.c
 
+V4L2 GENERIC ISP PARAMETERS AND STATISTIC FORMATS
+M:	Jacopo Mondi <jacopo.mondi at ideasonboard.com>
+L:	linux-media at vger.kernel.org
+S:	Maintained
+F:	include/uapi/linux/media/v4l2-isp.h
+
 VF610 NAND DRIVER
 M:	Stefan Agner <stefan at agner.ch>
 L:	linux-mtd at lists.infradead.org
diff --git a/include/uapi/linux/media/v4l2-isp.h b/include/uapi/linux/media/v4l2-isp.h
new file mode 100644
index 0000000000000000000000000000000000000000..779168f9058e3bcf6451f681e247d34d95676cc0
--- /dev/null
+++ b/include/uapi/linux/media/v4l2-isp.h
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+ * Video4Linux2 generic ISP parameters and statistics support
+ *
+ * Copyright (C) 2025 Ideas On Board Oy
+ * Author: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
+ */
+
+#ifndef _UAPI_V4L2_ISP_H_
+#define _UAPI_V4L2_ISP_H_
+
+#include <linux/stddef.h>
+#include <linux/types.h>
+
+/**
+ * enum v4l2_isp_params_version - V4L2 ISP parameters versioning
+ *
+ * @V4L2_ISP_PARAMS_VERSION_V0: First version of the V4L2 ISP parameters format
+ *				(for compatibility)
+ * @V4L2_ISP_PARAMS_VERSION_V1: First version of the V4L2 ISP parameters format
+ *
+ * V0 and V1 are identical in order to support drivers compatible with the V4L2
+ * ISP parameters format already upstreamed which use either 0 or 1 as their
+ * versioning identifier. Both V0 and V1 refers to the first version of the
+ * V4L2 ISP parameters format.
+ *
+ * Future revisions of the V4L2 ISP parameters format should start from the
+ * value of 2.
+ */
+enum v4l2_isp_params_version {
+	V4L2_ISP_PARAMS_VERSION_V0 = 0,
+	V4L2_ISP_PARAMS_VERSION_V1
+};
+
+#define V4L2_ISP_PARAMS_FL_BLOCK_DISABLE	(1U << 0)
+#define V4L2_ISP_PARAMS_FL_BLOCK_ENABLE		(1U << 1)
+
+/*
+ * Reserve the first 8 bits for V4L2_ISP_PARAMS_FL_* flag.
+ *
+ * Driver-specific flags should be defined as:
+ * #define DRIVER_SPECIFIC_FLAG0     ((1U << V4L2_ISP_PARAMS_FL_DRIVER_FLAGS(0))
+ * #define DRIVER_SPECIFIC_FLAG1     ((1U << V4L2_ISP_PARAMS_FL_DRIVER_FLAGS(1))
+ */
+#define V4L2_ISP_PARAMS_FL_DRIVER_FLAGS(n)       ((n) + 8)
+
+/**
+ * struct v4l2_isp_params_block_header - V4L2 extensible parameters block header
+ * @type: The parameters block type (driver-specific)
+ * @flags: A bitmask of block flags (driver-specific)
+ * @size: Size (in bytes) of the parameters block, including this header
+ *
+ * This structure represents the common part of all the ISP configuration
+ * blocks. Each parameters block shall embed an instance of this structure type
+ * as its first member, followed by the block-specific configuration data.
+ *
+ * The @type field is an ISP driver-specific value that identifies the block
+ * type. The @size field specifies the size of the parameters block.
+ *
+ * The @flags field is a bitmask of per-block flags V4L2_PARAMS_ISP_FL_* and
+ * driver-specific flags specified by the driver header.
+ */
+struct v4l2_isp_params_block_header {
+	__u16 type;
+	__u16 flags;
+	__u32 size;
+} __attribute__((aligned(8)));
+
+/**
+ * struct v4l2_isp_params_buffer - V4L2 extensible parameters configuration
+ * @version: The parameters buffer version (driver-specific)
+ * @data_size: The configuration data effective size, excluding this header
+ * @data: The configuration data
+ *
+ * This structure contains the configuration parameters of the ISP algorithms,
+ * serialized by userspace into a data buffer. Each configuration parameter
+ * block is represented by a block-specific structure which contains a
+ * :c:type:`v4l2_isp_params_block_header` entry as first member. Userspace
+ * populates the @data buffer with configuration parameters for the blocks that
+ * it intends to configure. As a consequence, the data buffer effective size
+ * changes according to the number of ISP blocks that userspace intends to
+ * configure and is set by userspace in the @data_size field.
+ *
+ * The parameters buffer is versioned by the @version field to allow modifying
+ * and extending its definition. Userspace shall populate the @version field to
+ * inform the driver about the version it intends to use. The driver will parse
+ * and handle the @data buffer according to the data layout specific to the
+ * indicated version and return an error if the desired version is not
+ * supported.
+ *
+ * For each ISP block that userspace wants to configure, a block-specific
+ * structure is appended to the @data buffer, one after the other without gaps
+ * in between. Userspace shall populate the @data_size field with the effective
+ * size, in bytes, of the @data buffer.
+ */
+struct v4l2_isp_params_buffer {
+	__u32 version;
+	__u32 data_size;
+	__u8 data[] __counted_by(data_size);
+};
+
+#endif /* _UAPI_V4L2_ISP_H_ */

-- 
2.51.0



From jacopo.mondi at ideasonboard.com  Sat Nov  8 01:36:23 2025
From: jacopo.mondi at ideasonboard.com (Jacopo Mondi)
Date: Sat, 08 Nov 2025 10:36:23 +0100
Subject: [PATCH v9 2/8] media: uapi: Convert RkISP1 to V4L2 extensible
 params
In-Reply-To: <20251108-extensible-parameters-validation-v9-0-6a7e22aa57d0@ideasonboard.com>
References: <20251108-extensible-parameters-validation-v9-0-6a7e22aa57d0@ideasonboard.com>
Message-ID: <20251108-extensible-parameters-validation-v9-2-6a7e22aa57d0@ideasonboard.com>

With the introduction of common types for extensible parameters
format, convert the rkisp1-config.h header to use the new types.

Factor out the documentation that is now part of the common header
and only keep the driver-specific on in place.

The conversion to use common types doesn't impact userspace as the
new types are either identical to the ones already existing in the
RkISP1 uAPI or are 1-to-1 type convertible.

Reviewed-by: Daniel Scally <dan.scally at ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas at ideasonboard.com>
Reviewed-by: Michael Riesch <michael.riesch at collabora.com>
Acked-by: Sakari Ailus <sakari.ailus at linux.intel.com>
Tested-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
---
 include/uapi/linux/rkisp1-config.h | 107 +++++++++----------------------------
 1 file changed, 24 insertions(+), 83 deletions(-)

diff --git a/include/uapi/linux/rkisp1-config.h b/include/uapi/linux/rkisp1-config.h
index 3b060ea6eed71b87d79abc8401eae4e9c9f5323a..b2d2a71f7baff3833b20519264b58db7f168af90 100644
--- a/include/uapi/linux/rkisp1-config.h
+++ b/include/uapi/linux/rkisp1-config.h
@@ -7,8 +7,13 @@
 #ifndef _UAPI_RKISP1_CONFIG_H
 #define _UAPI_RKISP1_CONFIG_H
 
+#ifdef __KERNEL__
+#include <linux/build_bug.h>
+#endif /* __KERNEL__ */
 #include <linux/types.h>
 
+#include <linux/media/v4l2-isp.h>
+
 /* Defect Pixel Cluster Detection */
 #define RKISP1_CIF_ISP_MODULE_DPCC		(1U << 0)
 /* Black Level Subtraction */
@@ -1158,79 +1163,26 @@ enum rkisp1_ext_params_block_type {
 	RKISP1_EXT_PARAMS_BLOCK_TYPE_WDR,
 };
 
-#define RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE	(1U << 0)
-#define RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE	(1U << 1)
+/* For backward compatibility */
+#define RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE	V4L2_ISP_PARAMS_FL_BLOCK_DISABLE
+#define RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE	V4L2_ISP_PARAMS_FL_BLOCK_ENABLE
 
 /* A bitmask of parameters blocks supported on the current hardware. */
 #define RKISP1_CID_SUPPORTED_PARAMS_BLOCKS	(V4L2_CID_USER_RKISP1_BASE + 0x01)
 
 /**
- * struct rkisp1_ext_params_block_header - RkISP1 extensible parameters block
- *					   header
+ * rkisp1_ext_params_block_header - RkISP1 extensible parameters block header
  *
  * This structure represents the common part of all the ISP configuration
- * blocks. Each parameters block shall embed an instance of this structure type
- * as its first member, followed by the block-specific configuration data. The
- * driver inspects this common header to discern the block type and its size and
- * properly handle the block content by casting it to the correct block-specific
- * type.
+ * blocks and is identical to :c:type:`v4l2_isp_params_block_header`.
  *
- * The @type field is one of the values enumerated by
+ * The type field is one of the values enumerated by
  * :c:type:`rkisp1_ext_params_block_type` and specifies how the data should be
- * interpreted by the driver. The @size field specifies the size of the
- * parameters block and is used by the driver for validation purposes.
- *
- * The @flags field is a bitmask of per-block flags RKISP1_EXT_PARAMS_FL_*.
- *
- * When userspace wants to configure and enable an ISP block it shall fully
- * populate the block configuration and set the
- * RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE bit in the @flags field.
- *
- * When userspace simply wants to disable an ISP block the
- * RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE bit should be set in @flags field. The
- * driver ignores the rest of the block configuration structure in this case.
- *
- * If a new configuration of an ISP block has to be applied userspace shall
- * fully populate the ISP block configuration and omit setting the
- * RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE and RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE bits
- * in the @flags field.
- *
- * Setting both the RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE and
- * RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE bits in the @flags field is not allowed
- * and not accepted by the driver.
- *
- * Userspace is responsible for correctly populating the parameters block header
- * fields (@type, @flags and @size) and the block-specific parameters.
- *
- * For example:
+ * interpreted by the driver.
  *
- * .. code-block:: c
- *
- *	void populate_bls(struct rkisp1_ext_params_block_header *block) {
- *		struct rkisp1_ext_params_bls_config *bls =
- *			(struct rkisp1_ext_params_bls_config *)block;
- *
- *		bls->header.type = RKISP1_EXT_PARAMS_BLOCK_ID_BLS;
- *		bls->header.flags = RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE;
- *		bls->header.size = sizeof(*bls);
- *
- *		bls->config.enable_auto = 0;
- *		bls->config.fixed_val.r = blackLevelRed_;
- *		bls->config.fixed_val.gr = blackLevelGreenR_;
- *		bls->config.fixed_val.gb = blackLevelGreenB_;
- *		bls->config.fixed_val.b = blackLevelBlue_;
- *	}
- *
- * @type: The parameters block type, see
- *	  :c:type:`rkisp1_ext_params_block_type`
- * @flags: A bitmask of block flags
- * @size: Size (in bytes) of the parameters block, including this header
+ * The flags field is a bitmask of per-block flags RKISP1_EXT_PARAMS_FL_*.
  */
-struct rkisp1_ext_params_block_header {
-	__u16 type;
-	__u16 flags;
-	__u32 size;
-};
+#define rkisp1_ext_params_block_header v4l2_isp_params_block_header
 
 /**
  * struct rkisp1_ext_params_bls_config - RkISP1 extensible params BLS config
@@ -1588,27 +1540,14 @@ struct rkisp1_ext_params_wdr_config {
  * @RKISP1_EXT_PARAM_BUFFER_V1: First version of RkISP1 extensible parameters
  */
 enum rksip1_ext_param_buffer_version {
-	RKISP1_EXT_PARAM_BUFFER_V1 = 1,
+	RKISP1_EXT_PARAM_BUFFER_V1 = V4L2_ISP_PARAMS_VERSION_V1,
 };
 
 /**
  * struct rkisp1_ext_params_cfg - RkISP1 extensible parameters configuration
  *
- * This struct contains the configuration parameters of the RkISP1 ISP
- * algorithms, serialized by userspace into a data buffer. Each configuration
- * parameter block is represented by a block-specific structure which contains a
- * :c:type:`rkisp1_ext_params_block_header` entry as first member. Userspace
- * populates the @data buffer with configuration parameters for the blocks that
- * it intends to configure. As a consequence, the data buffer effective size
- * changes according to the number of ISP blocks that userspace intends to
- * configure and is set by userspace in the @data_size field.
- *
- * The parameters buffer is versioned by the @version field to allow modifying
- * and extending its definition. Userspace shall populate the @version field to
- * inform the driver about the version it intends to use. The driver will parse
- * and handle the @data buffer according to the data layout specific to the
- * indicated version and return an error if the desired version is not
- * supported.
+ * This is the driver-specific implementation of
+ * :c:type:`v4l2_isp_params_buffer`.
  *
  * Currently the single RKISP1_EXT_PARAM_BUFFER_V1 version is supported.
  * When a new format version will be added, a mechanism for userspace to query
@@ -1624,11 +1563,6 @@ enum rksip1_ext_param_buffer_version {
  * the maximum value represents the blocks supported by the kernel driver,
  * independently of the device instance.
  *
- * For each ISP block that userspace wants to configure, a block-specific
- * structure is appended to the @data buffer, one after the other without gaps
- * in between nor overlaps. Userspace shall populate the @data_size field with
- * the effective size, in bytes, of the @data buffer.
- *
  * The expected memory layout of the parameters buffer is::
  *
  *	+-------------------- struct rkisp1_ext_params_cfg -------------------+
@@ -1678,4 +1612,11 @@ struct rkisp1_ext_params_cfg {
 	__u8 data[RKISP1_EXT_PARAMS_MAX_SIZE];
 };
 
+#ifdef __KERNEL__
+/* Make sure the header is type-convertible to the generic v4l2 params one */
+static_assert((sizeof(struct rkisp1_ext_params_cfg) -
+	      RKISP1_EXT_PARAMS_MAX_SIZE) ==
+	      sizeof(struct v4l2_isp_params_buffer));
+#endif /* __KERNEL__ */
+
 #endif /* _UAPI_RKISP1_CONFIG_H */

-- 
2.51.0



From jacopo.mondi at ideasonboard.com  Sat Nov  8 01:36:24 2025
From: jacopo.mondi at ideasonboard.com (Jacopo Mondi)
Date: Sat, 08 Nov 2025 10:36:24 +0100
Subject: [PATCH v9 3/8] media: uapi: Convert Amlogic C3 to V4L2 extensible
 params
In-Reply-To: <20251108-extensible-parameters-validation-v9-0-6a7e22aa57d0@ideasonboard.com>
References: <20251108-extensible-parameters-validation-v9-0-6a7e22aa57d0@ideasonboard.com>
Message-ID: <20251108-extensible-parameters-validation-v9-3-6a7e22aa57d0@ideasonboard.com>

With the introduction of common types for extensible parameters
format, convert the c3-isp-config.h header to use the new types.

Factor-out the documentation that is now part of the common header
and only keep the driver-specific on in place.

The conversion to use common types doesn't impact userspace as the
new types are either identical to the ones already existing in the
C3 ISP uAPI or are 1-to-1 type convertible.

Reviewed-by: Daniel Scally <dan.scally at ideasonboard.com>
Reviewed-by: Keke Li <keke.li at amlogic.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas at ideasonboard.com>
Acked-by: Sakari Ailus <sakari.ailus at linux.intel.com>
Tested-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
---
 include/uapi/linux/media/amlogic/c3-isp-config.h | 92 +++++++-----------------
 1 file changed, 24 insertions(+), 68 deletions(-)

diff --git a/include/uapi/linux/media/amlogic/c3-isp-config.h b/include/uapi/linux/media/amlogic/c3-isp-config.h
index ed085ea62a574932c7ad8d59d34b2c5c74a597d8..0a3c1cc55ccbbad12f18037d65f32ec9ca1a4ec0 100644
--- a/include/uapi/linux/media/amlogic/c3-isp-config.h
+++ b/include/uapi/linux/media/amlogic/c3-isp-config.h
@@ -6,8 +6,13 @@
 #ifndef _UAPI_C3_ISP_CONFIG_H_
 #define _UAPI_C3_ISP_CONFIG_H_
 
+#ifdef __KERNEL__
+#include <linux/build_bug.h>
+#endif /* __KERNEL__ */
 #include <linux/types.h>
 
+#include <linux/media/v4l2-isp.h>
+
 /*
  * Frames are split into zones of almost equal width and height - a zone is a
  * rectangular tile of a frame. The metering blocks within the ISP collect
@@ -141,7 +146,7 @@ struct c3_isp_stats_info {
  * @C3_ISP_PARAMS_BUFFER_V0: First version of C3 ISP parameters block
  */
 enum c3_isp_params_buffer_version {
-	C3_ISP_PARAMS_BUFFER_V0,
+	C3_ISP_PARAMS_BUFFER_V0 = V4L2_ISP_PARAMS_VERSION_V0,
 };
 
 /**
@@ -176,62 +181,23 @@ enum c3_isp_params_block_type {
 	C3_ISP_PARAMS_BLOCK_SENTINEL
 };
 
-#define C3_ISP_PARAMS_BLOCK_FL_DISABLE (1U << 0)
-#define C3_ISP_PARAMS_BLOCK_FL_ENABLE (1U << 1)
+/* For backward compatibility */
+#define C3_ISP_PARAMS_BLOCK_FL_DISABLE	V4L2_ISP_PARAMS_FL_BLOCK_DISABLE
+#define C3_ISP_PARAMS_BLOCK_FL_ENABLE	V4L2_ISP_PARAMS_FL_BLOCK_ENABLE
 
 /**
  * struct c3_isp_params_block_header - C3 ISP parameter block header
  *
  * This structure represents the common part of all the ISP configuration
- * blocks. Each parameters block shall embed an instance of this structure type
- * as its first member, followed by the block-specific configuration data. The
- * driver inspects this common header to discern the block type and its size and
- * properly handle the block content by casting it to the correct block-specific
- * type.
+ * blocks and is identical to :c:type:`v4l2_isp_params_block_header`.
  *
- * The @type field is one of the values enumerated by
+ * The type field is one of the values enumerated by
  * :c:type:`c3_isp_params_block_type` and specifies how the data should be
- * interpreted by the driver. The @size field specifies the size of the
- * parameters block and is used by the driver for validation purposes. The
- * @flags field is a bitmask of per-block flags C3_ISP_PARAMS_FL*.
- *
- * When userspace wants to disable an ISP block the
- * C3_ISP_PARAMS_BLOCK_FL_DISABLED bit should be set in the @flags field. In
- * this case userspace may optionally omit the remainder of the configuration
- * block, which will be ignored by the driver.
- *
- * When a new configuration of an ISP block needs to be applied userspace
- * shall fully populate the ISP block and omit setting the
- * C3_ISP_PARAMS_BLOCK_FL_DISABLED bit in the @flags field.
- *
- * Userspace is responsible for correctly populating the parameters block header
- * fields (@type, @flags and @size) and the block-specific parameters.
- *
- * For example:
- *
- * .. code-block:: c
+ * interpreted by the driver.
  *
- *	void populate_pst_gamma(struct c3_isp_params_block_header *block) {
- *		struct c3_isp_params_pst_gamma *gamma =
- *			(struct c3_isp_params_pst_gamma *)block;
- *
- *		gamma->header.type = C3_ISP_PARAMS_BLOCK_PST_GAMMA;
- *		gamma->header.flags = C3_ISP_PARAMS_BLOCK_FL_ENABLE;
- *		gamma->header.size = sizeof(*gamma);
- *
- *		for (unsigned int i = 0; i < 129; i++)
- *			gamma->pst_gamma_lut[i] = i;
- *	}
- *
- * @type: The parameters block type from :c:type:`c3_isp_params_block_type`
- * @flags: A bitmask of block flags
- * @size: Size (in bytes) of the parameters block, including this header
+ * The flags field is a bitmask of per-block flags C3_ISP_PARAMS_FL_*.
  */
-struct c3_isp_params_block_header {
-	__u16 type;
-	__u16 flags;
-	__u32 size;
-};
+#define c3_isp_params_block_header v4l2_isp_params_block_header
 
 /**
  * struct c3_isp_params_awb_gains - Gains for auto-white balance
@@ -498,26 +464,10 @@ struct c3_isp_params_blc {
 /**
  * struct c3_isp_params_cfg - C3 ISP configuration parameters
  *
- * This struct contains the configuration parameters of the C3 ISP
- * algorithms, serialized by userspace into an opaque data buffer. Each
- * configuration parameter block is represented by a block-specific structure
- * which contains a :c:type:`c3_isp_param_block_header` entry as first
- * member. Userspace populates the @data buffer with configuration parameters
- * for the blocks that it intends to configure. As a consequence, the data
- * buffer effective size changes according to the number of ISP blocks that
- * userspace intends to configure.
- *
- * The parameters buffer is versioned by the @version field to allow modifying
- * and extending its definition. Userspace should populate the @version field to
- * inform the driver about the version it intends to use. The driver will parse
- * and handle the @data buffer according to the data layout specific to the
- * indicated revision and return an error if the desired revision is not
- * supported.
- *
- * For each ISP block that userspace wants to configure, a block-specific
- * structure is appended to the @data buffer, one after the other without gaps
- * in between nor overlaps. Userspace shall populate the @total_size field with
- * the effective size, in bytes, of the @data buffer.
+ * This is the driver-specific implementation of
+ * :c:type:`v4l2_isp_params_buffer`.
+ *
+ * Currently only C3_ISP_PARAM_BUFFER_V0 is supported.
  *
  * The expected memory layout of the parameters buffer is::
  *
@@ -561,4 +511,10 @@ struct c3_isp_params_cfg {
 	__u8 data[C3_ISP_PARAMS_MAX_SIZE];
 };
 
+#ifdef __KERNEL__
+/* Make sure the header is type-convertible to the generic v4l2 params one */
+static_assert((sizeof(struct c3_isp_params_cfg) - C3_ISP_PARAMS_MAX_SIZE) ==
+	      sizeof(struct v4l2_isp_params_buffer));
+#endif /* __KERNEL__ */
+
 #endif

-- 
2.51.0



From jacopo.mondi at ideasonboard.com  Sat Nov  8 01:36:25 2025
From: jacopo.mondi at ideasonboard.com (Jacopo Mondi)
Date: Sat, 08 Nov 2025 10:36:25 +0100
Subject: [PATCH v9 4/8] media: Documentation: uapi: Add V4L2 ISP
 documentation
In-Reply-To: <20251108-extensible-parameters-validation-v9-0-6a7e22aa57d0@ideasonboard.com>
References: <20251108-extensible-parameters-validation-v9-0-6a7e22aa57d0@ideasonboard.com>
Message-ID: <20251108-extensible-parameters-validation-v9-4-6a7e22aa57d0@ideasonboard.com>

Add userspace documentation for V4L2 ISP generic parameters and
statistics formats.

Reviewed-by: Daniel Scally <dan.scally at ideasonboard.com>
Reviewed-by: Michael Riesch <michael.riesch at collabora.com>
Acked-by: Sakari Ailus <sakari.ailus at linux.intel.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas at ideasonboard.com>
Tested-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
---
 .../userspace-api/media/v4l/meta-formats.rst       |  1 +
 Documentation/userspace-api/media/v4l/v4l2-isp.rst | 67 ++++++++++++++++++++++
 MAINTAINERS                                        |  1 +
 3 files changed, 69 insertions(+)

diff --git a/Documentation/userspace-api/media/v4l/meta-formats.rst b/Documentation/userspace-api/media/v4l/meta-formats.rst
index d9868ee88a0717c1acaa4ee477eaed96a6411f73..7b758ea9eb4ac3c4b354bf8e2f319985ed9e2b37 100644
--- a/Documentation/userspace-api/media/v4l/meta-formats.rst
+++ b/Documentation/userspace-api/media/v4l/meta-formats.rst
@@ -25,3 +25,4 @@ These formats are used for the :ref:`metadata` interface only.
     metafmt-vivid
     metafmt-vsp1-hgo
     metafmt-vsp1-hgt
+    v4l2-isp
diff --git a/Documentation/userspace-api/media/v4l/v4l2-isp.rst b/Documentation/userspace-api/media/v4l/v4l2-isp.rst
new file mode 100644
index 0000000000000000000000000000000000000000..facf6dba1ca7fc34c40e285215cfcb6dfa4ee332
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/v4l2-isp.rst
@@ -0,0 +1,67 @@
+.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+
+.. _v4l2-isp:
+
+************************
+Generic V4L2 ISP formats
+************************
+
+Generic ISP formats are metadata formats that define a mechanism to pass ISP
+parameters and statistics between userspace and drivers in V4L2 buffers. They
+are designed to allow extending them in a backward-compatible way.
+
+ISP parameters
+==============
+
+The generic ISP configuration parameters format is realized by a defining a
+single C structure that contains a header, followed by a binary buffer where
+userspace programs a variable number of ISP configuration data block, one for
+each supported ISP feature.
+
+The :c:type:`v4l2_isp_params_buffer` structure defines the buffer header which
+is followed by a binary buffer of ISP configuration data. Userspace shall
+correctly populate the buffer header with the generic parameters format version
+and with the size (in bytes) of the binary data buffer where it will store the
+ISP blocks configuration.
+
+Each *ISP configuration block* is preceded by an header implemented by the
+:c:type:`v4l2_isp_params_block_header` structure, followed by the configuration
+parameters for that specific block, defined by the ISP driver specific data
+types.
+
+Userspace applications are responsible for correctly populating each block's
+header fields (type, flags and size) and the block-specific parameters.
+
+ISP block enabling, disabling and configuration
+-----------------------------------------------
+
+When userspace wants to configure and enable an ISP block it shall fully
+populate the block configuration and set the V4L2_ISP_PARAMS_FL_BLOCK_ENABLE
+bit in the block header's `flags` field.
+
+When userspace simply wants to disable an ISP block the
+V4L2_ISP_PARAMS_FL_BLOCK_DISABLE bit should be set in block header's `flags`
+field. Drivers accept a configuration parameters block with no additional
+data after the header in this case.
+
+If the configuration of an already active ISP block has to be updated,
+userspace shall fully populate the ISP block parameters and omit setting the
+V4L2_ISP_PARAMS_FL_BLOCK_ENABLE and V4L2_ISP_PARAMS_FL_BLOCK_DISABLE bits in the
+header's `flags` field.
+
+Setting both the V4L2_ISP_PARAMS_FL_BLOCK_ENABLE and
+V4L2_ISP_PARAMS_FL_BLOCK_DISABLE bits in the flags field is not allowed and
+returns an error.
+
+Extension to the parameters format can be implemented by adding new blocks
+definition without invalidating the existing ones.
+
+ISP statistics
+==============
+
+Support for generic statistics format is not yet implemented in Video4Linux2.
+
+V4L2 ISP uAPI data types
+========================
+
+.. kernel-doc:: include/uapi/linux/media/v4l2-isp.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 8989e7e00d86d0c13c4c0b7e5c7eb9481b65861f..b4dd272a0790c317580d0747c8043738a1a58d8e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -26859,6 +26859,7 @@ V4L2 GENERIC ISP PARAMETERS AND STATISTIC FORMATS
 M:	Jacopo Mondi <jacopo.mondi at ideasonboard.com>
 L:	linux-media at vger.kernel.org
 S:	Maintained
+F:	Documentation/userspace-api/media/v4l/v4l2-isp.rst
 F:	include/uapi/linux/media/v4l2-isp.h
 
 VF610 NAND DRIVER

-- 
2.51.0



From jacopo.mondi at ideasonboard.com  Sat Nov  8 01:36:26 2025
From: jacopo.mondi at ideasonboard.com (Jacopo Mondi)
Date: Sat, 08 Nov 2025 10:36:26 +0100
Subject: [PATCH v9 5/8] media: v4l2-core: Introduce v4l2-isp.c
In-Reply-To: <20251108-extensible-parameters-validation-v9-0-6a7e22aa57d0@ideasonboard.com>
References: <20251108-extensible-parameters-validation-v9-0-6a7e22aa57d0@ideasonboard.com>
Message-ID: <20251108-extensible-parameters-validation-v9-5-6a7e22aa57d0@ideasonboard.com>

Add to the V4L2 framework helper functions to support drivers when
validating a buffer of V4L2 ISP parameters.

Driver shall use v4l2_isp_params_validate_buffer_size() to verify the
size correctness of the data received from userspace, and after having
copied the data to a kernel-only memory location, complete the
validation by calling v4l2_isp_params_validate_buffer().

Reviewed-by: Daniel Scally <dan.scally at ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas at ideasonboard.com>
Reviewed-by: Michael Riesch <michael.riesch at collabora.com>
Acked-by: Sakari Ailus <sakari.ailus at linux.intel.com>
Tested-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
---
 MAINTAINERS                        |   2 +
 drivers/media/v4l2-core/Kconfig    |   4 ++
 drivers/media/v4l2-core/Makefile   |   1 +
 drivers/media/v4l2-core/v4l2-isp.c | 128 +++++++++++++++++++++++++++++++++++++
 include/media/v4l2-isp.h           |  91 ++++++++++++++++++++++++++
 5 files changed, 226 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index b4dd272a0790c317580d0747c8043738a1a58d8e..f9a86528a153f635a5a3db5ce9cf6854f699f47f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -26860,6 +26860,8 @@ M:	Jacopo Mondi <jacopo.mondi at ideasonboard.com>
 L:	linux-media at vger.kernel.org
 S:	Maintained
 F:	Documentation/userspace-api/media/v4l/v4l2-isp.rst
+F:	drivers/media/v4l2-core/v4l2-isp.c
+F:	include/media/v4l2-isp.h
 F:	include/uapi/linux/media/v4l2-isp.h
 
 VF610 NAND DRIVER
diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig
index 331b8e535e5bbf33f22638b2ae8bc764ad5fc407..d50ccac9733cc39a43426ae7e7996dd0b5b45186 100644
--- a/drivers/media/v4l2-core/Kconfig
+++ b/drivers/media/v4l2-core/Kconfig
@@ -82,3 +82,7 @@ config V4L2_CCI_I2C
 	depends on I2C
 	select REGMAP_I2C
 	select V4L2_CCI
+
+config V4L2_ISP
+	tristate
+	depends on VIDEOBUF2_CORE
diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile
index 2177b9d63a8ffc1127c5a70118249a2ff63cd759..329f0eadce994cc1c8580beb435f68fa7e2a7aeb 100644
--- a/drivers/media/v4l2-core/Makefile
+++ b/drivers/media/v4l2-core/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_V4L2_CCI) += v4l2-cci.o
 obj-$(CONFIG_V4L2_FLASH_LED_CLASS) += v4l2-flash-led-class.o
 obj-$(CONFIG_V4L2_FWNODE) += v4l2-fwnode.o
 obj-$(CONFIG_V4L2_H264) += v4l2-h264.o
+obj-$(CONFIG_V4L2_ISP) += v4l2-isp.o
 obj-$(CONFIG_V4L2_JPEG_HELPER) += v4l2-jpeg.o
 obj-$(CONFIG_V4L2_MEM2MEM_DEV) += v4l2-mem2mem.o
 obj-$(CONFIG_V4L2_VP9) += v4l2-vp9.o
diff --git a/drivers/media/v4l2-core/v4l2-isp.c b/drivers/media/v4l2-core/v4l2-isp.c
new file mode 100644
index 0000000000000000000000000000000000000000..35f0b701f1729c3c0ccc34b1c89189b179e0b684
--- /dev/null
+++ b/drivers/media/v4l2-core/v4l2-isp.c
@@ -0,0 +1,128 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Video4Linux2 generic ISP parameters and statistics support
+ *
+ * Copyright (C) 2025 Ideas On Board Oy
+ * Author: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
+ */
+
+#include <media/v4l2-isp.h>
+
+#include <linux/bitops.h>
+#include <linux/device.h>
+
+#include <media/videobuf2-core.h>
+
+int v4l2_isp_params_validate_buffer_size(struct device *dev,
+					 struct vb2_buffer *vb,
+					 size_t max_size)
+{
+	size_t header_size = offsetof(struct v4l2_isp_params_buffer, data);
+	size_t payload_size = vb2_get_plane_payload(vb, 0);
+
+	/* Payload size can't be greater than the destination buffer size */
+	if (payload_size > max_size) {
+		dev_dbg(dev, "Payload size is too large: %zu\n", payload_size);
+		return -EINVAL;
+	}
+
+	/* Payload size can't be smaller than the header size */
+	if (payload_size < header_size) {
+		dev_dbg(dev, "Payload size is too small: %zu\n", payload_size);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(v4l2_isp_params_validate_buffer_size);
+
+int v4l2_isp_params_validate_buffer(struct device *dev, struct vb2_buffer *vb,
+				    const struct v4l2_isp_params_buffer *buffer,
+				    const struct v4l2_isp_params_block_info *info,
+				    size_t num_blocks)
+{
+	size_t header_size = offsetof(struct v4l2_isp_params_buffer, data);
+	size_t payload_size = vb2_get_plane_payload(vb, 0);
+	size_t block_offset = 0;
+	size_t buffer_size;
+
+	/*
+	 * Currently only the first version of the V4L2 ISP parameters format is
+	 * supported. We accept both V0 and V1 to support existing drivers
+	 * compatible with V4L2 ISP that use either 0 or 1 as their "first
+	 * version" identifiers.
+	 */
+	if (buffer->version != V4L2_ISP_PARAMS_VERSION_V0 &&
+	    buffer->version != V4L2_ISP_PARAMS_VERSION_V1) {
+		dev_dbg(dev,
+			"Unsupported V4L2 ISP parameters format version: %u\n",
+			buffer->version);
+		return -EINVAL;
+	}
+
+	/* Validate the size reported in the header */
+	buffer_size = header_size + buffer->data_size;
+	if (buffer_size != payload_size) {
+		dev_dbg(dev, "Data size %zu and payload size %zu are different\n",
+			buffer_size, payload_size);
+		return -EINVAL;
+	}
+
+	/* Walk the list of ISP configuration blocks and validate them. */
+	buffer_size = buffer->data_size;
+	while (buffer_size >= sizeof(struct v4l2_isp_params_block_header)) {
+		const struct v4l2_isp_params_block_info *block_info;
+		const struct v4l2_isp_params_block_header *block;
+
+		block = (const struct v4l2_isp_params_block_header *)
+			(buffer->data + block_offset);
+
+		if (block->type >= num_blocks) {
+			dev_dbg(dev,
+				"Invalid block type %u at offset %zu\n",
+				block->type, block_offset);
+			return -EINVAL;
+		}
+
+		if (block->size > buffer_size) {
+			dev_dbg(dev, "Premature end of parameters data\n");
+			return -EINVAL;
+		}
+
+		/* It's invalid to specify both ENABLE and DISABLE. */
+		if ((block->flags & (V4L2_ISP_PARAMS_FL_BLOCK_ENABLE |
+				     V4L2_ISP_PARAMS_FL_BLOCK_DISABLE)) ==
+		     (V4L2_ISP_PARAMS_FL_BLOCK_ENABLE |
+		     V4L2_ISP_PARAMS_FL_BLOCK_DISABLE)) {
+			dev_dbg(dev, "Invalid block flags %x at offset %zu\n",
+				block->flags, block_offset);
+			return -EINVAL;
+		}
+
+		/*
+		 * Match the block reported size against the info provided
+		 * one, but allow the block to only contain the header in
+		 * case it is going to be disabled.
+		 */
+		block_info = &info[block->type];
+		if (block->size != block_info->size &&
+		    (!(block->flags & V4L2_ISP_PARAMS_FL_BLOCK_DISABLE) ||
+		    block->size != sizeof(*block))) {
+			dev_dbg(dev,
+				"Invalid block size %u (expected %zu) at offset %zu\n",
+				block->size, block_info->size, block_offset);
+			return -EINVAL;
+		}
+
+		block_offset += block->size;
+		buffer_size -= block->size;
+	}
+
+	if (buffer_size) {
+		dev_dbg(dev, "Unexpected data after the parameters buffer end\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(v4l2_isp_params_validate_buffer);
diff --git a/include/media/v4l2-isp.h b/include/media/v4l2-isp.h
new file mode 100644
index 0000000000000000000000000000000000000000..8b4695663699e7f176384739cf54ed7fa2c578f8
--- /dev/null
+++ b/include/media/v4l2-isp.h
@@ -0,0 +1,91 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Video4Linux2 generic ISP parameters and statistics support
+ *
+ * Copyright (C) 2025 Ideas On Board Oy
+ * Author: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
+ */
+
+#ifndef _V4L2_ISP_H_
+#define _V4L2_ISP_H_
+
+#include <linux/media/v4l2-isp.h>
+
+struct device;
+struct vb2_buffer;
+
+/**
+ * v4l2_isp_params_buffer_size - Calculate size of v4l2_isp_params_buffer
+ * @max_params_size: The total size of the ISP configuration blocks
+ *
+ * Users of the v4l2 extensible parameters will have differing sized data arrays
+ * depending on their specific parameter buffers. Drivers and userspace will
+ * need to be able to calculate the appropriate size of the struct to
+ * accommodate all ISP configuration blocks provided by the platform.
+ * This macro provides a convenient tool for the calculation.
+ */
+#define v4l2_isp_params_buffer_size(max_params_size) \
+	(offsetof(struct v4l2_isp_params_buffer, data) + (max_params_size))
+
+/**
+ * v4l2_isp_params_validate_buffer_size - Validate a V4L2 ISP buffer sizes
+ * @dev: the driver's device pointer
+ * @vb: the videobuf2 buffer
+ * @max_size: the maximum allowed buffer size
+ *
+ * This function performs validation of the size of a V4L2 ISP parameters buffer
+ * before the driver can access the actual data buffer content.
+ *
+ * After the sizes validation, drivers should copy the buffer content to a
+ * kernel-only memory area to prevent userspace from modifying it,
+ * before completing validation using v4l2_isp_params_validate_buffer().
+ *
+ * The @vb buffer as received from the vb2 .buf_prepare() operation is checked
+ * against @max_size and it's validated to be large enough to accommodate at
+ * least one ISP configuration block.
+ */
+int v4l2_isp_params_validate_buffer_size(struct device *dev,
+					 struct vb2_buffer *vb,
+					 size_t max_size);
+
+/**
+ * struct v4l2_isp_params_block_info - V4L2 ISP per-block info
+ * @size: the block expected size
+ *
+ * The v4l2_isp_params_block_info collects information of the ISP configuration
+ * blocks for validation purposes. It currently only contains the expected
+ * block size.
+ *
+ * Drivers shall prepare a list of block info, indexed by block type, one for
+ * each supported ISP block and correctly populate them with the expected block
+ * size.
+ */
+struct v4l2_isp_params_block_info {
+	size_t size;
+};
+
+/**
+ * v4l2_isp_params_validate_buffer - Validate a V4L2 ISP parameters buffer
+ * @dev: the driver's device pointer
+ * @vb: the videobuf2 buffer
+ * @buffer: the V4L2 ISP parameters buffer
+ * @info: the list of per-block validation info
+ * @num_blocks: the number of blocks
+ *
+ * This function completes the validation of a V4L2 ISP parameters buffer,
+ * verifying each configuration block correctness before the driver can use
+ * them to program the hardware.
+ *
+ * Drivers should use this function after having validated the correctness of
+ * the vb2 buffer sizes by using the v4l2_isp_params_validate_buffer_size()
+ * helper first. Once the buffer size has been validated, drivers should
+ * perform a copy of the user provided buffer into a kernel-only memory buffer
+ * to prevent userspace from modifying its content after it has been submitted
+ * to the driver, and then call this function to complete validation.
+ */
+int v4l2_isp_params_validate_buffer(struct device *dev, struct vb2_buffer *vb,
+				    const struct v4l2_isp_params_buffer *buffer,
+				    const struct v4l2_isp_params_block_info *info,
+				    size_t num_blocks);
+
+#endif /* _V4L2_ISP_H_ */

-- 
2.51.0



From jacopo.mondi at ideasonboard.com  Sat Nov  8 01:36:27 2025
From: jacopo.mondi at ideasonboard.com (Jacopo Mondi)
Date: Sat, 08 Nov 2025 10:36:27 +0100
Subject: [PATCH v9 6/8] media: rkisp1: Use v4l2-isp for validation
In-Reply-To: <20251108-extensible-parameters-validation-v9-0-6a7e22aa57d0@ideasonboard.com>
References: <20251108-extensible-parameters-validation-v9-0-6a7e22aa57d0@ideasonboard.com>
Message-ID: <20251108-extensible-parameters-validation-v9-6-6a7e22aa57d0@ideasonboard.com>

Convert rkisp1-params.c to use the helpers defined in v4l2-isp.h
to perform validation of a ISP parameters buffer.

Reviewed-by: Daniel Scally <dan.scally at ideasonboard.com>
Acked-by: Sakari Ailus <sakari.ailus at linux.intel.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Tested-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
---
 drivers/media/platform/rockchip/rkisp1/Kconfig     |   1 +
 .../media/platform/rockchip/rkisp1/rkisp1-params.c | 150 ++++++---------------
 2 files changed, 44 insertions(+), 107 deletions(-)

diff --git a/drivers/media/platform/rockchip/rkisp1/Kconfig b/drivers/media/platform/rockchip/rkisp1/Kconfig
index 731c9acbf6efa33188617204d441fb0ea59adebc..f53eb1f3f3e7003d8e02c9236aeabb5ae8844f7b 100644
--- a/drivers/media/platform/rockchip/rkisp1/Kconfig
+++ b/drivers/media/platform/rockchip/rkisp1/Kconfig
@@ -10,6 +10,7 @@ config VIDEO_ROCKCHIP_ISP1
 	select VIDEOBUF2_VMALLOC
 	select V4L2_FWNODE
 	select GENERIC_PHY_MIPI_DPHY
+	select V4L2_ISP
 	default n
 	help
 	  Enable this to support the Image Signal Processing (ISP) module
diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
index f1585f8fa0f478304f74317fd9dd09199c94ec82..2dde0c62c8e6b8f8447e0414950cec0a511169fd 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
@@ -6,12 +6,14 @@
  */
 
 #include <linux/bitfield.h>
+#include <linux/build_bug.h>
 #include <linux/math.h>
 #include <linux/string.h>
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-event.h>
 #include <media/v4l2-ioctl.h>
+#include <media/v4l2-isp.h>
 #include <media/videobuf2-core.h>
 #include <media/videobuf2-vmalloc.h>	/* for ISP params */
 
@@ -2097,122 +2099,132 @@ typedef void (*rkisp1_block_handler)(struct rkisp1_params *params,
 			     const union rkisp1_ext_params_config *config);
 
 static const struct rkisp1_ext_params_handler {
-	size_t size;
 	rkisp1_block_handler handler;
 	unsigned int group;
 	unsigned int features;
 } rkisp1_ext_params_handlers[] = {
 	[RKISP1_EXT_PARAMS_BLOCK_TYPE_BLS] = {
-		.size		= sizeof(struct rkisp1_ext_params_bls_config),
 		.handler	= rkisp1_ext_params_bls,
 		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
 		.features       = RKISP1_FEATURE_BLS,
 	},
 	[RKISP1_EXT_PARAMS_BLOCK_TYPE_DPCC] = {
-		.size		= sizeof(struct rkisp1_ext_params_dpcc_config),
 		.handler	= rkisp1_ext_params_dpcc,
 		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
 	},
 	[RKISP1_EXT_PARAMS_BLOCK_TYPE_SDG] = {
-		.size		= sizeof(struct rkisp1_ext_params_sdg_config),
 		.handler	= rkisp1_ext_params_sdg,
 		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
 	},
 	[RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_GAIN] = {
-		.size		= sizeof(struct rkisp1_ext_params_awb_gain_config),
 		.handler	= rkisp1_ext_params_awbg,
 		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
 	},
 	[RKISP1_EXT_PARAMS_BLOCK_TYPE_FLT] = {
-		.size		= sizeof(struct rkisp1_ext_params_flt_config),
 		.handler	= rkisp1_ext_params_flt,
 		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
 	},
 	[RKISP1_EXT_PARAMS_BLOCK_TYPE_BDM] = {
-		.size		= sizeof(struct rkisp1_ext_params_bdm_config),
 		.handler	= rkisp1_ext_params_bdm,
 		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
 	},
 	[RKISP1_EXT_PARAMS_BLOCK_TYPE_CTK] = {
-		.size		= sizeof(struct rkisp1_ext_params_ctk_config),
 		.handler	= rkisp1_ext_params_ctk,
 		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
 	},
 	[RKISP1_EXT_PARAMS_BLOCK_TYPE_GOC] = {
-		.size		= sizeof(struct rkisp1_ext_params_goc_config),
 		.handler	= rkisp1_ext_params_goc,
 		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
 	},
 	[RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF] = {
-		.size		= sizeof(struct rkisp1_ext_params_dpf_config),
 		.handler	= rkisp1_ext_params_dpf,
 		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
 	},
 	[RKISP1_EXT_PARAMS_BLOCK_TYPE_DPF_STRENGTH] = {
-		.size		= sizeof(struct rkisp1_ext_params_dpf_strength_config),
 		.handler	= rkisp1_ext_params_dpfs,
 		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
 	},
 	[RKISP1_EXT_PARAMS_BLOCK_TYPE_CPROC] = {
-		.size		= sizeof(struct rkisp1_ext_params_cproc_config),
 		.handler	= rkisp1_ext_params_cproc,
 		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
 	},
 	[RKISP1_EXT_PARAMS_BLOCK_TYPE_IE] = {
-		.size		= sizeof(struct rkisp1_ext_params_ie_config),
 		.handler	= rkisp1_ext_params_ie,
 		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
 	},
 	[RKISP1_EXT_PARAMS_BLOCK_TYPE_LSC] = {
-		.size		= sizeof(struct rkisp1_ext_params_lsc_config),
 		.handler	= rkisp1_ext_params_lsc,
 		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_LSC,
 	},
 	[RKISP1_EXT_PARAMS_BLOCK_TYPE_AWB_MEAS] = {
-		.size		= sizeof(struct rkisp1_ext_params_awb_meas_config),
 		.handler	= rkisp1_ext_params_awbm,
 		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
 	},
 	[RKISP1_EXT_PARAMS_BLOCK_TYPE_HST_MEAS] = {
-		.size		= sizeof(struct rkisp1_ext_params_hst_config),
 		.handler	= rkisp1_ext_params_hstm,
 		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
 	},
 	[RKISP1_EXT_PARAMS_BLOCK_TYPE_AEC_MEAS] = {
-		.size		= sizeof(struct rkisp1_ext_params_aec_config),
 		.handler	= rkisp1_ext_params_aecm,
 		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
 	},
 	[RKISP1_EXT_PARAMS_BLOCK_TYPE_AFC_MEAS] = {
-		.size		= sizeof(struct rkisp1_ext_params_afc_config),
 		.handler	= rkisp1_ext_params_afcm,
 		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
 	},
 	[RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_BLS] = {
-		.size		= sizeof(struct rkisp1_ext_params_compand_bls_config),
 		.handler	= rkisp1_ext_params_compand_bls,
 		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
 		.features	= RKISP1_FEATURE_COMPAND,
 	},
 	[RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_EXPAND] = {
-		.size		= sizeof(struct rkisp1_ext_params_compand_curve_config),
 		.handler	= rkisp1_ext_params_compand_expand,
 		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
 		.features	= RKISP1_FEATURE_COMPAND,
 	},
 	[RKISP1_EXT_PARAMS_BLOCK_TYPE_COMPAND_COMPRESS] = {
-		.size		= sizeof(struct rkisp1_ext_params_compand_curve_config),
 		.handler	= rkisp1_ext_params_compand_compress,
 		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
 		.features	= RKISP1_FEATURE_COMPAND,
 	},
 	[RKISP1_EXT_PARAMS_BLOCK_TYPE_WDR] = {
-		.size		= sizeof(struct rkisp1_ext_params_wdr_config),
 		.handler	= rkisp1_ext_params_wdr,
 		.group		= RKISP1_EXT_PARAMS_BLOCK_GROUP_OTHERS,
 	},
 };
 
+#define RKISP1_PARAMS_BLOCK_INFO(block, data) \
+	[RKISP1_EXT_PARAMS_BLOCK_TYPE_ ## block] = { \
+		.size = sizeof(struct rkisp1_ext_params_ ## data ## _config), \
+	}
+
+static const struct v4l2_isp_params_block_info rkisp1_ext_params_blocks_info[] = {
+	RKISP1_PARAMS_BLOCK_INFO(BLS, bls),
+	RKISP1_PARAMS_BLOCK_INFO(DPCC, dpcc),
+	RKISP1_PARAMS_BLOCK_INFO(SDG, sdg),
+	RKISP1_PARAMS_BLOCK_INFO(AWB_GAIN, awb_gain),
+	RKISP1_PARAMS_BLOCK_INFO(FLT, flt),
+	RKISP1_PARAMS_BLOCK_INFO(BDM, bdm),
+	RKISP1_PARAMS_BLOCK_INFO(CTK, ctk),
+	RKISP1_PARAMS_BLOCK_INFO(GOC, goc),
+	RKISP1_PARAMS_BLOCK_INFO(DPF, dpf),
+	RKISP1_PARAMS_BLOCK_INFO(DPF_STRENGTH, dpf_strength),
+	RKISP1_PARAMS_BLOCK_INFO(CPROC, cproc),
+	RKISP1_PARAMS_BLOCK_INFO(IE, ie),
+	RKISP1_PARAMS_BLOCK_INFO(LSC, lsc),
+	RKISP1_PARAMS_BLOCK_INFO(AWB_MEAS, awb_meas),
+	RKISP1_PARAMS_BLOCK_INFO(HST_MEAS, hst),
+	RKISP1_PARAMS_BLOCK_INFO(AEC_MEAS, aec),
+	RKISP1_PARAMS_BLOCK_INFO(AFC_MEAS, afc),
+	RKISP1_PARAMS_BLOCK_INFO(COMPAND_BLS, compand_bls),
+	RKISP1_PARAMS_BLOCK_INFO(COMPAND_EXPAND, compand_curve),
+	RKISP1_PARAMS_BLOCK_INFO(COMPAND_COMPRESS, compand_curve),
+	RKISP1_PARAMS_BLOCK_INFO(WDR, wdr),
+};
+
+static_assert(ARRAY_SIZE(rkisp1_ext_params_handlers) ==
+	      ARRAY_SIZE(rkisp1_ext_params_blocks_info));
+
 static void rkisp1_ext_params_config(struct rkisp1_params *params,
 				     struct rkisp1_ext_params_cfg *cfg,
 				     u32 block_group_mask)
@@ -2646,31 +2658,16 @@ static int rkisp1_params_prepare_ext_params(struct rkisp1_params *params,
 {
 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
 	struct rkisp1_params_buffer *params_buf = to_rkisp1_params_buffer(vbuf);
-	size_t header_size = offsetof(struct rkisp1_ext_params_cfg, data);
 	struct rkisp1_ext_params_cfg *cfg = params_buf->cfg;
 	size_t payload_size = vb2_get_plane_payload(vb, 0);
 	struct rkisp1_ext_params_cfg *usr_cfg =
 		vb2_plane_vaddr(&vbuf->vb2_buf, 0);
-	size_t block_offset = 0;
-	size_t cfg_size;
-
-	/*
-	 * Validate the buffer payload size before copying the parameters. The
-	 * payload has to be smaller than the destination buffer size and larger
-	 * than the header size.
-	 */
-	if (payload_size > params->metafmt->buffersize) {
-		dev_dbg(params->rkisp1->dev,
-			"Too large buffer payload size %zu\n", payload_size);
-		return -EINVAL;
-	}
+	int ret;
 
-	if (payload_size < header_size) {
-		dev_dbg(params->rkisp1->dev,
-			"Buffer payload %zu smaller than header size %zu\n",
-			payload_size, header_size);
-		return -EINVAL;
-	}
+	ret = v4l2_isp_params_validate_buffer_size(params->rkisp1->dev, vb,
+						   params->metafmt->buffersize);
+	if (ret)
+		return ret;
 
 	/*
 	 * Copy the parameters buffer to the internal scratch buffer to avoid
@@ -2678,71 +2675,10 @@ static int rkisp1_params_prepare_ext_params(struct rkisp1_params *params,
 	 */
 	memcpy(cfg, usr_cfg, payload_size);
 
-	/* Only v1 is supported at the moment. */
-	if (cfg->version != RKISP1_EXT_PARAM_BUFFER_V1) {
-		dev_dbg(params->rkisp1->dev,
-			"Unsupported extensible format version: %u\n",
-			cfg->version);
-		return -EINVAL;
-	}
-
-	/* Validate the size reported in the parameters buffer header. */
-	cfg_size = header_size + cfg->data_size;
-	if (cfg_size != payload_size) {
-		dev_dbg(params->rkisp1->dev,
-			"Data size %zu different than buffer payload size %zu\n",
-			cfg_size, payload_size);
-		return -EINVAL;
-	}
-
-	/* Walk the list of parameter blocks and validate them. */
-	cfg_size = cfg->data_size;
-	while (cfg_size >= sizeof(struct rkisp1_ext_params_block_header)) {
-		const struct rkisp1_ext_params_block_header *block;
-		const struct rkisp1_ext_params_handler *handler;
-
-		block = (const struct rkisp1_ext_params_block_header *)
-			&cfg->data[block_offset];
-
-		if (block->type >= ARRAY_SIZE(rkisp1_ext_params_handlers)) {
-			dev_dbg(params->rkisp1->dev,
-				"Invalid parameters block type\n");
-			return -EINVAL;
-		}
-
-		if (block->size > cfg_size) {
-			dev_dbg(params->rkisp1->dev,
-				"Premature end of parameters data\n");
-			return -EINVAL;
-		}
-
-		if ((block->flags & (RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE |
-				     RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE)) ==
-		   (RKISP1_EXT_PARAMS_FL_BLOCK_ENABLE |
-		    RKISP1_EXT_PARAMS_FL_BLOCK_DISABLE)) {
-			dev_dbg(params->rkisp1->dev,
-				"Invalid parameters block flags\n");
-			return -EINVAL;
-		}
-
-		handler = &rkisp1_ext_params_handlers[block->type];
-		if (block->size != handler->size) {
-			dev_dbg(params->rkisp1->dev,
-				"Invalid parameters block size\n");
-			return -EINVAL;
-		}
-
-		block_offset += block->size;
-		cfg_size -= block->size;
-	}
-
-	if (cfg_size) {
-		dev_dbg(params->rkisp1->dev,
-			"Unexpected data after the parameters buffer end\n");
-		return -EINVAL;
-	}
-
-	return 0;
+	return v4l2_isp_params_validate_buffer(params->rkisp1->dev, vb,
+				(struct v4l2_isp_params_buffer *)cfg,
+				rkisp1_ext_params_blocks_info,
+				ARRAY_SIZE(rkisp1_ext_params_blocks_info));
 }
 
 static int rkisp1_params_vb2_buf_prepare(struct vb2_buffer *vb)

-- 
2.51.0



From jacopo.mondi at ideasonboard.com  Sat Nov  8 01:36:28 2025
From: jacopo.mondi at ideasonboard.com (Jacopo Mondi)
Date: Sat, 08 Nov 2025 10:36:28 +0100
Subject: [PATCH v9 7/8] media: amlogic-c3: Use v4l2-isp for validation
In-Reply-To: <20251108-extensible-parameters-validation-v9-0-6a7e22aa57d0@ideasonboard.com>
References: <20251108-extensible-parameters-validation-v9-0-6a7e22aa57d0@ideasonboard.com>
Message-ID: <20251108-extensible-parameters-validation-v9-7-6a7e22aa57d0@ideasonboard.com>

Convert c3-isp-params.c to use the helpers defined in v4l2-isp.h
to perform validation of a ISP parameters buffer.

Reviewed-by: Keke Li <keke.li at amlogic.com>
Reviewed-by: Daniel Scally <dan.scally at ideasonboard.com>
Acked-by: Sakari Ailus <sakari.ailus at linux.intel.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas at ideasonboard.com>
Tested-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
---
 drivers/media/platform/amlogic/c3/isp/Kconfig      |   1 +
 .../media/platform/amlogic/c3/isp/c3-isp-params.c  | 165 ++++++---------------
 2 files changed, 44 insertions(+), 122 deletions(-)

diff --git a/drivers/media/platform/amlogic/c3/isp/Kconfig b/drivers/media/platform/amlogic/c3/isp/Kconfig
index 02c62a50a5e88eac665e27abf163e5d654faed3f..809208cd7e3aa7ca0821cb07366ec73a47edb278 100644
--- a/drivers/media/platform/amlogic/c3/isp/Kconfig
+++ b/drivers/media/platform/amlogic/c3/isp/Kconfig
@@ -10,6 +10,7 @@ config VIDEO_C3_ISP
 	select VIDEO_V4L2_SUBDEV_API
 	select VIDEOBUF2_DMA_CONTIG
 	select VIDEOBUF2_VMALLOC
+	select V4L2_ISP
 	help
 	  Video4Linux2 driver for Amlogic C3 ISP pipeline.
 	  The C3 ISP is used for processing raw images and
diff --git a/drivers/media/platform/amlogic/c3/isp/c3-isp-params.c b/drivers/media/platform/amlogic/c3/isp/c3-isp-params.c
index c80667dd766210d2b2e1ee60c8254a5814b9d81b..c2339d6dc1074818d333e0221b1d6a407a41acd7 100644
--- a/drivers/media/platform/amlogic/c3/isp/c3-isp-params.c
+++ b/drivers/media/platform/amlogic/c3/isp/c3-isp-params.c
@@ -3,11 +3,13 @@
  * Copyright (C) 2024 Amlogic, Inc. All rights reserved
  */
 
+#include <linux/build_bug.h>
 #include <linux/cleanup.h>
 #include <linux/media/amlogic/c3-isp-config.h>
 #include <linux/pm_runtime.h>
 
 #include <media/v4l2-ioctl.h>
+#include <media/v4l2-isp.h>
 #include <media/v4l2-mc.h>
 #include <media/videobuf2-vmalloc.h>
 
@@ -51,11 +53,6 @@ union c3_isp_params_block {
 typedef void (*c3_isp_block_handler)(struct c3_isp_device *isp,
 				     const union c3_isp_params_block *block);
 
-struct c3_isp_params_handler {
-	size_t size;
-	c3_isp_block_handler handler;
-};
-
 #define to_c3_isp_params_buffer(vbuf) \
 	container_of(vbuf, struct c3_isp_params_buffer, vb)
 
@@ -523,41 +520,36 @@ static void c3_isp_params_cfg_blc(struct c3_isp_device *isp,
 				   ISP_TOP_BEO_CTRL_BLC_EN);
 }
 
-static const struct c3_isp_params_handler c3_isp_params_handlers[] = {
-	[C3_ISP_PARAMS_BLOCK_AWB_GAINS] = {
-		.size = sizeof(struct c3_isp_params_awb_gains),
-		.handler = c3_isp_params_cfg_awb_gains,
-	},
-	[C3_ISP_PARAMS_BLOCK_AWB_CONFIG] = {
-		.size = sizeof(struct c3_isp_params_awb_config),
-		.handler = c3_isp_params_cfg_awb_config,
-	},
-	[C3_ISP_PARAMS_BLOCK_AE_CONFIG] = {
-		.size = sizeof(struct c3_isp_params_ae_config),
-		.handler = c3_isp_params_cfg_ae_config,
-	},
-	[C3_ISP_PARAMS_BLOCK_AF_CONFIG] = {
-		.size = sizeof(struct c3_isp_params_af_config),
-		.handler = c3_isp_params_cfg_af_config,
-	},
-	[C3_ISP_PARAMS_BLOCK_PST_GAMMA] = {
-		.size = sizeof(struct c3_isp_params_pst_gamma),
-		.handler = c3_isp_params_cfg_pst_gamma,
-	},
-	[C3_ISP_PARAMS_BLOCK_CCM] = {
-		.size = sizeof(struct c3_isp_params_ccm),
-		.handler = c3_isp_params_cfg_ccm,
-	},
-	[C3_ISP_PARAMS_BLOCK_CSC] = {
-		.size = sizeof(struct c3_isp_params_csc),
-		.handler = c3_isp_params_cfg_csc,
-	},
-	[C3_ISP_PARAMS_BLOCK_BLC] = {
-		.size = sizeof(struct c3_isp_params_blc),
-		.handler = c3_isp_params_cfg_blc,
-	},
+static const c3_isp_block_handler c3_isp_params_handlers[] = {
+	[C3_ISP_PARAMS_BLOCK_AWB_GAINS] = c3_isp_params_cfg_awb_gains,
+	[C3_ISP_PARAMS_BLOCK_AWB_CONFIG] = c3_isp_params_cfg_awb_config,
+	[C3_ISP_PARAMS_BLOCK_AE_CONFIG] = c3_isp_params_cfg_ae_config,
+	[C3_ISP_PARAMS_BLOCK_AF_CONFIG] = c3_isp_params_cfg_af_config,
+	[C3_ISP_PARAMS_BLOCK_PST_GAMMA] = c3_isp_params_cfg_pst_gamma,
+	[C3_ISP_PARAMS_BLOCK_CCM] = c3_isp_params_cfg_ccm,
+	[C3_ISP_PARAMS_BLOCK_CSC] = c3_isp_params_cfg_csc,
+	[C3_ISP_PARAMS_BLOCK_BLC] = c3_isp_params_cfg_blc,
+};
+
+#define C3_ISP_PARAMS_BLOCK_INFO(block, data) \
+	[C3_ISP_PARAMS_BLOCK_ ## block] = { \
+		.size = sizeof(struct c3_isp_params_ ## data), \
+	}
+
+static const struct v4l2_isp_params_block_info c3_isp_params_blocks_info[] = {
+	C3_ISP_PARAMS_BLOCK_INFO(AWB_GAINS, awb_gains),
+	C3_ISP_PARAMS_BLOCK_INFO(AWB_CONFIG, awb_config),
+	C3_ISP_PARAMS_BLOCK_INFO(AE_CONFIG, ae_config),
+	C3_ISP_PARAMS_BLOCK_INFO(AF_CONFIG, af_config),
+	C3_ISP_PARAMS_BLOCK_INFO(PST_GAMMA, pst_gamma),
+	C3_ISP_PARAMS_BLOCK_INFO(CCM, ccm),
+	C3_ISP_PARAMS_BLOCK_INFO(CSC, csc),
+	C3_ISP_PARAMS_BLOCK_INFO(BLC, blc),
 };
 
+static_assert(ARRAY_SIZE(c3_isp_params_handlers) ==
+	      ARRAY_SIZE(c3_isp_params_blocks_info));
+
 static void c3_isp_params_cfg_blocks(struct c3_isp_params *params)
 {
 	struct c3_isp_params_cfg *config = params->buff->cfg;
@@ -568,14 +560,14 @@ static void c3_isp_params_cfg_blocks(struct c3_isp_params *params)
 
 	/* Walk the list of parameter blocks and process them */
 	while (block_offset < config->data_size) {
-		const struct c3_isp_params_handler *block_handler;
 		const union c3_isp_params_block *block;
+		c3_isp_block_handler block_handler;
 
 		block = (const union c3_isp_params_block *)
 			 &config->data[block_offset];
 
-		block_handler = &c3_isp_params_handlers[block->header.type];
-		block_handler->handler(params->isp, block);
+		block_handler = c3_isp_params_handlers[block->header.type];
+		block_handler(params->isp, block);
 
 		block_offset += block->header.size;
 	}
@@ -771,26 +763,15 @@ static int c3_isp_params_vb2_buf_prepare(struct vb2_buffer *vb)
 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
 	struct c3_isp_params_buffer *buf = to_c3_isp_params_buffer(vbuf);
 	struct c3_isp_params *params = vb2_get_drv_priv(vb->vb2_queue);
-	struct c3_isp_params_cfg *cfg = buf->cfg;
 	struct c3_isp_params_cfg *usr_cfg = vb2_plane_vaddr(vb, 0);
 	size_t payload_size = vb2_get_plane_payload(vb, 0);
-	size_t header_size = offsetof(struct c3_isp_params_cfg, data);
-	size_t block_offset = 0;
-	size_t cfg_size;
-
-	/* Payload size can't be greater than the destination buffer size */
-	if (payload_size > params->vfmt.fmt.meta.buffersize) {
-		dev_dbg(params->isp->dev,
-			"Payload size is too large: %zu\n", payload_size);
-		return -EINVAL;
-	}
+	struct c3_isp_params_cfg *cfg = buf->cfg;
+	int ret;
 
-	/* Payload size can't be smaller than the header size */
-	if (payload_size < header_size) {
-		dev_dbg(params->isp->dev,
-			"Payload size is too small: %zu\n", payload_size);
-		return -EINVAL;
-	}
+	ret = v4l2_isp_params_validate_buffer_size(params->isp->dev, vb,
+						   params->vfmt.fmt.meta.buffersize);
+	if (ret)
+		return ret;
 
 	/*
 	 * Use the internal scratch buffer to avoid userspace modifying
@@ -798,70 +779,10 @@ static int c3_isp_params_vb2_buf_prepare(struct vb2_buffer *vb)
 	 */
 	memcpy(cfg, usr_cfg, payload_size);
 
-	/* Only v0 is supported at the moment */
-	if (cfg->version != C3_ISP_PARAMS_BUFFER_V0) {
-		dev_dbg(params->isp->dev,
-			"Invalid params buffer version: %u\n", cfg->version);
-		return -EINVAL;
-	}
-
-	/* Validate the size reported in the parameter buffer header */
-	cfg_size = header_size + cfg->data_size;
-	if (cfg_size != payload_size) {
-		dev_dbg(params->isp->dev,
-			"Data size %zu and payload size %zu are different\n",
-			cfg_size, payload_size);
-		return -EINVAL;
-	}
-
-	/* Walk the list of parameter blocks and validate them */
-	cfg_size = cfg->data_size;
-	while (cfg_size >= sizeof(struct c3_isp_params_block_header)) {
-		const struct c3_isp_params_block_header *block;
-		const struct c3_isp_params_handler *handler;
-
-		block = (struct c3_isp_params_block_header *)
-			&cfg->data[block_offset];
-
-		if (block->type >= ARRAY_SIZE(c3_isp_params_handlers)) {
-			dev_dbg(params->isp->dev,
-				"Invalid params block type\n");
-			return -EINVAL;
-		}
-
-		if (block->size > cfg_size) {
-			dev_dbg(params->isp->dev,
-				"Block size is greater than cfg size\n");
-			return -EINVAL;
-		}
-
-		if ((block->flags & (C3_ISP_PARAMS_BLOCK_FL_ENABLE |
-				     C3_ISP_PARAMS_BLOCK_FL_DISABLE)) ==
-		    (C3_ISP_PARAMS_BLOCK_FL_ENABLE |
-		     C3_ISP_PARAMS_BLOCK_FL_DISABLE)) {
-			dev_dbg(params->isp->dev,
-				"Invalid parameters block flags\n");
-			return -EINVAL;
-		}
-
-		handler = &c3_isp_params_handlers[block->type];
-		if (block->size != handler->size) {
-			dev_dbg(params->isp->dev,
-				"Invalid params block size\n");
-			return -EINVAL;
-		}
-
-		block_offset += block->size;
-		cfg_size -= block->size;
-	}
-
-	if (cfg_size) {
-		dev_dbg(params->isp->dev,
-			"Unexpected data after the params buffer end\n");
-		return -EINVAL;
-	}
-
-	return 0;
+	return v4l2_isp_params_validate_buffer(params->isp->dev, vb,
+					(struct v4l2_isp_params_buffer *)cfg,
+					c3_isp_params_blocks_info,
+					ARRAY_SIZE(c3_isp_params_blocks_info));
 }
 
 static int c3_isp_params_vb2_buf_init(struct vb2_buffer *vb)

-- 
2.51.0



From jacopo.mondi at ideasonboard.com  Sat Nov  8 01:36:29 2025
From: jacopo.mondi at ideasonboard.com (Jacopo Mondi)
Date: Sat, 08 Nov 2025 10:36:29 +0100
Subject: [PATCH v9 8/8] media: Documentation: kapi: Add v4l2 generic ISP
 support
In-Reply-To: <20251108-extensible-parameters-validation-v9-0-6a7e22aa57d0@ideasonboard.com>
References: <20251108-extensible-parameters-validation-v9-0-6a7e22aa57d0@ideasonboard.com>
Message-ID: <20251108-extensible-parameters-validation-v9-8-6a7e22aa57d0@ideasonboard.com>

Add to the driver-api documentation the v4l2-isp.h types and
helpers documentation.

Reviewed-by: Daniel Scally <dan.scally at ideasonboard.com>
Reviewed-by: Michael Riesch <michael.riesch at collabora.com>
Acked-by: Sakari Ailus <sakari.ailus at linux.intel.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas at ideasonboard.com>
Tested-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
Signed-off-by: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
---
 Documentation/driver-api/media/v4l2-core.rst |  1 +
 Documentation/driver-api/media/v4l2-isp.rst  | 49 ++++++++++++++++++++++++++++
 MAINTAINERS                                  |  1 +
 3 files changed, 51 insertions(+)

diff --git a/Documentation/driver-api/media/v4l2-core.rst b/Documentation/driver-api/media/v4l2-core.rst
index ad987c34ad2a8460bb95e97adc4d850d624e0b81..a5f5102c64cca57b57b54ab95882b26286fb27de 100644
--- a/Documentation/driver-api/media/v4l2-core.rst
+++ b/Documentation/driver-api/media/v4l2-core.rst
@@ -27,3 +27,4 @@ Video4Linux devices
     v4l2-common
     v4l2-tveeprom
     v4l2-jpeg
+    v4l2-isp
diff --git a/Documentation/driver-api/media/v4l2-isp.rst b/Documentation/driver-api/media/v4l2-isp.rst
new file mode 100644
index 0000000000000000000000000000000000000000..618ae614ff79424a9edb23509644e89d57071b2a
--- /dev/null
+++ b/Documentation/driver-api/media/v4l2-isp.rst
@@ -0,0 +1,49 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+V4L2 generic ISP parameters and statistics support
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Design rationale
+================
+
+ISP configuration parameters and statistics are processed and collected by
+drivers and exchanged with userspace through data types that usually
+reflect the ISP peripheral registers layout.
+
+Each ISP driver defines its own metadata output format for parameters and
+a metadata capture format for statistics. The buffer layout is realized by a
+set of C structures that reflects the registers layout. The number and types
+of C structures is fixed by the format definition and becomes part of the Linux
+kernel uAPI/uABI interface.
+
+Because of the hard requirement of backward compatibility when extending the
+user API/ABI interface, modifying an ISP driver capture or output metadata
+format after it has been accepted by mainline is very hard if not impossible.
+
+It generally happens, in fact, that after the first accepted revision of an ISP
+driver the buffers layout need to be modified, either to support new hardware
+blocks, to fix bugs or to support different revisions of the hardware.
+
+Each of these situations would require defining a new metadata format, making it
+really hard to maintain and extend drivers and requiring userspace to use
+the correct format depending on the kernel revision in use.
+
+V4L2 ISP configuration parameters
+=================================
+
+For these reasons, Video4Linux2 defines generic types for ISP configuration
+parameters and statistics. Drivers are still expected to define their own
+formats for their metadata output and capture nodes, but the buffers layout can
+be defined using the extensible and versioned types defined by
+include/uapi/linux/media/v4l2-isp.h.
+
+Drivers are expected to provide the definitions of their supported ISP blocks
+and the expected maximum size of a buffer.
+
+For driver developers a set of helper functions to assist them with validation
+of the buffer received from userspace is available in
+drivers/media/v4l2-core/v4l2-isp.c
+
+V4L2 ISP support driver documentation
+=====================================
+.. kernel-doc:: include/media/v4l2-isp.h
diff --git a/MAINTAINERS b/MAINTAINERS
index f9a86528a153f635a5a3db5ce9cf6854f699f47f..931b0fc72279a5ce2830d1ce5d2845ed1a2ae633 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -26859,6 +26859,7 @@ V4L2 GENERIC ISP PARAMETERS AND STATISTIC FORMATS
 M:	Jacopo Mondi <jacopo.mondi at ideasonboard.com>
 L:	linux-media at vger.kernel.org
 S:	Maintained
+F:	Documentation/driver-api/media/v4l2-isp.rst
 F:	Documentation/userspace-api/media/v4l/v4l2-isp.rst
 F:	drivers/media/v4l2-core/v4l2-isp.c
 F:	include/media/v4l2-isp.h

-- 
2.51.0



From vasant.hegde at amd.com  Sat Nov  8 03:17:02 2025
From: vasant.hegde at amd.com (Vasant Hegde)
Date: Sat, 8 Nov 2025 16:47:02 +0530
Subject: [PATCH v2 2/3] iommu/amd: Don't call report_iommu_fault()
In-Reply-To: <2-v2-25fc75484cab+ab-iommu_set_fault_jgg@nvidia.com>
References: <2-v2-25fc75484cab+ab-iommu_set_fault_jgg@nvidia.com>
Message-ID: <93fd05cd-b227-42ab-8d96-7873a830e6be@amd.com>

On 11/7/2025 2:04 AM, Jason Gunthorpe wrote:
> This old style API is only used by drivers/gpu/drm/msm,
> drivers/remoteproc/omap_remoteproc.c, and
> drivers/remoteproc/qcom_q6v5_adsp.c none are used on x86 HW.
> 
> Remove the dead code to discourage new users.
> 
> Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>

Reviewed-by: Vasant Hegde <vasant.hegde at amd.com>


> ---
>  drivers/iommu/amd/iommu.c | 7 -------
>  1 file changed, 7 deletions(-)
> 
> diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
> index 2e1865daa1cee8..d4d9a5dbfa6333 100644
> --- a/drivers/iommu/amd/iommu.c
> +++ b/drivers/iommu/amd/iommu.c
> @@ -854,13 +854,6 @@ static void amd_iommu_report_page_fault(struct amd_iommu *iommu,
>  						   PCI_FUNC(devid), domain_id);
>  				goto out;
>  			}

If you're planning to respin this series, could you please update the comment
above the if condition?

-Vasant


> -
> -			if (!report_iommu_fault(&dev_data->domain->domain,
> -						&pdev->dev, address,
> -						IS_WRITE_REQUEST(flags) ?
> -							IOMMU_FAULT_WRITE :
> -							IOMMU_FAULT_READ))
> -				goto out;
>  		}
>  
>  		if (__ratelimit(&dev_data->rs)) {



From vasant.hegde at amd.com  Sat Nov  8 03:20:41 2025
From: vasant.hegde at amd.com (Vasant Hegde)
Date: Sat, 8 Nov 2025 16:50:41 +0530
Subject: [PATCH v2 3/3] iommu: Allow drivers to say if they use
 report_iommu_fault()
In-Reply-To: <3-v2-25fc75484cab+ab-iommu_set_fault_jgg@nvidia.com>
References: <3-v2-25fc75484cab+ab-iommu_set_fault_jgg@nvidia.com>
Message-ID: <70252b95-6980-423b-a7cb-005f5064fe45@amd.com>

On 11/7/2025 2:04 AM, Jason Gunthorpe wrote:
> report_iommu_fault() is an older API that has been superseded by
> iommu_report_device_fault() which is capable to support PRI.
> 
> Only two external drivers consume this, drivers/remoteproc and
> drivers/gpu/drm/msm. Ideally they would move over to the new APIs, but for
> now protect against accidentally mix and matching the wrong components.
> 
> The iommu drivers support either the old iommu_set_fault_handler() via the
> driver calling report_iommu_fault(), or they are newer server focused
> drivers that call iommu_report_device_fault().
> 
> Include a flag in the iommu_ops if the driver calls report_iommu_fault()
> and block iommu_set_fault_handler() for domain's of iommu drivers that
> can't support it.
> 
> Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
> Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>

Reviewed-by: Vasant Hegde <vasant.hegde at amd.com>

-Vasant




From cassel at kernel.org  Sat Nov  8 04:34:26 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Sat, 8 Nov 2025 13:34:26 +0100
Subject: [PATCH] PCI: dw-rockchip: Skip waiting for link up
In-Reply-To: <6e87b611-13ea-4d89-8dbf-85510dd86fa6@rock-chips.com>
References: <20250113-rockchip-no-wait-v1-1-25417f37b92f@kernel.org>
 <1E8E4DB773970CB5+5a52c9e1-01b8-4872-99b7-021099f04031@radxa.com>
 <6e87b611-13ea-4d89-8dbf-85510dd86fa6@rock-chips.com>
Message-ID: <aQ840q5BxNS1eIai@ryzen>

Hello Shawn,

On Tue, Oct 21, 2025 at 03:10:13PM +0800, Shawn Lin wrote:
> ? 2025/10/21 ??? 12:26, FUKAUMI Naoki ??:
> > Hi Niklas, Bjorn,
> > 
> > I noticed an issue on the Rockchip RK3588S SoC using the ASMedia ASM2806
> > PCIe bridge where devices behind the bridge fail to probe since v6.14.
> > Specifically, this started happening after commit
> > 647d69605c70368d54fc012fce8a43e8e5955b04.
> > dmesg logs from before and after this commit are available at:
> >  ?https://gist.github.com/RadxaNaoki/fca2bfca2ee80fefee7b00c7967d2e3d
> > 
> > I have confirmed that reverting the following commits fixes the issue:
> >  ?commit ec9fd499b9c6 ("PCI: dw-rockchip: Don't wait for link since we
> > can detect Link Up")
> >  ?commit 0e0b45ab5d77 ("PCI: dw-rockchip: Enumerate endpoints based on
> > dll_link_up IRQ")
> > 
> 
> Then these two commits would like to reply on link up irq instead of
> fixed delay in dwc framework. Here is a not very precise timeline
> description.
> 
> time(ms) |  dw_pcie_wait_for_link??     | sys irq_thread() | Hot reset
> -------------------------------------------------------------------------
> 0:       |  dw_pcie_link_up return false  |  link up irq     |
> 1x       |  Physical link up happend      |                  |
> 90:      |  dw_pcie_link_up return true   |                  |
> 100:     |                                |  msleep(100) done|
> 10x:     |                                |  pci_rescan_bus  |
> 1xx:     |                                |                  | <==occur
> 190:     |  msleep(90) done               |                  |
> 19x:     |  pci_host_probe                |                  |
> 
> What if the hot reset happens when pci_rescan_bus() starts. I think
> scan devices possible fail when seeing 0xffffffff from cfg read. But
> a 90ms delay perfectly avoids this event in dw_pcie_wait_for_link(), and by
> the time the 90ms delay is completed, the link is actually in an
> accessible state.

The pcie-dw-rockchip.c driver is modelled after the qcom driver.
So if this is a problem when a ASM2806 switch is connected, I would
expect qcom platforms to have the same problem.


Do we have a PCI trace that can tell us exactly what goes wrong?

FUKAUMI-san tells us that the enumeration does not detect any devices,
but also that there is no crash.

If we assume the scenario from your timeline above, that a hot reset
happens just after pci_rescan_bus(), after a hot reset, LTSSM should
re-enter link training.

I verified this:
# bc=$(setpci -s 0000:00:00.0 BRIDGE_CONTROL)
# setpci -s 0000:00:00.0 BRIDGE_CONTROL=$(printf "%04x" $((0x$bc | 0x40))) && sl eep 0.01 && setpci -s 0000:00:00.0 BRIDGE_CONTROL=$bc
[   65.723990] rockchip-dw-pcie a40000000.pcie: PCIE_CLIENT_INTR_STATUS_MISC: 0x7
[   65.724701] rockchip-dw-pcie a40000000.pcie: LTSSM_STATUS: 0x30011
[   65.825787] rockchip-dw-pcie a40000000.pcie: Received Link up event. Starting enumeration!

So we get another link up IRQ after the hot reset.

The IRQ handler for this IRQ will once again call pci_rescan_bus().
So I would expect that this second pci_rescan_bus() call would actually
be able to find the device behind the switch.


Mani, Bjorn, thoughts?



Kind regards,
Niklas


From cassel at kernel.org  Sat Nov  8 05:27:52 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Sat, 8 Nov 2025 14:27:52 +0100
Subject: [PATCH] PCI: dw-rockchip: Skip waiting for link up
In-Reply-To: <aQ840q5BxNS1eIai@ryzen>
References: <20250113-rockchip-no-wait-v1-1-25417f37b92f@kernel.org>
 <1E8E4DB773970CB5+5a52c9e1-01b8-4872-99b7-021099f04031@radxa.com>
 <6e87b611-13ea-4d89-8dbf-85510dd86fa6@rock-chips.com>
 <aQ840q5BxNS1eIai@ryzen>
Message-ID: <aQ9FWEuW47L8YOxC@ryzen>

On Sat, Nov 08, 2025 at 01:34:32PM +0100, Niklas Cassel wrote:
> 
> The pcie-dw-rockchip.c driver is modelled after the qcom driver.
> So if this is a problem when a ASM2806 switch is connected, I would
> expect qcom platforms to have the same problem.

Looking more closely at this, comparing the "good" kernel:

[    1.868857] pci 0004:40:00.0: [1d87:3588] type 01 class 0x060400 PCIe Root Port
[    1.869509] pci 0004:40:00.0: ROM [mem 0x00000000-0x0000ffff pref]
[    1.870050] pci 0004:40:00.0: PCI bridge to [bus 01-ff]
[    1.870510] pci 0004:40:00.0:   bridge window [io  0x0000-0x0fff]
[    1.871044] pci 0004:40:00.0:   bridge window [mem 0x00000000-0x000fffff]
[    1.871640] pci 0004:40:00.0:   bridge window [mem 0x00000000-0x000fffff 64bit pref]
[    1.872353] pci 0004:40:00.0: supports D1 D2
[    1.872738] pci 0004:40:00.0: PME# supported from D0 D1 D3hot
[    1.875190] pci 0004:40:00.0: Primary bus is hard wired to 0
[    1.875690] pci 0004:40:00.0: bridge configuration invalid ([bus 01-ff]), reconfiguring
[    1.876543] pci 0004:41:00.0: [1b21:2806] type 01 class 0x060400 PCIe Switch Upstream Port
[    1.877384] pci 0004:41:00.0: PCI bridge to [bus 00]
[    1.877846] pci 0004:41:00.0:   bridge window [io  0x0000-0x0fff]
[    1.878389] pci 0004:41:00.0:   bridge window [mem 0x00000000-0x000fffff]
[    1.879030] pci 0004:41:00.0:   bridge window [mem 0x00000000-0x000fffff 64bit pref]
[    1.879764] pci 0004:41:00.0: enabling Extended Tags
[    1.880614] pci 0004:41:00.0: PME# supported from D0 D3hot D3cold
[    1.881409] pci 0004:41:00.0: 2.000 Gb/s available PCIe bandwidth, limited by 2.5 GT/s PCIe x1 link at 0004:40:00.0 (capable of 15.752 Gb/s with 8.0 GT/s PCIe x2 link)
[    1.888729] pci 0004:41:00.0: bridge configuration invalid ([bus 00-00]), reconfiguring
[    1.889766] pci 0004:42:00.0: [1b21:2806] type 01 class 0x060400 PCIe Switch Downstream Port
[    1.890621] pci 0004:42:00.0: PCI bridge to [bus 00]
[    1.891084] pci 0004:42:00.0:   bridge window [io  0x0000-0x0fff]
[    1.891628] pci 0004:42:00.0:   bridge window [mem 0x00000000-0x000fffff]
[    1.892269] pci 0004:42:00.0:   bridge window [mem 0x00000000-0x000fffff 64bit pref]
[    1.893028] pci 0004:42:00.0: enabling Extended Tags
...
[    1.928510] pci_bus 0004:43: busn_res: [bus 43-4f] end is updated to 44
[    1.929432] pci_bus 0004:45: busn_res: [bus 45-4f] end is updated to 45
[    1.944674] pci_bus 0004:46: busn_res: [bus 46-4f] end is updated to 46
[    1.956691] pci_bus 0004:47: busn_res: [bus 47-4f] end is updated to 47
[    1.957298] pci_bus 0004:42: busn_res: [bus 42-4f] end is updated to 47
[    1.957893] pci_bus 0004:41: busn_res: [bus 41-4f] end is updated to 47


With the "bad" kernel:
[    1.383075] pci 0004:40:00.0: [1d87:3588] type 01 class 0x060400 PCIe Root Port
[    1.383738] pci 0004:40:00.0: ROM [mem 0x00000000-0x0000ffff pref]
[    1.384280] pci 0004:40:00.0: PCI bridge to [bus 01-ff]
[    1.384740] pci 0004:40:00.0:   bridge window [io  0x0000-0x0fff]
[    1.385274] pci 0004:40:00.0:   bridge window [mem 0x00000000-0x000fffff]
[    1.385871] pci 0004:40:00.0:   bridge window [mem 0x00000000-0x000fffff 64bit pref]
[    1.386582] pci 0004:40:00.0: supports D1 D2
[    1.386957] pci 0004:40:00.0: PME# supported from D0 D1 D3hot
[    1.389549] pci 0004:40:00.0: Primary bus is hard wired to 0
[    1.390062] pci 0004:40:00.0: bridge configuration invalid ([bus 01-ff]), reconfiguring
[    1.390897] pci_bus 0004:41: busn_res: [bus 41-4f] end is updated to 41
[    1.391505] pci 0004:40:00.0: ROM [mem 0xf4200000-0xf420ffff pref]: assigned
[    1.392130] pci 0004:40:00.0: PCI bridge to [bus 41]
[    1.392607] pci_bus 0004:40: resource 4 [io  0x0000-0xfffff]
[    1.393103] pci_bus 0004:40: resource 5 [mem 0xf4200000-0xf4ffffff]
[    1.393657] pci_bus 0004:40: resource 6 [mem 0xa00000000-0xa3fffffff]
[    1.412296] pci 0004:41:00.0: [1b21:2806] type 01 class 0x060400 PCIe Switch Upstream Port
[    1.413155] pci 0004:41:00.0: PCI bridge to [bus 00]
[    1.413641] pci 0004:41:00.0:   bridge window [io  0x0000-0x0fff]
[    1.414204] pci 0004:41:00.0:   bridge window [mem 0x00000000-0x000fffff]
[    1.414934] pci 0004:41:00.0:   bridge window [mem 0x00000000-0x000fffff 64bit pref]
[    1.415746] pci 0004:41:00.0: enabling Extended Tags
[    1.416465] pci 0004:41:00.0: PME# supported from D0 D3hot D3cold
[    1.417181] pci 0004:41:00.0: 4.000 Gb/s available PCIe bandwidth, limited by 5.0 GT/s PCIe x1 link at 0004:40:00.0 (capable of 15.752 Gb/s with 8.0 GT/s PCIe x2 link)
[    1.423384] pci 0004:41:00.0: bridge configuration invalid ([bus 00-00]), reconfiguring
[    1.424348] pci_bus 0004:42: busn_res: can not insert [bus 42-41] under [bus 41] (conflicts with (null) [bus 41])
[    1.425351] pci 0004:42:00.0: [1b21:2806] type 01 class 0x060400 PCIe Switch Downstream Port
[    1.426698] pci 0004:42:00.0: PCI bridge to [bus 00]
[    1.427184] pci 0004:42:00.0:   bridge window [io  0x0000-0x0fff]
[    1.427766] pci 0004:42:00.0:   bridge window [mem 0x00000000-0x000fffff]
[    1.428415] pci 0004:42:00.0:   bridge window [mem 0x00000000-0x000fffff 64bit pref]
[    1.429171] pci 0004:42:00.0: enabling Extended Tags
...
[    1.462051] pci_bus 0004:43: busn_res: can not insert [bus 43-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
[    1.463116] pci_bus 0004:43: busn_res: [bus 43-41] end is updated to 43
[    1.463718] pci_bus 0004:43: busn_res: can not insert [bus 43] under [bus 42-41] (conflicts with (null) [bus 42-41])
[    1.464651] pci 0004:42:00.0: devices behind bridge are unusable because [bus 43] cannot be assigned for them
[    1.465688] pci_bus 0004:44: busn_res: can not insert [bus 44-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
[    1.466747] pci_bus 0004:44: busn_res: [bus 44-41] end is updated to 44
[    1.467351] pci_bus 0004:44: busn_res: can not insert [bus 44] under [bus 42-41] (conflicts with (null) [bus 42-41])
[    1.468283] pci 0004:42:02.0: devices behind bridge are unusable because [bus 44] cannot be assigned for them
[    1.469322] pci_bus 0004:45: busn_res: can not insert [bus 45-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
[    1.470370] pci_bus 0004:45: busn_res: [bus 45-41] end is updated to 45
[    1.470960] pci_bus 0004:45: busn_res: can not insert [bus 45] under [bus 42-41] (conflicts with (null) [bus 42-41])
[    1.471902] pci 0004:42:06.0: devices behind bridge are unusable because [bus 45] cannot be assigned for them
[    1.472930] pci_bus 0004:46: busn_res: can not insert [bus 46-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
[    1.473985] pci_bus 0004:46: busn_res: [bus 46-41] end is updated to 46
[    1.474578] pci_bus 0004:46: busn_res: can not insert [bus 46] under [bus 42-41] (conflicts with (null) [bus 42-41])
[    1.475530] pci 0004:42:0e.0: devices behind bridge are unusable because [bus 46] cannot be assigned for them
[    1.476414] pci_bus 0004:42: busn_res: [bus 42-41] end is updated to 46
[    1.477001] pci_bus 0004:42: busn_res: can not insert [bus 42-46] under [bus 41] (conflicts with (null) [bus 41])
[    1.477911] pci 0004:41:00.0: devices behind bridge are unusable because [bus 42-46] cannot be assigned for them
[    1.478814] pcieport 0004:40:00.0: bridge has subordinate 41 but max busn 46


We can see that the pcie-dw-rockchip.c driver detects the ASM2806 switch
in both cases. So the problem is not really with enumerating the root port.

The problem seems to be that with the "bad" kernel, you get a lot of:
[    1.464651] pci 0004:42:00.0: devices behind bridge are unusable because [bus 43] cannot be assigned for them

Because the bus ends are different, and conflicts with each other.
I don't know why this happens.

Perhaps we could add a quirk for ASM2806 that does some extra sleep if that
switch is detected, if for some reason, the switch is not actually ready
after the delays defined by the PCIe specification.

(And btw. please test with the latest 6.18-rc, as, from experience, the
ASPM problems in earlier RCs can result in some weird problems that are
not immediately deduced to be caused by the ASPM enablement.)


Kind regards,
Niklas


From diederik at cknow-tech.com  Sat Nov  8 06:21:45 2025
From: diederik at cknow-tech.com (Diederik de Haas)
Date: Sat, 08 Nov 2025 15:21:45 +0100
Subject: [PATCH] PCI: dw-rockchip: Skip waiting for link up
In-Reply-To: <aQ9FWEuW47L8YOxC@ryzen>
References: <20250113-rockchip-no-wait-v1-1-25417f37b92f@kernel.org>
 <1E8E4DB773970CB5+5a52c9e1-01b8-4872-99b7-021099f04031@radxa.com>
 <6e87b611-13ea-4d89-8dbf-85510dd86fa6@rock-chips.com>
 <aQ840q5BxNS1eIai@ryzen> <aQ9FWEuW47L8YOxC@ryzen>
Message-ID: <DE3DPAVIOGZP.7RW4SGB8HXUT@cknow-tech.com>

On Sat Nov 8, 2025 at 2:27 PM CET, Niklas Cassel wrote:
> On Sat, Nov 08, 2025 at 01:34:32PM +0100, Niklas Cassel wrote:
>> 
>> The pcie-dw-rockchip.c driver is modelled after the qcom driver.
>> So if this is a problem when a ASM2806 switch is connected, I would
>> expect qcom platforms to have the same problem.
>
> Looking more closely at this, comparing the "good" kernel:

There's another thing that caught my eye ...

> [    1.868857] pci 0004:40:00.0: [1d87:3588] type 01 class 0x060400 PCIe Root Port
> [    1.869509] pci 0004:40:00.0: ROM [mem 0x00000000-0x0000ffff pref]
> ...
> [    1.879764] pci 0004:41:00.0: enabling Extended Tags
> [    1.880614] pci 0004:41:00.0: PME# supported from D0 D3hot D3cold
> [    1.881409] pci 0004:41:00.0: 2.000 Gb/s available PCIe bandwidth, limited by 2.5 GT/s PCIe x1 link at 0004:40:00.0 (capable of 15.752 Gb/s with 8.0 GT/s PCIe x2 link)

... 2.000 Gb/s ...

> [    1.888729] pci 0004:41:00.0: bridge configuration invalid ([bus 00-00]), reconfiguring
> ...
>
>
> With the "bad" kernel:
> [    1.383075] pci 0004:40:00.0: [1d87:3588] type 01 class 0x060400 PCIe Root Port
> [    1.383738] pci 0004:40:00.0: ROM [mem 0x00000000-0x0000ffff pref]
> ...
> [    1.415746] pci 0004:41:00.0: enabling Extended Tags
> [    1.416465] pci 0004:41:00.0: PME# supported from D0 D3hot D3cold
> [    1.417181] pci 0004:41:00.0: 4.000 Gb/s available PCIe bandwidth, limited by 5.0 GT/s PCIe x1 link at 0004:40:00.0 (capable of 15.752 Gb/s with 8.0 GT/s PCIe x2 link)

... 4.0000 Gb/s

I don't know if that's relevant or important, but wanted to mention it.

Cheers,
  Diederik

> [    1.423384] pci 0004:41:00.0: bridge configuration invalid ([bus 00-00]), reconfiguring
> ...
>
>
> We can see that the pcie-dw-rockchip.c driver detects the ASM2806 switch
> in both cases. So the problem is not really with enumerating the root port.
>
> The problem seems to be that with the "bad" kernel, you get a lot of:
> [    1.464651] pci 0004:42:00.0: devices behind bridge are unusable because [bus 43] cannot be assigned for them
>
> Because the bus ends are different, and conflicts with each other.
> I don't know why this happens.
>
> Perhaps we could add a quirk for ASM2806 that does some extra sleep if that
> switch is detected, if for some reason, the switch is not actually ready
> after the delays defined by the PCIe specification.
>
> (And btw. please test with the latest 6.18-rc, as, from experience, the
> ASPM problems in earlier RCs can result in some weird problems that are
> not immediately deduced to be caused by the ASPM enablement.)
>
>
> Kind regards,
> Niklas


From sebastian.reichel at collabora.com  Sat Nov  8 14:12:54 2025
From: sebastian.reichel at collabora.com (Sebastian Reichel)
Date: Sat, 8 Nov 2025 23:12:54 +0100
Subject: [PATCH] arm64: dts: rockchip: align bindings to PCIe spec
In-Reply-To: <d9e257bd-806c-48b4-bb22-f1342e9fc15a@rock-chips.com>
References: <4b5ffcccfef2a61838aa563521672a171acb27b2.1762321976.git.geraldogabriel@gmail.com>
 <ba120577-42da-424d-8102-9d085c1494c8@rock-chips.com>
 <aQsIXcQzeYop6a0B@geday>
 <67b605b0-7046-448a-bc9b-d3ac56333809@rock-chips.com>
 <aQ1c7ZDycxiOIy8Y@geday>
 <d9e257bd-806c-48b4-bb22-f1342e9fc15a@rock-chips.com>
Message-ID: <sbulnlwz3vxyk3yw2c2tcsdvyu57cdvyixkpeq2okh4vn6yyod@4o4kltfb5u6n>

Hi,

On Fri, Nov 07, 2025 at 11:01:04AM +0800, Shawn Lin wrote:
> + Ye Zhang
> 
> ? 2025/11/07 ??? 10:43, Geraldo Nascimento ??:
> > On Wed, Nov 05, 2025 at 04:56:36PM +0800, Shawn Lin wrote:
> > > ? 2025/11/05 ??? 16:18, Geraldo Nascimento ??:
> > > > Hi Shawn, glad to hear from you.
> > > > 
> > > > Perhaps the following change is better? It resolves the issue
> > > > without the added complication of open drain. After you questioned
> > > > if open drain is actually part of the spec, I remembered that
> > > > GPIO_OPEN_DRAIN is actually (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_DRAIN)
> > > > so I decided to test with just GPIO_SINGLE_ENDED and it works.
> > 
> > Shawn,
> > 
> > I quote from the PCIe Mini Card Electromechanical Specification Rev 1.2
> > 
> > "3.4.1. Logic Signal Requirements
> > 
> > The 3.3V card logic levels for single-ended digital signals (WAKE#,
> > CLKREQ#, PERST#, and W_DISABLE#) are given in Table 3-7. [...]"
> > 
> > So while you are correct that PERST# is most definitely not Open Drain,
> > there's evidence on the spec that defines this signal as Single-Ended.
> > 
> 
> This's true. But I couldn't find any user in dts using either
> GPIO_SINGLE_ENDED or GPIO_OPEN_DRAIN for PCIe PERST#. I'm curious
> how these two flags affect actual behavior of chips. Ye, could you
> please help check it?

FWIW I assume single-ended in the spec means it's not differential
like all the highspeed signals on the PCIe connection. This says
nothing about open-drain, open-source or push-pull being used. The
kernel on the other hand has a very specific understanding of
GPIO_SINGLE_ENDED:

	if (flags & OF_GPIO_SINGLE_ENDED) {
		if (flags & OF_GPIO_OPEN_DRAIN)
			lflags |= GPIO_OPEN_DRAIN;
		else
			lflags |= GPIO_OPEN_SOURCE;
	}

I.e. it is the same as configuring open-source ;)

Greetings,

-- Sebastian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251108/d3aa5038/attachment.sig>

From geraldogabriel at gmail.com  Sat Nov  8 14:43:17 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Sat, 8 Nov 2025 19:43:17 -0300
Subject: [PATCH] arm64: dts: rockchip: align bindings to PCIe spec
In-Reply-To: <sbulnlwz3vxyk3yw2c2tcsdvyu57cdvyixkpeq2okh4vn6yyod@4o4kltfb5u6n>
References: <4b5ffcccfef2a61838aa563521672a171acb27b2.1762321976.git.geraldogabriel@gmail.com>
 <ba120577-42da-424d-8102-9d085c1494c8@rock-chips.com>
 <aQsIXcQzeYop6a0B@geday>
 <67b605b0-7046-448a-bc9b-d3ac56333809@rock-chips.com>
 <aQ1c7ZDycxiOIy8Y@geday>
 <d9e257bd-806c-48b4-bb22-f1342e9fc15a@rock-chips.com>
 <sbulnlwz3vxyk3yw2c2tcsdvyu57cdvyixkpeq2okh4vn6yyod@4o4kltfb5u6n>
Message-ID: <aQ_HhfK0pbOE1m1R@geday>

On Sat, Nov 08, 2025 at 11:12:54PM +0100, Sebastian Reichel wrote:
> Hi,

Hi Sebastian,

> 
> On Fri, Nov 07, 2025 at 11:01:04AM +0800, Shawn Lin wrote:
> > + Ye Zhang
> > 
> > ? 2025/11/07 ??? 10:43, Geraldo Nascimento ??:
> > > On Wed, Nov 05, 2025 at 04:56:36PM +0800, Shawn Lin wrote:
> > > > ? 2025/11/05 ??? 16:18, Geraldo Nascimento ??:
> > > > > Hi Shawn, glad to hear from you.
> > > > > 
> > > > > Perhaps the following change is better? It resolves the issue
> > > > > without the added complication of open drain. After you questioned
> > > > > if open drain is actually part of the spec, I remembered that
> > > > > GPIO_OPEN_DRAIN is actually (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_DRAIN)
> > > > > so I decided to test with just GPIO_SINGLE_ENDED and it works.
> > > 
> > > Shawn,
> > > 
> > > I quote from the PCIe Mini Card Electromechanical Specification Rev 1.2
> > > 
> > > "3.4.1. Logic Signal Requirements
> > > 
> > > The 3.3V card logic levels for single-ended digital signals (WAKE#,
> > > CLKREQ#, PERST#, and W_DISABLE#) are given in Table 3-7. [...]"
> > > 
> > > So while you are correct that PERST# is most definitely not Open Drain,
> > > there's evidence on the spec that defines this signal as Single-Ended.
> > > 
> > 
> > This's true. But I couldn't find any user in dts using either
> > GPIO_SINGLE_ENDED or GPIO_OPEN_DRAIN for PCIe PERST#. I'm curious
> > how these two flags affect actual behavior of chips. Ye, could you
> > please help check it?
> 
> FWIW I assume single-ended in the spec means it's not differential
> like all the highspeed signals on the PCIe connection. This says
> nothing about open-drain, open-source or push-pull being used. The

yes, I agree. It was an oversight on my part to assume open-drain on
PERST# was part of the spec just because many cores implement it that
way. Kudos to Shawn for correcting me.

> kernel on the other hand has a very specific understanding of
> GPIO_SINGLE_ENDED:
> 
> 	if (flags & OF_GPIO_SINGLE_ENDED) {
> 		if (flags & OF_GPIO_OPEN_DRAIN)
> 			lflags |= GPIO_OPEN_DRAIN;
> 		else
> 			lflags |= GPIO_OPEN_SOURCE;
> 	}
> 
> I.e. it is the same as configuring open-source ;)

Yup, I had noticed that. This works because the reset value of PMU GRF
register PMUGRF_GPIO0B_P sets the relevant PERST# GPIO (GPIO0-12) on my
board to pull-down, which can work with Open Source/Emitter. If we set
the GPIO to Open Drain/Collector we must on the other hand set that pin
to pull-up. Either way it works.

I've been investigating why that GPIO isn't properly working as
Push-Pull for my board (Rock PI N10) but so far I'm clueless.

Thank you,
Geraldo Nascimento

> 
> Greetings,
> 
> -- Sebastian




From naoki at radxa.com  Sat Nov  8 20:42:23 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Sun, 9 Nov 2025 13:42:23 +0900
Subject: [PATCH] PCI: dw-rockchip: Skip waiting for link up
In-Reply-To: <aQ9FWEuW47L8YOxC@ryzen>
References: <20250113-rockchip-no-wait-v1-1-25417f37b92f@kernel.org>
 <1E8E4DB773970CB5+5a52c9e1-01b8-4872-99b7-021099f04031@radxa.com>
 <6e87b611-13ea-4d89-8dbf-85510dd86fa6@rock-chips.com>
 <aQ840q5BxNS1eIai@ryzen> <aQ9FWEuW47L8YOxC@ryzen>
Message-ID: <55EB0E5F655F3AFC+136b89fd-98d4-42af-a99d-a0bb05cc93f3@radxa.com>

Hi Niklas,

On 11/8/25 22:27, Niklas Cassel wrote:
(snip)> (And btw. please test with the latest 6.18-rc, as, from 
experience, the
> ASPM problems in earlier RCs can result in some weird problems that are
> not immediately deduced to be caused by the ASPM enablement.)

Here is dmesg from v6.18-rc4:
  https://gist.github.com/RadxaNaoki/40e1d049bff4f1d2d4773a5ba0ed9dff

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> Kind regards,
> Niklas
> 



From cassel at kernel.org  Sun Nov  9 04:28:22 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Sun, 9 Nov 2025 13:28:22 +0100
Subject: [PATCH] PCI: dw-rockchip: Skip waiting for link up
In-Reply-To: <55EB0E5F655F3AFC+136b89fd-98d4-42af-a99d-a0bb05cc93f3@radxa.com>
References: <20250113-rockchip-no-wait-v1-1-25417f37b92f@kernel.org>
 <1E8E4DB773970CB5+5a52c9e1-01b8-4872-99b7-021099f04031@radxa.com>
 <6e87b611-13ea-4d89-8dbf-85510dd86fa6@rock-chips.com>
 <aQ840q5BxNS1eIai@ryzen>
 <aQ9FWEuW47L8YOxC@ryzen>
 <55EB0E5F655F3AFC+136b89fd-98d4-42af-a99d-a0bb05cc93f3@radxa.com>
Message-ID: <aRCI5kG16_1erMME@ryzen>

On Sun, Nov 09, 2025 at 01:42:23PM +0900, FUKAUMI Naoki wrote:
> Hi Niklas,
> 
> On 11/8/25 22:27, Niklas Cassel wrote:
> (snip)> (And btw. please test with the latest 6.18-rc, as, from experience,
> the
> > ASPM problems in earlier RCs can result in some weird problems that are
> > not immediately deduced to be caused by the ASPM enablement.)
> 
> Here is dmesg from v6.18-rc4:
>  https://gist.github.com/RadxaNaoki/40e1d049bff4f1d2d4773a5ba0ed9dff

Same problem as before:
[    1.732538] pci_bus 0004:43: busn_res: can not insert [bus 43-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
[    1.732645] pci_bus 0004:43: busn_res: [bus 43-41] end is updated to 43
[    1.732651] pci_bus 0004:43: busn_res: can not insert [bus 43] under [bus 42-41] (conflicts with (null) [bus 42-41])
[    1.732661] pci 0004:42:00.0: devices behind bridge are unusable because [bus 43] cannot be assigned for them
[    1.732840] pci_bus 0004:44: busn_res: can not insert [bus 44-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
[    1.732947] pci_bus 0004:44: busn_res: [bus 44-41] end is updated to 44
[    1.732952] pci_bus 0004:44: busn_res: can not insert [bus 44] under [bus 42-41] (conflicts with (null) [bus 42-41])
[    1.732962] pci 0004:42:02.0: devices behind bridge are unusable because [bus 44] cannot be assigned for them
[    1.733134] pci_bus 0004:45: busn_res: can not insert [bus 45-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
[    1.733246] pci_bus 0004:45: busn_res: [bus 45-41] end is updated to 45
[    1.733255] pci_bus 0004:45: busn_res: can not insert [bus 45] under [bus 42-41] (conflicts with (null) [bus 42-41])
[    1.733266] pci 0004:42:06.0: devices behind bridge are unusable because [bus 45] cannot be assigned for them
[    1.733438] pci_bus 0004:46: busn_res: can not insert [bus 46-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
[    1.733544] pci_bus 0004:46: busn_res: [bus 46-41] end is updated to 46
[    1.733550] pci_bus 0004:46: busn_res: can not insert [bus 46] under [bus 42-41] (conflicts with (null) [bus 42-41])
[    1.733560] pci 0004:42:0e.0: devices behind bridge are unusable because [bus 46] cannot be assigned for them
[    1.733571] pci_bus 0004:42: busn_res: [bus 42-41] end is updated to 46
[    1.733575] pci_bus 0004:42: busn_res: can not insert [bus 42-46] under [bus 41] (conflicts with (null) [bus 41])
[    1.733585] pci 0004:41:00.0: devices behind bridge are unusable because [bus 42-46] cannot be assigned for them
[    1.733596] pcieport 0004:40:00.0: bridge has subordinate 41 but max busn 46


Seems like the ASM2806 switch, for some reason, is not ready.

One change that Diederik pointed out is that in the "good" case,
the link is always in Gen1 speed.

Perhaps you could build with CONFIG_PCI_QUIRKS=y and try this patch:

diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 214ed060ca1b..ac134d95a97f 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -96,6 +96,7 @@ int pcie_failed_link_retrain(struct pci_dev *dev)
 {
 	static const struct pci_device_id ids[] = {
 		{ PCI_VDEVICE(ASMEDIA, 0x2824) }, /* ASMedia ASM2824 */
+		{ PCI_VDEVICE(ASMEDIA, 0x2806) }, /* ASMedia ASM2806 */
 		{}
 	};
 	u16 lnksta, lnkctl2;





If that does not work, perhaps you could try this patch
(assuming that all Rock 5C:s have a ASM2806 on pcie2x1l2):

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
index dd7317bab613..26f8539d934a 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
@@ -452,6 +452,7 @@ &pcie2x1l2 {
 	pinctrl-0 = <&pcie20x1_2_perstn_m0>;
 	reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
 	vpcie3v3-supply = <&pcie2x1l2_3v3>;
+	max-link-speed = <1>;
 	status = "okay";
 };



Kind regards,
Niklas


From naoki at radxa.com  Sun Nov  9 06:18:53 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Sun,  9 Nov 2025 14:18:53 +0000
Subject: [PATCH v7 08/14] arm64: dts: rockchip: Make eeprom read-only for Radxa ROCK 5C
In-Reply-To: <20251109141859.206835-1-naoki@radxa.com>
References: <20251109141859.206835-1-naoki@radxa.com>
Message-ID: <20251109141859.206835-9-naoki@radxa.com>

Make EEPROM read-only as it may contain factory-programmed
board-specific data.

Fixes: 3ddf5cdb77e6 ("arm64: dts: rockchip: add Radxa ROCK 5C")
Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
Changes in v7:
- New
---
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
index e3f286df93b05..4f5376d0d109c 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
@@ -325,6 +325,7 @@ eeprom at 50 {
 		compatible = "belling,bl24c16a", "atmel,24c16";
 		reg = <0x50>;
 		pagesize = <16>;
+		read-only;
 		vcc-supply = <&vcc_3v3_pmu>;
 	};
 };
-- 
2.43.0



From naoki at radxa.com  Sun Nov  9 06:18:47 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Sun,  9 Nov 2025 14:18:47 +0000
Subject: [PATCH v7 02/14] arm64: dts: rockchip: Use a longer PWM period for the fan on Radxa ROCK 5C
In-Reply-To: <20251109141859.206835-1-naoki@radxa.com>
References: <20251109141859.206835-1-naoki@radxa.com>
Message-ID: <20251109141859.206835-3-naoki@radxa.com>

The fan on Radxa ROCK 5C is driven via an AO3416 MOSFET, which has a
total switch-on time of 0.6us and a total switch-off time of 6us [1],
meaning that the current PWM period of just 10us is too short for
fine-grained fan speed control. Increase the PWM period to 60us, so
that the switch-on and switch-off time of the MOSFET fall within a
more reasonable ~10% of the full period, thus making lower PWM duty
cycles meaningful.

[1] https://www.aosmd.com/pdfs/datasheet/AO3416.pdf

Fixes: 3ddf5cdb77e6 ("arm64: dts: rockchip: add Radxa ROCK 5C")
Reviewed-by: Dragan Simic <dsimic at manjaro.org>
Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
Changes in v7:
- Collect R-b tag
- Reword commit message
Changes in v6:
- None
Changes in v5:
- Reword commit message (Alexey Charkov)
Changes in v4:
- None
Changes in v3:
- None
Changes in v2:
- Reword commit message
---
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
index 378a65e2561ad..086b4f45fabf3 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
@@ -73,7 +73,7 @@ fan: fan {
 		#cooling-cells = <2>;
 		cooling-levels = <0 24 44 64 128 192 255>;
 		fan-supply = <&vcc_5v0>;
-		pwms = <&pwm3 0 10000 0>;
+		pwms = <&pwm3 0 60000 0>;
 	};
 
 	pcie2x1l2_3v3: regulator-pcie2x1l2-3v3 {
-- 
2.43.0



From naoki at radxa.com  Sun Nov  9 06:18:49 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Sun,  9 Nov 2025 14:18:49 +0000
Subject: [PATCH v7 04/14] arm64: dts: rockchip: Fix microSD card detect for Radxa ROCK 5C
In-Reply-To: <20251109141859.206835-1-naoki@radxa.com>
References: <20251109141859.206835-1-naoki@radxa.com>
Message-ID: <20251109141859.206835-5-naoki@radxa.com>

Due to the discussion about cd-gpios and sdmmmc_det pin
functionality[1], it would be better to use cd-gpios for now.

[1] https://lore.kernel.org/linux-rockchip/20240912152538.1.I858c2a0bf83606c8b59ba1ab6944978a398d2ac5 at changeid/T/#u

Fixes: 3ddf5cdb77e6 ("arm64: dts: rockchip: add Radxa ROCK 5C")
Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
Changes in v7:
- Add pinctrl-*
- Reword commit message
Changes in v6:
- Reword commit message
Changes in v5:
- Reword commit message
Changes in v4:
- None
Changes in v3:
- None
Changes in v2:
- None
---
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
index 9a9430b2494b7..1257aaac8f350 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
@@ -510,9 +510,12 @@ &sdmmc {
 	bus-width = <4>;
 	cap-mmc-highspeed;
 	cap-sd-highspeed;
+	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
 	disable-wp;
 	no-sdio;
 	no-mmc;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd>;
 	sd-uhs-sdr104;
 	vmmc-supply = <&vcc_3v3_s3>;
 	vqmmc-supply = <&vccio_sd_s0>;
-- 
2.43.0



From naoki at radxa.com  Sun Nov  9 06:18:58 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Sun,  9 Nov 2025 14:18:58 +0000
Subject: [PATCH v7 13/14] arm64: dts: rockchip: Enable NPU for Radxa ROCK 5C
In-Reply-To: <20251109141859.206835-1-naoki@radxa.com>
References: <20251109141859.206835-1-naoki@radxa.com>
Message-ID: <20251109141859.206835-14-naoki@radxa.com>

Enable NPU for Radxa ROCK 5C.

Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
Changes in v7:
- New
---
 .../boot/dts/rockchip/rk3588s-rock-5c.dts     | 34 +++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
index 6f942fd70b12f..f5cc2f91b1456 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
@@ -444,6 +444,10 @@ &pd_gpu {
 	domain-supply = <&vdd_gpu_s0>;
 };
 
+&pd_npu {
+	domain-supply = <&vdd_npu_s0>;
+};
+
 &pinctrl {
 	ethernet {
 		gmac1_rstn: gmac1-rstn {
@@ -498,6 +502,36 @@ &pwm3 {
 	status = "okay";
 };
 
+&rknn_core_0 {
+	npu-supply = <&vdd_npu_s0>;
+	sram-supply = <&vdd_npu_s0>;
+	status = "okay";
+};
+
+&rknn_core_1 {
+	npu-supply = <&vdd_npu_s0>;
+	sram-supply = <&vdd_npu_s0>;
+	status = "okay";
+};
+
+&rknn_core_2 {
+	npu-supply = <&vdd_npu_s0>;
+	sram-supply = <&vdd_npu_s0>;
+	status = "okay";
+};
+
+&rknn_mmu_0 {
+	status = "okay";
+};
+
+&rknn_mmu_1 {
+	status = "okay";
+};
+
+&rknn_mmu_2 {
+	status = "okay";
+};
+
 &saradc {
 	vref-supply = <&vcca_1v8_s0>;
 	status = "okay";
-- 
2.43.0



From naoki at radxa.com  Sun Nov  9 06:18:48 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Sun,  9 Nov 2025 14:18:48 +0000
Subject: [PATCH v7 03/14] arm64: dts: rockchip: Remove rtc for Radxa ROCK 5C
In-Reply-To: <20251109141859.206835-1-naoki@radxa.com>
References: <20251109141859.206835-1-naoki@radxa.com>
Message-ID: <20251109141859.206835-4-naoki@radxa.com>

There is no RTC on the actual board, so remove it.

Fixes: 3ddf5cdb77e6 ("arm64: dts: rockchip: add Radxa ROCK 5C")
Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
Changes in v7:
- Reword commit message
Changes in v6:
- Reword commit message
Changes in v5:
- Reword commit message
Changes in v4:
- None
Changes in v3:
- None
Changes in v2:
- New
---
 .../boot/dts/rockchip/rk3588s-rock-5c.dts     | 23 -------------------
 1 file changed, 23 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
index 086b4f45fabf3..9a9430b2494b7 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
@@ -350,23 +350,6 @@ regulator-state-mem {
 	};
 };
 
-&i2c5 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&i2c5m2_xfer>;
-	status = "okay";
-
-	rtc at 51 {
-		compatible = "haoyu,hym8563";
-		reg = <0x51>;
-		#clock-cells = <0>;
-		clock-output-names = "rtcic_32kout";
-		interrupt-parent = <&gpio0>;
-		interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&rtc_int_l>;
-	};
-};
-
 &i2c7 {
 	status = "okay";
 
@@ -483,12 +466,6 @@ pow_en: pow-en {
 		};
 	};
 
-	rtc {
-		rtc_int_l: rtc-int-l {
-			rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
-		};
-	};
-
 	usb {
 		usb_host_pwren_h: usb-host-pwren-h {
 			rockchip,pins = <4 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
-- 
2.43.0



From naoki at radxa.com  Sun Nov  9 06:18:54 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Sun,  9 Nov 2025 14:18:54 +0000
Subject: [PATCH v7 09/14] arm64: dts: rockchip: Fix vcc_3v3_s0 vin-supply for Radxa ROCK 5C
In-Reply-To: <20251109141859.206835-1-naoki@radxa.com>
References: <20251109141859.206835-1-naoki@radxa.com>
Message-ID: <20251109141859.206835-10-naoki@radxa.com>

vcc_3v3_s3 is the right vin-supply for vcc_3v3_s0.

Fixes: 3ddf5cdb77e6 ("arm64: dts: rockchip: add Radxa ROCK 5C")
Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
Changes in v7:
- New
---
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
index 4f5376d0d109c..e693eedcbc378 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
@@ -148,7 +148,7 @@ vcc_3v3_s0: regulator-vcc-3v3-s0 {
 		regulator-boot-on;
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
-		vin-supply = <&vcc_1v8_s0>;
+		vin-supply = <&vcc_3v3_s3>;
 	};
 
 	vcc_5v0: regulator-vcc-5v0 {
-- 
2.43.0



From naoki at radxa.com  Sun Nov  9 06:18:57 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Sun,  9 Nov 2025 14:18:57 +0000
Subject: [PATCH v7 12/14] arm64: dts: rockchip: Enable HDMI audio for Radxa ROCK 5C
In-Reply-To: <20251109141859.206835-1-naoki@radxa.com>
References: <20251109141859.206835-1-naoki@radxa.com>
Message-ID: <20251109141859.206835-13-naoki@radxa.com>

Enable HDMI audio output for Radxa ROCK 5C.

Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
Changes in v7:
- New
---
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
index 6ef9a5d8cd9c1..6f942fd70b12f 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
@@ -271,6 +271,10 @@ hdmi0_out_con: endpoint {
 	};
 };
 
+&hdmi0_sound {
+	status = "okay";
+};
+
 &hdptxphy0 {
 	status = "okay";
 };
@@ -382,6 +386,10 @@ i2s0_8ch_p0_0: endpoint {
 	};
 };
 
+&i2s5_8ch {
+	status = "okay";
+};
+
 &mdio1 {
 	rgmii_phy1: ethernet-phy at 1 {
 		compatible = "ethernet-phy-id001c.c916";
-- 
2.43.0



From naoki at radxa.com  Sun Nov  9 06:18:56 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Sun,  9 Nov 2025 14:18:56 +0000
Subject: [PATCH v7 11/14] arm64: dts: rockchip: Sort nodes/properties for Radxa ROCK 5C
In-Reply-To: <20251109141859.206835-1-naoki@radxa.com>
References: <20251109141859.206835-1-naoki@radxa.com>
Message-ID: <20251109141859.206835-12-naoki@radxa.com>

Sort nodes/properties alphanumerically. No functional change.

Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
Changes in v7:
- Reflect other commits, no functional change
Changes in v6:
- Reflect other commits, no functional change
Changes in v5:
- Reword commit message
Changes in v4:
- Reflect other commits, no functional change
Changes in v3:
- None
Changes in v2:
- New
---
 .../boot/dts/rockchip/rk3588s-rock-5c.dts     | 162 +++++++++---------
 1 file changed, 81 insertions(+), 81 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
index 4e15c28f8a5fa..6ef9a5d8cd9c1 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
@@ -25,15 +25,12 @@ chosen {
 		stdout-path = "serial2:1500000n8";
 	};
 
-	sound {
-		compatible = "audio-graph-card";
-		label = "rk3588-es8316";
-		dais = <&i2s0_8ch_p0>;
-		routing = "MIC2", "Mic Jack",
-			  "Headphones", "HPOL",
-			  "Headphones", "HPOR";
-		widgets = "Microphone", "Mic Jack",
-			  "Headphone", "Headphones";
+	fan: fan {
+		compatible = "pwm-fan";
+		#cooling-cells = <2>;
+		cooling-levels = <0 64 128 192 255>;
+		fan-supply = <&vcc_5v0>;
+		pwms = <&pwm3 0 60000 0>;
 	};
 
 	hdmi0-con {
@@ -70,12 +67,14 @@ led-1 {
 		};
 	};
 
-	fan: fan {
-		compatible = "pwm-fan";
-		#cooling-cells = <2>;
-		cooling-levels = <0 24 44 64 128 192 255>;
-		fan-supply = <&vcc_5v0>;
-		pwms = <&pwm3 0 60000 0>;
+	vcc_1v1_nldo_s3: regulator-1v1 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_1v1_nldo_s3";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1100000>;
+		regulator-max-microvolt = <1100000>;
+		vin-supply = <&vcc_sysin>;
 	};
 
 	vcc3v3_pcie2x1l2: regulator-3v3-0 {
@@ -90,6 +89,40 @@ vcc3v3_pcie2x1l2: regulator-3v3-0 {
 		vin-supply = <&vcc_sysin>;
 	};
 
+	vcc_3v3_s0: regulator-3v3-1 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_3v3_s0";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc_3v3_s3>;
+	};
+
+	vdd_3v3: regulator-3v3-2 {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&usb_wifi_pwr>;
+		regulator-name = "vdd_3v3";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc_3v3_s3>;
+	};
+
+	vcca: regulator-4v0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcca";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <4000000>;
+		regulator-max-microvolt = <4000000>;
+		vin-supply = <&vcc_sysin>;
+	};
+
 	vcc5v_dcin: regulator-5v0-0 {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc5v_dcin";
@@ -123,26 +156,6 @@ vcc5v0_usb_otg0: regulator-5v0-2 {
 		vin-supply = <&vcc_sysin>;
 	};
 
-	vcc_1v1_nldo_s3: regulator-1v1 {
-		compatible = "regulator-fixed";
-		regulator-name = "vcc_1v1_nldo_s3";
-		regulator-always-on;
-		regulator-boot-on;
-		regulator-min-microvolt = <1100000>;
-		regulator-max-microvolt = <1100000>;
-		vin-supply = <&vcc_sysin>;
-	};
-
-	vcc_3v3_s0: regulator-3v3-1 {
-		compatible = "regulator-fixed";
-		regulator-name = "vcc_3v3_s0";
-		regulator-always-on;
-		regulator-boot-on;
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		vin-supply = <&vcc_3v3_s3>;
-	};
-
 	vcc_5v0: regulator-5v0-3 {
 		compatible = "regulator-fixed";
 		enable-active-high;
@@ -165,28 +178,15 @@ vcc_sysin: regulator-5v0-4 {
 		vin-supply = <&vcc5v_dcin>;
 	};
 
-	vcca: regulator-4v0 {
-		compatible = "regulator-fixed";
-		regulator-name = "vcca";
-		regulator-always-on;
-		regulator-boot-on;
-		regulator-min-microvolt = <4000000>;
-		regulator-max-microvolt = <4000000>;
-		vin-supply = <&vcc_sysin>;
-	};
-
-	vdd_3v3: regulator-3v3-2 {
-		compatible = "regulator-fixed";
-		enable-active-high;
-		gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&usb_wifi_pwr>;
-		regulator-name = "vdd_3v3";
-		regulator-always-on;
-		regulator-boot-on;
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		vin-supply = <&vcc_3v3_s3>;
+	sound {
+		compatible = "audio-graph-card";
+		label = "rk3588-es8316";
+		dais = <&i2s0_8ch_p0>;
+		routing = "MIC2", "Mic Jack",
+			  "Headphones", "HPOL",
+			  "Headphones", "HPOR";
+		widgets = "Microphone", "Mic Jack",
+			  "Headphone", "Headphones";
 	};
 };
 
@@ -399,27 +399,27 @@ &package_thermal {
 
 	trips {
 		package_fan0: package-fan0 {
-			temperature = <55000>;
 			hysteresis = <2000>;
+			temperature = <55000>;
 			type = "active";
 		};
 
 		package_fan1: package-fan1 {
-			temperature = <65000>;
 			hysteresis = <2000>;
+			temperature = <65000>;
 			type = "active";
 		};
 	};
 
 	cooling-maps {
 		map0 {
-			trip = <&package_fan0>;
 			cooling-device = <&fan THERMAL_NO_LIMIT 1>;
+			trip = <&package_fan0>;
 		};
 
 		map1 {
-			trip = <&package_fan1>;
 			cooling-device = <&fan 2 THERMAL_NO_LIMIT>;
+			trip = <&package_fan1>;
 		};
 	};
 };
@@ -437,6 +437,12 @@ &pd_gpu {
 };
 
 &pinctrl {
+	ethernet {
+		gmac1_rstn: gmac1-rstn {
+			rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
 	leds {
 		io_led: io-led {
 			rockchip,pins = <3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
@@ -447,12 +453,6 @@ power_led: power-led {
 		};
 	};
 
-	ethernet {
-		gmac1_rstn: gmac1-rstn {
-			rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
-		};
-	};
-
 	pcie {
 		pcie20x1_2_perstn_m0: pcie20x1-2-perstn-m0 {
 			rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
@@ -463,6 +463,12 @@ pow_en: pow-en {
 		};
 	};
 
+	regulators {
+		vcc_5v0_pwren_h: vcc-5v0-pwren-h {
+			rockchip,pins = <4 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
 	usb {
 		usb_host_pwren_h: usb-host-pwren-h {
 			rockchip,pins = <4 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
@@ -476,12 +482,6 @@ usb_wifi_pwr: usb-wifi-pwr {
 			rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
 		};
 	};
-
-	regulators {
-		vcc_5v0_pwren_h: vcc-5v0-pwren-h {
-			rockchip,pins = <4 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
-		};
-	};
 };
 
 &pwm3 {
@@ -500,8 +500,8 @@ &sdhci {
 	cap-mmc-highspeed;
 	mmc-hs400-1_8v;
 	mmc-hs400-enhanced-strobe;
-	no-sdio;
 	no-sd;
+	no-sdio;
 	non-removable;
 	vmmc-supply = <&vcc_3v3_s0>;
 	vqmmc-supply = <&vccio_flash>;
@@ -514,8 +514,8 @@ &sdmmc {
 	cap-sd-highspeed;
 	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
 	disable-wp;
-	no-sdio;
 	no-mmc;
+	no-sdio;
 	pinctrl-names = "default";
 	pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd>;
 	sd-uhs-sdr104;
@@ -538,12 +538,12 @@ flash at 0 {
 };
 
 &spi2 {
-	status = "okay";
 	assigned-clocks = <&cru CLK_SPI2>;
 	assigned-clock-rates = <200000000>;
 	num-cs = <1>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
+	status = "okay";
 
 	pmic at 0 {
 		compatible = "rockchip,rk806";
@@ -898,10 +898,6 @@ &uart2 {
 	status = "okay";
 };
 
-&usbdp_phy0 {
-	status = "okay";
-};
-
 &usb_host0_ehci {
 	status = "okay";
 };
@@ -923,7 +919,7 @@ &usb_host2_xhci {
 	status = "okay";
 };
 
-&vop_mmu {
+&usbdp_phy0 {
 	status = "okay";
 };
 
@@ -931,6 +927,10 @@ &vop {
 	status = "okay";
 };
 
+&vop_mmu {
+	status = "okay";
+};
+
 &vp0 {
 	vp0_out_hdmi0: endpoint at ROCKCHIP_VOP2_EP_HDMI0 {
 		reg = <ROCKCHIP_VOP2_EP_HDMI0>;
-- 
2.43.0



From naoki at radxa.com  Sun Nov  9 06:18:45 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Sun,  9 Nov 2025 14:18:45 +0000
Subject: [PATCH v7 00/14] arm64: dts: rockchip: Refine dts for Radxa ROCK 5C
Message-ID: <20251109141859.206835-1-naoki@radxa.com>

This patch series provides fixes, improvements, and other minor
changes for the Radxa ROCK 5C.

FUKAUMI Naoki (14):
  arm64: dts: rockchip: Fix the function of the blue LED for Radxa ROCK
    5C
  arm64: dts: rockchip: Use a longer PWM period for the fan on Radxa
    ROCK 5C
  arm64: dts: rockchip: Remove rtc for Radxa ROCK 5C
  arm64: dts: rockchip: Fix microSD card detect for Radxa ROCK 5C
  arm64: dts: rockchip: Fix pmic properties for Radxa ROCK 5C
  arm64: dts: rockchip: Add missing properties for sdhci for Radxa ROCK
    5C
  arm64: dts: rockchip: Add pinctrl-names for uart2 for Radxa ROCK 5C
  arm64: dts: rockchip: Make eeprom read-only for Radxa ROCK 5C
  arm64: dts: rockchip: Fix vcc_3v3_s0 vin-supply for Radxa ROCK 5C
  arm64: dts: rockchip: Trivial changes for Radxa ROCK 5C
  arm64: dts: rockchip: Sort nodes/properties for Radxa ROCK 5C
  arm64: dts: rockchip: Enable HDMI audio for Radxa ROCK 5C
  arm64: dts: rockchip: Enable NPU for Radxa ROCK 5C
  arm64: dts: rockchip: Add eMMC to uSD module support for Radxa ROCK 5C

 .../boot/dts/rockchip/rk3588s-rock-5c.dts     | 290 ++++++++++--------
 1 file changed, 157 insertions(+), 133 deletions(-)

-- 
2.43.0



From naoki at radxa.com  Sun Nov  9 06:18:59 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Sun,  9 Nov 2025 14:18:59 +0000
Subject: [PATCH v7 14/14] arm64: dts: rockchip: Add eMMC to uSD module support for Radxa ROCK 5C
In-Reply-To: <20251109141859.206835-1-naoki@radxa.com>
References: <20251109141859.206835-1-naoki@radxa.com>
Message-ID: <20251109141859.206835-15-naoki@radxa.com>

Add support for Radxa eMMC to uSD module[1].

[1] https://radxa.com/products/accessories/emmc-to-usd

Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
Changes in v7:
- New
---
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
index f5cc2f91b1456..603d914374bdd 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
@@ -556,7 +556,6 @@ &sdmmc {
 	cap-sd-highspeed;
 	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
 	disable-wp;
-	no-mmc;
 	no-sdio;
 	pinctrl-names = "default";
 	pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd>;
-- 
2.43.0



From naoki at radxa.com  Sun Nov  9 06:18:52 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Sun,  9 Nov 2025 14:18:52 +0000
Subject: [PATCH v7 07/14] arm64: dts: rockchip: Add pinctrl-names for uart2 for Radxa ROCK 5C
In-Reply-To: <20251109141859.206835-1-naoki@radxa.com>
References: <20251109141859.206835-1-naoki@radxa.com>
Message-ID: <20251109141859.206835-8-naoki@radxa.com>

Add missing pinctrl-names for uart2.

Fixes: 3ddf5cdb77e6 ("arm64: dts: rockchip: add Radxa ROCK 5C")
Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
Changes in v7:
- new
---
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
index 0f0a0b03fbf46..e3f286df93b05 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
@@ -894,6 +894,7 @@ &u2phy3_host {
 };
 
 &uart2 {
+	pinctrl-names = "default";
 	pinctrl-0 = <&uart2m0_xfer>;
 	status = "okay";
 };
-- 
2.43.0



From naoki at radxa.com  Sun Nov  9 06:18:46 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Sun,  9 Nov 2025 14:18:46 +0000
Subject: [PATCH v7 01/14] arm64: dts: rockchip: Fix the function of the blue LED for Radxa ROCK 5C
In-Reply-To: <20251109141859.206835-1-naoki@radxa.com>
References: <20251109141859.206835-1-naoki@radxa.com>
Message-ID: <20251109141859.206835-2-naoki@radxa.com>

Radxa ROCK 5C is an updated version of Radxa ROCK 5A so everything
should be as compatible as possible.

Fix the function of the blue LED from HEARTBEAT to STATUS.

Fixes: 3ddf5cdb77e6 ("arm64: dts: rockchip: add Radxa ROCK 5C")
Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
Changes in v7:
- Reword commit message
Changes in v6:
- Reword commit message
Changes in v5:
- Reword commit message
Changes in v4:
- New
---
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
index dd7317bab6135..378a65e2561ad 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
@@ -62,7 +62,7 @@ led-0 {
 		led-1 {
 			color = <LED_COLOR_ID_BLUE>;
 			default-state = "on";
-			function = LED_FUNCTION_HEARTBEAT;
+			function = LED_FUNCTION_STATUS;
 			gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "heartbeat";
 		};
-- 
2.43.0



From naoki at radxa.com  Sun Nov  9 06:18:51 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Sun,  9 Nov 2025 14:18:51 +0000
Subject: [PATCH v7 06/14] arm64: dts: rockchip: Add missing properties for sdhci for Radxa ROCK 5C
In-Reply-To: <20251109141859.206835-1-naoki@radxa.com>
References: <20251109141859.206835-1-naoki@radxa.com>
Message-ID: <20251109141859.206835-7-naoki@radxa.com>

Add cap-mmc-highspeed for high-speed timing.
Add v(q)mmc-supply for card(i/o) power.

Fixes: 3ddf5cdb77e6 ("arm64: dts: rockchip: add Radxa ROCK 5C")
Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
Changes in v7:
- New
---
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
index eb0d5a0a41509..0f0a0b03fbf46 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
@@ -498,11 +498,14 @@ &saradc {
 
 &sdhci {
 	bus-width = <8>;
+	cap-mmc-highspeed;
 	mmc-hs400-1_8v;
 	mmc-hs400-enhanced-strobe;
 	no-sdio;
 	no-sd;
 	non-removable;
+	vmmc-supply = <&vcc_3v3_s0>;
+	vqmmc-supply = <&vcc_1v8_s3>;
 	status = "okay";
 };
 
-- 
2.43.0



From naoki at radxa.com  Sun Nov  9 06:18:50 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Sun,  9 Nov 2025 14:18:50 +0000
Subject: [PATCH v7 05/14] arm64: dts: rockchip: Fix pmic properties for Radxa ROCK 5C
In-Reply-To: <20251109141859.206835-1-naoki@radxa.com>
References: <20251109141859.206835-1-naoki@radxa.com>
Message-ID: <20251109141859.206835-6-naoki@radxa.com>

Fix copy-pasto in the initial commit. Labels/names match schematic[1],
and values match schematic and downstream kernel[2][3].

[1] https://dl.radxa.com/rock5/5c/docs/hw/v1100/radxa_rock_5c_schematic_v1100.pdf
[2] https://github.com/radxa/kernel/blob/linux-6.1-stan-rkr5.1/arch/arm64/boot/dts/rockchip/rk3588-rk806-single.dtsi
[3] https://github.com/radxa/kernel/blob/linux-6.1-stan-rkr5.1/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts

Fixes: 3ddf5cdb77e6 ("arm64: dts: rockchip: add Radxa ROCK 5C")
Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
Changes in v7:
- More fixes
- Reword commit message
Changes in v6:
- Reword commit message
Changes in v5:
- Reword commit message
Changes in v4:
- None
Changes in v3:
- None
Changes in v2:
- Split from "arm64: dts: rockchip: fix pmic properties for Radxa ROCK 5C"
---
 .../boot/dts/rockchip/rk3588s-rock-5c.dts     | 20 +++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
index 1257aaac8f350..eb0d5a0a41509 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
@@ -619,7 +619,7 @@ vdd_logic_s0: dcdc-reg3 {
 				regulator-always-on;
 				regulator-boot-on;
 				regulator-min-microvolt = <675000>;
-				regulator-max-microvolt = <750000>;
+				regulator-max-microvolt = <800000>;
 				regulator-ramp-delay = <12500>;
 
 				regulator-state-mem {
@@ -666,12 +666,11 @@ regulator-state-mem {
 			};
 
 			vcc_2v0_pldo_s3: dcdc-reg7 {
-				regulator-name = "vdd_2v0_pldo_s3";
+				regulator-name = "vcc_2v0_pldo_s3";
 				regulator-always-on;
 				regulator-boot-on;
 				regulator-min-microvolt = <2000000>;
 				regulator-max-microvolt = <2000000>;
-				regulator-ramp-delay = <12500>;
 
 				regulator-state-mem {
 					regulator-on-in-suspend;
@@ -702,8 +701,8 @@ regulator-state-mem {
 				};
 			};
 
-			vcc1v8_pmu_ddr_s3: dcdc-reg10 {
-				regulator-name = "vcc1v8_pmu_ddr_s3";
+			vcc_1v8_s3: dcdc-reg10 {
+				regulator-name = "vcc_1v8_s3";
 				regulator-always-on;
 				regulator-boot-on;
 				regulator-min-microvolt = <1800000>;
@@ -778,8 +777,8 @@ regulator-state-mem {
 				};
 			};
 
-			pldo6_s3: pldo-reg6 {
-				regulator-name = "pldo6_s3";
+			pldo-reg6 {
+				regulator-name = "pldo_reg6";
 				regulator-always-on;
 				regulator-boot-on;
 				regulator-min-microvolt = <1800000>;
@@ -821,11 +820,12 @@ vdda_0v75_s0: nldo-reg3 {
 				regulator-name = "vdda_0v75_s0";
 				regulator-always-on;
 				regulator-boot-on;
-				regulator-min-microvolt = <750000>;
-				regulator-max-microvolt = <750000>;
+				regulator-min-microvolt = <837500>;
+				regulator-max-microvolt = <837500>;
 
 				regulator-state-mem {
-					regulator-off-in-suspend;
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <750000>;
 				};
 			};
 
-- 
2.43.0



From naoki at radxa.com  Sun Nov  9 06:18:55 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Sun,  9 Nov 2025 14:18:55 +0000
Subject: [PATCH v7 10/14] arm64: dts: rockchip: Trivial changes for Radxa ROCK 5C
In-Reply-To: <20251109141859.206835-1-naoki@radxa.com>
References: <20251109141859.206835-1-naoki@radxa.com>
Message-ID: <20251109141859.206835-11-naoki@radxa.com>

No functional change.

Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
Changes in v7:
- Reflect other commits, no functional change
Changes in v6:
- New
---
 .../boot/dts/rockchip/rk3588s-rock-5c.dts     | 64 +++++++++----------
 1 file changed, 31 insertions(+), 33 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
index e693eedcbc378..4e15c28f8a5fa 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
 /*
- * Copyright (c) 2024 Radxa Computer (Shenzhen) Co., Ltd.
+ * Copyright (c) 2024,2025 Radxa Computer (Shenzhen) Co., Ltd.
  */
 
 /dts-v1/;
@@ -25,7 +25,7 @@ chosen {
 		stdout-path = "serial2:1500000n8";
 	};
 
-	analog-sound {
+	sound {
 		compatible = "audio-graph-card";
 		label = "rk3588-es8316";
 		dais = <&i2s0_8ch_p0>;
@@ -49,14 +49,14 @@ hdmi0_con_in: endpoint {
 
 	leds {
 		compatible = "gpio-leds";
-		pinctrl-names = "default";
-		pinctrl-0 = <&led_pins>;
 
 		led-0 {
 			color = <LED_COLOR_ID_GREEN>;
 			default-state = "on";
 			function = LED_FUNCTION_POWER;
 			gpios = <&gpio3 RK_PC4 GPIO_ACTIVE_HIGH>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&power_led>;
 		};
 
 		led-1 {
@@ -65,6 +65,8 @@ led-1 {
 			function = LED_FUNCTION_STATUS;
 			gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "heartbeat";
+			pinctrl-names = "default";
+			pinctrl-0 = <&io_led>;
 		};
 	};
 
@@ -76,19 +78,19 @@ fan: fan {
 		pwms = <&pwm3 0 60000 0>;
 	};
 
-	pcie2x1l2_3v3: regulator-pcie2x1l2-3v3 {
+	vcc3v3_pcie2x1l2: regulator-3v3-0 {
 		compatible = "regulator-fixed";
 		enable-active-high;
 		gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&pow_en>;
-		regulator-name = "pcie2x1l2_3v3";
+		regulator-name = "vcc3v3_pcie2x1l2";
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
 		vin-supply = <&vcc_sysin>;
 	};
 
-	vcc5v_dcin: regulator-vcc5v-dcin {
+	vcc5v_dcin: regulator-5v0-0 {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc5v_dcin";
 		regulator-always-on;
@@ -97,7 +99,7 @@ vcc5v_dcin: regulator-vcc5v-dcin {
 		regulator-max-microvolt = <5000000>;
 	};
 
-	vcc5v0_usb_host: regulator-vcc5v0-usb-host {
+	vcc5v0_usb_host: regulator-5v0-1 {
 		compatible = "regulator-fixed";
 		enable-active-high;
 		gpio = <&gpio4 RK_PB5 GPIO_ACTIVE_HIGH>;
@@ -109,7 +111,7 @@ vcc5v0_usb_host: regulator-vcc5v0-usb-host {
 		vin-supply = <&vcc_sysin>;
 	};
 
-	vcc5v0_usb_otg0: regulator-vcc5v0-usb-otg0 {
+	vcc5v0_usb_otg0: regulator-5v0-2 {
 		compatible = "regulator-fixed";
 		enable-active-high;
 		gpio = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>;
@@ -121,7 +123,7 @@ vcc5v0_usb_otg0: regulator-vcc5v0-usb-otg0 {
 		vin-supply = <&vcc_sysin>;
 	};
 
-	vcc_1v1_nldo_s3: regulator-vcc-1v1-nldo-s3 {
+	vcc_1v1_nldo_s3: regulator-1v1 {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc_1v1_nldo_s3";
 		regulator-always-on;
@@ -131,17 +133,7 @@ vcc_1v1_nldo_s3: regulator-vcc-1v1-nldo-s3 {
 		vin-supply = <&vcc_sysin>;
 	};
 
-	vcc_3v3_pmu: regulator-vcc-3v3-pmu {
-		compatible = "regulator-fixed";
-		regulator-name = "vcc_3v3_pmu";
-		regulator-always-on;
-		regulator-boot-on;
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		vin-supply = <&vcc_3v3_s3>;
-	};
-
-	vcc_3v3_s0: regulator-vcc-3v3-s0 {
+	vcc_3v3_s0: regulator-3v3-1 {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc_3v3_s0";
 		regulator-always-on;
@@ -151,7 +143,7 @@ vcc_3v3_s0: regulator-vcc-3v3-s0 {
 		vin-supply = <&vcc_3v3_s3>;
 	};
 
-	vcc_5v0: regulator-vcc-5v0 {
+	vcc_5v0: regulator-5v0-3 {
 		compatible = "regulator-fixed";
 		enable-active-high;
 		gpio = <&gpio4 RK_PA3 GPIO_ACTIVE_HIGH>;
@@ -163,7 +155,7 @@ vcc_5v0: regulator-vcc-5v0 {
 		vin-supply = <&vcc_sysin>;
 	};
 
-	vcc_sysin: regulator-vcc-sysin {
+	vcc_sysin: regulator-5v0-4 {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc_sysin";
 		regulator-always-on;
@@ -173,7 +165,7 @@ vcc_sysin: regulator-vcc-sysin {
 		vin-supply = <&vcc5v_dcin>;
 	};
 
-	vcca: regulator-vcca {
+	vcca: regulator-4v0 {
 		compatible = "regulator-fixed";
 		regulator-name = "vcca";
 		regulator-always-on;
@@ -183,7 +175,7 @@ vcca: regulator-vcca {
 		vin-supply = <&vcc_sysin>;
 	};
 
-	vdd_3v3: regulator-vdd-3v3 {
+	vdd_3v3: regulator-3v3-2 {
 		compatible = "regulator-fixed";
 		enable-active-high;
 		gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
@@ -203,6 +195,7 @@ &combphy0_ps {
 };
 
 &combphy2_psu {
+	phy-supply = <&vcc5v0_usb_host>;
 	status = "okay";
 };
 
@@ -435,7 +428,7 @@ &pcie2x1l2 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pcie20x1_2_perstn_m0>;
 	reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
-	vpcie3v3-supply = <&pcie2x1l2_3v3>;
+	vpcie3v3-supply = <&vcc3v3_pcie2x1l2>;
 	status = "okay";
 };
 
@@ -445,13 +438,16 @@ &pd_gpu {
 
 &pinctrl {
 	leds {
-		led_pins: led-pins {
-			rockchip,pins = <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>,
-					<3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
+		io_led: io-led {
+			rockchip,pins = <3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		power_led: power-led {
+			rockchip,pins = <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
 		};
 	};
 
-	mdio {
+	ethernet {
 		gmac1_rstn: gmac1-rstn {
 			rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
 		};
@@ -479,7 +475,9 @@ usb_otg_pwren_h: usb-otg-pwren-h {
 		usb_wifi_pwr: usb-wifi-pwr {
 			rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
 		};
+	};
 
+	regulators {
 		vcc_5v0_pwren_h: vcc-5v0-pwren-h {
 			rockchip,pins = <4 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
 		};
@@ -506,7 +504,7 @@ &sdhci {
 	no-sd;
 	non-removable;
 	vmmc-supply = <&vcc_3v3_s0>;
-	vqmmc-supply = <&vcc_1v8_s3>;
+	vqmmc-supply = <&vccio_flash>;
 	status = "okay";
 };
 
@@ -682,7 +680,7 @@ regulator-state-mem {
 				};
 			};
 
-			vcc_3v3_s3: dcdc-reg8 {
+			vcc_3v3_pmu: vcc_3v3_s3: dcdc-reg8 {
 				regulator-name = "vcc_3v3_s3";
 				regulator-always-on;
 				regulator-boot-on;
@@ -705,7 +703,7 @@ regulator-state-mem {
 				};
 			};
 
-			vcc_1v8_s3: dcdc-reg10 {
+			vccio_flash: vcc_1v8_s3: dcdc-reg10 {
 				regulator-name = "vcc_1v8_s3";
 				regulator-always-on;
 				regulator-boot-on;
-- 
2.43.0



From diederik at cknow-tech.com  Sun Nov  9 09:05:26 2025
From: diederik at cknow-tech.com (Diederik de Haas)
Date: Sun, 09 Nov 2025 18:05:26 +0100
Subject: [PATCH 1/2] arm64: dts: rockchip: Simplify usb-c-connector port on
 rk3566-pinenote
In-Reply-To: <20251109-rk3566-pinenote-dt-fixes-upstream-v1-0-ed38d200cc04@cknow-tech.com>
References: <20251109-rk3566-pinenote-dt-fixes-upstream-v1-0-ed38d200cc04@cknow-tech.com>
Message-ID: <20251109-rk3566-pinenote-dt-fixes-upstream-v1-1-ed38d200cc04@cknow-tech.com>

The USB-C connector on the PineNote has only 1 port, so there's no need
for a 'ports' node with address-/size-cells properties as a single
'port' node suffices.

This fixes the following DT validation issue:

  Warning (graph_child_address): /i2c at fe5c0000/tcpc at 60/connector/ports:
    graph node has single child node 'port at 0',
    #address-cells/#size-cells are not necessary

Signed-off-by: Diederik de Haas <diederik at cknow-tech.com>
---
 arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi
index 5c6f8cc401c9..7c65fe4900be 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi
@@ -485,16 +485,9 @@ connector {
 			typec-power-opmode = "default";
 			pd-disable;
 
-			ports {
-				#address-cells = <0x1>;
-				#size-cells = <0x0>;
-
-				port at 0 {
-					reg = <0x0>;
-
-					typec_hs_usb2phy0: endpoint {
-						remote-endpoint = <&usb2phy0_typec_hs>;
-					};
+			port {
+				typec_hs_usb2phy0: endpoint {
+					remote-endpoint = <&usb2phy0_typec_hs>;
 				};
 			};
 		};

-- 
2.51.0



From diederik at cknow-tech.com  Sun Nov  9 09:05:27 2025
From: diederik at cknow-tech.com (Diederik de Haas)
Date: Sun, 09 Nov 2025 18:05:27 +0100
Subject: [PATCH 2/2] arm64: dts: rockchip: Move otg-port to controller on
 rk3566-pinenote
In-Reply-To: <20251109-rk3566-pinenote-dt-fixes-upstream-v1-0-ed38d200cc04@cknow-tech.com>
References: <20251109-rk3566-pinenote-dt-fixes-upstream-v1-0-ed38d200cc04@cknow-tech.com>
Message-ID: <20251109-rk3566-pinenote-dt-fixes-upstream-v1-2-ed38d200cc04@cknow-tech.com>

The 'rockchip,inno-usb2phy' binding's otg-port node does not have a port
node, so the current definition causes this DT validation issue:

  usb2phy at fe8a0000 (rockchip,rk3568-usb2phy): otg-port:
    'port' does not match any of the regexes: '^pinctrl-[0-9]+$'

Its purpose was to define the other endpoint for the USB-C connector
port. The 'snps,dwc3-common.yaml' DT binding does have a port node to
connect the dwc3 to type C connector with the 'usb-role-switch'
property. Therefore move the port node to the dwc3 node and add the
'usb-role-switch' property to it.
This fixes the above mention DT validation issue.

The incorrect definition also caused these kernel errors:

  rockchip-usb2phy fe8a0000.usb2phy: Failed to create device link (0x180) with supplier port0 for /usb2phy at fe8a0000/otg-port
  rockchip-usb2phy fe8a0000.usb2phy: Failed to create device link (0x180) with supplier 3-0060 for /usb2phy at fe8a0000/otg-port

With the changed definition, those errors are now also gone.

While at it, remove the 'dr_mode' property as that's already defined in
rk356x-base.dtsi and there's no point in redefining it.

Fixes: 87a267b4af09 ("arm64: dts: rockchip: Add USB and TCPC to rk3566-pinenote")
Cc: stable at vger.kernel.org
Signed-off-by: Diederik de Haas <diederik at cknow-tech.com>
---
 arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi
index 7c65fe4900be..be8076a8e30c 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi
@@ -694,8 +694,14 @@ &uart2 {
 };
 
 &usb_host0_xhci {
-	dr_mode = "otg";
+	usb-role-switch;
 	status = "okay";
+
+	port {
+		usb2phy0_typec_hs: endpoint {
+			remote-endpoint = <&typec_hs_usb2phy0>;
+		};
+	};
 };
 
 &usb2phy0 {
@@ -704,10 +710,4 @@ &usb2phy0 {
 
 &usb2phy0_otg {
 	status = "okay";
-
-	port {
-		usb2phy0_typec_hs: endpoint {
-			remote-endpoint = <&typec_hs_usb2phy0>;
-		};
-	};
 };

-- 
2.51.0



From diederik at cknow-tech.com  Sun Nov  9 09:05:25 2025
From: diederik at cknow-tech.com (Diederik de Haas)
Date: Sun, 09 Nov 2025 18:05:25 +0100
Subject: [PATCH 0/2] Fixes for PineNote DT validation issues
Message-ID: <20251109-rk3566-pinenote-dt-fixes-upstream-v1-0-ed38d200cc04@cknow-tech.com>

These patches fix the following DeviceTree validation issues on the
PineNote dtb files:

    Warning (graph_child_address): /i2c at fe5c0000/tcpc at 60/connector/ports:
      graph node has single child node 'port at 0', #address-cells/#size-cells
      are not necessary

    usb2phy at fe8a0000 (rockchip,rk3568-usb2phy): otg-port: 'port' does not
      match any of the regexes: '^pinctrl-[0-9]+$'

And with these 2 fixes, there are no more DT validation issues :-)

The fix for the 2nd issue also fix these kernel errors:

  rockchip-usb2phy fe8a0000.usb2phy: Failed to create device link (0x180) with supplier port0 for /usb2phy at fe8a0000/otg-port
  rockchip-usb2phy fe8a0000.usb2phy: Failed to create device link (0x180) with supplier 3-0060 for /usb2phy at fe8a0000/otg-port

Cheers,
  Diederik

Signed-off-by: Diederik de Haas <diederik at cknow-tech.com>
---
Diederik de Haas (2):
      arm64: dts: rockchip: Simplify usb-c-connector port on rk3566-pinenote
      arm64: dts: rockchip: Move otg-port to controller on rk3566-pinenote

 arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi | 27 +++++++++--------------
 1 file changed, 10 insertions(+), 17 deletions(-)
---
base-commit: 6146a0f1dfae5d37442a9ddcba012add260bceb0
change-id: 20251109-rk3566-pinenote-dt-fixes-upstream-1fb32eff43ea

Best regards,
-- 
Diederik de Haas <diederik at cknow-tech.com>



From krzk at kernel.org  Sun Nov  9 09:37:26 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sun, 9 Nov 2025 18:37:26 +0100
Subject: [PATCH 1/2] arm64: dts: rockchip: Simplify usb-c-connector port
 on rk3566-pinenote
In-Reply-To: <20251109-rk3566-pinenote-dt-fixes-upstream-v1-1-ed38d200cc04@cknow-tech.com>
References: <20251109-rk3566-pinenote-dt-fixes-upstream-v1-0-ed38d200cc04@cknow-tech.com>
 <20251109-rk3566-pinenote-dt-fixes-upstream-v1-1-ed38d200cc04@cknow-tech.com>
Message-ID: <a726fac9-afe5-4639-b06a-4bccc256d98f@kernel.org>

On 09/11/2025 18:05, Diederik de Haas wrote:
> The USB-C connector on the PineNote has only 1 port, so there's no need
> for a 'ports' node with address-/size-cells properties as a single
> 'port' node suffices.
> 
> This fixes the following DT validation issue:
> 
>   Warning (graph_child_address): /i2c at fe5c0000/tcpc at 60/connector/ports:
>     graph node has single child node 'port at 0',
>     #address-cells/#size-cells are not necessary

This is not a DT validation, but DTC warning which we do not really fix.
Are you sure the 'port' is accepted by bindings?

Best regards,
Krzysztof


From sigmaris at gmail.com  Sun Nov  9 11:20:51 2025
From: sigmaris at gmail.com (Hugh Cole-Baker)
Date: Sun,  9 Nov 2025 19:20:51 +0000
Subject: [PATCH v2] arm64: dts: rockchip: add pwm-fan for NanoPC-T6
Message-ID: <20251109192128.72527-1-sigmaris@gmail.com>

FriendlyELEC offers an optional heatsink and fan addon for the NanoPC-T6
and T6 LTS, which plugs in to the fan connector on the board driven by
pwm1. Add the fan as an active cooling device for the SoC package.

Signed-off-by: Hugh Cole-Baker <sigmaris at gmail.com>
---
Changes from v1: https://lore.kernel.org/linux-rockchip/20251026194858.92461-1-sigmaris at gmail.com/
* add the fan to the base board dtsi instead of overlay (Heiko)
* just use 2 trip points for warm and hot temperatures (Dragan, Alexey)

References:
FriendlyELEC heatsink with fan addon:
https://www.friendlyelec.com/index.php?route=product/product&product_id=305
Vendor DT with trip points and PWM duty cycle values:
https://github.com/friendlyarm/kernel-rockchip/blob/4944602540b62f5aad139fe602a76cf7c3176128/arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev01.dts#L75-L90

 .../boot/dts/rockchip/rk3588-nanopc-t6.dtsi   | 39 +++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
index fafeabe9adf9e..9164a0ee6228e 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
@@ -11,6 +11,7 @@
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/pinctrl/rockchip.h>
 #include <dt-bindings/soc/rockchip,vop2.h>
+#include <dt-bindings/thermal/thermal.h>
 #include <dt-bindings/usb/pd.h>
 #include "rk3588.dtsi"
 
@@ -89,6 +90,14 @@ usr_led: led-1 {
 		};
 	};
 
+	fan: pwm-fan {
+		compatible = "pwm-fan";
+		cooling-levels = <0 35 64 100 150 255>;
+		fan-supply = <&vcc5v0_sys>;
+		pwms = <&pwm1 0 50000 0>;
+		#cooling-cells = <2>;
+	};
+
 	sound {
 		compatible = "simple-audio-card";
 		pinctrl-names = "default";
@@ -591,6 +600,36 @@ &i2s6_8ch {
 	status = "okay";
 };
 
+&package_thermal {
+	polling-delay = <1000>;
+
+	trips {
+		package_warm: package-warm {
+			temperature = <50000>;
+			hysteresis = <2000>;
+			type = "active";
+		};
+
+		package_hot: package-hot {
+			temperature = <60000>;
+			hysteresis = <2000>;
+			type = "active";
+		};
+	};
+
+	cooling-maps {
+		map0 {
+			trip = <&package_warm>;
+			cooling-device = <&fan THERMAL_NO_LIMIT 1>;
+		};
+
+		map1 {
+			trip = <&package_hot>;
+			cooling-device = <&fan 2 THERMAL_NO_LIMIT>;
+		};
+	};
+};
+
 &pcie2x1l0 {
 	reset-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_HIGH>;
 	vpcie3v3-supply = <&vcc_3v3_pcie20>;
-- 
2.50.1 (Apple Git-155)



From diederik at cknow-tech.com  Sun Nov  9 13:52:13 2025
From: diederik at cknow-tech.com (Diederik de Haas)
Date: Sun, 09 Nov 2025 22:52:13 +0100
Subject: [PATCH 0/2] Fixes for PineNote DT validation issues
In-Reply-To: <20251109-rk3566-pinenote-dt-fixes-upstream-v1-0-ed38d200cc04@cknow-tech.com>
References: <20251109-rk3566-pinenote-dt-fixes-upstream-v1-0-ed38d200cc04@cknow-tech.com>
Message-ID: <DE4HWR95IFVW.1GG1O5GO9GKKV@cknow-tech.com>

On Sun Nov 9, 2025 at 6:05 PM CET, Diederik de Haas wrote:
> These patches fix the following DeviceTree validation issues on the
> PineNote dtb files:

Please ignore this patch set. Sorry about the noise.

Cheers,
  Diederik

>     Warning (graph_child_address): /i2c at fe5c0000/tcpc at 60/connector/ports:
>       graph node has single child node 'port at 0', #address-cells/#size-cells
>       are not necessary
>
>     usb2phy at fe8a0000 (rockchip,rk3568-usb2phy): otg-port: 'port' does not
>       match any of the regexes: '^pinctrl-[0-9]+$'
>
> And with these 2 fixes, there are no more DT validation issues :-)
>
> The fix for the 2nd issue also fix these kernel errors:
>
>   rockchip-usb2phy fe8a0000.usb2phy: Failed to create device link (0x180) with supplier port0 for /usb2phy at fe8a0000/otg-port
>   rockchip-usb2phy fe8a0000.usb2phy: Failed to create device link (0x180) with supplier 3-0060 for /usb2phy at fe8a0000/otg-port
>
> Cheers,
>   Diederik
>
> Signed-off-by: Diederik de Haas <diederik at cknow-tech.com>
> ---
> Diederik de Haas (2):
>       arm64: dts: rockchip: Simplify usb-c-connector port on rk3566-pinenote
>       arm64: dts: rockchip: Move otg-port to controller on rk3566-pinenote
>
>  arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi | 27 +++++++++--------------
>  1 file changed, 10 insertions(+), 17 deletions(-)
> ---
> base-commit: 6146a0f1dfae5d37442a9ddcba012add260bceb0
> change-id: 20251109-rk3566-pinenote-dt-fixes-upstream-1fb32eff43ea
>
> Best regards,



From heiko at sntech.de  Sun Nov  9 14:16:22 2025
From: heiko at sntech.de (Heiko =?UTF-8?B?U3TDvGJuZXI=?=)
Date: Sun, 09 Nov 2025 23:16:22 +0100
Subject: [PATCH 1/2] arm64: dts: rockchip: Simplify usb-c-connector port on
 rk3566-pinenote
In-Reply-To: <a726fac9-afe5-4639-b06a-4bccc256d98f@kernel.org>
References: <20251109-rk3566-pinenote-dt-fixes-upstream-v1-0-ed38d200cc04@cknow-tech.com>
 <20251109-rk3566-pinenote-dt-fixes-upstream-v1-1-ed38d200cc04@cknow-tech.com>
 <a726fac9-afe5-4639-b06a-4bccc256d98f@kernel.org>
Message-ID: <5024969.GXAFRqVoOG@diego>

Am Sonntag, 9. November 2025, 18:37:26 Mitteleurop?ische Normalzeit schrieb Krzysztof Kozlowski:
> On 09/11/2025 18:05, Diederik de Haas wrote:
> > The USB-C connector on the PineNote has only 1 port, so there's no need
> > for a 'ports' node with address-/size-cells properties as a single
> > 'port' node suffices.
> > 
> > This fixes the following DT validation issue:
> > 
> >   Warning (graph_child_address): /i2c at fe5c0000/tcpc at 60/connector/ports:
> >     graph node has single child node 'port at 0',
> >     #address-cells/#size-cells are not necessary
> 
> This is not a DT validation, but DTC warning which we do not really fix.

That is good to know. Is the same true for other dtc warnings?

Thanks
Heiko




From naoki at radxa.com  Sun Nov  9 15:16:40 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Mon, 10 Nov 2025 08:16:40 +0900
Subject: [PATCH] PCI: dw-rockchip: Skip waiting for link up
In-Reply-To: <aRCI5kG16_1erMME@ryzen>
References: <20250113-rockchip-no-wait-v1-1-25417f37b92f@kernel.org>
 <1E8E4DB773970CB5+5a52c9e1-01b8-4872-99b7-021099f04031@radxa.com>
 <6e87b611-13ea-4d89-8dbf-85510dd86fa6@rock-chips.com>
 <aQ840q5BxNS1eIai@ryzen> <aQ9FWEuW47L8YOxC@ryzen>
 <55EB0E5F655F3AFC+136b89fd-98d4-42af-a99d-a0bb05cc93f3@radxa.com>
 <aRCI5kG16_1erMME@ryzen>
Message-ID: <E739D84F1F86AA6E+92a19e8b-ce67-4fb2-aa74-f5e5b0a075d3@radxa.com>

Hi Niklas,

On 11/9/25 21:28, Niklas Cassel wrote:
> On Sun, Nov 09, 2025 at 01:42:23PM +0900, FUKAUMI Naoki wrote:
>> Hi Niklas,
>>
>> On 11/8/25 22:27, Niklas Cassel wrote:
>> (snip)> (And btw. please test with the latest 6.18-rc, as, from experience,
>> the
>>> ASPM problems in earlier RCs can result in some weird problems that are
>>> not immediately deduced to be caused by the ASPM enablement.)
>>
>> Here is dmesg from v6.18-rc4:
>>   https://gist.github.com/RadxaNaoki/40e1d049bff4f1d2d4773a5ba0ed9dff
> 
> Same problem as before:
> [    1.732538] pci_bus 0004:43: busn_res: can not insert [bus 43-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> [    1.732645] pci_bus 0004:43: busn_res: [bus 43-41] end is updated to 43
> [    1.732651] pci_bus 0004:43: busn_res: can not insert [bus 43] under [bus 42-41] (conflicts with (null) [bus 42-41])
> [    1.732661] pci 0004:42:00.0: devices behind bridge are unusable because [bus 43] cannot be assigned for them
> [    1.732840] pci_bus 0004:44: busn_res: can not insert [bus 44-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> [    1.732947] pci_bus 0004:44: busn_res: [bus 44-41] end is updated to 44
> [    1.732952] pci_bus 0004:44: busn_res: can not insert [bus 44] under [bus 42-41] (conflicts with (null) [bus 42-41])
> [    1.732962] pci 0004:42:02.0: devices behind bridge are unusable because [bus 44] cannot be assigned for them
> [    1.733134] pci_bus 0004:45: busn_res: can not insert [bus 45-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> [    1.733246] pci_bus 0004:45: busn_res: [bus 45-41] end is updated to 45
> [    1.733255] pci_bus 0004:45: busn_res: can not insert [bus 45] under [bus 42-41] (conflicts with (null) [bus 42-41])
> [    1.733266] pci 0004:42:06.0: devices behind bridge are unusable because [bus 45] cannot be assigned for them
> [    1.733438] pci_bus 0004:46: busn_res: can not insert [bus 46-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> [    1.733544] pci_bus 0004:46: busn_res: [bus 46-41] end is updated to 46
> [    1.733550] pci_bus 0004:46: busn_res: can not insert [bus 46] under [bus 42-41] (conflicts with (null) [bus 42-41])
> [    1.733560] pci 0004:42:0e.0: devices behind bridge are unusable because [bus 46] cannot be assigned for them
> [    1.733571] pci_bus 0004:42: busn_res: [bus 42-41] end is updated to 46
> [    1.733575] pci_bus 0004:42: busn_res: can not insert [bus 42-46] under [bus 41] (conflicts with (null) [bus 41])
> [    1.733585] pci 0004:41:00.0: devices behind bridge are unusable because [bus 42-46] cannot be assigned for them
> [    1.733596] pcieport 0004:40:00.0: bridge has subordinate 41 but max busn 46
> 
> 
> Seems like the ASM2806 switch, for some reason, is not ready.
> 
> One change that Diederik pointed out is that in the "good" case,
> the link is always in Gen1 speed.
> 
> Perhaps you could build with CONFIG_PCI_QUIRKS=y and try this patch:
> 
> diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
> index 214ed060ca1b..ac134d95a97f 100644
> --- a/drivers/pci/quirks.c
> +++ b/drivers/pci/quirks.c
> @@ -96,6 +96,7 @@ int pcie_failed_link_retrain(struct pci_dev *dev)
>   {
>   	static const struct pci_device_id ids[] = {
>   		{ PCI_VDEVICE(ASMEDIA, 0x2824) }, /* ASMedia ASM2824 */
> +		{ PCI_VDEVICE(ASMEDIA, 0x2806) }, /* ASMedia ASM2806 */
>   		{}
>   	};
>   	u16 lnksta, lnkctl2;

It doesn't help with either probing behind the bridge or the link speed.

> If that does not work, perhaps you could try this patch
> (assuming that all Rock 5C:s have a ASM2806 on pcie2x1l2):

ROCK 5C has a PCIe FPC connector and I'm using Dual 2.5G Router HAT.
  https://radxa.com/products/rock5/5c#techspec
  https://radxa.com/products/accessories/dual-2-5g-router-hat

Regarding the link speed, I initially suspected the FPC connector and/or 
cable might be the issue. However, I tried the Dual 2.5G Router HAT with 
the ROCK 5A (which uses a different cable), and I got the same result.

BTW, the link speed varies between 2Gb/s and 4Gb/s depending on the 
reboot. (with or without quirk)

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
> index dd7317bab613..26f8539d934a 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
> @@ -452,6 +452,7 @@ &pcie2x1l2 {
>   	pinctrl-0 = <&pcie20x1_2_perstn_m0>;
>   	reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
>   	vpcie3v3-supply = <&pcie2x1l2_3v3>;
> +	max-link-speed = <1>;
>   	status = "okay";
>   };
> 
> 
> 
> Kind regards,
> Niklas
> 



From naoki at radxa.com  Sun Nov  9 15:26:56 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Mon, 10 Nov 2025 08:26:56 +0900
Subject: [RESEND] Re: [PATCH] PCI: dw-rockchip: Skip waiting for link up
In-Reply-To: <aRCI5kG16_1erMME@ryzen>
References: <20250113-rockchip-no-wait-v1-1-25417f37b92f@kernel.org>
 <1E8E4DB773970CB5+5a52c9e1-01b8-4872-99b7-021099f04031@radxa.com>
 <6e87b611-13ea-4d89-8dbf-85510dd86fa6@rock-chips.com>
 <aQ840q5BxNS1eIai@ryzen> <aQ9FWEuW47L8YOxC@ryzen>
 <55EB0E5F655F3AFC+136b89fd-98d4-42af-a99d-a0bb05cc93f3@radxa.com>
 <aRCI5kG16_1erMME@ryzen>
Message-ID: <F8B2B6FA2884D69A+b7da13f2-0ffb-4308-b1ba-0549bc461be8@radxa.com>

(RESEND: fix mani's email address)

Hi Niklas,

On 11/9/25 21:28, Niklas Cassel wrote:
> On Sun, Nov 09, 2025 at 01:42:23PM +0900, FUKAUMI Naoki wrote:
>> Hi Niklas,
>>
>> On 11/8/25 22:27, Niklas Cassel wrote:
>> (snip)> (And btw. please test with the latest 6.18-rc, as, from experience,
>> the
>>> ASPM problems in earlier RCs can result in some weird problems that are
>>> not immediately deduced to be caused by the ASPM enablement.)
>>
>> Here is dmesg from v6.18-rc4:
>>   https://gist.github.com/RadxaNaoki/40e1d049bff4f1d2d4773a5ba0ed9dff
> 
> Same problem as before:
> [    1.732538] pci_bus 0004:43: busn_res: can not insert [bus 43-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> [    1.732645] pci_bus 0004:43: busn_res: [bus 43-41] end is updated to 43
> [    1.732651] pci_bus 0004:43: busn_res: can not insert [bus 43] under [bus 42-41] (conflicts with (null) [bus 42-41])
> [    1.732661] pci 0004:42:00.0: devices behind bridge are unusable because [bus 43] cannot be assigned for them
> [    1.732840] pci_bus 0004:44: busn_res: can not insert [bus 44-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> [    1.732947] pci_bus 0004:44: busn_res: [bus 44-41] end is updated to 44
> [    1.732952] pci_bus 0004:44: busn_res: can not insert [bus 44] under [bus 42-41] (conflicts with (null) [bus 42-41])
> [    1.732962] pci 0004:42:02.0: devices behind bridge are unusable because [bus 44] cannot be assigned for them
> [    1.733134] pci_bus 0004:45: busn_res: can not insert [bus 45-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> [    1.733246] pci_bus 0004:45: busn_res: [bus 45-41] end is updated to 45
> [    1.733255] pci_bus 0004:45: busn_res: can not insert [bus 45] under [bus 42-41] (conflicts with (null) [bus 42-41])
> [    1.733266] pci 0004:42:06.0: devices behind bridge are unusable because [bus 45] cannot be assigned for them
> [    1.733438] pci_bus 0004:46: busn_res: can not insert [bus 46-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> [    1.733544] pci_bus 0004:46: busn_res: [bus 46-41] end is updated to 46
> [    1.733550] pci_bus 0004:46: busn_res: can not insert [bus 46] under [bus 42-41] (conflicts with (null) [bus 42-41])
> [    1.733560] pci 0004:42:0e.0: devices behind bridge are unusable because [bus 46] cannot be assigned for them
> [    1.733571] pci_bus 0004:42: busn_res: [bus 42-41] end is updated to 46
> [    1.733575] pci_bus 0004:42: busn_res: can not insert [bus 42-46] under [bus 41] (conflicts with (null) [bus 41])
> [    1.733585] pci 0004:41:00.0: devices behind bridge are unusable because [bus 42-46] cannot be assigned for them
> [    1.733596] pcieport 0004:40:00.0: bridge has subordinate 41 but max busn 46
> 
> 
> Seems like the ASM2806 switch, for some reason, is not ready.
> 
> One change that Diederik pointed out is that in the "good" case,
> the link is always in Gen1 speed.
> 
> Perhaps you could build with CONFIG_PCI_QUIRKS=y and try this patch:
> 
> diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
> index 214ed060ca1b..ac134d95a97f 100644
> --- a/drivers/pci/quirks.c
> +++ b/drivers/pci/quirks.c
> @@ -96,6 +96,7 @@ int pcie_failed_link_retrain(struct pci_dev *dev)
>   {
>   	static const struct pci_device_id ids[] = {
>   		{ PCI_VDEVICE(ASMEDIA, 0x2824) }, /* ASMedia ASM2824 */
> +		{ PCI_VDEVICE(ASMEDIA, 0x2806) }, /* ASMedia ASM2806 */
>   		{}
>   	};
>   	u16 lnksta, lnkctl2;

It doesn't help with either probing behind the bridge or the link speed.

> If that does not work, perhaps you could try this patch
> (assuming that all Rock 5C:s have a ASM2806 on pcie2x1l2):

ROCK 5C has a PCIe FPC connector and I'm using Dual 2.5G Router HAT.
  https://radxa.com/products/rock5/5c#techspec
  https://radxa.com/products/accessories/dual-2-5g-router-hat

Regarding the link speed, I initially suspected the FPC connector and/or 
cable might be the issue. However, I tried the Dual 2.5G Router HAT with 
the ROCK 5A (which uses a different cable), and I got the same result.

BTW, the link speed varies between 2Gb/s and 4Gb/s depending on the 
reboot. (with or without quirk)

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
> index dd7317bab613..26f8539d934a 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
> @@ -452,6 +452,7 @@ &pcie2x1l2 {
>   	pinctrl-0 = <&pcie20x1_2_perstn_m0>;
>   	reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
>   	vpcie3v3-supply = <&pcie2x1l2_3v3>;
> +	max-link-speed = <1>;
>   	status = "okay";
>   };
> 
> 
> 
> Kind regards,
> Niklas
> 



From dsimic at manjaro.org  Sun Nov  9 15:51:49 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Mon, 10 Nov 2025 00:51:49 +0100
Subject: =?utf-8?q?Re=3A?= [RFC PATCH 2/2] =?utf-8?q?PCI=3A?=
 =?utf-8?q?_rockchip-host=3A?= drop wait on PERST# toggle
In-Reply-To: <aQrKtFT0ldc70gKj@geday>
References: <d3d0c3a387ff461e62bbd66a0bde654a9a17761e.1762150971.git.geraldogabriel@gmail.com>
 <20251103181038.GA1814635@bhelgaas> <aQrKtFT0ldc70gKj@geday>
Message-ID: <17220ae9-9e0e-cb0b-63bd-eaf9a6ed6411@manjaro.org>

Hello Geraldo,

On Wednesday, November 05, 2025 04:55 CET, Geraldo Nascimento <geraldogabriel at gmail.com> wrote:
> I did some more testing, intrigued by why would a delay of more than
> 5 ms after the enablement of the power rails trigger failure in
> initial link-training.
> 
> Something in my intuition kept telling me this was PERST# related,
> and so I followed that rabbit-hole.
> 
> It seems the following change will allow the SSD to work with the
> Rockchip-IP PCIe core without any other changes. So it is purely
> a DT change and we are able to keep the mandatory 100ms delay
> after driving PERST# low, as well as the always-on/boot-on
> properties of the 3v3 power regulator.
> 
> This time everything is within the PCIe spec AFAICT, PERST# indeed
> is an Open Drain signal, and indeed it does requires pull-up resistor
> to maintain the drive after driving it high.
> 
> I'm still testing the overall stability of this, let's hope for the
> best!
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
> index aa70776e898a..1c5afc0413bc 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
> @@ -383,13 +383,14 @@ &pcie_phy {
>  };
>  
>  &pcie0 {
> -	ep-gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>;
> +	ep-gpios = <&gpio0 RK_PB4 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
>  	num-lanes = <4>;
> -	pinctrl-0 = <&pcie_clkreqnb_cpm>;
> +	pinctrl-0 = <&pcie_clkreqnb_cpm>, <&pcie_perst>;
>  	pinctrl-names = "default";
>  	vpcie0v9-supply = <&vcca_0v9>;	/* VCC_0V9_S0 */
>  	vpcie1v8-supply = <&vcca_1v8>;	/* VCC_1V8_S0 */
>  	vpcie3v3-supply = <&vcc3v3_pcie>;
> +	max-link-speed = <2>;

FWIW, we shouldn't be enabling PCIe Gen2 here, because it's been
already disabled for the RK3399 due to unknown errata in the commit
712fa1777207 ("arm64: dts: rockchip: add max-link-speed for rk3399",
2016-12-16).  It's perfectly reasonable to assume the same for the
RK3399Pro, which is basically RK3399 packaged together with RK1808,
AFAIK with no on-package interconnects.

>  	status = "okay";
>  };
>  
> @@ -408,6 +409,10 @@ pcie {
>  		pcie_pwr: pcie-pwr {
>  			rockchip,pins = <4 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>;
>  		};
> +		pcie_perst: pcie-perst {
> +			rockchip,pins = <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>;
> +		};
> +
>  	};
>  
>  	pmic {



From geraldogabriel at gmail.com  Sun Nov  9 15:57:52 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Sun, 9 Nov 2025 20:57:52 -0300
Subject: [RFC PATCH 2/2] PCI: rockchip-host: drop wait on PERST# toggle
In-Reply-To: <17220ae9-9e0e-cb0b-63bd-eaf9a6ed6411@manjaro.org>
References: <d3d0c3a387ff461e62bbd66a0bde654a9a17761e.1762150971.git.geraldogabriel@gmail.com>
 <20251103181038.GA1814635@bhelgaas>
 <aQrKtFT0ldc70gKj@geday>
 <17220ae9-9e0e-cb0b-63bd-eaf9a6ed6411@manjaro.org>
Message-ID: <aREqgL8JVYUcKO7R@geday>

On Mon, Nov 10, 2025 at 12:51:49AM +0100, Dragan Simic wrote:
> Hello Geraldo,
> 
> On Wednesday, November 05, 2025 04:55 CET, Geraldo Nascimento <geraldogabriel at gmail.com> wrote:
> > I did some more testing, intrigued by why would a delay of more than
> > 5 ms after the enablement of the power rails trigger failure in
> > initial link-training.
> > 
> > Something in my intuition kept telling me this was PERST# related,
> > and so I followed that rabbit-hole.
> > 
> > It seems the following change will allow the SSD to work with the
> > Rockchip-IP PCIe core without any other changes. So it is purely
> > a DT change and we are able to keep the mandatory 100ms delay
> > after driving PERST# low, as well as the always-on/boot-on
> > properties of the 3v3 power regulator.
> > 
> > This time everything is within the PCIe spec AFAICT, PERST# indeed
> > is an Open Drain signal, and indeed it does requires pull-up resistor
> > to maintain the drive after driving it high.
> > 
> > I'm still testing the overall stability of this, let's hope for the
> > best!
> > 
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
> > index aa70776e898a..1c5afc0413bc 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
> > +++ b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
> > @@ -383,13 +383,14 @@ &pcie_phy {
> >  };
> >  
> >  &pcie0 {
> > -	ep-gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>;
> > +	ep-gpios = <&gpio0 RK_PB4 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
> >  	num-lanes = <4>;
> > -	pinctrl-0 = <&pcie_clkreqnb_cpm>;
> > +	pinctrl-0 = <&pcie_clkreqnb_cpm>, <&pcie_perst>;
> >  	pinctrl-names = "default";
> >  	vpcie0v9-supply = <&vcca_0v9>;	/* VCC_0V9_S0 */
> >  	vpcie1v8-supply = <&vcca_1v8>;	/* VCC_1V8_S0 */
> >  	vpcie3v3-supply = <&vcc3v3_pcie>;
> > +	max-link-speed = <2>;
> 
> FWIW, we shouldn't be enabling PCIe Gen2 here, because it's been
> already disabled for the RK3399 due to unknown errata in the commit
> 712fa1777207 ("arm64: dts: rockchip: add max-link-speed for rk3399",
> 2016-12-16).  It's perfectly reasonable to assume the same for the
> RK3399Pro, which is basically RK3399 packaged together with RK1808,
> AFAIK with no on-package interconnects.

Hi Dragan!

Thanks for the catch, you are correct. But in this case it was just
for my tests and it crept in in the git diff. I wasn't really proposing
to make that change.

Thanks,
Geraldo Nascimento



From dsimic at manjaro.org  Sun Nov  9 16:23:06 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Mon, 10 Nov 2025 01:23:06 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v2] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= add pwm-fan for NanoPC-T6
In-Reply-To: <20251109192128.72527-1-sigmaris@gmail.com>
References: <20251109192128.72527-1-sigmaris@gmail.com>
Message-ID: <da6721a3-8f59-9c0c-762c-bc02b39ac472@manjaro.org>

Hello Hugh,

Thanks for the v2!  Please, see a couple of nitpicks below.

On Sunday, November 09, 2025 20:20 CET, Hugh Cole-Baker <sigmaris at gmail.com> wrote:
> FriendlyELEC offers an optional heatsink and fan addon for the NanoPC-T6
> and T6 LTS, which plugs in to the fan connector on the board driven by
> pwm1. Add the fan as an active cooling device for the SoC package.
> 
> Signed-off-by: Hugh Cole-Baker <sigmaris at gmail.com>
> ---
> Changes from v1: https://lore.kernel.org/linux-rockchip/20251026194858.92461-1-sigmaris at gmail.com/
> * add the fan to the base board dtsi instead of overlay (Heiko)
> * just use 2 trip points for warm and hot temperatures (Dragan, Alexey)
> 
> References:
> FriendlyELEC heatsink with fan addon:
> https://www.friendlyelec.com/index.php?route=product/product&product_id=305
> Vendor DT with trip points and PWM duty cycle values:
> https://github.com/friendlyarm/kernel-rockchip/blob/4944602540b62f5aad139fe602a76cf7c3176128/arch/arm64/boot/dts/rockchip/rk3588-nanopi6-rev01.dts#L75-L90

I think it would be better to move these references to the patch
description, so they become directly available in the repository.
It might be the best to use the "... [n]" form for the references,
which puts them as close to the backed contents as possible.

Oh, and I think that "arm64: dts: rockchip: Enable active cooling
on NanoPC-T6" as the patch subject would read nicer. :)

>  .../boot/dts/rockchip/rk3588-nanopc-t6.dtsi   | 39 +++++++++++++++++++
>  1 file changed, 39 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
> index fafeabe9adf9e..9164a0ee6228e 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
> @@ -11,6 +11,7 @@
>  #include <dt-bindings/input/input.h>
>  #include <dt-bindings/pinctrl/rockchip.h>
>  #include <dt-bindings/soc/rockchip,vop2.h>
> +#include <dt-bindings/thermal/thermal.h>
>  #include <dt-bindings/usb/pd.h>
>  #include "rk3588.dtsi"
>  
> @@ -89,6 +90,14 @@ usr_led: led-1 {
>  		};
>  	};
>  
> +	fan: pwm-fan {
> +		compatible = "pwm-fan";
> +		cooling-levels = <0 35 64 100 150 255>;
> +		fan-supply = <&vcc5v0_sys>;
> +		pwms = <&pwm1 0 50000 0>;
> +		#cooling-cells = <2>;
> +	};
> +
>  	sound {
>  		compatible = "simple-audio-card";
>  		pinctrl-names = "default";
> @@ -591,6 +600,36 @@ &i2s6_8ch {
>  	status = "okay";
>  };
>  
> +&package_thermal {
> +	polling-delay = <1000>;
> +
> +	trips {
> +		package_warm: package-warm {
> +			temperature = <50000>;
> +			hysteresis = <2000>;
> +			type = "active";
> +		};
> +
> +		package_hot: package-hot {
> +			temperature = <60000>;
> +			hysteresis = <2000>;
> +			type = "active";
> +		};
> +	};

It should be better to use 55 and 65 oC as the trip thresholds,
because people often report around 50 oC as the observed idle-state
temperature of their RK3588 SoCs, so increasing the first threshold
to 55 oC should be beneficial by preventing the fan from spinning
when the SoC is actually idle.  The second threshold is usually set
to be 10 oC higher, so it should end up at 65 oC.

> +	cooling-maps {
> +		map0 {
> +			trip = <&package_warm>;
> +			cooling-device = <&fan THERMAL_NO_LIMIT 1>;
> +		};
> +
> +		map1 {
> +			trip = <&package_hot>;
> +			cooling-device = <&fan 2 THERMAL_NO_LIMIT>;
> +		};
> +	};
> +};
> +
>  &pcie2x1l0 {
>  	reset-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_HIGH>;
>  	vpcie3v3-supply = <&vcc_3v3_pcie20>;



From naoki at radxa.com  Sun Nov  9 18:27:32 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Mon, 10 Nov 2025 02:27:32 +0000
Subject: [PATCH] arm64: dts: rockchip: Turn all LEDs on at boot for Radxa boards
Message-ID: <20251110022732.809145-1-naoki@radxa.com>

Radxa's boards turn all LEDs on at boot(loader), but some boards, e.g.
ROCK Pi E don't have `default-state` property in Linux kernel tree but
have it in U-Boot tree[1] instead.

This patch adds `default-state = "on"` for (almost) all LEDs (with a
few exceptions which should be "off" such as RGB LEDs on E25 and LAN/
WAN LEDs on E20C/E52C).

Also, remove following redundant properties:
 linux,default-trigger = "default-on"; // use default-state = "on"
 default-state = "off"; // default is "off"

[1] https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3328-rock-pi-e-base-u-boot.dtsi#L11

Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
 arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts    | 1 -
 arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts    | 1 +
 arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts | 3 ++-
 arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi   | 1 +
 arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts   | 2 --
 arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts      | 1 -
 arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts | 1 +
 arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts      | 1 +
 arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi  | 1 +
 arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts      | 1 +
 arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts      | 3 ++-
 arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts   | 2 --
 arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts   | 3 ++-
 arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi     | 1 +
 arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts      | 1 +
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts     | 3 ++-
 16 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
index 7a32972bc2496..c1e3098b9a7bc 100644
--- a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
@@ -35,7 +35,6 @@ green-led {
 			function = LED_FUNCTION_POWER;
 			gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
 			label = "rockpis:green:power";
-			linux,default-trigger = "default-on";
 		};
 
 		blue-led {
diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
index a4bdd87d0729f..d3d6f34b66fb0 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
@@ -59,6 +59,7 @@ leds {
 
 		led-0 {
 			color = <LED_COLOR_ID_BLUE>;
+			default-state = "on";
 			gpios = <&gpio3 RK_PA5 GPIO_ACTIVE_LOW>;
 			linux,default-trigger = "heartbeat";
 		};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts
index 962b8b231c960..a83ffbef22a7b 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts
@@ -39,14 +39,15 @@ leds {
 		led-0 {
 			function = LED_FUNCTION_POWER;
 			color = <LED_COLOR_ID_GREEN>;
+			default-state = "on";
 			gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_LOW>;
-			linux,default-trigger = "default-on";
 		};
 
 		/* USER_LED2 */
 		led-1 {
 			function = LED_FUNCTION_STATUS;
 			color = <LED_COLOR_ID_BLUE>;
+			default-state = "on";
 			gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "heartbeat";
 		};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
index 046dbe3290178..ef434c23fe85c 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
@@ -35,6 +35,7 @@ leds {
 		led-0 {
 			function = LED_FUNCTION_STATUS;
 			color = <LED_COLOR_ID_BLUE>;
+			default-state = "on";
 			gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "heartbeat";
 		};
diff --git a/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts b/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts
index b324527561558..79d316a1d8495 100644
--- a/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts
@@ -62,7 +62,6 @@ leds {
 
 		led-lan {
 			color = <LED_COLOR_ID_GREEN>;
-			default-state = "off";
 			function = LED_FUNCTION_LAN;
 			gpios = <&gpio4 RK_PB5 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "netdev";
@@ -78,7 +77,6 @@ led-sys {
 
 		led-wan {
 			color = <LED_COLOR_ID_GREEN>;
-			default-state = "off";
 			function = LED_FUNCTION_WAN;
 			gpios = <&gpio4 RK_PC0 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "netdev";
diff --git a/arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts b/arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts
index c03ae1dd34560..0b696d49b71fa 100644
--- a/arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts
@@ -45,7 +45,6 @@ led-1 {
 		default-state = "on";
 		function = LED_FUNCTION_STATUS;
 		gpios = <&gpio3 RK_PC1 GPIO_ACTIVE_LOW>;
-		linux,default-trigger = "default-on";
 	};
 };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts b/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
index b5b253f04cdf5..9e7212b70e3f1 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
@@ -46,6 +46,7 @@ leds {
 		led-1 {
 			gpios = <&gpio4 RK_PA4 GPIO_ACTIVE_LOW>;
 			color = <LED_COLOR_ID_GREEN>;
+			default-state = "on";
 			function = LED_FUNCTION_ACTIVITY;
 			linux,default-trigger = "heartbeat";
 			pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
index 6224d72813e59..3ec108bcf89a1 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
@@ -47,6 +47,7 @@ led-0 {
 			gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
 			function = LED_FUNCTION_HEARTBEAT;
 			color = <LED_COLOR_ID_BLUE>;
+			default-state = "on";
 			linux,default-trigger = "heartbeat";
 			pinctrl-names = "default";
 			pinctrl-0 = <&user_led2>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi b/arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi
index 729e38b9f620e..140582f8e1034 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi
@@ -23,6 +23,7 @@ led_user: led-0 {
 			gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
 			function = LED_FUNCTION_HEARTBEAT;
 			color = <LED_COLOR_ID_GREEN>;
+			default-state = "on";
 			linux,default-trigger = "heartbeat";
 			pinctrl-names = "default";
 			pinctrl-0 = <&led_user_en>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
index 44cfdfeed6681..e6c18df0fa582 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
@@ -47,6 +47,7 @@ led_user: led-0 {
 			gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
 			function = LED_FUNCTION_HEARTBEAT;
 			color = <LED_COLOR_ID_BLUE>;
+			default-state = "on";
 			linux,default-trigger = "heartbeat";
 			pinctrl-names = "default";
 			pinctrl-0 = <&led_user_en>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts b/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts
index 9bc33422ced50..99d3a8be8f18c 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts
@@ -52,13 +52,14 @@ leds: leds {
 
 		power-led {
 			color = <LED_COLOR_ID_GREEN>;
+			default-state = "on";
 			function = LED_FUNCTION_STATUS;
 			gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>;
-			linux,default-trigger = "default-on";
 		};
 
 		user-led {
 			color = <LED_COLOR_ID_BLUE>;
+			default-state = "on";
 			function = LED_FUNCTION_HEARTBEAT;
 			gpios = <&gpio0 RK_PC4 GPIO_ACTIVE_LOW>;
 			linux,default-trigger = "heartbeat";
diff --git a/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts b/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts
index 854c118418eb8..f737769d4a007 100644
--- a/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts
@@ -71,7 +71,6 @@ leds-1 {
 
 		led-1 {
 			color = <LED_COLOR_ID_GREEN>;
-			default-state = "off";
 			function = LED_FUNCTION_LAN;
 			linux,default-trigger = "netdev";
 			pwms = <&pwm14 0 1000000 PWM_POLARITY_INVERTED>;
@@ -80,7 +79,6 @@ led-1 {
 
 		led-2 {
 			color = <LED_COLOR_ID_GREEN>;
-			default-state = "off";
 			function = LED_FUNCTION_WAN;
 			linux,default-trigger = "netdev";
 			pwms = <&pwm11 0 1000000 PWM_POLARITY_INVERTED>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
index bc8140883de47..86477346c3f5a 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
@@ -88,11 +88,12 @@ gpio-leds {
 		pinctrl-0 = <&led_pins>;
 
 		power-led1 {
+			default-state = "on";
 			gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
-			linux,default-trigger = "default-on";
 		};
 
 		hdd-led2 {
+			default-state = "on";
 			gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "disk-activity";
 		};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi
index e5c474e4d02a6..8c4a4270f9f93 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi
@@ -30,6 +30,7 @@ leds {
 		led_rgb_b {
 			function = LED_FUNCTION_STATUS;
 			color = <LED_COLOR_ID_BLUE>;
+			default-state = "on";
 			gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "heartbeat";
 		};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts
index 0dd90c744380b..87e9d4b86dad4 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts
@@ -33,6 +33,7 @@ leds {
 		led_rgb_b {
 			function = LED_FUNCTION_STATUS;
 			color = <LED_COLOR_ID_BLUE>;
+			default-state = "on";
 			gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "heartbeat";
 		};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
index 19a08f7794e67..46c81e796b100 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
@@ -54,6 +54,7 @@ leds {
 
 		io-led {
 			color = <LED_COLOR_ID_BLUE>;
+			default-state = "on";
 			function = LED_FUNCTION_STATUS;
 			gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "heartbeat";
@@ -61,9 +62,9 @@ io-led {
 
 		power-led {
 			color = <LED_COLOR_ID_GREEN>;
+			default-state = "on";
 			function = LED_FUNCTION_POWER;
 			gpios = <&gpio3 RK_PC4 GPIO_ACTIVE_HIGH>;
-			linux,default-trigger = "default-on";
 		};
 	};
 
-- 
2.43.0



From shawn.lin at rock-chips.com  Sun Nov  9 18:30:20 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Mon, 10 Nov 2025 10:30:20 +0800
Subject: [RESEND] Re: [PATCH] PCI: dw-rockchip: Skip waiting for link up
In-Reply-To: <F8B2B6FA2884D69A+b7da13f2-0ffb-4308-b1ba-0549bc461be8@radxa.com>
References: <20250113-rockchip-no-wait-v1-1-25417f37b92f@kernel.org>
 <1E8E4DB773970CB5+5a52c9e1-01b8-4872-99b7-021099f04031@radxa.com>
 <6e87b611-13ea-4d89-8dbf-85510dd86fa6@rock-chips.com>
 <aQ840q5BxNS1eIai@ryzen> <aQ9FWEuW47L8YOxC@ryzen>
 <55EB0E5F655F3AFC+136b89fd-98d4-42af-a99d-a0bb05cc93f3@radxa.com>
 <aRCI5kG16_1erMME@ryzen>
 <F8B2B6FA2884D69A+b7da13f2-0ffb-4308-b1ba-0549bc461be8@radxa.com>
Message-ID: <780a4209-f89f-43a9-9364-331d3b77e61e@rock-chips.com>

Hi Fukaumi

? 2025/11/10 ??? 7:26, FUKAUMI Naoki ??:
> (RESEND: fix mani's email address)
> 
> Hi Niklas,
> 
> On 11/9/25 21:28, Niklas Cassel wrote:
>> On Sun, Nov 09, 2025 at 01:42:23PM +0900, FUKAUMI Naoki wrote:
>>> Hi Niklas,
>>>
>>> On 11/8/25 22:27, Niklas Cassel wrote:
>>> (snip)> (And btw. please test with the latest 6.18-rc, as, from 
>>> experience,
>>> the
>>>> ASPM problems in earlier RCs can result in some weird problems that are
>>>> not immediately deduced to be caused by the ASPM enablement.)
>>>
>>> Here is dmesg from v6.18-rc4:
>>> ? https://gist.github.com/RadxaNaoki/40e1d049bff4f1d2d4773a5ba0ed9dff
>>
>> Same problem as before:
>> [??? 1.732538] pci_bus 0004:43: busn_res: can not insert [bus 43-41] 
>> under [bus 42-41] (conflicts with (null) [bus 42-41])
>> [??? 1.732645] pci_bus 0004:43: busn_res: [bus 43-41] end is updated 
>> to 43
>> [??? 1.732651] pci_bus 0004:43: busn_res: can not insert [bus 43] 
>> under [bus 42-41] (conflicts with (null) [bus 42-41])
>> [??? 1.732661] pci 0004:42:00.0: devices behind bridge are unusable 
>> because [bus 43] cannot be assigned for them
>> [??? 1.732840] pci_bus 0004:44: busn_res: can not insert [bus 44-41] 
>> under [bus 42-41] (conflicts with (null) [bus 42-41])
>> [??? 1.732947] pci_bus 0004:44: busn_res: [bus 44-41] end is updated 
>> to 44
>> [??? 1.732952] pci_bus 0004:44: busn_res: can not insert [bus 44] 
>> under [bus 42-41] (conflicts with (null) [bus 42-41])
>> [??? 1.732962] pci 0004:42:02.0: devices behind bridge are unusable 
>> because [bus 44] cannot be assigned for them
>> [??? 1.733134] pci_bus 0004:45: busn_res: can not insert [bus 45-41] 
>> under [bus 42-41] (conflicts with (null) [bus 42-41])
>> [??? 1.733246] pci_bus 0004:45: busn_res: [bus 45-41] end is updated 
>> to 45
>> [??? 1.733255] pci_bus 0004:45: busn_res: can not insert [bus 45] 
>> under [bus 42-41] (conflicts with (null) [bus 42-41])
>> [??? 1.733266] pci 0004:42:06.0: devices behind bridge are unusable 
>> because [bus 45] cannot be assigned for them
>> [??? 1.733438] pci_bus 0004:46: busn_res: can not insert [bus 46-41] 
>> under [bus 42-41] (conflicts with (null) [bus 42-41])
>> [??? 1.733544] pci_bus 0004:46: busn_res: [bus 46-41] end is updated 
>> to 46
>> [??? 1.733550] pci_bus 0004:46: busn_res: can not insert [bus 46] 
>> under [bus 42-41] (conflicts with (null) [bus 42-41])
>> [??? 1.733560] pci 0004:42:0e.0: devices behind bridge are unusable 
>> because [bus 46] cannot be assigned for them
>> [??? 1.733571] pci_bus 0004:42: busn_res: [bus 42-41] end is updated 
>> to 46
>> [??? 1.733575] pci_bus 0004:42: busn_res: can not insert [bus 42-46] 
>> under [bus 41] (conflicts with (null) [bus 41])
>> [??? 1.733585] pci 0004:41:00.0: devices behind bridge are unusable 
>> because [bus 42-46] cannot be assigned for them
>> [??? 1.733596] pcieport 0004:40:00.0: bridge has subordinate 41 but 
>> max busn 46
>>
>>
>> Seems like the ASM2806 switch, for some reason, is not ready.
>>
>> One change that Diederik pointed out is that in the "good" case,
>> the link is always in Gen1 speed.
>>
>> Perhaps you could build with CONFIG_PCI_QUIRKS=y and try this patch:
>>
>> diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
>> index 214ed060ca1b..ac134d95a97f 100644
>> --- a/drivers/pci/quirks.c
>> +++ b/drivers/pci/quirks.c
>> @@ -96,6 +96,7 @@ int pcie_failed_link_retrain(struct pci_dev *dev)
>> ? {
>> ????? static const struct pci_device_id ids[] = {
>> ????????? { PCI_VDEVICE(ASMEDIA, 0x2824) }, /* ASMedia ASM2824 */
>> +??????? { PCI_VDEVICE(ASMEDIA, 0x2806) }, /* ASMedia ASM2806 */
>> ????????? {}
>> ????? };
>> ????? u16 lnksta, lnkctl2;
> 
> It doesn't help with either probing behind the bridge or the link speed.
> 
>> If that does not work, perhaps you could try this patch
>> (assuming that all Rock 5C:s have a ASM2806 on pcie2x1l2):
> 
> ROCK 5C has a PCIe FPC connector and I'm using Dual 2.5G Router HAT.
>  ?https://radxa.com/products/rock5/5c#techspec
>  ?https://radxa.com/products/accessories/dual-2-5g-router-hat
> 
> Regarding the link speed, I initially suspected the FPC connector and/or 
> cable might be the issue. However, I tried the Dual 2.5G Router HAT with 
> the ROCK 5A (which uses a different cable), and I got the same result.
> 
> BTW, the link speed varies between 2Gb/s and 4Gb/s depending on the 
> reboot. (with or without quirk)

Could you please help check this patch?

--- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
+++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
@@ -454,6 +454,8 @@ static irqreturn_t 
rockchip_pcie_rc_sys_irq_thread(int irq, void *arg)
         struct dw_pcie *pci = &rockchip->pci;
         struct dw_pcie_rp *pp = &pci->pp;
         struct device *dev = pci->dev;
+       struct pci_bus *child, *root_bus = NULL;
+       struct pci_dev *bridge;
         u32 reg;

         reg = rockchip_pcie_readl_apb(rockchip, 
PCIE_CLIENT_INTR_STATUS_MISC);
@@ -462,12 +464,21 @@ static irqreturn_t 
rockchip_pcie_rc_sys_irq_thread(int irq, void *arg)
         dev_dbg(dev, "PCIE_CLIENT_INTR_STATUS_MISC: %#x\n", reg);
         dev_dbg(dev, "LTSSM_STATUS: %#x\n", 
rockchip_pcie_get_ltssm(rockchip));

+       list_for_each_entry(child, &pp->bridge->bus->children, node) {
+               if (child->parent == pp->bridge->bus) {
+                       root_bus = child;
+                       bridge = root_bus->self;
+                       break;
+               }
+        }
+
         if (reg & PCIE_RDLH_LINK_UP_CHGED) {
                 if (rockchip_pcie_link_up(pci)) {
                         msleep(PCIE_RESET_CONFIG_WAIT_MS);
                         dev_dbg(dev, "Received Link up event. Starting 
enumeration!\n");
                         /* Rescan the bus to enumerate endpoint devices */
                         pci_lock_rescan_remove();
+                       pci_stop_and_remove_bus_device(bridge);
                         pci_rescan_bus(pp->bridge->bus);
                         pci_unlock_rescan_remove();
                 }


> 
> Best regards,
> 
> -- 
> FUKAUMI Naoki
> Radxa Computer (Shenzhen) Co., Ltd.
> 
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/arch/ 
>> arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
>> index dd7317bab613..26f8539d934a 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
>> +++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
>> @@ -452,6 +452,7 @@ &pcie2x1l2 {
>> ????? pinctrl-0 = <&pcie20x1_2_perstn_m0>;
>> ????? reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
>> ????? vpcie3v3-supply = <&pcie2x1l2_3v3>;
>> +??? max-link-speed = <1>;
>> ????? status = "okay";
>> ? };
>>
>>
>>
>> Kind regards,
>> Niklas
>>
> 
> 



From naoki at radxa.com  Sun Nov  9 19:00:36 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Mon, 10 Nov 2025 03:00:36 +0000
Subject: [RFC PATCH] arm64: dts: rockchip: Fix microSD card detect for Radxa ROCK 5 ITX
Message-ID: <20251110030036.825150-1-naoki@radxa.com>

Due to the discussion about cd-gpios and sdmmmc_det pin
functionality[1], it would be better to use cd-gpios for now.

[1] https://lore.kernel.org/linux-rockchip/20240912152538.1.I858c2a0bf83606c8b59ba1ab6944978a398d2ac5 at changeid/T/#u

Fixes: 31390eb8ffbf2 ("arm64: dts: rockchip: add ROCK 5 ITX board")
Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
 arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
index bc8140883de47..391c6482e8ee3 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
@@ -670,6 +670,12 @@ led_pins: led-pins {
 		};
 	};
 
+	mmc {
+		sdmmc_det_gpio: sdmmc-det-gpio {
+			rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
 	pcie {
 		pcie20x1_2_perstn: pcie20x1-2-perstn {
 			rockchip,pins = <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
@@ -795,12 +801,13 @@ &sdmmc {
 	bus-width = <4>;
 	cap-mmc-highspeed;
 	cap-sd-highspeed;
+	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
 	disable-wp;
 	max-frequency = <200000000>;
 	no-sdio;
 	no-mmc;
 	pinctrl-names = "default";
-	pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd &sdmmc_det>;
+	pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd &sdmmc_det_gpio>;
 	sd-uhs-sdr104;
 	vmmc-supply = <&vcc_3v3_s3>;
 	vqmmc-supply = <&vccio_sd_s0>;
-- 
2.43.0



From naoki at radxa.com  Sun Nov  9 19:16:37 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Mon, 10 Nov 2025 12:16:37 +0900
Subject: [RFC PATCH] arm64: dts: rockchip: Fix microSD card detect for
 Radxa ROCK 5 ITX
In-Reply-To: <20251110030036.825150-1-naoki@radxa.com>
References: <20251110030036.825150-1-naoki@radxa.com>
Message-ID: <EECF7629320EEEDD+03c6ee06-4351-4150-b1b0-957d5cfc3d6d@radxa.com>

Hi,

On 11/10/25 12:00, FUKAUMI Naoki wrote:
> Due to the discussion about cd-gpios and sdmmmc_det pin
> functionality[1], it would be better to use cd-gpios for now.
> 
> [1] https://lore.kernel.org/linux-rockchip/20240912152538.1.I858c2a0bf83606c8b59ba1ab6944978a398d2ac5 at changeid/T/#u
> 
> Fixes: 31390eb8ffbf2 ("arm64: dts: rockchip: add ROCK 5 ITX board")
> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> ---
>   arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts | 9 ++++++++-
>   1 file changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
> index bc8140883de47..391c6482e8ee3 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
> @@ -670,6 +670,12 @@ led_pins: led-pins {
>   		};
>   	};
>   
> +	mmc {
> +		sdmmc_det_gpio: sdmmc-det-gpio {
> +			rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
> +		};
> +	};
> +

I got following error:

$ make CHECK_DTBS=y rockchip/rk3588-rock-5-itx.dtb
   UPD     include/config/kernel.release
   DTC [C] arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dtb
/home/radxa/linux/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dtb: 
mmc: sdmmc-det-gpio: {'rockchip,pins': [[0, 4, 0, 270]], 'phandle': 145} 
is not of type 'array'
	from schema $id: http://devicetree.org/schemas/gpio/gpio-consumer.yaml#

What's wrong?

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

>   	pcie {
>   		pcie20x1_2_perstn: pcie20x1-2-perstn {
>   			rockchip,pins = <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
> @@ -795,12 +801,13 @@ &sdmmc {
>   	bus-width = <4>;
>   	cap-mmc-highspeed;
>   	cap-sd-highspeed;
> +	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
>   	disable-wp;
>   	max-frequency = <200000000>;
>   	no-sdio;
>   	no-mmc;
>   	pinctrl-names = "default";
> -	pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd &sdmmc_det>;
> +	pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd &sdmmc_det_gpio>;
>   	sd-uhs-sdr104;
>   	vmmc-supply = <&vcc_3v3_s3>;
>   	vqmmc-supply = <&vccio_sd_s0>;




From dsimic at manjaro.org  Sun Nov  9 19:18:04 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Mon, 10 Nov 2025 04:18:04 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v6 3/3] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= Add Radxa CM5 IO Board
In-Reply-To: <CALWfF7K3zNxSsXVpW8pLc_xWi793HG99OvbshtP-0=764JmPKw@mail.gmail.com>
References: <20251105051335.17652-1-naoki@radxa.com> <20251105051335.17652-4-naoki@radxa.com>
 <CALWfF7KyTfpXSyjVQaFzqtn6KyDxuyZOBpPR8y-jf6sduNxq5A@mail.gmail.com>
 <1EE1A1D9D7C100DA+1b365782-98c4-4ee0-ab96-920990841903@radxa.com> <35ff8e6f-dd2b-d909-70c7-b19240e32ccf@manjaro.org> <CALWfF7K3zNxSsXVpW8pLc_xWi793HG99OvbshtP-0=764JmPKw@mail.gmail.com>
Message-ID: <fab774df-de59-f101-55ec-5d4f691955eb@manjaro.org>

Hello Jimmy,

On Thursday, November 06, 2025 05:53 CET, Jimmy Hon <honyuenkwun at gmail.com> wrote:
> On Wed, Nov 5, 2025 at 9:31?PM Dragan Simic <dsimic at manjaro.org> wrote:
> > With all that in mind, we should specify "no-mmc" here, because
> > we're describing a microSD slot, instead of describing some hybrid
> > MMC/microSD slot.  That also explains why the adapter sold by Radxa
> > is described as not to be used with microSD card slots on SBCs.  I'd
> > also like to hear is this adapter/eMMC chip combo recognized by the
> > kernel when "no-mmc" is specified; it should fail.
> >
> > Actually, not specifying "no-mmc" here may result in some unforeseen
> > issues with some (or perhaps many?) microSD cards, because the MMC
> > drivers will treat them as MMC-capable devices and try to initialize
> > them as such, which may cause all kinds of issues.  In fact, I'm not
> > really sure that the MMC drivers are actually implemented in a way
> > that avoids all possible issues with the storage controllers that
> > are capable of both SD and MMC modes when neither of "no-sd" and
> > "no-mmc" is specified in their DT nodes.
> 
> Hybrid MMC and SD slots are pretty normal on USB card readers. So it's
> normal for the host controller to figure out what kind of card is in
> the slot.
> https://uditagarwal.in/understanding-sd-sdio-and-mmc-interface/
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6ae3e537eab9f560b516b001eb89f0cd568bdced
> was the commit that introduced the device tree properties. By the
> wording of the commit message, these device tree properties are used
> to indicate to the driver if the host controller hardware is capable
> of MMC initialization or SD initialization.
> 
> Since the host controller in the RK3588 is capable of all the modes,
> these properties do not need to be specified.
> 
> Since Radxa has the eMMC to uSD adapter, it makes sense Radxa would
> want to configure their microSD card slot on their boards to be a
> hybrid SD/MMC slot.

Thanks for providing further insights!  After thinking a bit more
about it and after remembering that HardKernel also offers a similar
microSD-to-MMC adapter, [1] there should be very few roadblocks that
may actually prevent us from defining physical microSD slots found
on Rockchip boards as hybrid microSD/MMC slots wherever that's
allowed by the slot implementation and tested to work as expected.
Supporting more card standards is always good.

This approach shouldn't be limited to Radxa (or HardKernel) boards
only, because the available microSD-to-MMC adapters aren't designed
specifically to fit some boards only.

The possible roadblocks, as mentioned above, are some unexpected
signal integrity issues that may prevent the MMC mode from working
as expected on some boards, which Jonas pointed out already, [2][3]
and any associated issues in the MMC drivers.

I'll keep checking the code of MMC drivers for the existence of any
associated issues, and I'll possibly turn a few microSD-only slots
into hybrid ones. :)

[1] https://www.hardkernel.com/shop/emmc-module-reader-board-for-os-upgrade/
[2] https://libera.catirclogs.org/linux-rockchip/2025-11-06#38976445;
[3] https://libera.catirclogs.org/linux-rockchip/2025-11-07#38981060;



From naoki at radxa.com  Sun Nov  9 19:54:55 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Mon, 10 Nov 2025 03:54:55 +0000
Subject: [PATCH 2/2] arm64: dts: rockchip: Make eeprom read-only for Radxa ROCK 5A
In-Reply-To: <20251110035455.839863-1-naoki@radxa.com>
References: <20251110035455.839863-1-naoki@radxa.com>
Message-ID: <20251110035455.839863-2-naoki@radxa.com>

Make EEPROM read-only as it may contain factory-programmed
board-specific data.

Fixes: 89c880808cff8 ("arm64: dts: rockchip: add I2C EEPROM to rock-5a")
Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
index 19a08f7794e67..ae7b03488c9e7 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
@@ -254,6 +254,7 @@ eeprom: eeprom at 50 {
 		compatible = "belling,bl24c16a", "atmel,24c16";
 		reg = <0x50>;
 		pagesize = <16>;
+		read-only;
 	};
 };
 
-- 
2.43.0



From naoki at radxa.com  Sun Nov  9 19:54:54 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Mon, 10 Nov 2025 03:54:54 +0000
Subject: [PATCH 1/2] arm64: dts: rockchip: Make eeprom read-only for Radxa ROCK 3C
Message-ID: <20251110035455.839863-1-naoki@radxa.com>

Make EEPROM read-only as it may contain factory-programmed
board-specific data.

Fixes: ee219017ddb50 ("arm64: dts: rockchip: Add Radxa ROCK 3C")
Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
 arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
index 6224d72813e59..f92f6374c6255 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
@@ -466,6 +466,7 @@ eeprom: eeprom at 50 {
 		compatible = "belling,bl24c16a", "atmel,24c16";
 		reg = <0x50>;
 		pagesize = <16>;
+		read-only;
 	};
 };
 
-- 
2.43.0



From naoki at radxa.com  Sun Nov  9 20:56:03 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Mon, 10 Nov 2025 13:56:03 +0900
Subject: [RESEND] Re: [PATCH] PCI: dw-rockchip: Skip waiting for link up
In-Reply-To: <780a4209-f89f-43a9-9364-331d3b77e61e@rock-chips.com>
References: <20250113-rockchip-no-wait-v1-1-25417f37b92f@kernel.org>
 <1E8E4DB773970CB5+5a52c9e1-01b8-4872-99b7-021099f04031@radxa.com>
 <6e87b611-13ea-4d89-8dbf-85510dd86fa6@rock-chips.com>
 <aQ840q5BxNS1eIai@ryzen> <aQ9FWEuW47L8YOxC@ryzen>
 <55EB0E5F655F3AFC+136b89fd-98d4-42af-a99d-a0bb05cc93f3@radxa.com>
 <aRCI5kG16_1erMME@ryzen>
 <F8B2B6FA2884D69A+b7da13f2-0ffb-4308-b1ba-0549bc461be8@radxa.com>
 <780a4209-f89f-43a9-9364-331d3b77e61e@rock-chips.com>
Message-ID: <4487DA40249CC821+19232169-a096-4737-bc6a-5cec9592d65f@radxa.com>

Hi Shawn,

On 11/10/25 11:30, Shawn Lin wrote:
> Hi Fukaumi
> 
> ? 2025/11/10 ??? 7:26, FUKAUMI Naoki ??:
>> (RESEND: fix mani's email address)
>>
>> Hi Niklas,
>>
>> On 11/9/25 21:28, Niklas Cassel wrote:
>>> On Sun, Nov 09, 2025 at 01:42:23PM +0900, FUKAUMI Naoki wrote:
>>>> Hi Niklas,
>>>>
>>>> On 11/8/25 22:27, Niklas Cassel wrote:
>>>> (snip)> (And btw. please test with the latest 6.18-rc, as, from 
>>>> experience,
>>>> the
>>>>> ASPM problems in earlier RCs can result in some weird problems that 
>>>>> are
>>>>> not immediately deduced to be caused by the ASPM enablement.)
>>>>
>>>> Here is dmesg from v6.18-rc4:
>>>> ? https://gist.github.com/RadxaNaoki/40e1d049bff4f1d2d4773a5ba0ed9dff
>>>
>>> Same problem as before:
>>> [??? 1.732538] pci_bus 0004:43: busn_res: can not insert [bus 43-41] 
>>> under [bus 42-41] (conflicts with (null) [bus 42-41])
>>> [??? 1.732645] pci_bus 0004:43: busn_res: [bus 43-41] end is updated 
>>> to 43
>>> [??? 1.732651] pci_bus 0004:43: busn_res: can not insert [bus 43] 
>>> under [bus 42-41] (conflicts with (null) [bus 42-41])
>>> [??? 1.732661] pci 0004:42:00.0: devices behind bridge are unusable 
>>> because [bus 43] cannot be assigned for them
>>> [??? 1.732840] pci_bus 0004:44: busn_res: can not insert [bus 44-41] 
>>> under [bus 42-41] (conflicts with (null) [bus 42-41])
>>> [??? 1.732947] pci_bus 0004:44: busn_res: [bus 44-41] end is updated 
>>> to 44
>>> [??? 1.732952] pci_bus 0004:44: busn_res: can not insert [bus 44] 
>>> under [bus 42-41] (conflicts with (null) [bus 42-41])
>>> [??? 1.732962] pci 0004:42:02.0: devices behind bridge are unusable 
>>> because [bus 44] cannot be assigned for them
>>> [??? 1.733134] pci_bus 0004:45: busn_res: can not insert [bus 45-41] 
>>> under [bus 42-41] (conflicts with (null) [bus 42-41])
>>> [??? 1.733246] pci_bus 0004:45: busn_res: [bus 45-41] end is updated 
>>> to 45
>>> [??? 1.733255] pci_bus 0004:45: busn_res: can not insert [bus 45] 
>>> under [bus 42-41] (conflicts with (null) [bus 42-41])
>>> [??? 1.733266] pci 0004:42:06.0: devices behind bridge are unusable 
>>> because [bus 45] cannot be assigned for them
>>> [??? 1.733438] pci_bus 0004:46: busn_res: can not insert [bus 46-41] 
>>> under [bus 42-41] (conflicts with (null) [bus 42-41])
>>> [??? 1.733544] pci_bus 0004:46: busn_res: [bus 46-41] end is updated 
>>> to 46
>>> [??? 1.733550] pci_bus 0004:46: busn_res: can not insert [bus 46] 
>>> under [bus 42-41] (conflicts with (null) [bus 42-41])
>>> [??? 1.733560] pci 0004:42:0e.0: devices behind bridge are unusable 
>>> because [bus 46] cannot be assigned for them
>>> [??? 1.733571] pci_bus 0004:42: busn_res: [bus 42-41] end is updated 
>>> to 46
>>> [??? 1.733575] pci_bus 0004:42: busn_res: can not insert [bus 42-46] 
>>> under [bus 41] (conflicts with (null) [bus 41])
>>> [??? 1.733585] pci 0004:41:00.0: devices behind bridge are unusable 
>>> because [bus 42-46] cannot be assigned for them
>>> [??? 1.733596] pcieport 0004:40:00.0: bridge has subordinate 41 but 
>>> max busn 46
>>>
>>>
>>> Seems like the ASM2806 switch, for some reason, is not ready.
>>>
>>> One change that Diederik pointed out is that in the "good" case,
>>> the link is always in Gen1 speed.
>>>
>>> Perhaps you could build with CONFIG_PCI_QUIRKS=y and try this patch:
>>>
>>> diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
>>> index 214ed060ca1b..ac134d95a97f 100644
>>> --- a/drivers/pci/quirks.c
>>> +++ b/drivers/pci/quirks.c
>>> @@ -96,6 +96,7 @@ int pcie_failed_link_retrain(struct pci_dev *dev)
>>> ? {
>>> ????? static const struct pci_device_id ids[] = {
>>> ????????? { PCI_VDEVICE(ASMEDIA, 0x2824) }, /* ASMedia ASM2824 */
>>> +??????? { PCI_VDEVICE(ASMEDIA, 0x2806) }, /* ASMedia ASM2806 */
>>> ????????? {}
>>> ????? };
>>> ????? u16 lnksta, lnkctl2;
>>
>> It doesn't help with either probing behind the bridge or the link speed.
>>
>>> If that does not work, perhaps you could try this patch
>>> (assuming that all Rock 5C:s have a ASM2806 on pcie2x1l2):
>>
>> ROCK 5C has a PCIe FPC connector and I'm using Dual 2.5G Router HAT.
>> ??https://radxa.com/products/rock5/5c#techspec
>> ??https://radxa.com/products/accessories/dual-2-5g-router-hat
>>
>> Regarding the link speed, I initially suspected the FPC connector and/ 
>> or cable might be the issue. However, I tried the Dual 2.5G Router HAT 
>> with the ROCK 5A (which uses a different cable), and I got the same 
>> result.
>>
>> BTW, the link speed varies between 2Gb/s and 4Gb/s depending on the 
>> reboot. (with or without quirk)
> 
> Could you please help check this patch?

I tried your patch on top of vanilla v6.18-rc5.
  https://gist.github.com/RadxaNaoki/b42252ce3209d9f6bc2d4c90c71956ae

I got 2 oops,

- its_msi_teardown+0x120/0x140
   New with this patch.

- of_pci_add_properties+0x284/0x4c4
   It sometimes happen with vanilla v6.18-rcX.

Nothing behind the bridge is probed.

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> @@ -454,6 +454,8 @@ static irqreturn_t 
> rockchip_pcie_rc_sys_irq_thread(int irq, void *arg)
>  ??????? struct dw_pcie *pci = &rockchip->pci;
>  ??????? struct dw_pcie_rp *pp = &pci->pp;
>  ??????? struct device *dev = pci->dev;
> +?????? struct pci_bus *child, *root_bus = NULL;
> +?????? struct pci_dev *bridge;
>  ??????? u32 reg;
> 
>  ??????? reg = rockchip_pcie_readl_apb(rockchip, 
> PCIE_CLIENT_INTR_STATUS_MISC);
> @@ -462,12 +464,21 @@ static irqreturn_t 
> rockchip_pcie_rc_sys_irq_thread(int irq, void *arg)
>  ??????? dev_dbg(dev, "PCIE_CLIENT_INTR_STATUS_MISC: %#x\n", reg);
>  ??????? dev_dbg(dev, "LTSSM_STATUS: %#x\n", 
> rockchip_pcie_get_ltssm(rockchip));
> 
> +?????? list_for_each_entry(child, &pp->bridge->bus->children, node) {
> +?????????????? if (child->parent == pp->bridge->bus) {
> +?????????????????????? root_bus = child;
> +?????????????????????? bridge = root_bus->self;
> +?????????????????????? break;
> +?????????????? }
> +??????? }
> +
>  ??????? if (reg & PCIE_RDLH_LINK_UP_CHGED) {
>  ??????????????? if (rockchip_pcie_link_up(pci)) {
>  ??????????????????????? msleep(PCIE_RESET_CONFIG_WAIT_MS);
>  ??????????????????????? dev_dbg(dev, "Received Link up event. Starting 
> enumeration!\n");
>  ??????????????????????? /* Rescan the bus to enumerate endpoint devices */
>  ??????????????????????? pci_lock_rescan_remove();
> +?????????????????????? pci_stop_and_remove_bus_device(bridge);
>  ??????????????????????? pci_rescan_bus(pp->bridge->bus);
>  ??????????????????????? pci_unlock_rescan_remove();
>  ??????????????? }
> 
> 
>>
>> Best regards,
>>
>> -- 
>> FUKAUMI Naoki
>> Radxa Computer (Shenzhen) Co., Ltd.
>>
>>> diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/arch/ 
>>> arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
>>> index dd7317bab613..26f8539d934a 100644
>>> --- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
>>> +++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
>>> @@ -452,6 +452,7 @@ &pcie2x1l2 {
>>> ????? pinctrl-0 = <&pcie20x1_2_perstn_m0>;
>>> ????? reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
>>> ????? vpcie3v3-supply = <&pcie2x1l2_3v3>;
>>> +??? max-link-speed = <1>;
>>> ????? status = "okay";
>>> ? };
>>>
>>>
>>>
>>> Kind regards,
>>> Niklas
>>>
>>
>>
> 
> 



From dsimic at manjaro.org  Sun Nov  9 21:12:31 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Mon, 10 Nov 2025 06:12:31 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH 1/2] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= Make eeprom read-only for Radxa ROCK 3C
In-Reply-To: <20251110035455.839863-1-naoki@radxa.com>
References: <20251110035455.839863-1-naoki@radxa.com>
Message-ID: <4a4961af-8648-9c0c-5ddf-82ec156354c1@manjaro.org>

Hello Naoki,

On Monday, November 10, 2025 04:54 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> Make EEPROM read-only as it may contain factory-programmed
> board-specific data.
> 
> Fixes: ee219017ddb50 ("arm64: dts: rockchip: Add Radxa ROCK 3C")
> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> ---
>  arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
> index 6224d72813e59..f92f6374c6255 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
> @@ -466,6 +466,7 @@ eeprom: eeprom at 50 {
>  		compatible = "belling,bl24c16a", "atmel,24c16";
>  		reg = <0x50>;
>  		pagesize = <16>;
> +		read-only;
>  	};
>  };

I've checked the board schematic and making this BL24C16 chip
read-only makes sense to me.  However, I think that the patch
description should be expanded to contain a better description
of what might be found in the chip, such as a factory-programmed
MAC address.  Also, providing a link to the board schematic, as
a reference, would be a good idea.

With these remarks addressed in a v2, please feel free to include

Reviewed-by: Dragan Simic <dsimic at manjaro.org>



From dsimic at manjaro.org  Sun Nov  9 21:17:25 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Mon, 10 Nov 2025 06:17:25 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH 2/2] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= Make eeprom read-only for Radxa ROCK 5A
In-Reply-To: <20251110035455.839863-2-naoki@radxa.com>
References: <20251110035455.839863-1-naoki@radxa.com> <20251110035455.839863-2-naoki@radxa.com>
Message-ID: <36843804-433a-5c0c-4961-451b44d70bc4@manjaro.org>

Hello Naoki,

On Monday, November 10, 2025 04:54 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> Make EEPROM read-only as it may contain factory-programmed
> board-specific data.
> 
> Fixes: 89c880808cff8 ("arm64: dts: rockchip: add I2C EEPROM to rock-5a")
> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> ---
>  arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
> index 19a08f7794e67..ae7b03488c9e7 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
> @@ -254,6 +254,7 @@ eeprom: eeprom at 50 {
>  		compatible = "belling,bl24c16a", "atmel,24c16";
>  		reg = <0x50>;
>  		pagesize = <16>;
> +		read-only;
>  	};
>  };

I've checked the board schematic and making this BL24C16 chip
read-only makes sense to me.  However, I think that the patch
description should be expanded to contain a better description
of what might be found in the chip, such as a factory-programmed
MAC address.  Also, providing a link to the board schematic, as
a reference, would be a good idea.

With these remarks addressed in a v2, please feel free to include

Reviewed-by: Dragan Simic <dsimic at manjaro.org>

Additionally, it would make sense to squash this patch and your
other patch that addresses the ROCK 5C together.  They're very
similar and having them together in a single commit might actually
help the people browsing the repository understand it better.



From naoki at radxa.com  Sun Nov  9 23:05:02 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Mon, 10 Nov 2025 16:05:02 +0900
Subject: [PATCH 2/2] arm64: dts: rockchip: Make eeprom read-only for Radxa
 ROCK 5A
In-Reply-To: <36843804-433a-5c0c-4961-451b44d70bc4@manjaro.org>
References: <20251110035455.839863-1-naoki@radxa.com>
 <20251110035455.839863-2-naoki@radxa.com>
 <36843804-433a-5c0c-4961-451b44d70bc4@manjaro.org>
Message-ID: <38861A00B4F4BA62+e3221913-43e5-4335-9aaf-9b9eed5834ac@radxa.com>

Hi Dragan,

Thank you very much for your review!

On 11/10/25 14:17, Dragan Simic wrote:
> Hello Naoki,
> 
> On Monday, November 10, 2025 04:54 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
>> Make EEPROM read-only as it may contain factory-programmed
>> board-specific data.
>>
>> Fixes: 89c880808cff8 ("arm64: dts: rockchip: add I2C EEPROM to rock-5a")
>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
>> ---
>>   arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 1 +
>>   1 file changed, 1 insertion(+)
>>
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
>> index 19a08f7794e67..ae7b03488c9e7 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
>> +++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
>> @@ -254,6 +254,7 @@ eeprom: eeprom at 50 {
>>   		compatible = "belling,bl24c16a", "atmel,24c16";
>>   		reg = <0x50>;
>>   		pagesize = <16>;
>> +		read-only;
>>   	};
>>   };
> 
> I've checked the board schematic and making this BL24C16 chip
> read-only makes sense to me.  However, I think that the patch
> description should be expanded to contain a better description
> of what might be found in the chip, such as a factory-programmed
> MAC address.  Also, providing a link to the board schematic, as
> a reference, would be a good idea.

----
arm64: dts: rockchip: Make eeprom read-only for Radxa ROCK 3C/5A/5C

Make the EEPROM[1][2][3] read-only. Board-specific data written to the 
EEPROM at the factory includes, but is not limited to, the SKU (~ 
product name), BOM version (~ board version), and MAC address.

[1] 
https://dl.radxa.com/rock3/docs/hw/3c/v1400/radxa_rock_3c_v1400_schematic.pdf 
p.13
[2] https://dl.radxa.com/rock5/5a/docs/hw/radxa_rock5a_V1.1_sch.pdf p.19
[3] 
https://dl.radxa.com/rock5/5c/docs/hw/v1100/radxa_rock_5c_schematic_v1100.pdf 
p.18
----

> With these remarks addressed in a v2, please feel free to include
> 
> Reviewed-by: Dragan Simic <dsimic at manjaro.org>
> 
> Additionally, it would make sense to squash this patch and your
> other patch that addresses the ROCK 5C together.  They're very
> similar and having them together in a single commit might actually
> help the people browsing the repository understand it better.

I'll drop eeprom patch from ROCK 5C v7 patch series, and squash eeprom 
patches for ROCK 3C/5A/5C.

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.


From krzk at kernel.org  Sun Nov  9 23:12:32 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 10 Nov 2025 08:12:32 +0100
Subject: [PATCH 1/2] arm64: dts: rockchip: Simplify usb-c-connector port
 on rk3566-pinenote
In-Reply-To: <5024969.GXAFRqVoOG@diego>
References: <20251109-rk3566-pinenote-dt-fixes-upstream-v1-0-ed38d200cc04@cknow-tech.com>
 <20251109-rk3566-pinenote-dt-fixes-upstream-v1-1-ed38d200cc04@cknow-tech.com>
 <a726fac9-afe5-4639-b06a-4bccc256d98f@kernel.org> <5024969.GXAFRqVoOG@diego>
Message-ID: <19169092-78f8-4b86-9f43-ea7a2ea20b9f@kernel.org>

On 09/11/2025 23:16, Heiko St?bner wrote:
> Am Sonntag, 9. November 2025, 18:37:26 Mitteleurop?ische Normalzeit schrieb Krzysztof Kozlowski:
>> On 09/11/2025 18:05, Diederik de Haas wrote:
>>> The USB-C connector on the PineNote has only 1 port, so there's no need
>>> for a 'ports' node with address-/size-cells properties as a single
>>> 'port' node suffices.
>>>
>>> This fixes the following DT validation issue:
>>>
>>>   Warning (graph_child_address): /i2c at fe5c0000/tcpc at 60/connector/ports:
>>>     graph node has single child node 'port at 0',
>>>     #address-cells/#size-cells are not necessary
>>
>> This is not a DT validation, but DTC warning which we do not really fix.
> 
> That is good to know. Is the same true for other dtc warnings?
>

No, depends, the same for compiler warnings. That's the only warning I
remember we considered moving from W=1 to W=2.

Best regards,
Krzysztof


From shawn.lin at rock-chips.com  Sun Nov  9 23:12:52 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Mon, 10 Nov 2025 15:12:52 +0800
Subject: [RESEND] Re: [PATCH] PCI: dw-rockchip: Skip waiting for link up
In-Reply-To: <4487DA40249CC821+19232169-a096-4737-bc6a-5cec9592d65f@radxa.com>
References: <20250113-rockchip-no-wait-v1-1-25417f37b92f@kernel.org>
 <1E8E4DB773970CB5+5a52c9e1-01b8-4872-99b7-021099f04031@radxa.com>
 <6e87b611-13ea-4d89-8dbf-85510dd86fa6@rock-chips.com>
 <aQ840q5BxNS1eIai@ryzen> <aQ9FWEuW47L8YOxC@ryzen>
 <55EB0E5F655F3AFC+136b89fd-98d4-42af-a99d-a0bb05cc93f3@radxa.com>
 <aRCI5kG16_1erMME@ryzen>
 <F8B2B6FA2884D69A+b7da13f2-0ffb-4308-b1ba-0549bc461be8@radxa.com>
 <780a4209-f89f-43a9-9364-331d3b77e61e@rock-chips.com>
 <4487DA40249CC821+19232169-a096-4737-bc6a-5cec9592d65f@radxa.com>
Message-ID: <363d6b4d-c999-43d4-866e-880ef7d0dec3@rock-chips.com>


? 2025/11/10 ??? 12:56, FUKAUMI Naoki ??:
> Hi Shawn,
> 
> On 11/10/25 11:30, Shawn Lin wrote:
>> Hi Fukaumi
>>
>> ? 2025/11/10 ??? 7:26, FUKAUMI Naoki ??:
>>> (RESEND: fix mani's email address)
>>>
>>> Hi Niklas,
>>>
>>> On 11/9/25 21:28, Niklas Cassel wrote:
>>>> On Sun, Nov 09, 2025 at 01:42:23PM +0900, FUKAUMI Naoki wrote:
>>>>> Hi Niklas,
>>>>>
>>>>> On 11/8/25 22:27, Niklas Cassel wrote:
>>>>> (snip)> (And btw. please test with the latest 6.18-rc, as, from 
>>>>> experience,
>>>>> the
>>>>>> ASPM problems in earlier RCs can result in some weird problems 
>>>>>> that are
>>>>>> not immediately deduced to be caused by the ASPM enablement.)
>>>>>
>>>>> Here is dmesg from v6.18-rc4:
>>>>> ? https://gist.github.com/RadxaNaoki/40e1d049bff4f1d2d4773a5ba0ed9dff
>>>>
>>>> Same problem as before:
>>>> [??? 1.732538] pci_bus 0004:43: busn_res: can not insert [bus 43-41] 
>>>> under [bus 42-41] (conflicts with (null) [bus 42-41])
>>>> [??? 1.732645] pci_bus 0004:43: busn_res: [bus 43-41] end is updated 
>>>> to 43
>>>> [??? 1.732651] pci_bus 0004:43: busn_res: can not insert [bus 43] 
>>>> under [bus 42-41] (conflicts with (null) [bus 42-41])
>>>> [??? 1.732661] pci 0004:42:00.0: devices behind bridge are unusable 
>>>> because [bus 43] cannot be assigned for them
>>>> [??? 1.732840] pci_bus 0004:44: busn_res: can not insert [bus 44-41] 
>>>> under [bus 42-41] (conflicts with (null) [bus 42-41])
>>>> [??? 1.732947] pci_bus 0004:44: busn_res: [bus 44-41] end is updated 
>>>> to 44
>>>> [??? 1.732952] pci_bus 0004:44: busn_res: can not insert [bus 44] 
>>>> under [bus 42-41] (conflicts with (null) [bus 42-41])
>>>> [??? 1.732962] pci 0004:42:02.0: devices behind bridge are unusable 
>>>> because [bus 44] cannot be assigned for them
>>>> [??? 1.733134] pci_bus 0004:45: busn_res: can not insert [bus 45-41] 
>>>> under [bus 42-41] (conflicts with (null) [bus 42-41])
>>>> [??? 1.733246] pci_bus 0004:45: busn_res: [bus 45-41] end is updated 
>>>> to 45
>>>> [??? 1.733255] pci_bus 0004:45: busn_res: can not insert [bus 45] 
>>>> under [bus 42-41] (conflicts with (null) [bus 42-41])
>>>> [??? 1.733266] pci 0004:42:06.0: devices behind bridge are unusable 
>>>> because [bus 45] cannot be assigned for them
>>>> [??? 1.733438] pci_bus 0004:46: busn_res: can not insert [bus 46-41] 
>>>> under [bus 42-41] (conflicts with (null) [bus 42-41])
>>>> [??? 1.733544] pci_bus 0004:46: busn_res: [bus 46-41] end is updated 
>>>> to 46
>>>> [??? 1.733550] pci_bus 0004:46: busn_res: can not insert [bus 46] 
>>>> under [bus 42-41] (conflicts with (null) [bus 42-41])
>>>> [??? 1.733560] pci 0004:42:0e.0: devices behind bridge are unusable 
>>>> because [bus 46] cannot be assigned for them
>>>> [??? 1.733571] pci_bus 0004:42: busn_res: [bus 42-41] end is updated 
>>>> to 46
>>>> [??? 1.733575] pci_bus 0004:42: busn_res: can not insert [bus 42-46] 
>>>> under [bus 41] (conflicts with (null) [bus 41])
>>>> [??? 1.733585] pci 0004:41:00.0: devices behind bridge are unusable 
>>>> because [bus 42-46] cannot be assigned for them
>>>> [??? 1.733596] pcieport 0004:40:00.0: bridge has subordinate 41 but 
>>>> max busn 46
>>>>
>>>>
>>>> Seems like the ASM2806 switch, for some reason, is not ready.
>>>>
>>>> One change that Diederik pointed out is that in the "good" case,
>>>> the link is always in Gen1 speed.
>>>>
>>>> Perhaps you could build with CONFIG_PCI_QUIRKS=y and try this patch:
>>>>
>>>> diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
>>>> index 214ed060ca1b..ac134d95a97f 100644
>>>> --- a/drivers/pci/quirks.c
>>>> +++ b/drivers/pci/quirks.c
>>>> @@ -96,6 +96,7 @@ int pcie_failed_link_retrain(struct pci_dev *dev)
>>>> ? {
>>>> ????? static const struct pci_device_id ids[] = {
>>>> ????????? { PCI_VDEVICE(ASMEDIA, 0x2824) }, /* ASMedia ASM2824 */
>>>> +??????? { PCI_VDEVICE(ASMEDIA, 0x2806) }, /* ASMedia ASM2806 */
>>>> ????????? {}
>>>> ????? };
>>>> ????? u16 lnksta, lnkctl2;
>>>
>>> It doesn't help with either probing behind the bridge or the link speed.
>>>
>>>> If that does not work, perhaps you could try this patch
>>>> (assuming that all Rock 5C:s have a ASM2806 on pcie2x1l2):
>>>
>>> ROCK 5C has a PCIe FPC connector and I'm using Dual 2.5G Router HAT.
>>> ??https://radxa.com/products/rock5/5c#techspec
>>> ??https://radxa.com/products/accessories/dual-2-5g-router-hat
>>>
>>> Regarding the link speed, I initially suspected the FPC connector 
>>> and/ or cable might be the issue. However, I tried the Dual 2.5G 
>>> Router HAT with the ROCK 5A (which uses a different cable), and I got 
>>> the same result.
>>>
>>> BTW, the link speed varies between 2Gb/s and 4Gb/s depending on the 
>>> reboot. (with or without quirk)
>>
>> Could you please help check this patch?
> 
> I tried your patch on top of vanilla v6.18-rc5.
>  ?https://gist.github.com/RadxaNaoki/b42252ce3209d9f6bc2d4c90c71956ae
> 
> I got 2 oops,
> 
> - its_msi_teardown+0x120/0x140
>  ? New with this patch.
> 
> - of_pci_add_properties+0x284/0x4c4
>  ? It sometimes happen with vanilla v6.18-rcX.
> 
> Nothing behind the bridge is probed.

Hi Fukaumi,

Thanks for testing. I just got a ASM2806 switch as yours and verified it
on vanilla v6.18-rc5. After 30 times of cold boot, two NVMes behind
ASM2806 work as expected. Nothing special happened when I checked
with PA as well. You could help check the log and lspci dump there[1].

[1]https://pastebin.com/sAF1fT0g

> 
> Best regards,
> 
> -- 
> FUKAUMI Naoki
> Radxa Computer (Shenzhen) Co., Ltd.
> 
>> --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
>> +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
>> @@ -454,6 +454,8 @@ static irqreturn_t 
>> rockchip_pcie_rc_sys_irq_thread(int irq, void *arg)
>> ???????? struct dw_pcie *pci = &rockchip->pci;
>> ???????? struct dw_pcie_rp *pp = &pci->pp;
>> ???????? struct device *dev = pci->dev;
>> +?????? struct pci_bus *child, *root_bus = NULL;
>> +?????? struct pci_dev *bridge;
>> ???????? u32 reg;
>>
>> ???????? reg = rockchip_pcie_readl_apb(rockchip, 
>> PCIE_CLIENT_INTR_STATUS_MISC);
>> @@ -462,12 +464,21 @@ static irqreturn_t 
>> rockchip_pcie_rc_sys_irq_thread(int irq, void *arg)
>> ???????? dev_dbg(dev, "PCIE_CLIENT_INTR_STATUS_MISC: %#x\n", reg);
>> ???????? dev_dbg(dev, "LTSSM_STATUS: %#x\n", 
>> rockchip_pcie_get_ltssm(rockchip));
>>
>> +?????? list_for_each_entry(child, &pp->bridge->bus->children, node) {
>> +?????????????? if (child->parent == pp->bridge->bus) {
>> +?????????????????????? root_bus = child;
>> +?????????????????????? bridge = root_bus->self;
>> +?????????????????????? break;
>> +?????????????? }
>> +??????? }
>> +
>> ???????? if (reg & PCIE_RDLH_LINK_UP_CHGED) {
>> ???????????????? if (rockchip_pcie_link_up(pci)) {
>> ???????????????????????? msleep(PCIE_RESET_CONFIG_WAIT_MS);
>> ???????????????????????? dev_dbg(dev, "Received Link up event. 
>> Starting enumeration!\n");
>> ???????????????????????? /* Rescan the bus to enumerate endpoint 
>> devices */
>> ???????????????????????? pci_lock_rescan_remove();
>> +?????????????????????? pci_stop_and_remove_bus_device(bridge);
>> ???????????????????????? pci_rescan_bus(pp->bridge->bus);
>> ???????????????????????? pci_unlock_rescan_remove();
>> ???????????????? }
>>
>>
>>>
>>> Best regards,
>>>
>>> -- 
>>> FUKAUMI Naoki
>>> Radxa Computer (Shenzhen) Co., Ltd.
>>>
>>>> diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/ 
>>>> arch/ arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
>>>> index dd7317bab613..26f8539d934a 100644
>>>> --- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
>>>> +++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
>>>> @@ -452,6 +452,7 @@ &pcie2x1l2 {
>>>> ????? pinctrl-0 = <&pcie20x1_2_perstn_m0>;
>>>> ????? reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
>>>> ????? vpcie3v3-supply = <&pcie2x1l2_3v3>;
>>>> +??? max-link-speed = <1>;
>>>> ????? status = "okay";
>>>> ? };
>>>>
>>>>
>>>>
>>>> Kind regards,
>>>> Niklas
>>>>
>>>
>>>
>>
>>
> 
> 



From naoki at radxa.com  Sun Nov  9 23:20:52 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Mon, 10 Nov 2025 16:20:52 +0900
Subject: [PATCH] arm64: dts: rockchip: Turn all LEDs on at boot for Radxa
 boards
In-Reply-To: <20251110022732.809145-1-naoki@radxa.com>
References: <20251110022732.809145-1-naoki@radxa.com>
Message-ID: <6A1E6DDCEB1C076D+69dd1564-cc49-4f61-9834-97e78dc5d793@radxa.com>

Hi,

On 11/10/25 11:27, FUKAUMI Naoki wrote:
> Radxa's boards turn all LEDs on at boot(loader), but some boards, e.g.
> ROCK Pi E don't have `default-state` property in Linux kernel tree but
> have it in U-Boot tree[1] instead.
> 
> This patch adds `default-state = "on"` for (almost) all LEDs (with a
> few exceptions which should be "off" such as RGB LEDs on E25 and LAN/
> WAN LEDs on E20C/E52C).
> 
> Also, remove following redundant properties:
>   linux,default-trigger = "default-on"; // use default-state = "on"
>   default-state = "off"; // default is "off"
> 
> [1] https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3328-rock-pi-e-base-u-boot.dtsi#L11

I'll add the following as a reference:

https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3399-rock-4c-plus-u-boot.dtsi#L11-17
https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3399-rock-pi-4-u-boot.dtsi#L11-13
https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3566-radxa-cm3-io-u-boot.dtsi#L10-12
https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3566-rock-3c-u-boot.dtsi#L14-16
https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3568-radxa-e25-u-boot.dtsi#L7-24
https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3568-rock-3a-u-boot.dtsi#L11-13
https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3588-rock-5b-u-boot.dtsi#L11-13
https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3588-rock-5b-u-boot.dtsi#L11-13

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> ---
>   arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts    | 1 -
>   arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts    | 1 +
>   arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts | 3 ++-
>   arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi   | 1 +
>   arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts   | 2 --
>   arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts      | 1 -
>   arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts | 1 +
>   arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts      | 1 +
>   arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi  | 1 +
>   arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts      | 1 +
>   arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts      | 3 ++-
>   arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts   | 2 --
>   arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts   | 3 ++-
>   arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi     | 1 +
>   arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts      | 1 +
>   arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts     | 3 ++-
>   16 files changed, 16 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
> index 7a32972bc2496..c1e3098b9a7bc 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
> @@ -35,7 +35,6 @@ green-led {
>   			function = LED_FUNCTION_POWER;
>   			gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
>   			label = "rockpis:green:power";
> -			linux,default-trigger = "default-on";
>   		};
>   
>   		blue-led {
> diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
> index a4bdd87d0729f..d3d6f34b66fb0 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
> @@ -59,6 +59,7 @@ leds {
>   
>   		led-0 {
>   			color = <LED_COLOR_ID_BLUE>;
> +			default-state = "on";
>   			gpios = <&gpio3 RK_PA5 GPIO_ACTIVE_LOW>;
>   			linux,default-trigger = "heartbeat";
>   		};
> diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts
> index 962b8b231c960..a83ffbef22a7b 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts
> @@ -39,14 +39,15 @@ leds {
>   		led-0 {
>   			function = LED_FUNCTION_POWER;
>   			color = <LED_COLOR_ID_GREEN>;
> +			default-state = "on";
>   			gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_LOW>;
> -			linux,default-trigger = "default-on";
>   		};
>   
>   		/* USER_LED2 */
>   		led-1 {
>   			function = LED_FUNCTION_STATUS;
>   			color = <LED_COLOR_ID_BLUE>;
> +			default-state = "on";
>   			gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
>   			linux,default-trigger = "heartbeat";
>   		};
> diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
> index 046dbe3290178..ef434c23fe85c 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
> @@ -35,6 +35,7 @@ leds {
>   		led-0 {
>   			function = LED_FUNCTION_STATUS;
>   			color = <LED_COLOR_ID_BLUE>;
> +			default-state = "on";
>   			gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
>   			linux,default-trigger = "heartbeat";
>   		};
> diff --git a/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts b/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts
> index b324527561558..79d316a1d8495 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts
> @@ -62,7 +62,6 @@ leds {
>   
>   		led-lan {
>   			color = <LED_COLOR_ID_GREEN>;
> -			default-state = "off";
>   			function = LED_FUNCTION_LAN;
>   			gpios = <&gpio4 RK_PB5 GPIO_ACTIVE_HIGH>;
>   			linux,default-trigger = "netdev";
> @@ -78,7 +77,6 @@ led-sys {
>   
>   		led-wan {
>   			color = <LED_COLOR_ID_GREEN>;
> -			default-state = "off";
>   			function = LED_FUNCTION_WAN;
>   			gpios = <&gpio4 RK_PC0 GPIO_ACTIVE_HIGH>;
>   			linux,default-trigger = "netdev";
> diff --git a/arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts b/arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts
> index c03ae1dd34560..0b696d49b71fa 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts
> @@ -45,7 +45,6 @@ led-1 {
>   		default-state = "on";
>   		function = LED_FUNCTION_STATUS;
>   		gpios = <&gpio3 RK_PC1 GPIO_ACTIVE_LOW>;
> -		linux,default-trigger = "default-on";
>   	};
>   };
>   
> diff --git a/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts b/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
> index b5b253f04cdf5..9e7212b70e3f1 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
> @@ -46,6 +46,7 @@ leds {
>   		led-1 {
>   			gpios = <&gpio4 RK_PA4 GPIO_ACTIVE_LOW>;
>   			color = <LED_COLOR_ID_GREEN>;
> +			default-state = "on";
>   			function = LED_FUNCTION_ACTIVITY;
>   			linux,default-trigger = "heartbeat";
>   			pinctrl-names = "default";
> diff --git a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
> index 6224d72813e59..3ec108bcf89a1 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
> @@ -47,6 +47,7 @@ led-0 {
>   			gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
>   			function = LED_FUNCTION_HEARTBEAT;
>   			color = <LED_COLOR_ID_BLUE>;
> +			default-state = "on";
>   			linux,default-trigger = "heartbeat";
>   			pinctrl-names = "default";
>   			pinctrl-0 = <&user_led2>;
> diff --git a/arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi b/arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi
> index 729e38b9f620e..140582f8e1034 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi
> @@ -23,6 +23,7 @@ led_user: led-0 {
>   			gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
>   			function = LED_FUNCTION_HEARTBEAT;
>   			color = <LED_COLOR_ID_GREEN>;
> +			default-state = "on";
>   			linux,default-trigger = "heartbeat";
>   			pinctrl-names = "default";
>   			pinctrl-0 = <&led_user_en>;
> diff --git a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
> index 44cfdfeed6681..e6c18df0fa582 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
> @@ -47,6 +47,7 @@ led_user: led-0 {
>   			gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
>   			function = LED_FUNCTION_HEARTBEAT;
>   			color = <LED_COLOR_ID_BLUE>;
> +			default-state = "on";
>   			linux,default-trigger = "heartbeat";
>   			pinctrl-names = "default";
>   			pinctrl-0 = <&led_user_en>;
> diff --git a/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts b/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts
> index 9bc33422ced50..99d3a8be8f18c 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts
> @@ -52,13 +52,14 @@ leds: leds {
>   
>   		power-led {
>   			color = <LED_COLOR_ID_GREEN>;
> +			default-state = "on";
>   			function = LED_FUNCTION_STATUS;
>   			gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>;
> -			linux,default-trigger = "default-on";
>   		};
>   
>   		user-led {
>   			color = <LED_COLOR_ID_BLUE>;
> +			default-state = "on";
>   			function = LED_FUNCTION_HEARTBEAT;
>   			gpios = <&gpio0 RK_PC4 GPIO_ACTIVE_LOW>;
>   			linux,default-trigger = "heartbeat";
> diff --git a/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts b/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts
> index 854c118418eb8..f737769d4a007 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts
> @@ -71,7 +71,6 @@ leds-1 {
>   
>   		led-1 {
>   			color = <LED_COLOR_ID_GREEN>;
> -			default-state = "off";
>   			function = LED_FUNCTION_LAN;
>   			linux,default-trigger = "netdev";
>   			pwms = <&pwm14 0 1000000 PWM_POLARITY_INVERTED>;
> @@ -80,7 +79,6 @@ led-1 {
>   
>   		led-2 {
>   			color = <LED_COLOR_ID_GREEN>;
> -			default-state = "off";
>   			function = LED_FUNCTION_WAN;
>   			linux,default-trigger = "netdev";
>   			pwms = <&pwm11 0 1000000 PWM_POLARITY_INVERTED>;
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
> index bc8140883de47..86477346c3f5a 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
> @@ -88,11 +88,12 @@ gpio-leds {
>   		pinctrl-0 = <&led_pins>;
>   
>   		power-led1 {
> +			default-state = "on";
>   			gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
> -			linux,default-trigger = "default-on";
>   		};
>   
>   		hdd-led2 {
> +			default-state = "on";
>   			gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>;
>   			linux,default-trigger = "disk-activity";
>   		};
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi
> index e5c474e4d02a6..8c4a4270f9f93 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi
> @@ -30,6 +30,7 @@ leds {
>   		led_rgb_b {
>   			function = LED_FUNCTION_STATUS;
>   			color = <LED_COLOR_ID_BLUE>;
> +			default-state = "on";
>   			gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
>   			linux,default-trigger = "heartbeat";
>   		};
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts
> index 0dd90c744380b..87e9d4b86dad4 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts
> @@ -33,6 +33,7 @@ leds {
>   		led_rgb_b {
>   			function = LED_FUNCTION_STATUS;
>   			color = <LED_COLOR_ID_BLUE>;
> +			default-state = "on";
>   			gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
>   			linux,default-trigger = "heartbeat";
>   		};
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
> index 19a08f7794e67..46c81e796b100 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
> @@ -54,6 +54,7 @@ leds {
>   
>   		io-led {
>   			color = <LED_COLOR_ID_BLUE>;
> +			default-state = "on";
>   			function = LED_FUNCTION_STATUS;
>   			gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
>   			linux,default-trigger = "heartbeat";
> @@ -61,9 +62,9 @@ io-led {
>   
>   		power-led {
>   			color = <LED_COLOR_ID_GREEN>;
> +			default-state = "on";
>   			function = LED_FUNCTION_POWER;
>   			gpios = <&gpio3 RK_PC4 GPIO_ACTIVE_HIGH>;
> -			linux,default-trigger = "default-on";
>   		};
>   	};
>   



From dsimic at manjaro.org  Sun Nov  9 23:38:46 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Mon, 10 Nov 2025 08:38:46 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH 2/2] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= Make eeprom read-only for Radxa ROCK 5A
In-Reply-To: <38861A00B4F4BA62+e3221913-43e5-4335-9aaf-9b9eed5834ac@radxa.com>
References: <20251110035455.839863-1-naoki@radxa.com>
 <20251110035455.839863-2-naoki@radxa.com>
 <36843804-433a-5c0c-4961-451b44d70bc4@manjaro.org> <38861A00B4F4BA62+e3221913-43e5-4335-9aaf-9b9eed5834ac@radxa.com>
Message-ID: <65f17890-c052-f303-4731-f882946df1f1@manjaro.org>

On Monday, November 10, 2025 08:05 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> On 11/10/25 14:17, Dragan Simic wrote:
> > On Monday, November 10, 2025 04:54 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> >> Make EEPROM read-only as it may contain factory-programmed
> >> board-specific data.
> >>
> >> Fixes: 89c880808cff8 ("arm64: dts: rockchip: add I2C EEPROM to rock-5a")
> >> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> >> ---
> >>   arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 1 +
> >>   1 file changed, 1 insertion(+)
> >>
> >> diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
> >> index 19a08f7794e67..ae7b03488c9e7 100644
> >> --- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
> >> +++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
> >> @@ -254,6 +254,7 @@ eeprom: eeprom at 50 {
> >>   		compatible = "belling,bl24c16a", "atmel,24c16";
> >>   		reg = <0x50>;
> >>   		pagesize = <16>;
> >> +		read-only;
> >>   	};
> >>   };
> > 
> > I've checked the board schematic and making this BL24C16 chip
> > read-only makes sense to me.  However, I think that the patch
> > description should be expanded to contain a better description
> > of what might be found in the chip, such as a factory-programmed
> > MAC address.  Also, providing a link to the board schematic, as
> > a reference, would be a good idea.
> 
> ----
> arm64: dts: rockchip: Make eeprom read-only for Radxa ROCK 3C/5A/5C
> 
> Make the EEPROM[1][2][3] read-only. Board-specific data written to the 
> EEPROM at the factory includes, but is not limited to, the SKU (~ 
> product name), BOM version (~ board version), and MAC address.

Thanks for the improvements!  I'd just suggest that the opening
sentence above is rewritten like this:

  Make the BL24C16 EEPROM chips found on Radxa ROCK 3C, 5A and
  5C SBCs [1][2][3] read-only, because they contain factory-
  programmed data that isn't supposed to be modified by the end
  users.

This would also be perfect timing for Radxa to officially release
the layout of the board-specific data that goes into these EPROM
chips, so the data can actually be used.

> [1] 
> https://dl.radxa.com/rock3/docs/hw/3c/v1400/radxa_rock_3c_v1400_schematic.pdf 
> p.13
> [2] https://dl.radxa.com/rock5/5a/docs/hw/radxa_rock5a_V1.1_sch.pdf p.19
> [3] 
> https://dl.radxa.com/rock5/5c/docs/hw/v1100/radxa_rock_5c_schematic_v1100.pdf 
> p.18
> ----
> 
> > With these remarks addressed in a v2, please feel free to include
> > 
> > Reviewed-by: Dragan Simic <dsimic at manjaro.org>
> > 
> > Additionally, it would make sense to squash this patch and your
> > other patch that addresses the ROCK 5C together.  They're very
> > similar and having them together in a single commit might actually
> > help the people browsing the repository understand it better.
> 
> I'll drop eeprom patch from ROCK 5C v7 patch series, and squash eeprom 
> patches for ROCK 3C/5A/5C.

Thanks!



From naoki at radxa.com  Sun Nov  9 23:52:46 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Mon, 10 Nov 2025 16:52:46 +0900
Subject: [RESEND] Re: [PATCH] PCI: dw-rockchip: Skip waiting for link up
In-Reply-To: <363d6b4d-c999-43d4-866e-880ef7d0dec3@rock-chips.com>
References: <20250113-rockchip-no-wait-v1-1-25417f37b92f@kernel.org>
 <1E8E4DB773970CB5+5a52c9e1-01b8-4872-99b7-021099f04031@radxa.com>
 <6e87b611-13ea-4d89-8dbf-85510dd86fa6@rock-chips.com>
 <aQ840q5BxNS1eIai@ryzen> <aQ9FWEuW47L8YOxC@ryzen>
 <55EB0E5F655F3AFC+136b89fd-98d4-42af-a99d-a0bb05cc93f3@radxa.com>
 <aRCI5kG16_1erMME@ryzen>
 <F8B2B6FA2884D69A+b7da13f2-0ffb-4308-b1ba-0549bc461be8@radxa.com>
 <780a4209-f89f-43a9-9364-331d3b77e61e@rock-chips.com>
 <4487DA40249CC821+19232169-a096-4737-bc6a-5cec9592d65f@radxa.com>
 <363d6b4d-c999-43d4-866e-880ef7d0dec3@rock-chips.com>
Message-ID: <0C31787C387488ED+fd39bfe6-0844-4a87-bf48-675dd6d6a2df@radxa.com>

Hi Shawn,

On 11/10/25 16:12, Shawn Lin wrote:
(snip)> Thanks for testing. I just got a ASM2806 switch as yours and 
verified it
> on vanilla v6.18-rc5. After 30 times of cold boot, two NVMes behind
> ASM2806 work as expected. Nothing special happened when I checked
> with PA as well. You could help check the log and lspci dump there[1].
> 
> [1]https://pastebin.com/sAF1fT0g

Thanks for the info!

I tried ASM2806 on Radxa ROCK 5B (RK3588).
  https://gist.github.com/RadxaNaoki/640e47d377add9fe38301de164d4058e

It doesn't work on PCIe 2.0 (M.2 E Key), but it does work on PCIe 3.0 
(M.2 M Key).

Could you try PCIe 2.0 slot on your board?

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.



From adrian.hunter at intel.com  Sun Nov  9 23:58:24 2025
From: adrian.hunter at intel.com (Adrian Hunter)
Date: Mon, 10 Nov 2025 09:58:24 +0200
Subject: [PATCH v2 1/2] mmc: sdhci-of-dwcmshc: Add command queue support
 for rockchip SOCs
In-Reply-To: <20251031-rockchip-emmc-cqe-support-v2-1-958171f5edad@collabora.com>
References: <20251031-rockchip-emmc-cqe-support-v2-0-958171f5edad@collabora.com>
 <20251031-rockchip-emmc-cqe-support-v2-1-958171f5edad@collabora.com>
Message-ID: <abb4a253-6f4b-4547-a238-db6f60ee3244@intel.com>

On 31/10/2025 17:58, Sebastian Reichel wrote:
> This adds CQE support for the Rockchip RK3588 and RK3576 platform. To
> be functional, the eMMC device-tree node must have a 'supports-cqe;'
> flag property.
> 
> As the RK3576 device-tree has been upstreamed with the 'supports-cqe;'
> property set by default, the kernel already tried to use CQE, which
> results in system hang during suspend. This fixes the issue.
> 
> Co-developed-by: Yifeng Zhao <yifeng.zhao at rock-chips.com>
> Signed-off-by: Yifeng Zhao <yifeng.zhao at rock-chips.com>
> Signed-off-by: Sebastian Reichel <sebastian.reichel at collabora.com>

One question below, otherwise:

Acked-by: Adrian Hunter <adrian.hunter at intel.com>

> ---
>  drivers/mmc/host/sdhci-of-dwcmshc.c | 93 +++++++++++++++++++++++++++++++++++--
>  1 file changed, 90 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c
> index eebd45389956..47509435254b 100644
> --- a/drivers/mmc/host/sdhci-of-dwcmshc.c
> +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c
> @@ -24,6 +24,7 @@
>  
>  #include "sdhci-pltfm.h"
>  #include "cqhci.h"
> +#include "sdhci-cqhci.h"
>  
>  #define SDHCI_DWCMSHC_ARG2_STUFF	GENMASK(31, 16)
>  
> @@ -82,6 +83,8 @@
>  #define DWCMSHC_EMMC_DLL_TXCLK		0x808
>  #define DWCMSHC_EMMC_DLL_STRBIN		0x80c
>  #define DECMSHC_EMMC_DLL_CMDOUT		0x810
> +#define DECMSHC_EMMC_MISC_CON		0x81C
> +#define MISC_INTCLK_EN			BIT(1)
>  #define DWCMSHC_EMMC_DLL_STATUS0	0x840
>  #define DWCMSHC_EMMC_DLL_START		BIT(0)
>  #define DWCMSHC_EMMC_DLL_LOCKED		BIT(8)
> @@ -234,6 +237,7 @@ struct dwcmshc_priv {
>  
>  struct dwcmshc_pltfm_data {
>  	const struct sdhci_pltfm_data pdata;
> +	const struct cqhci_host_ops *cqhci_host_ops;
>  	int (*init)(struct device *dev, struct sdhci_host *host, struct dwcmshc_priv *dwc_priv);
>  	void (*postinit)(struct sdhci_host *host, struct dwcmshc_priv *dwc_priv);
>  };
> @@ -561,6 +565,68 @@ static void dwcmshc_cqhci_dumpregs(struct mmc_host *mmc)
>  	sdhci_dumpregs(mmc_priv(mmc));
>  }
>  
> +static void rk35xx_sdhci_cqe_pre_enable(struct mmc_host *mmc)
> +{
> +	struct sdhci_host *host = mmc_priv(mmc);
> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> +	struct dwcmshc_priv *dwc_priv = sdhci_pltfm_priv(pltfm_host);
> +	u32 reg;
> +
> +	reg = sdhci_readl(host, dwc_priv->vendor_specific_area2 + CQHCI_CFG);
> +	reg |= CQHCI_ENABLE;
> +	sdhci_writel(host, reg, dwc_priv->vendor_specific_area2 + CQHCI_CFG);
> +}
> +
> +static void rk35xx_sdhci_cqe_enable(struct mmc_host *mmc)
> +{
> +	struct sdhci_host *host = mmc_priv(mmc);
> +	u32 reg;
> +
> +	reg = sdhci_readl(host, SDHCI_PRESENT_STATE);
> +	while (reg & SDHCI_DATA_AVAILABLE) {
> +		sdhci_readl(host, SDHCI_BUFFER);
> +		reg = sdhci_readl(host, SDHCI_PRESENT_STATE);
> +	}
> +
> +	sdhci_writew(host, DWCMSHC_SDHCI_CQE_TRNS_MODE, SDHCI_TRANSFER_MODE);
> +
> +	sdhci_cqe_enable(mmc);
> +}
> +
> +static void rk35xx_sdhci_cqe_disable(struct mmc_host *mmc, bool recovery)
> +{
> +	struct sdhci_host *host = mmc_priv(mmc);
> +	unsigned long flags;
> +	u32 ctrl;
> +
> +	/*
> +	 * During CQE command transfers, command complete bit gets latched.
> +	 * So s/w should clear command complete interrupt status when CQE is
> +	 * either halted or disabled. Otherwise unexpected SDCHI legacy
> +	 * interrupt gets triggered when CQE is halted/disabled.
> +	 */
> +	spin_lock_irqsave(&host->lock, flags);
> +	ctrl = sdhci_readl(host, SDHCI_INT_ENABLE);
> +	ctrl |= SDHCI_INT_RESPONSE;
> +	sdhci_writel(host,  ctrl, SDHCI_INT_ENABLE);
> +	sdhci_writel(host, SDHCI_INT_RESPONSE, SDHCI_INT_STATUS);
> +	spin_unlock_irqrestore(&host->lock, flags);
> +
> +	sdhci_cqe_disable(mmc, recovery);
> +}
> +
> +static void rk35xx_sdhci_cqe_post_disable(struct mmc_host *mmc)
> +{
> +	struct sdhci_host *host = mmc_priv(mmc);
> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> +	struct dwcmshc_priv *dwc_priv = sdhci_pltfm_priv(pltfm_host);
> +	u32 ctrl;
> +
> +	ctrl = sdhci_readl(host, dwc_priv->vendor_specific_area2 + CQHCI_CFG);
> +	ctrl &= ~CQHCI_ENABLE;
> +	sdhci_writel(host, ctrl, dwc_priv->vendor_specific_area2 + CQHCI_CFG);
> +}
> +
>  static void dwcmshc_rk3568_set_clock(struct sdhci_host *host, unsigned int clock)
>  {
>  	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> @@ -679,6 +745,10 @@ static void rk35xx_sdhci_reset(struct sdhci_host *host, u8 mask)
>  	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>  	struct dwcmshc_priv *dwc_priv = sdhci_pltfm_priv(pltfm_host);
>  	struct rk35xx_priv *priv = dwc_priv->priv;
> +	u32 extra = sdhci_readl(host, DECMSHC_EMMC_MISC_CON);
> +
> +	if ((host->mmc->caps2 & MMC_CAP2_CQE) && (mask & SDHCI_RESET_ALL))
> +		cqhci_deactivate(host->mmc);
>  
>  	if (mask & SDHCI_RESET_ALL && priv->reset) {
>  		reset_control_assert(priv->reset);
> @@ -687,6 +757,9 @@ static void rk35xx_sdhci_reset(struct sdhci_host *host, u8 mask)
>  	}
>  
>  	sdhci_reset(host, mask);
> +
> +	/* Enable INTERNAL CLOCK */
> +	sdhci_writel(host, MISC_INTCLK_EN | extra, DECMSHC_EMMC_MISC_CON);

rk35xx_sdhci_reset() is in sdhci_dwcmshc_rk35xx_ops.
sdhci_dwcmshc_rk3576_pdata also uses sdhci_dwcmshc_rk35xx_ops but isn't
supporting CQE ops.  Is this change OK for rk3576?

>  }
>  
>  static int dwcmshc_rk35xx_init(struct device *dev, struct sdhci_host *host,
> @@ -1188,6 +1261,15 @@ static const struct dwcmshc_pltfm_data sdhci_dwcmshc_bf3_pdata = {
>  };
>  #endif
>  
> +static const struct cqhci_host_ops rk35xx_cqhci_ops = {
> +	.pre_enable	= rk35xx_sdhci_cqe_pre_enable,
> +	.enable		= rk35xx_sdhci_cqe_enable,
> +	.disable	= rk35xx_sdhci_cqe_disable,
> +	.post_disable	= rk35xx_sdhci_cqe_post_disable,
> +	.dumpregs	= dwcmshc_cqhci_dumpregs,
> +	.set_tran_desc	= dwcmshc_set_tran_desc,
> +};
> +
>  static const struct dwcmshc_pltfm_data sdhci_dwcmshc_rk35xx_pdata = {
>  	.pdata = {
>  		.ops = &sdhci_dwcmshc_rk35xx_ops,
> @@ -1196,6 +1278,7 @@ static const struct dwcmshc_pltfm_data sdhci_dwcmshc_rk35xx_pdata = {
>  		.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
>  			   SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN,
>  	},
> +	.cqhci_host_ops = &rk35xx_cqhci_ops,
>  	.init = dwcmshc_rk35xx_init,
>  	.postinit = dwcmshc_rk35xx_postinit,
>  };
> @@ -1245,7 +1328,8 @@ static const struct cqhci_host_ops dwcmshc_cqhci_ops = {
>  	.set_tran_desc	= dwcmshc_set_tran_desc,
>  };
>  
> -static void dwcmshc_cqhci_init(struct sdhci_host *host, struct platform_device *pdev)
> +static void dwcmshc_cqhci_init(struct sdhci_host *host, struct platform_device *pdev,
> +			       const struct dwcmshc_pltfm_data *pltfm_data)
>  {
>  	struct cqhci_host *cq_host;
>  	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> @@ -1275,7 +1359,10 @@ static void dwcmshc_cqhci_init(struct sdhci_host *host, struct platform_device *
>  	}
>  
>  	cq_host->mmio = host->ioaddr + priv->vendor_specific_area2;
> -	cq_host->ops = &dwcmshc_cqhci_ops;
> +	if (pltfm_data->cqhci_host_ops)
> +		cq_host->ops = pltfm_data->cqhci_host_ops;
> +	else
> +		cq_host->ops = &dwcmshc_cqhci_ops;
>  
>  	/* Enable using of 128-bit task descriptors */
>  	dma64 = host->flags & SDHCI_USE_64_BIT_DMA;
> @@ -1443,7 +1530,7 @@ static int dwcmshc_probe(struct platform_device *pdev)
>  		priv->vendor_specific_area2 =
>  			sdhci_readw(host, DWCMSHC_P_VENDOR_AREA2);
>  
> -		dwcmshc_cqhci_init(host, pdev);
> +		dwcmshc_cqhci_init(host, pdev, pltfm_data);
>  	}
>  
>  	if (pltfm_data->postinit)
> 



From damon.ding at rock-chips.com  Sun Nov  9 23:58:17 2025
From: damon.ding at rock-chips.com (Damon Ding)
Date: Mon, 10 Nov 2025 15:58:17 +0800
Subject: [PATCH v1] drm/rockchip: analogix_dp: Use dev_err_probe() instead of DRM_DEV_ERROR() during probing
Message-ID: <20251110075817.1159857-1-damon.ding@rock-chips.com>

The DRM_DEV_ERROR() has been deprecated, and use dev_err_probe()
can be better. The other reason is that dev_err_probe() help avoid
unexpected repeated err logs during defered probing.

Signed-off-by: Damon Ding <damon.ding at rock-chips.com>

---

As Heiko suggested[0], the other similar codes in
rockchip_dp_of_probe() should be modified to dev_err_probe().

[0] https://lore.kernel.org/all/8513b4b6-0b59-4b42-864b-0fe0423cd7fd at rock-chips.com/
---
 .../gpu/drm/rockchip/analogix_dp-rockchip.c   | 31 +++++++++----------
 1 file changed, 14 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 937f83cf42fc..94da0f745525 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -330,32 +330,29 @@ static int rockchip_dp_of_probe(struct rockchip_dp_device *dp)
 	struct device_node *np = dev->of_node;
 
 	dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
-	if (IS_ERR(dp->grf)) {
-		DRM_DEV_ERROR(dev, "failed to get rockchip,grf property\n");
-		return PTR_ERR(dp->grf);
-	}
+	if (IS_ERR(dp->grf))
+		return dev_err_probe(dev, PTR_ERR(dp->grf),
+				     "failed to get rockchip,grf property\n");
 
 	dp->grfclk = devm_clk_get_optional(dev, "grf");
 	if (IS_ERR(dp->grfclk))
-		return dev_err_probe(dev, PTR_ERR(dp->grfclk), "failed to get grf clock\n");
+		return dev_err_probe(dev, PTR_ERR(dp->grfclk),
+				     "failed to get grf clock\n");
 
 	dp->pclk = devm_clk_get(dev, "pclk");
-	if (IS_ERR(dp->pclk)) {
-		DRM_DEV_ERROR(dev, "failed to get pclk property\n");
-		return PTR_ERR(dp->pclk);
-	}
+	if (IS_ERR(dp->pclk))
+		return dev_err_probe(dev, PTR_ERR(dp->pclk),
+				     "failed to get pclk property\n");
 
 	dp->rst = devm_reset_control_get(dev, "dp");
-	if (IS_ERR(dp->rst)) {
-		DRM_DEV_ERROR(dev, "failed to get dp reset control\n");
-		return PTR_ERR(dp->rst);
-	}
+	if (IS_ERR(dp->rst))
+		return dev_err_probe(dev, PTR_ERR(dp->rst),
+				     "failed to get dp reset control\n");
 
 	dp->apbrst = devm_reset_control_get_optional(dev, "apb");
-	if (IS_ERR(dp->apbrst)) {
-		DRM_DEV_ERROR(dev, "failed to get apb reset control\n");
-		return PTR_ERR(dp->apbrst);
-	}
+	if (IS_ERR(dp->apbrst))
+		return dev_err_probe(dev, PTR_ERR(dp->apbrst),
+				     "failed to get apb reset control\n");
 
 	return 0;
 }
-- 
2.34.1



From naoki at radxa.com  Mon Nov 10 00:03:04 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Mon, 10 Nov 2025 17:03:04 +0900
Subject: [PATCH 2/2] arm64: dts: rockchip: Make eeprom read-only for Radxa
 ROCK 5A
In-Reply-To: <65f17890-c052-f303-4731-f882946df1f1@manjaro.org>
References: <20251110035455.839863-1-naoki@radxa.com>
 <20251110035455.839863-2-naoki@radxa.com>
 <36843804-433a-5c0c-4961-451b44d70bc4@manjaro.org>
 <38861A00B4F4BA62+e3221913-43e5-4335-9aaf-9b9eed5834ac@radxa.com>
 <65f17890-c052-f303-4731-f882946df1f1@manjaro.org>
Message-ID: <51135107D357A73A+50c2300d-7cc0-4f0d-99e7-8b67c0e43dff@radxa.com>

Hi Dragan,

On 11/10/25 16:38, Dragan Simic wrote:
> On Monday, November 10, 2025 08:05 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
>> On 11/10/25 14:17, Dragan Simic wrote:
>>> On Monday, November 10, 2025 04:54 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
>>>> Make EEPROM read-only as it may contain factory-programmed
>>>> board-specific data.
>>>>
>>>> Fixes: 89c880808cff8 ("arm64: dts: rockchip: add I2C EEPROM to rock-5a")
>>>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
>>>> ---
>>>>    arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 1 +
>>>>    1 file changed, 1 insertion(+)
>>>>
>>>> diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
>>>> index 19a08f7794e67..ae7b03488c9e7 100644
>>>> --- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
>>>> +++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
>>>> @@ -254,6 +254,7 @@ eeprom: eeprom at 50 {
>>>>    		compatible = "belling,bl24c16a", "atmel,24c16";
>>>>    		reg = <0x50>;
>>>>    		pagesize = <16>;
>>>> +		read-only;
>>>>    	};
>>>>    };
>>>
>>> I've checked the board schematic and making this BL24C16 chip
>>> read-only makes sense to me.  However, I think that the patch
>>> description should be expanded to contain a better description
>>> of what might be found in the chip, such as a factory-programmed
>>> MAC address.  Also, providing a link to the board schematic, as
>>> a reference, would be a good idea.
>>
>> ----
>> arm64: dts: rockchip: Make eeprom read-only for Radxa ROCK 3C/5A/5C
>>
>> Make the EEPROM[1][2][3] read-only. Board-specific data written to the
>> EEPROM at the factory includes, but is not limited to, the SKU (~
>> product name), BOM version (~ board version), and MAC address.
> 
> Thanks for the improvements!  I'd just suggest that the opening
> sentence above is rewritten like this:
> 
>    Make the BL24C16 EEPROM chips found on Radxa ROCK 3C, 5A and
>    5C SBCs [1][2][3] read-only, because they contain factory-
>    programmed data that isn't supposed to be modified by the end
>    users.
> 
> This would also be perfect timing for Radxa to officially release
> the layout of the board-specific data that goes into these EPROM
> chips, so the data can actually be used.

  https://github.com/radxa/u-boot/blob/next-dev-v2024.10/drivers/misc/radxa-i2c-eeprom.c

The actual data in the EEPROMs of my boards has some content 
inconsistencies with the code descriptions, but the format is 
consistent. The SKU, BOM, and MAC mentioned previously should be available.

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

>> [1]
>> https://dl.radxa.com/rock3/docs/hw/3c/v1400/radxa_rock_3c_v1400_schematic.pdf
>> p.13
>> [2] https://dl.radxa.com/rock5/5a/docs/hw/radxa_rock5a_V1.1_sch.pdf p.19
>> [3]
>> https://dl.radxa.com/rock5/5c/docs/hw/v1100/radxa_rock_5c_schematic_v1100.pdf
>> p.18
>> ----
>>
>>> With these remarks addressed in a v2, please feel free to include
>>>
>>> Reviewed-by: Dragan Simic <dsimic at manjaro.org>
>>>
>>> Additionally, it would make sense to squash this patch and your
>>> other patch that addresses the ROCK 5C together.  They're very
>>> similar and having them together in a single commit might actually
>>> help the people browsing the repository understand it better.
>>
>> I'll drop eeprom patch from ROCK 5C v7 patch series, and squash eeprom
>> patches for ROCK 3C/5A/5C.
> 
> Thanks!
> 
> 




From linux.amoon at gmail.com  Mon Nov 10 00:40:56 2025
From: linux.amoon at gmail.com (Anand Moon)
Date: Mon, 10 Nov 2025 14:10:56 +0530
Subject: [PATCH v4 0/9] PCI: dw-rockchip: add system suspend support
In-Reply-To: <CANAwSgSvtc57kh-VJewk5=_MvfL3KVxNFU8C+tGh4iqJhnEVtw@mail.gmail.com>
References: <20251029-rockchip-pcie-system-suspend-v4-0-ce2e1b0692d2@collabora.com>
 <cf6zumlp4iiltglu7bbrpdeysaznrkyvlemwl4lxwkfjkgux7a@wl37bxilsprx>
 <cbvcjgcd7saxj42ifgqn3l6mwpgenlhbr4zuf5ibqbtj6rmzqh@yuc7flbwyi2y> <CANAwSgSvtc57kh-VJewk5=_MvfL3KVxNFU8C+tGh4iqJhnEVtw@mail.gmail.com>
Message-ID: <CANAwSgTj0JzFN2CHOSG=X_gx5KttP-tZeLaC5uYZYhcPheP_Vg@mail.gmail.com>

Hi All,

On Fri, 7 Nov 2025 at 00:31, Anand Moon <linux.amoon at gmail.com> wrote:
>
> Hi Sebastian,
>
> On Tue, 4 Nov 2025 at 00:29, Sebastian Reichel
> <sebastian.reichel at collabora.com> wrote:
> >
> > Hi,
> >
> > On Sat, Nov 01, 2025 at 07:29:41PM +0530, Manivannan Sadhasivam wrote:
> > > On Wed, Oct 29, 2025 at 06:56:39PM +0100, Sebastian Reichel wrote:
> > > > I've recently been working on fixing up at least basic system suspend
> > > > support on the Rockchip RK3576 platform. Currently the biggest open
> > > > issue is missing support in the PCIe driver. This series is a follow-up
> > > > for Shawn Lin's series with feedback from Niklas Cassel and Manivannan
> > > > Sadhasivam being handled as well as some of my own changes fixing up
> > > > things I noticed.
> > > >
> > > > In opposite to Shawn Lin I did not test with different peripherals as my
> > > > main goal is getting basic suspend to ram working in the first place.
> > >
> > > Wouldn't it break users who have connected endpoint devices and suspend their
> > > platform? I don't want to have an untested feature that could potentially cause
> > > regressions, just for the sake of getting basic system PM.
> > >
> > > But if your goal is to just add basic system PM operations for CI
> > > testing, then I would suggest you to do something minimal in the
> > > suspend/resume path that don't disrupt the operation of a device.
> > >
> > > But this also should be tested with some devices for sanity.
> >
> > My goal is proper system PM support, but I would like to go step by
> > step. Right now system suspend on the Rockchip RK3576 EVB just hangs
> > the board and it has to be power cycled afterwards. In parallel to
> > this series I've send a bunch of fixes to get it working. It surely
> > isn't perfect, but I fear things regressing again in other areas while
> > the complex PCIe system sleep is being worked on - simply blocking system
> > suspend is not very helpful, since it effectively hides suspend problems.
> >
> As per my understanding, the current DTS configuration is missing definitions
> for critical PCIe power management GPIOs (clkreq-gpios, perst-gpios, wake-gpios)
>
> clkreq-gpios, such as PCIE30x1_0_CLKREQn_M1_L (not sure if it is used ?)
> perst-gpios such as PCIE30x1_0_PERSTn_M1_L
> wake-gpios, such as PCIE30x1_0_WAKEn_M1_L.
>
As per the TRM 11.5 Interface Description
Signal Name     Direction   IO Attribute             Description
------------    ---------   -----------------------
------------------------------------------------------------
BUTTON_RSTN     I             Pull-down                    External
reset button input; pulled low to initiate reset
WAKEN                   I/O        Open-drain, pull-up      Wake
signal; enables device or host to signal wake events
PERSTN                 I/O         Pull-down                     PCIe
reset signal; asserted low to reset endpoint or root complex
CLKREQN              I/O         Open-drain, pull-up      Clock
request signal; used for dynamic clock management

See the following commit 4294e3211178 ("arm64: dts: rockchip: Split up
RK3588's PCIe pinctrls")

    These pinctrls manage the low-speed PCIe signals:
    - CLKREQ#: An output on the RK3588 (both RC or EP modes), used to
      request that external clock-generation circuitry provide a clock.
    - PERST#: An input on the RK3588 in EP mode, used to detect a reset
      signal from the RC. In RC mode, the hardware does not use this signal:
      Linux itself generates it by putting the pin in GPIO mode.
    - WAKE#: In EP mode, this is an output; in RC mode, this is an input.

    Each of these signals serves a distinct purpose, and more importantly,
    PERST# should not be muxed when the RK3588 is in the RC role. Bundling
    them together in pinctrl groups prevents proper use: indeed, almost none
    of the current board-specific .dts files make any use of them.
    (Exception: Rock 5A recently had a patch land that misuses _pins; this
     patch corrects that.)

    However, on some RK3588 boards, the PCIe 3 controller will indefinitely
    stall the boot if CLKREQ# is not muxed (details in the next patch).
    This patch unbundles the signals to allow them to be used.

So we can use these pinctrl to perform different tasks
like PERST# to reset and WAKE# to wake the PCIE in suspend / resume state.

Is this a good way to split the rk368 PCIe pinctrl into separate components?

Here is the example user wake gpio.

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
index 19a08f7794e6..13a7aa3ec1fc 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
@@ -359,9 +359,10 @@ rgmii_phy1: ethernet-phy at 1 {
 };

 &pcie2x1l2 {
-       pinctrl-0 = <&pcie2_reset>, <&pcie20x1m0_clkreqn>, <&pcie20x1m0_waken>;
+       pinctrl-0 = <&pcie2_reset>, <&pcie20x1m0_clkreqn>, <&pcie2wakeup>;
        pinctrl-names = "default";
        reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
+       wakeup-gpio = <&gpio3 RK_PD0 GPIO_ACTIVE_HIGH>;
        vpcie3v3-supply = <&vcc3v3_wf>;
        status = "okay";
 };

I haven?t come across a working example for this in RC mode.
Is there any confirmation that this approach functions as expected?


> However, the RK3588 TRM indicates that these power management functions
> can be controlled programmatically using specific memory-mapped registers:
>
> The PCIE_CLIENT_POWER_CON register at 0x002C provides comprehensive
> power management controls, including link-state management, wake-up
> event handling,
> and clock management.
>
> In PHY GRF, we have the PCIe3PHY_GRF_PHY0_LN0_CON0 register at 0x1000 allows
> direct control over the PHY's power state (P-states like P1, P2),
> enabling transitions into
> deep suspend (L2/L3) via register writes
> clkreq_n Clock request for lane X. This is a side-band signal that a
> PIPE 4.2 controller needs
> to enter and exit P1.CPM, P1.1, and P1.2 power states.
>
> My thought is that using rockchip_pcie_phy_deinit() in the suspend
> routine and rockchip_pcie_phy_init() in the resume routine are
> incorrect; these functions
> likely perform full resets or power cuts rather than managed power
> state transitions,
> thus disrupting the desired suspended state of the PCIe link
>
> I tried a few things on my own, but I am not moving forward.
>
Thanks
-Anand


From sakari.ailus at linux.intel.com  Mon Nov 10 00:43:41 2025
From: sakari.ailus at linux.intel.com (Sakari Ailus)
Date: Mon, 10 Nov 2025 10:43:41 +0200
Subject: [PATCH v14 00/18] media: rockchip: add a driver for the rockchip
 camera interface
In-Reply-To: <13c43edb-9592-4779-a39a-7856bb0f964d@collabora.com>
References: <20240220-rk3568-vicap-v14-0-b38b6da0fc80@collabora.com>
 <aQ4tJg8r_j4NyKhv@kekkonen.localdomain>
 <074cd08e-0412-49f9-8dd9-b1f96eb11717@collabora.com>
 <20251107185441.GG5558@pendragon.ideasonboard.com>
 <13c43edb-9592-4779-a39a-7856bb0f964d@collabora.com>
Message-ID: <aRGlvQRVoQs0WjyA@kekkonen.localdomain>

Hi Michael, Laurent,

On Fri, Nov 07, 2025 at 09:51:37PM +0100, Michael Riesch wrote:
> Hi Laurent,
> 
> On 11/7/25 19:54, Laurent Pinchart wrote:
> > On Fri, Nov 07, 2025 at 07:41:59PM +0100, Michael Riesch wrote:
> >> On 11/7/25 18:32, Sakari Ailus wrote:
> >>> On Fri, Oct 24, 2025 at 02:51:29PM +0200, Michael Riesch via B4 Relay wrote:
> >>>> Habidere,
> >>>>
> >>>> This series introduces support for the Rockchip Camera Interface (CIF),
> >>>> which is featured in many Rockchip SoCs in different variations.
> >>>> For example, the PX30 Video Input Processor (VIP) is able to receive
> >>>> video data via the Digital Video Port (DVP, a parallel data interface)
> >>>> and transfer it into system memory using a double-buffering mechanism
> >>>> called ping-pong mode.
> >>>> The RK3568 Video Capture (VICAP) unit, on the other hand, features a
> >>>> DVP and a MIPI CSI-2 receiver that can receive video data independently
> >>>> (both using the ping-pong scheme).
> >>>> The different variants may have additional features, such as scaling
> >>>> and/or cropping.
> >>>> Finally, the RK3588 VICAP unit constitutes an essential piece of the
> >>>> camera interface with one DVP, six MIPI CSI-2 receivers, scale/crop
> >>>> units, and a data path multiplexer (to scaler units, to ISP, ...).
> >>>
> >>> I understand both RK3568 and RK3588 include an ISP. Do you have insight on
> >>> how would this work, should the support for the ISP be added later on?
> >>
> >> Short answer: Yes and yes.
> >>
> >> Long answer:
> >>
> >> The patch series at hand adds support for the PX30 VIP and the RK3568
> >> VICAP. I cannot really say something about the PX30, but on the RK3568
> >> VICAP and ISP are orthogonal (the ISP features its own MIPI CSI-2
> >> receiver, different from that introduced in this series). Thus, ISP
> >> support can be introduced anytime (whenever someone is motivated ;-)).
> > 
> > Won't they both be connected to the same sensor though, and probably the
> > same D-PHY in the SoC ? They don't seem entirely separate to me.
> 
> The MIPI CSI-2 DPHY is shared, indeed. Thus, they *maybe technically
> could be* connected to the same sensor, but I don't know whether that
> works and fail to see why anyone would to such a thing (if it is about
> raw capture, the MIPI CSI-2 receiver in the ISP can do that on its own).
> 
> The DPHY can be operated in split mode, with two lanes for VICAP and two
> lanes for ISP. This is not implemented yet, but can be done at a later
> stage on PHY level (not media related). In this case, ISP and VICAP can
> receive data from different subdevices via CSI-2.

The two would be part of the same media graph in that case and as there are
two CSI-2 receivers and a single PHY, the PHY would probably need to have a
sub-device as well, to allow link configuration to be used to select where
the PHY is connected.

I don't think we have such a setup elsewhere, and supporting this would
require changes in the MC framework.

How does the media graph look like for the device at the moment?

> 
> BTW the ISP is able to process the data captured by VICAP, but
> apparently this includes a RAM round trip (VICAP captures to memory, ISP
> operates in mem2mem mode).
> 
> > A block diagram that shows connections between the CSI-2 pins, D-PHY,
> > CSI-2 receivers, VICAP and ISP could help.
> > 
> >> Once this patch series is merged, I'll push out changes that introduce
> >> support for the RK3588 VICAP. We can discuss the integration of any
> >> RK3588 ISP in this scope then -- and there may be some things to discuss
> >> as there the VICAP and the ISP(s) are directly connected by means of a
> >> MUX unit in the VICAP.
> >>
> >> Alright?
> > 

-- 
Kind regards,

Sakari Ailus


From naoki at radxa.com  Mon Nov 10 01:44:31 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Mon, 10 Nov 2025 18:44:31 +0900
Subject: [PATCH 2/2] arm64: dts: rockchip: Make eeprom read-only for Radxa
 ROCK 5A
In-Reply-To: <65f17890-c052-f303-4731-f882946df1f1@manjaro.org>
References: <20251110035455.839863-1-naoki@radxa.com>
 <20251110035455.839863-2-naoki@radxa.com>
 <36843804-433a-5c0c-4961-451b44d70bc4@manjaro.org>
 <38861A00B4F4BA62+e3221913-43e5-4335-9aaf-9b9eed5834ac@radxa.com>
 <65f17890-c052-f303-4731-f882946df1f1@manjaro.org>
Message-ID: <8934442FCE2020A5+855829eb-e783-4aa5-b4a1-13b0a519c46d@radxa.com>

Hi Dragan,

On 11/10/25 16:38, Dragan Simic wrote:
(snip)>>> Additionally, it would make sense to squash this patch and your
>>> other patch that addresses the ROCK 5C together.  They're very
>>> similar and having them together in a single commit might actually
>>> help the people browsing the repository understand it better.
>>
>> I'll drop eeprom patch from ROCK 5C v7 patch series, and squash eeprom
>> patches for ROCK 3C/5A/5C.
> 
> Thanks!

I'm preparing a patch series for Radxa ROCK 5A and I just remembered 
that the eeprom node in 5a.dts is totally incorrect. The eeprom is on 
i2c0, not on i2c2.

I'm planning to include this eeprom fix as a part of the patch series 
for 5A.

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.


From naoki at radxa.com  Mon Nov 10 02:03:13 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Mon, 10 Nov 2025 19:03:13 +0900
Subject: [PATCH v7 11/14] arm64: dts: rockchip: Sort nodes/properties for
 Radxa ROCK 5C
In-Reply-To: <20251109141859.206835-12-naoki@radxa.com>
References: <20251109141859.206835-1-naoki@radxa.com>
 <20251109141859.206835-12-naoki@radxa.com>
Message-ID: <860B315F1E384446+bead5cf3-487a-46e4-a7c1-aaa1020c967f@radxa.com>

Hi,

On 11/9/25 23:18, FUKAUMI Naoki wrote:
> Sort nodes/properties alphanumerically. No functional change.
> 
> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> ---
> Changes in v7:
> - Reflect other commits, no functional change
> Changes in v6:
> - Reflect other commits, no functional change
> Changes in v5:
> - Reword commit message
> Changes in v4:
> - Reflect other commits, no functional change
> Changes in v3:
> - None
> Changes in v2:
> - New
> ---
>   .../boot/dts/rockchip/rk3588s-rock-5c.dts     | 162 +++++++++---------
>   1 file changed, 81 insertions(+), 81 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
> index 4e15c28f8a5fa..6ef9a5d8cd9c1 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
> @@ -25,15 +25,12 @@ chosen {
>   		stdout-path = "serial2:1500000n8";
>   	};
>   
> -	sound {
> -		compatible = "audio-graph-card";
> -		label = "rk3588-es8316";
> -		dais = <&i2s0_8ch_p0>;
> -		routing = "MIC2", "Mic Jack",
> -			  "Headphones", "HPOL",
> -			  "Headphones", "HPOR";
> -		widgets = "Microphone", "Mic Jack",
> -			  "Headphone", "Headphones";
> +	fan: fan {
> +		compatible = "pwm-fan";
> +		#cooling-cells = <2>;
> +		cooling-levels = <0 64 128 192 255>;

This should be

		cooling-levels = <0 24 44 64 128 192 255>;

I'll fix this in v8.

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> +		fan-supply = <&vcc_5v0>;
> +		pwms = <&pwm3 0 60000 0>;
>   	};
>   
>   	hdmi0-con {
> @@ -70,12 +67,14 @@ led-1 {
>   		};
>   	};
>   
> -	fan: fan {
> -		compatible = "pwm-fan";
> -		#cooling-cells = <2>;
> -		cooling-levels = <0 24 44 64 128 192 255>;
> -		fan-supply = <&vcc_5v0>;
> -		pwms = <&pwm3 0 60000 0>;
> +	vcc_1v1_nldo_s3: regulator-1v1 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "vcc_1v1_nldo_s3";
> +		regulator-always-on;
> +		regulator-boot-on;
> +		regulator-min-microvolt = <1100000>;
> +		regulator-max-microvolt = <1100000>;
> +		vin-supply = <&vcc_sysin>;
>   	};
>   
>   	vcc3v3_pcie2x1l2: regulator-3v3-0 {
> @@ -90,6 +89,40 @@ vcc3v3_pcie2x1l2: regulator-3v3-0 {
>   		vin-supply = <&vcc_sysin>;
>   	};
>   
> +	vcc_3v3_s0: regulator-3v3-1 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "vcc_3v3_s0";
> +		regulator-always-on;
> +		regulator-boot-on;
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		vin-supply = <&vcc_3v3_s3>;
> +	};
> +
> +	vdd_3v3: regulator-3v3-2 {
> +		compatible = "regulator-fixed";
> +		enable-active-high;
> +		gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&usb_wifi_pwr>;
> +		regulator-name = "vdd_3v3";
> +		regulator-always-on;
> +		regulator-boot-on;
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		vin-supply = <&vcc_3v3_s3>;
> +	};
> +
> +	vcca: regulator-4v0 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "vcca";
> +		regulator-always-on;
> +		regulator-boot-on;
> +		regulator-min-microvolt = <4000000>;
> +		regulator-max-microvolt = <4000000>;
> +		vin-supply = <&vcc_sysin>;
> +	};
> +
>   	vcc5v_dcin: regulator-5v0-0 {
>   		compatible = "regulator-fixed";
>   		regulator-name = "vcc5v_dcin";
> @@ -123,26 +156,6 @@ vcc5v0_usb_otg0: regulator-5v0-2 {
>   		vin-supply = <&vcc_sysin>;
>   	};
>   
> -	vcc_1v1_nldo_s3: regulator-1v1 {
> -		compatible = "regulator-fixed";
> -		regulator-name = "vcc_1v1_nldo_s3";
> -		regulator-always-on;
> -		regulator-boot-on;
> -		regulator-min-microvolt = <1100000>;
> -		regulator-max-microvolt = <1100000>;
> -		vin-supply = <&vcc_sysin>;
> -	};
> -
> -	vcc_3v3_s0: regulator-3v3-1 {
> -		compatible = "regulator-fixed";
> -		regulator-name = "vcc_3v3_s0";
> -		regulator-always-on;
> -		regulator-boot-on;
> -		regulator-min-microvolt = <3300000>;
> -		regulator-max-microvolt = <3300000>;
> -		vin-supply = <&vcc_3v3_s3>;
> -	};
> -
>   	vcc_5v0: regulator-5v0-3 {
>   		compatible = "regulator-fixed";
>   		enable-active-high;
> @@ -165,28 +178,15 @@ vcc_sysin: regulator-5v0-4 {
>   		vin-supply = <&vcc5v_dcin>;
>   	};
>   
> -	vcca: regulator-4v0 {
> -		compatible = "regulator-fixed";
> -		regulator-name = "vcca";
> -		regulator-always-on;
> -		regulator-boot-on;
> -		regulator-min-microvolt = <4000000>;
> -		regulator-max-microvolt = <4000000>;
> -		vin-supply = <&vcc_sysin>;
> -	};
> -
> -	vdd_3v3: regulator-3v3-2 {
> -		compatible = "regulator-fixed";
> -		enable-active-high;
> -		gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
> -		pinctrl-names = "default";
> -		pinctrl-0 = <&usb_wifi_pwr>;
> -		regulator-name = "vdd_3v3";
> -		regulator-always-on;
> -		regulator-boot-on;
> -		regulator-min-microvolt = <3300000>;
> -		regulator-max-microvolt = <3300000>;
> -		vin-supply = <&vcc_3v3_s3>;
> +	sound {
> +		compatible = "audio-graph-card";
> +		label = "rk3588-es8316";
> +		dais = <&i2s0_8ch_p0>;
> +		routing = "MIC2", "Mic Jack",
> +			  "Headphones", "HPOL",
> +			  "Headphones", "HPOR";
> +		widgets = "Microphone", "Mic Jack",
> +			  "Headphone", "Headphones";
>   	};
>   };
>   
> @@ -399,27 +399,27 @@ &package_thermal {
>   
>   	trips {
>   		package_fan0: package-fan0 {
> -			temperature = <55000>;
>   			hysteresis = <2000>;
> +			temperature = <55000>;
>   			type = "active";
>   		};
>   
>   		package_fan1: package-fan1 {
> -			temperature = <65000>;
>   			hysteresis = <2000>;
> +			temperature = <65000>;
>   			type = "active";
>   		};
>   	};
>   
>   	cooling-maps {
>   		map0 {
> -			trip = <&package_fan0>;
>   			cooling-device = <&fan THERMAL_NO_LIMIT 1>;
> +			trip = <&package_fan0>;
>   		};
>   
>   		map1 {
> -			trip = <&package_fan1>;
>   			cooling-device = <&fan 2 THERMAL_NO_LIMIT>;
> +			trip = <&package_fan1>;
>   		};
>   	};
>   };
> @@ -437,6 +437,12 @@ &pd_gpu {
>   };
>   
>   &pinctrl {
> +	ethernet {
> +		gmac1_rstn: gmac1-rstn {
> +			rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
> +		};
> +	};
> +
>   	leds {
>   		io_led: io-led {
>   			rockchip,pins = <3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
> @@ -447,12 +453,6 @@ power_led: power-led {
>   		};
>   	};
>   
> -	ethernet {
> -		gmac1_rstn: gmac1-rstn {
> -			rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
> -		};
> -	};
> -
>   	pcie {
>   		pcie20x1_2_perstn_m0: pcie20x1-2-perstn-m0 {
>   			rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
> @@ -463,6 +463,12 @@ pow_en: pow-en {
>   		};
>   	};
>   
> +	regulators {
> +		vcc_5v0_pwren_h: vcc-5v0-pwren-h {
> +			rockchip,pins = <4 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
> +		};
> +	};
> +
>   	usb {
>   		usb_host_pwren_h: usb-host-pwren-h {
>   			rockchip,pins = <4 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
> @@ -476,12 +482,6 @@ usb_wifi_pwr: usb-wifi-pwr {
>   			rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
>   		};
>   	};
> -
> -	regulators {
> -		vcc_5v0_pwren_h: vcc-5v0-pwren-h {
> -			rockchip,pins = <4 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
> -		};
> -	};
>   };
>   
>   &pwm3 {
> @@ -500,8 +500,8 @@ &sdhci {
>   	cap-mmc-highspeed;
>   	mmc-hs400-1_8v;
>   	mmc-hs400-enhanced-strobe;
> -	no-sdio;
>   	no-sd;
> +	no-sdio;
>   	non-removable;
>   	vmmc-supply = <&vcc_3v3_s0>;
>   	vqmmc-supply = <&vccio_flash>;
> @@ -514,8 +514,8 @@ &sdmmc {
>   	cap-sd-highspeed;
>   	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
>   	disable-wp;
> -	no-sdio;
>   	no-mmc;
> +	no-sdio;
>   	pinctrl-names = "default";
>   	pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd>;
>   	sd-uhs-sdr104;
> @@ -538,12 +538,12 @@ flash at 0 {
>   };
>   
>   &spi2 {
> -	status = "okay";
>   	assigned-clocks = <&cru CLK_SPI2>;
>   	assigned-clock-rates = <200000000>;
>   	num-cs = <1>;
>   	pinctrl-names = "default";
>   	pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
> +	status = "okay";
>   
>   	pmic at 0 {
>   		compatible = "rockchip,rk806";
> @@ -898,10 +898,6 @@ &uart2 {
>   	status = "okay";
>   };
>   
> -&usbdp_phy0 {
> -	status = "okay";
> -};
> -
>   &usb_host0_ehci {
>   	status = "okay";
>   };
> @@ -923,7 +919,7 @@ &usb_host2_xhci {
>   	status = "okay";
>   };
>   
> -&vop_mmu {
> +&usbdp_phy0 {
>   	status = "okay";
>   };
>   
> @@ -931,6 +927,10 @@ &vop {
>   	status = "okay";
>   };
>   
> +&vop_mmu {
> +	status = "okay";
> +};
> +
>   &vp0 {
>   	vp0_out_hdmi0: endpoint at ROCKCHIP_VOP2_EP_HDMI0 {
>   		reg = <ROCKCHIP_VOP2_EP_HDMI0>;



From heiko at sntech.de  Mon Nov 10 02:05:18 2025
From: heiko at sntech.de (Heiko =?UTF-8?B?U3TDvGJuZXI=?=)
Date: Mon, 10 Nov 2025 11:05:18 +0100
Subject: [RFC PATCH] arm64: dts: rockchip: Fix microSD card detect for Radxa ROCK
 5 ITX
In-Reply-To: <EECF7629320EEEDD+03c6ee06-4351-4150-b1b0-957d5cfc3d6d@radxa.com>
References: <20251110030036.825150-1-naoki@radxa.com>
 <EECF7629320EEEDD+03c6ee06-4351-4150-b1b0-957d5cfc3d6d@radxa.com>
Message-ID: <2242815.irdbgypaU6@diego>

Hi,

Am Montag, 10. November 2025, 04:16:37 Mitteleurop?ische Normalzeit schrieb FUKAUMI Naoki:
> On 11/10/25 12:00, FUKAUMI Naoki wrote:
> > Due to the discussion about cd-gpios and sdmmmc_det pin
> > functionality[1], it would be better to use cd-gpios for now.
> > 
> > [1] https://lore.kernel.org/linux-rockchip/20240912152538.1.I858c2a0bf83606c8b59ba1ab6944978a398d2ac5 at changeid/T/#u
> > 
> > Fixes: 31390eb8ffbf2 ("arm64: dts: rockchip: add ROCK 5 ITX board")
> > Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> > ---
> >   arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts | 9 ++++++++-
> >   1 file changed, 8 insertions(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
> > index bc8140883de47..391c6482e8ee3 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
> > +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
> > @@ -670,6 +670,12 @@ led_pins: led-pins {
> >   		};
> >   	};
> >   
> > +	mmc {
> > +		sdmmc_det_gpio: sdmmc-det-gpio {
> > +			rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
> > +		};
> > +	};
> > +
> 
> I got following error:
> 
> $ make CHECK_DTBS=y rockchip/rk3588-rock-5-itx.dtb
>    UPD     include/config/kernel.release
>    DTC [C] arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dtb
> /home/radxa/linux/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dtb: 
> mmc: sdmmc-det-gpio: {'rockchip,pins': [[0, 4, 0, 270]], 'phandle': 145} 
> is not of type 'array'
> 	from schema $id: http://devicetree.org/schemas/gpio/gpio-consumer.yaml#
> 
> What's wrong?

the problem is the "-gpio" in the pinctrl node-name,which triggers
a pattern matching against a normal gpios property.

So ideally rename sdmmc-det-gpio to sdmmc-det-pin or so.


Hope that helps
Heiko




From shawn.lin at rock-chips.com  Mon Nov 10 02:15:33 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Mon, 10 Nov 2025 18:15:33 +0800
Subject: [RESEND] Re: [PATCH] PCI: dw-rockchip: Skip waiting for link up
In-Reply-To: <0C31787C387488ED+fd39bfe6-0844-4a87-bf48-675dd6d6a2df@radxa.com>
References: <20250113-rockchip-no-wait-v1-1-25417f37b92f@kernel.org>
 <1E8E4DB773970CB5+5a52c9e1-01b8-4872-99b7-021099f04031@radxa.com>
 <6e87b611-13ea-4d89-8dbf-85510dd86fa6@rock-chips.com>
 <aQ840q5BxNS1eIai@ryzen> <aQ9FWEuW47L8YOxC@ryzen>
 <55EB0E5F655F3AFC+136b89fd-98d4-42af-a99d-a0bb05cc93f3@radxa.com>
 <aRCI5kG16_1erMME@ryzen>
 <F8B2B6FA2884D69A+b7da13f2-0ffb-4308-b1ba-0549bc461be8@radxa.com>
 <780a4209-f89f-43a9-9364-331d3b77e61e@rock-chips.com>
 <4487DA40249CC821+19232169-a096-4737-bc6a-5cec9592d65f@radxa.com>
 <363d6b4d-c999-43d4-866e-880ef7d0dec3@rock-chips.com>
 <0C31787C387488ED+fd39bfe6-0844-4a87-bf48-675dd6d6a2df@radxa.com>
Message-ID: <dc932773-af5b-4af7-a0d0-8cc72dfbd3c7@rock-chips.com>

? 2025/11/10 ??? 15:52, FUKAUMI Naoki ??:
> Hi Shawn,
> 
> On 11/10/25 16:12, Shawn Lin wrote:
> (snip)> Thanks for testing. I just got a ASM2806 switch as yours and 
> verified it
>> on vanilla v6.18-rc5. After 30 times of cold boot, two NVMes behind
>> ASM2806 work as expected. Nothing special happened when I checked
>> with PA as well. You could help check the log and lspci dump there[1].
>>
>> [1]https://pastebin.com/sAF1fT0g
> 
> Thanks for the info!
> 
> I tried ASM2806 on Radxa ROCK 5B (RK3588).
>  ?https://gist.github.com/RadxaNaoki/640e47d377add9fe38301de164d4058e
> 
> It doesn't work on PCIe 2.0 (M.2 E Key), but it does work on PCIe 3.0 
> (M.2 M Key).
> 
> Could you try PCIe 2.0 slot on your board?

I did, it doesn't work on PCIe 2.0 slot. From the PA, I could see
the link is still in training during pci_host_probe() is called.
Add some delay before pci_rescan_bus() in pcie-dw-rockchip doesn't
help. But the below change should work as we delayed pci_host_probe().

--- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
+++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
@@ -236,6 +236,8 @@ static int rockchip_pcie_start_link(struct dw_pcie *pci)
         msleep(PCIE_T_PVPERL_MS);
         gpiod_set_value_cansleep(rockchip->rst_gpio, 1);

+       msleep(50);
+
         return 0;

Otherwise we got:

[    0.841518] pci_bus 0003:33: busn_res: can not insert [bus 33-31] 
under [bus 32-31] (conflicts with (null) [bus 32-31])
[    0.842596] pci_bus 0003:33: busn_res: [bus 33-31] end is updated to 33
[    0.843184] pci_bus 0003:33: busn_res: can not insert [bus 33] under 
[bus 32-31] (conflicts with (null) [bus 32-31])
[    0.844120] pci 0003:32:00.0: devices behind bridge are unusable 
because [bus 33] cannot be assigned for them
[    0.845229] pci_bus 0003:34: busn_res: can not insert [bus 34-31] 
under [bus 32-31] (conflicts with (null) [bus 32-31])
[    0.846309] pci_bus 0003:34: busn_res: [bus 34-31] end is updated to 34
[    0.846898] pci_bus 0003:34: busn_res: can not insert [bus 34] under 
[bus 32-31] (conflicts with (null) [bus 32-31])
[    0.847833] pci 0003:32:06.0: devices behind bridge are unusable 
because [bus 34] cannot be assigned for them
[    0.848923] pci_bus 0003:35: busn_res: can not insert [bus 35-31] 
under [bus 32-31] (conflicts with (null) [bus 32-31])
[    0.850014] pci_bus 0003:35: busn_res: [bus 35-31] end is updated to 35
[    0.850605] pci_bus 0003:35: busn_res: can not insert [bus 35] under 
[bus 32-31] (conflicts with (null) [bus 32-31])
[    0.851540] pci 0003:32:0e.0: devices behind bridge are unusable 
because [bus 35] cannot be assigned for them
[    0.852424] pci_bus 0003:32: busn_res: [bus 32-31] end is updated to 35
[    0.853028] pci_bus 0003:32: busn_res: can not insert [bus 32-35] 
under [bus 31] (conflicts with (null) [bus 31])
[    0.853184] hub 3-0:1.0: USB hub found
[    0.853931] pci 0003:31:00.0: devices behind bridge are unusable 
because [bus 32-35] cannot be assigned for them
[    0.854262] hub 3-0:1.0: 1 port detected
[    0.855144] pcieport 0003:30:00.0: bridge has subordinate 31 but max 
busn 35
[    0.855722] hub 4-0:1.0: USB hub found
[    0.856109] pci 0003:32:00.0: PCI bridge to [bus 33]
[    0.856939] pci 0003:32:06.0: PCI bridge to [bus 34]
[    0.857133] hub 4-0:1.0: 1 port detected
[    0.857430] pci 0003:32:0e.0: PCI bridge to [bus 35]
[    0.858236] pci 0003:31:00.0: PCI bridge to [bus 32-35]

> 
> Best regards,
> 
> -- 
> FUKAUMI Naoki
> Radxa Computer (Shenzhen) Co., Ltd.
> 
> 



From naoki at radxa.com  Mon Nov 10 02:19:26 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Mon, 10 Nov 2025 19:19:26 +0900
Subject: [RFC PATCH] arm64: dts: rockchip: Fix microSD card detect for
 Radxa ROCK 5 ITX
In-Reply-To: <2242815.irdbgypaU6@diego>
References: <20251110030036.825150-1-naoki@radxa.com>
 <EECF7629320EEEDD+03c6ee06-4351-4150-b1b0-957d5cfc3d6d@radxa.com>
 <2242815.irdbgypaU6@diego>
Message-ID: <5763F732CB44709F+2774ec07-a035-4a4c-81f5-1bcf603945c9@radxa.com>

Hi Heiko,

On 11/10/25 19:05, Heiko St?bner wrote:
> Hi,
> 
> Am Montag, 10. November 2025, 04:16:37 Mitteleurop?ische Normalzeit schrieb FUKAUMI Naoki:
>> On 11/10/25 12:00, FUKAUMI Naoki wrote:
>>> Due to the discussion about cd-gpios and sdmmmc_det pin
>>> functionality[1], it would be better to use cd-gpios for now.
>>>
>>> [1] https://lore.kernel.org/linux-rockchip/20240912152538.1.I858c2a0bf83606c8b59ba1ab6944978a398d2ac5 at changeid/T/#u
>>>
>>> Fixes: 31390eb8ffbf2 ("arm64: dts: rockchip: add ROCK 5 ITX board")
>>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
>>> ---
>>>    arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts | 9 ++++++++-
>>>    1 file changed, 8 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
>>> index bc8140883de47..391c6482e8ee3 100644
>>> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
>>> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
>>> @@ -670,6 +670,12 @@ led_pins: led-pins {
>>>    		};
>>>    	};
>>>    
>>> +	mmc {
>>> +		sdmmc_det_gpio: sdmmc-det-gpio {
>>> +			rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
>>> +		};
>>> +	};
>>> +
>>
>> I got following error:
>>
>> $ make CHECK_DTBS=y rockchip/rk3588-rock-5-itx.dtb
>>     UPD     include/config/kernel.release
>>     DTC [C] arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dtb
>> /home/radxa/linux/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dtb:
>> mmc: sdmmc-det-gpio: {'rockchip,pins': [[0, 4, 0, 270]], 'phandle': 145}
>> is not of type 'array'
>> 	from schema $id: http://devicetree.org/schemas/gpio/gpio-consumer.yaml#
>>
>> What's wrong?
> 
> the problem is the "-gpio" in the pinctrl node-name,which triggers
> a pattern matching against a normal gpios property.
> 
> So ideally rename sdmmc-det-gpio to sdmmc-det-pin or so.

sdmmc-det-pin works! Thanks!

I'll send v2 with this fix.

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> Hope that helps
> Heiko
> 
> 
> 



From michael.riesch at collabora.com  Mon Nov 10 02:29:57 2025
From: michael.riesch at collabora.com (Michael Riesch)
Date: Mon, 10 Nov 2025 11:29:57 +0100
Subject: [PATCH v14 00/18] media: rockchip: add a driver for the rockchip
 camera interface
In-Reply-To: <aRGlvQRVoQs0WjyA@kekkonen.localdomain>
References: <20240220-rk3568-vicap-v14-0-b38b6da0fc80@collabora.com>
 <aQ4tJg8r_j4NyKhv@kekkonen.localdomain>
 <074cd08e-0412-49f9-8dd9-b1f96eb11717@collabora.com>
 <20251107185441.GG5558@pendragon.ideasonboard.com>
 <13c43edb-9592-4779-a39a-7856bb0f964d@collabora.com>
 <aRGlvQRVoQs0WjyA@kekkonen.localdomain>
Message-ID: <b89746e1-4574-4b65-af69-c533576ed185@collabora.com>

Hi Sakari,

On 11/10/25 09:43, Sakari Ailus wrote:
> Hi Michael, Laurent,
> 
> On Fri, Nov 07, 2025 at 09:51:37PM +0100, Michael Riesch wrote:
>> Hi Laurent,
>>
>> On 11/7/25 19:54, Laurent Pinchart wrote:
>>> On Fri, Nov 07, 2025 at 07:41:59PM +0100, Michael Riesch wrote:
>>>> On 11/7/25 18:32, Sakari Ailus wrote:
>>>>> On Fri, Oct 24, 2025 at 02:51:29PM +0200, Michael Riesch via B4 Relay wrote:
>>>>>> Habidere,
>>>>>>
>>>>>> This series introduces support for the Rockchip Camera Interface (CIF),
>>>>>> which is featured in many Rockchip SoCs in different variations.
>>>>>> For example, the PX30 Video Input Processor (VIP) is able to receive
>>>>>> video data via the Digital Video Port (DVP, a parallel data interface)
>>>>>> and transfer it into system memory using a double-buffering mechanism
>>>>>> called ping-pong mode.
>>>>>> The RK3568 Video Capture (VICAP) unit, on the other hand, features a
>>>>>> DVP and a MIPI CSI-2 receiver that can receive video data independently
>>>>>> (both using the ping-pong scheme).
>>>>>> The different variants may have additional features, such as scaling
>>>>>> and/or cropping.
>>>>>> Finally, the RK3588 VICAP unit constitutes an essential piece of the
>>>>>> camera interface with one DVP, six MIPI CSI-2 receivers, scale/crop
>>>>>> units, and a data path multiplexer (to scaler units, to ISP, ...).
>>>>>
>>>>> I understand both RK3568 and RK3588 include an ISP. Do you have insight on
>>>>> how would this work, should the support for the ISP be added later on?
>>>>
>>>> Short answer: Yes and yes.
>>>>
>>>> Long answer:
>>>>
>>>> The patch series at hand adds support for the PX30 VIP and the RK3568
>>>> VICAP. I cannot really say something about the PX30, but on the RK3568
>>>> VICAP and ISP are orthogonal (the ISP features its own MIPI CSI-2
>>>> receiver, different from that introduced in this series). Thus, ISP
>>>> support can be introduced anytime (whenever someone is motivated ;-)).
>>>
>>> Won't they both be connected to the same sensor though, and probably the
>>> same D-PHY in the SoC ? They don't seem entirely separate to me.
>>
>> The MIPI CSI-2 DPHY is shared, indeed. Thus, they *maybe technically
>> could be* connected to the same sensor, but I don't know whether that
>> works and fail to see why anyone would to such a thing (if it is about
>> raw capture, the MIPI CSI-2 receiver in the ISP can do that on its own).
>>
>> The DPHY can be operated in split mode, with two lanes for VICAP and two
>> lanes for ISP. This is not implemented yet, but can be done at a later
>> stage on PHY level (not media related). In this case, ISP and VICAP can
>> receive data from different subdevices via CSI-2.
> 
> The two would be part of the same media graph in that case and as there are
> two CSI-2 receivers and a single PHY, the PHY would probably need to have a
> sub-device as well, to allow link configuration to be used to select where
> the PHY is connected.
> 
> I don't think we have such a setup elsewhere, and supporting this would
> require changes in the MC framework.

What follows is a response that also addresses issues raised during our
off-list discussion.

First of all, I agree with you that the RK3568 HW is "a bit special" (to
say the least) in that regard. Let's have an outlook to newer SoCs, such
as the RK3588: Here, the MIPI CSI-2 DPHYs (there are two of them) with
their split mode are present as well, but the assignment is fixed. For
example, the RK3588 VICAP has six MIPI CSI-2 receiver units and six MIPI
CSI-2 capture units. Units 1 and 2 handle a different MIPI PHY, units 3
and 5 handle the DPHYs (without split mode), units 4 and/or 6 are active
whenever DPHY 1 and/or 2 is in split mode.

I would model this by adding support for more than one (logical) PHYs
(phy-cells = <1>;) and assigning the logical PHYs to the MIPI CSI-2
receivers. There is not really a possibility to route anything at this
point (routing is done in a MUX unit that takes the different MIPI CSI-2
receivers as inputs).

Now back to the peculiar RK3568 situation: By default the split mode of
the DPHY is off and both VICAP and ISP are able to receive the same data
(from up to four lanes) with their MIPI CSI-2 receivers (not sure
whether both can be active at the same time, though). There are two bits
in the GRF that define the lanes that ISP and VICAP receive in split
mode (lane 0/1 or lane 2/3). Not sure whether these bits are supposed to
be changed during runtime.

I would suggest modelling this on PHY level in DT, e.g., by passing
reasonable properties to the dphy node, such as
    rockchip,dphy-split-mode;
    rockchip,dphy-split-invert;
where the former activates the split mode and assigns lanes 0/1 to the
ISP and lanes 2/3 to the VICAP, and the latter inverts this assignment
(lanes 2/3 to the ISP and lanes 0/1 to the VICAP). This would facilitate
the reasonable use cases with reasonable effort.

Otherwise, to keep it perfectly general and most flexible and
everything, we would have to introduce another subdevice indeed, which
would be active on the RK3568 exclusively. Therefore, I don't see that
the PHY driver introduces this subdevice, but a specialized (syscon?)
MUX driver that deals with the RK3568 GRF bits. Something like this

                           |----------------------|     |-------------|
 Sensor A --- /2 lanes --- | lane 0/1      to ISP | --- | ISP MIPI RX |
                           |                      |     |-------------|
                           |                      |
                           |                      |     |-------------|
 Sensor B --- /2 lanes --- | lane 2/3    to VICAP | --- |VICAP MIPI RX|
                           |----------------------|     |-------------|

But IMHO this will be too much effort for corner use case that I doubt
anyone will actually use.

What do you think:
 - Let's keep the PHYs out of V4L2/MC, ok?
 - Let's model the reasonable use cases with device tree properties in
   the dphy DT node, ok?

> How does the media graph look like for the device at the moment?

Please take a look at the media graph in the documentation patch (PATCH
v14 01/18). This is without the ISP, but gives an overview of what the
RK3568 VICAP is capable of.

Best regards,
Michael

> 
>>
>> BTW the ISP is able to process the data captured by VICAP, but
>> apparently this includes a RAM round trip (VICAP captures to memory, ISP
>> operates in mem2mem mode).
>>
>>> A block diagram that shows connections between the CSI-2 pins, D-PHY,
>>> CSI-2 receivers, VICAP and ISP could help.
>>>
>>>> Once this patch series is merged, I'll push out changes that introduce
>>>> support for the RK3588 VICAP. We can discuss the integration of any
>>>> RK3588 ISP in this scope then -- and there may be some things to discuss
>>>> as there the VICAP and the ISP(s) are directly connected by means of a
>>>> MUX unit in the VICAP.
>>>>
>>>> Alright?
>>>
> 



From mani at kernel.org  Mon Nov 10 03:24:13 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Mon, 10 Nov 2025 16:54:13 +0530
Subject: [RESEND] Re: [PATCH] PCI: dw-rockchip: Skip waiting for link up
In-Reply-To: <F8B2B6FA2884D69A+b7da13f2-0ffb-4308-b1ba-0549bc461be8@radxa.com>
References: <20250113-rockchip-no-wait-v1-1-25417f37b92f@kernel.org>
 <1E8E4DB773970CB5+5a52c9e1-01b8-4872-99b7-021099f04031@radxa.com>
 <6e87b611-13ea-4d89-8dbf-85510dd86fa6@rock-chips.com>
 <aQ840q5BxNS1eIai@ryzen>
 <aQ9FWEuW47L8YOxC@ryzen>
 <55EB0E5F655F3AFC+136b89fd-98d4-42af-a99d-a0bb05cc93f3@radxa.com>
 <aRCI5kG16_1erMME@ryzen>
 <F8B2B6FA2884D69A+b7da13f2-0ffb-4308-b1ba-0549bc461be8@radxa.com>
Message-ID: <4f4wsgf56eublizg63fz6xmdjixesalb2q3rxetphd55jpqqju@zfyzsxfgiyim>

On Mon, Nov 10, 2025 at 08:26:56AM +0900, FUKAUMI Naoki wrote:
> (RESEND: fix mani's email address)
> 

Thanks for looping me in! My Linaro email is not functional anymore.

> Hi Niklas,
> 
> On 11/9/25 21:28, Niklas Cassel wrote:
> > On Sun, Nov 09, 2025 at 01:42:23PM +0900, FUKAUMI Naoki wrote:
> > > Hi Niklas,
> > > 
> > > On 11/8/25 22:27, Niklas Cassel wrote:
> > > (snip)> (And btw. please test with the latest 6.18-rc, as, from experience,
> > > the
> > > > ASPM problems in earlier RCs can result in some weird problems that are
> > > > not immediately deduced to be caused by the ASPM enablement.)
> > > 
> > > Here is dmesg from v6.18-rc4:
> > >   https://gist.github.com/RadxaNaoki/40e1d049bff4f1d2d4773a5ba0ed9dff
> > 
> > Same problem as before:
> > [    1.732538] pci_bus 0004:43: busn_res: can not insert [bus 43-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> > [    1.732645] pci_bus 0004:43: busn_res: [bus 43-41] end is updated to 43
> > [    1.732651] pci_bus 0004:43: busn_res: can not insert [bus 43] under [bus 42-41] (conflicts with (null) [bus 42-41])
> > [    1.732661] pci 0004:42:00.0: devices behind bridge are unusable because [bus 43] cannot be assigned for them
> > [    1.732840] pci_bus 0004:44: busn_res: can not insert [bus 44-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> > [    1.732947] pci_bus 0004:44: busn_res: [bus 44-41] end is updated to 44
> > [    1.732952] pci_bus 0004:44: busn_res: can not insert [bus 44] under [bus 42-41] (conflicts with (null) [bus 42-41])
> > [    1.732962] pci 0004:42:02.0: devices behind bridge are unusable because [bus 44] cannot be assigned for them
> > [    1.733134] pci_bus 0004:45: busn_res: can not insert [bus 45-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> > [    1.733246] pci_bus 0004:45: busn_res: [bus 45-41] end is updated to 45
> > [    1.733255] pci_bus 0004:45: busn_res: can not insert [bus 45] under [bus 42-41] (conflicts with (null) [bus 42-41])
> > [    1.733266] pci 0004:42:06.0: devices behind bridge are unusable because [bus 45] cannot be assigned for them
> > [    1.733438] pci_bus 0004:46: busn_res: can not insert [bus 46-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> > [    1.733544] pci_bus 0004:46: busn_res: [bus 46-41] end is updated to 46
> > [    1.733550] pci_bus 0004:46: busn_res: can not insert [bus 46] under [bus 42-41] (conflicts with (null) [bus 42-41])
> > [    1.733560] pci 0004:42:0e.0: devices behind bridge are unusable because [bus 46] cannot be assigned for them
> > [    1.733571] pci_bus 0004:42: busn_res: [bus 42-41] end is updated to 46
> > [    1.733575] pci_bus 0004:42: busn_res: can not insert [bus 42-46] under [bus 41] (conflicts with (null) [bus 41])
> > [    1.733585] pci 0004:41:00.0: devices behind bridge are unusable because [bus 42-46] cannot be assigned for them
> > [    1.733596] pcieport 0004:40:00.0: bridge has subordinate 41 but max busn 46
> > 
> > 
> > Seems like the ASM2806 switch, for some reason, is not ready.
> > 
> > One change that Diederik pointed out is that in the "good" case,
> > the link is always in Gen1 speed.
> > 
> > Perhaps you could build with CONFIG_PCI_QUIRKS=y and try this patch:
> > 
> > diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
> > index 214ed060ca1b..ac134d95a97f 100644
> > --- a/drivers/pci/quirks.c
> > +++ b/drivers/pci/quirks.c
> > @@ -96,6 +96,7 @@ int pcie_failed_link_retrain(struct pci_dev *dev)
> >   {
> >   	static const struct pci_device_id ids[] = {
> >   		{ PCI_VDEVICE(ASMEDIA, 0x2824) }, /* ASMedia ASM2824 */
> > +		{ PCI_VDEVICE(ASMEDIA, 0x2806) }, /* ASMedia ASM2806 */
> >   		{}
> >   	};
> >   	u16 lnksta, lnkctl2;
> 
> It doesn't help with either probing behind the bridge or the link speed.
> 
> > If that does not work, perhaps you could try this patch
> > (assuming that all Rock 5C:s have a ASM2806 on pcie2x1l2):
> 
> ROCK 5C has a PCIe FPC connector and I'm using Dual 2.5G Router HAT.
>  https://radxa.com/products/rock5/5c#techspec
>  https://radxa.com/products/accessories/dual-2-5g-router-hat
> 
> Regarding the link speed, I initially suspected the FPC connector and/or
> cable might be the issue. However, I tried the Dual 2.5G Router HAT with the
> ROCK 5A (which uses a different cable), and I got the same result.
> 
> BTW, the link speed varies between 2Gb/s and 4Gb/s depending on the reboot.
> (with or without quirk)
> 

>From the dmesg log, it looks like the issue is most probably due to bus number
assignment for the Root Port. During the initial bus scan, the PCI core will
assign the subordinate bus number (max bus number behind the PCI bridge) of the
PCI bridge based on the available busses scanned behind the bridge. Before the
link up IRQ patch, I guess the PCIe switch connected to the Root Port gets
enumerated during dw_pcie_wait_for_link() itself i.e., before the PCI core
starts the bus scan with a call to pci_host_probe(). So the switch appears when
the PCI core starts scanning the bus and the subordinate bus number gets
assigned correctly as the PCI core could see the available busses behind the
Root Port.

This could be confirmed from the timing of the success log:

[    1.875690] pci 0004:40:00.0: bridge configuration invalid ([bus 01-ff]), reconfiguring
[    1.876543] pci 0004:41:00.0: [1b21:2806] type 01 class 0x060400 PCIe Switch Upstream Port

Time difference is 853ms.

But with the link up IRQ patch, dw_pcie_wait_for_link() is skipped and the
device appears *after* the initial bus scan by the PCI core.

>From the failure log:

[    1.392130] pci 0004:40:00.0: PCI bridge to [bus 41]
[    1.392607] pci_bus 0004:40: resource 4 [io  0x0000-0xfffff]
[    1.393103] pci_bus 0004:40: resource 5 [mem 0xf4200000-0xf4ffffff]
[    1.393657] pci_bus 0004:40: resource 6 [mem 0xa00000000-0xa3fffffff]
[    1.412296] pci 0004:41:00.0: [1b21:2806] type 01 class 0x060400 PCIe Switch Upstream Port

Note the timing and also the PCI bridge resource assignment.

So during the initial scan, PCI core doesn't see the switch and since the Root
Port is not hot plug capable (I'm assuming that's the case), the secondary bus
number gets assigned as the subordinate bus number (41). This means, the PCI
core assumes that only one bus will appear behind the Root Port since the Root
Port is not hot plug capable. This will work perfectly fine for PCIe endpoints
connected to the Root Port, since they don't extend the bus. But if you connect
a PCIe switch, then you'll see the issue as the downstream busses starts showing
up and PCI core doesn't extend the subordinate bus number after initial scan
during boot.

This is also confirmed by the below log in failure case:

[    1.478814] pcieport 0004:40:00.0: bridge has subordinate 41 but max busn 46

If you try the below hack, you might get the switch working:

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index c83e75a0ec12..01afb5b23eba 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1701,6 +1701,11 @@ void set_pcie_hotplug_bridge(struct pci_dev *pdev)
 {
        u32 reg32;
 
+       if (pdev->vendor == 0x1d87 && pdev->device == 0x3588) {
+               pdev->is_hotplug_bridge = pdev->is_pciehp = 1;
+               return;
+       }
+
        pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, &reg32);
        if (reg32 & PCI_EXP_SLTCAP_HPC)
                pdev->is_hotplug_bridge = pdev->is_pciehp = 1;

The above diff just fakes the Root Port as hot plug capable to the PCI core so
that more subordinate bus numbers gets assigned to it in the anticipation of
more busses showing up post scan.

If the above works, then you should make sure that the switch is powered and the
link to be up before the initial bus scan. The proper way to do this would be by
modeling your switch power resources in devicetree and relying on the
CONFIG_PWRCTRL_SLOT driver to power it up and scan the bus. But this driver
needs some extra work to satisfy your needs and I'm going to post a series in
the coming weeks for that.

Until then, I'd suggest to revert the link up IRQ patch as a stop-gap solution.

NOTE: As Niklas rightly pointed out, this issue also affects the Qcom platforms
which follows the same code pattern and also other platforms as well. For Qcom,
we are relying on the upcoming pwrctrl fixes to properly enumerate the PCIe
switches in upstream.

- Mani

-- 
????????? ????????


From cassel at kernel.org  Mon Nov 10 04:34:41 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Mon, 10 Nov 2025 13:34:41 +0100
Subject: [RESEND] Re: [PATCH] PCI: dw-rockchip: Skip waiting for link up
In-Reply-To: <dc932773-af5b-4af7-a0d0-8cc72dfbd3c7@rock-chips.com>
References: <aQ840q5BxNS1eIai@ryzen>
 <aQ9FWEuW47L8YOxC@ryzen>
 <55EB0E5F655F3AFC+136b89fd-98d4-42af-a99d-a0bb05cc93f3@radxa.com>
 <aRCI5kG16_1erMME@ryzen>
 <F8B2B6FA2884D69A+b7da13f2-0ffb-4308-b1ba-0549bc461be8@radxa.com>
 <780a4209-f89f-43a9-9364-331d3b77e61e@rock-chips.com>
 <4487DA40249CC821+19232169-a096-4737-bc6a-5cec9592d65f@radxa.com>
 <363d6b4d-c999-43d4-866e-880ef7d0dec3@rock-chips.com>
 <0C31787C387488ED+fd39bfe6-0844-4a87-bf48-675dd6d6a2df@radxa.com>
 <dc932773-af5b-4af7-a0d0-8cc72dfbd3c7@rock-chips.com>
Message-ID: <aRHb4S40a7ZUDop1@ryzen>

On Mon, Nov 10, 2025 at 06:15:33PM +0800, Shawn Lin wrote:
> > 
> > Could you try PCIe 2.0 slot on your board?
> 
> I did, it doesn't work on PCIe 2.0 slot. From the PA, I could see
> the link is still in training during pci_host_probe() is called.
> Add some delay before pci_rescan_bus() in pcie-dw-rockchip doesn't
> help. But the below change should work as we delayed pci_host_probe().
> 
> --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> @@ -236,6 +236,8 @@ static int rockchip_pcie_start_link(struct dw_pcie *pci)
>         msleep(PCIE_T_PVPERL_MS);
>         gpiod_set_value_cansleep(rockchip->rst_gpio, 1);
> 
> +       msleep(50);
> +
>         return 0;
> 
> Otherwise we got:
> 
> [    0.841518] pci_bus 0003:33: busn_res: can not insert [bus 33-31] under
> [bus 32-31] (conflicts with (null) [bus 32-31])
> [    0.842596] pci_bus 0003:33: busn_res: [bus 33-31] end is updated to 33
> [    0.843184] pci_bus 0003:33: busn_res: can not insert [bus 33] under [bus
> 32-31] (conflicts with (null) [bus 32-31])
> [    0.844120] pci 0003:32:00.0: devices behind bridge are unusable because
> [bus 33] cannot be assigned for them
> [    0.845229] pci_bus 0003:34: busn_res: can not insert [bus 34-31] under
> [bus 32-31] (conflicts with (null) [bus 32-31])
> [    0.846309] pci_bus 0003:34: busn_res: [bus 34-31] end is updated to 34
> [    0.846898] pci_bus 0003:34: busn_res: can not insert [bus 34] under [bus
> 32-31] (conflicts with (null) [bus 32-31])
> [    0.847833] pci 0003:32:06.0: devices behind bridge are unusable because
> [bus 34] cannot be assigned for them
> [    0.848923] pci_bus 0003:35: busn_res: can not insert [bus 35-31] under
> [bus 32-31] (conflicts with (null) [bus 32-31])
> [    0.850014] pci_bus 0003:35: busn_res: [bus 35-31] end is updated to 35
> [    0.850605] pci_bus 0003:35: busn_res: can not insert [bus 35] under [bus
> 32-31] (conflicts with (null) [bus 32-31])
> [    0.851540] pci 0003:32:0e.0: devices behind bridge are unusable because
> [bus 35] cannot be assigned for them
> [    0.852424] pci_bus 0003:32: busn_res: [bus 32-31] end is updated to 35
> [    0.853028] pci_bus 0003:32: busn_res: can not insert [bus 32-35] under
> [bus 31] (conflicts with (null) [bus 31])
> [    0.853184] hub 3-0:1.0: USB hub found
> [    0.853931] pci 0003:31:00.0: devices behind bridge are unusable because
> [bus 32-35] cannot be assigned for them
> [    0.854262] hub 3-0:1.0: 1 port detected
> [    0.855144] pcieport 0003:30:00.0: bridge has subordinate 31 but max busn
> 35
> [    0.855722] hub 4-0:1.0: USB hub found
> [    0.856109] pci 0003:32:00.0: PCI bridge to [bus 33]
> [    0.856939] pci 0003:32:06.0: PCI bridge to [bus 34]
> [    0.857133] hub 4-0:1.0: 1 port detected
> [    0.857430] pci 0003:32:0e.0: PCI bridge to [bus 35]
> [    0.858236] pci 0003:31:00.0: PCI bridge to [bus 32-35]

Mani,

while I see the idea behind your suggested hack:
 
+       if (pdev->vendor == 0x1d87 && pdev->device == 0x3588) {
+               pdev->is_hotplug_bridge = pdev->is_pciehp = 1;
+               return;
+       }


Considering what Shawn says, that the switch gets enumerated properly
if we simply add a msleep() in ->start_link(), which will be called
by dw_pcie_host_init() before pci_host_probe() is called...

...we already have a delay in the link up IRQ handler, before calling
pci_rescan_bus().

So, I think that the problem is that we are unconditionally calling
pci_host_probe() in dw_pcie_host_init(), even for platforms that have
a link-up IRQ.


I think a better solution would be something like:

diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index e92513c5bda5..42d987ddab7d 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -565,6 +565,39 @@ static int dw_pcie_host_get_resources(struct dw_pcie_rp *pp)
 	return 0;
 }
 
+static int dw_pcie_host_initial_scan(struct dw_pcie_rp *pp)
+{
+	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+	struct pci_host_bridge *bridge = pp->bridge;
+	int ret;
+
+	ret = pci_host_probe(bridge);
+	if (ret)
+		return ret;
+
+	if (pp->ops->post_init)
+		pp->ops->post_init(pp);
+
+	dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
+
+	return 0;
+}
+
+void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp)
+{
+	if (!pp->initial_linkup_irq_done) {
+		if (dw_pcie_host_initial_scan(pp)) {
+			//TODO: cleanup
+		}
+		pp->initial_linkup_irq_done = true;
+	} else {
+		/* Rescan the bus to enumerate endpoint devices */
+		pci_lock_rescan_remove();
+		pci_rescan_bus(pp->bridge->bus);
+		pci_unlock_rescan_remove();
+	}
+}
+
 int dw_pcie_host_init(struct dw_pcie_rp *pp)
 {
 	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
@@ -672,15 +705,13 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
 	if (!pp->use_linkup_irq)
 		/* Ignore errors, the link may come up later */
 		dw_pcie_wait_for_link(pci);
-
-	ret = pci_host_probe(bridge);
-	if (ret)
-		goto err_stop_link;
-
-	if (pp->ops->post_init)
-		pp->ops->post_init(pp);
-
-	dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
+	else
+		/*
+		 * For platforms with Link Up IRQ, initial scan will be done
+		 * on first Link Up IRQ.
+		 */
+		if (dw_pcie_host_initial_scan(pp))
+			goto err_stop_link;
 
 	return 0;
 
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index e995f692a1ec..a31bd93490dc 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -427,6 +427,7 @@ struct dw_pcie_rp {
 	int			msg_atu_index;
 	struct resource		*msg_res;
 	bool			use_linkup_irq;
+	bool			initial_linkup_irq_done;
 	struct pci_eq_presets	presets;
 	struct pci_config_window *cfg;
 	bool			ecam_enabled;
@@ -807,6 +808,7 @@ void dw_pcie_msi_init(struct dw_pcie_rp *pp);
 int dw_pcie_msi_host_init(struct dw_pcie_rp *pp);
 void dw_pcie_free_msi(struct dw_pcie_rp *pp);
 int dw_pcie_setup_rc(struct dw_pcie_rp *pp);
+void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp);
 int dw_pcie_host_init(struct dw_pcie_rp *pp);
 void dw_pcie_host_deinit(struct dw_pcie_rp *pp);
 int dw_pcie_allocate_domains(struct dw_pcie_rp *pp);
@@ -844,6 +846,9 @@ static inline int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
 	return 0;
 }
 
+static inline void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp)
+{ }
+
 static inline int dw_pcie_host_init(struct dw_pcie_rp *pp)
 {
 	return 0;
diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
index 8a882dcd1e4e..042e5845bdd6 100644
--- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
+++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
@@ -468,10 +468,7 @@ static irqreturn_t rockchip_pcie_rc_sys_irq_thread(int irq, void *arg)
 		if (rockchip_pcie_link_up(pci)) {
 			msleep(PCIE_RESET_CONFIG_WAIT_MS);
 			dev_dbg(dev, "Received Link up event. Starting enumeration!\n");
-			/* Rescan the bus to enumerate endpoint devices */
-			pci_lock_rescan_remove();
-			pci_rescan_bus(pp->bridge->bus);
-			pci_unlock_rescan_remove();
+			dw_pcie_handle_link_up_irq(pp);
 		}
 	}
 




What do you think?



Kind regards,
Niklas


From cassel at kernel.org  Mon Nov 10 04:41:29 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Mon, 10 Nov 2025 13:41:29 +0100
Subject: [RESEND] Re: [PATCH] PCI: dw-rockchip: Skip waiting for link up
In-Reply-To: <aRHb4S40a7ZUDop1@ryzen>
References: <aQ9FWEuW47L8YOxC@ryzen>
 <55EB0E5F655F3AFC+136b89fd-98d4-42af-a99d-a0bb05cc93f3@radxa.com>
 <aRCI5kG16_1erMME@ryzen>
 <F8B2B6FA2884D69A+b7da13f2-0ffb-4308-b1ba-0549bc461be8@radxa.com>
 <780a4209-f89f-43a9-9364-331d3b77e61e@rock-chips.com>
 <4487DA40249CC821+19232169-a096-4737-bc6a-5cec9592d65f@radxa.com>
 <363d6b4d-c999-43d4-866e-880ef7d0dec3@rock-chips.com>
 <0C31787C387488ED+fd39bfe6-0844-4a87-bf48-675dd6d6a2df@radxa.com>
 <dc932773-af5b-4af7-a0d0-8cc72dfbd3c7@rock-chips.com>
 <aRHb4S40a7ZUDop1@ryzen>
Message-ID: <aRHdeVCY3rRmxe80@ryzen>

On Mon, Nov 10, 2025 at 01:34:41PM +0100, Niklas Cassel wrote:
> @@ -672,15 +705,13 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
>  	if (!pp->use_linkup_irq)
>  		/* Ignore errors, the link may come up later */
>  		dw_pcie_wait_for_link(pci);
> -
> -	ret = pci_host_probe(bridge);
> -	if (ret)
> -		goto err_stop_link;
> -
> -	if (pp->ops->post_init)
> -		pp->ops->post_init(pp);
> -
> -	dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
> +	else
> +		/*
> +		 * For platforms with Link Up IRQ, initial scan will be done
> +		 * on first Link Up IRQ.
> +		 */
> +		if (dw_pcie_host_initial_scan(pp))
> +			goto err_stop_link;

Oops.. this condition was inverted, what I meant was:

diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index e92513c5bda5..0e04c1d6d260 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -565,6 +565,39 @@ static int dw_pcie_host_get_resources(struct dw_pcie_rp *pp)
 	return 0;
 }
 
+static int dw_pcie_host_initial_scan(struct dw_pcie_rp *pp)
+{
+	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+	struct pci_host_bridge *bridge = pp->bridge;
+	int ret;
+
+	ret = pci_host_probe(bridge);
+	if (ret)
+		return ret;
+
+	if (pp->ops->post_init)
+		pp->ops->post_init(pp);
+
+	dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
+
+	return 0;
+}
+
+void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp)
+{
+	if (!pp->initial_linkup_irq_done) {
+		if (dw_pcie_host_initial_scan(pp)) {
+			//TODO: cleanup
+		}
+		pp->initial_linkup_irq_done = true;
+	} else {
+		/* Rescan the bus to enumerate endpoint devices */
+		pci_lock_rescan_remove();
+		pci_rescan_bus(pp->bridge->bus);
+		pci_unlock_rescan_remove();
+	}
+}
+
 int dw_pcie_host_init(struct dw_pcie_rp *pp)
 {
 	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
@@ -669,18 +702,17 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
 	 * If there is no Link Up IRQ, we should not bypass the delay
 	 * because that would require users to manually rescan for devices.
 	 */
-	if (!pp->use_linkup_irq)
+	if (!pp->use_linkup_irq) {
 		/* Ignore errors, the link may come up later */
 		dw_pcie_wait_for_link(pci);
 
-	ret = pci_host_probe(bridge);
-	if (ret)
-		goto err_stop_link;
-
-	if (pp->ops->post_init)
-		pp->ops->post_init(pp);
-
-	dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
+		/*
+		 * For platforms with Link Up IRQ, initial scan will be done
+		 * on first Link Up IRQ.
+		 */
+		if (dw_pcie_host_initial_scan(pp))
+			goto err_stop_link;
+	}
 
 	return 0;
 
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index e995f692a1ec..a31bd93490dc 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -427,6 +427,7 @@ struct dw_pcie_rp {
 	int			msg_atu_index;
 	struct resource		*msg_res;
 	bool			use_linkup_irq;
+	bool			initial_linkup_irq_done;
 	struct pci_eq_presets	presets;
 	struct pci_config_window *cfg;
 	bool			ecam_enabled;
@@ -807,6 +808,7 @@ void dw_pcie_msi_init(struct dw_pcie_rp *pp);
 int dw_pcie_msi_host_init(struct dw_pcie_rp *pp);
 void dw_pcie_free_msi(struct dw_pcie_rp *pp);
 int dw_pcie_setup_rc(struct dw_pcie_rp *pp);
+void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp);
 int dw_pcie_host_init(struct dw_pcie_rp *pp);
 void dw_pcie_host_deinit(struct dw_pcie_rp *pp);
 int dw_pcie_allocate_domains(struct dw_pcie_rp *pp);
@@ -844,6 +846,9 @@ static inline int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
 	return 0;
 }
 
+static inline void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp)
+{ }
+
 static inline int dw_pcie_host_init(struct dw_pcie_rp *pp)
 {
 	return 0;
diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
index 8a882dcd1e4e..042e5845bdd6 100644
--- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
+++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
@@ -468,10 +468,7 @@ static irqreturn_t rockchip_pcie_rc_sys_irq_thread(int irq, void *arg)
 		if (rockchip_pcie_link_up(pci)) {
 			msleep(PCIE_RESET_CONFIG_WAIT_MS);
 			dev_dbg(dev, "Received Link up event. Starting enumeration!\n");
-			/* Rescan the bus to enumerate endpoint devices */
-			pci_lock_rescan_remove();
-			pci_rescan_bus(pp->bridge->bus);
-			pci_unlock_rescan_remove();
+			dw_pcie_handle_link_up_irq(pp);
 		}
 	}
 


From cristian.ciocaltea at collabora.com  Mon Nov 10 05:18:05 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Mon, 10 Nov 2025 15:18:05 +0200
Subject: [PATCH i-g-t] tests: (Re)add kms_crtc_background_color test
Message-ID: <20251110-crtc-bgcolor-v1-1-28669b692970@collabora.com>

Provide test to verify the behavior of BACKGROUND_COLOR DRM CRTC
property.

This is done by filling a full-screen primary plane with a given color
and comparing the resulting CRC with the one obtained after turning off
all planes while having the CRTC background set to the same color.

It's worth noting this is a reworked version of the test that has been
dropped over 5 years ago via commit 33f07391e5f6 ("tests: Remove
kms_crtc_background_color test"), as the required kernel changes never
landed because of missing userspace support.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
This has been tested on a Radxa ROCK 5B board which is based on Rockchip
RK3588 SoC.  It relies on the kernel series [1] introducing the
BACKGROUND_COLOR CRTC property and a few additional patches from [2]
enabling the required CRC functionality for the Rockchip platform (still
require a bit more work before sending those upstream).

It's worth noting CRC is only supported by the display controller (VOP2)
present in the RK3576 SoC variant.  However, the computation is done by
the hardware before applying the background color, hence it has limited
usage in IGT testing.

Luckily, the frame CRCs can be captured through DPCD, i.e. at
DisplayPort AUX channel level, hence I used the USB-C DP AltMode capable
port of the aforementioned board to perform the actual validation.

[1] https://lore.kernel.org/all/20251013-rk3588-bgcolor-v2-0-25cc3810ba8c at collabora.com/
[2] https://gitlab.collabora.com/hardware-enablement/rockchip-3588/linux/-/commits/cristicc/rk3588-vop2-crc

root at rock5b$ cat /sys/kernel/debug/dri/1/vop2/summary

cat /sys/kernel/debug/dri/1/vop2/summary
Video Port0: DISABLED
Video Port1: DISABLED
Video Port2: ACTIVE
    Connector: DP-1
	bus_format[1018]: RGB101010_1X30
	output_mode[f] color_space[0]
	background color (10bpc): r=0x0 g=0x0 b=0x0
    Display mode: 3840x2160p60
	clk[594000] real_clk[594000] type[48] flag[9]
	H: 3840 4016 4104 4400
	V: 2160 2164 2174 2250
    Cluster2-win0: ACTIVE
	win_id: 2
	format: XR24 little-endian (0x34325258) glb_alpha[0xff]
	rotate: xmirror: 0 ymirror: 0 rotate_90: 0 rotate_270: 0
	zpos: 0
	src: pos[0, 0] rect[3840 x 2160]
	dst: pos[0, 0] rect[3840 x 2160]
	buf[0]: addr: 0x0000000000000000 pitch: 15360 offset: 0

root at rock5b$ ./kms_crtc_background_color --device drm:/dev/dri/card1

IGT-Version: 2.2-g3e4ec308e (aarch64) (Linux: 6.18.0-rc1 aarch64)
Using IGT_SRANDOM=1762774806 for randomisation
Opened device: /dev/dri/card1
Starting subtest: background-color-red
Starting dynamic subtest: pipe-C-DP-1
Dynamic subtest pipe-C-DP-1: SUCCESS (0.491s)
Subtest background-color-red: SUCCESS (0.493s)
Starting subtest: background-color-green
Starting dynamic subtest: pipe-C-DP-1
Dynamic subtest pipe-C-DP-1: SUCCESS (0.533s)
Subtest background-color-green: SUCCESS (0.535s)
Starting subtest: background-color-blue
Starting dynamic subtest: pipe-C-DP-1
Dynamic subtest pipe-C-DP-1: SUCCESS (0.541s)
Subtest background-color-blue: SUCCESS (0.544s)
Starting subtest: background-color-yellow
Starting dynamic subtest: pipe-C-DP-1
Dynamic subtest pipe-C-DP-1: SUCCESS (0.535s)
Subtest background-color-yellow: SUCCESS (0.537s)
Starting subtest: background-color-purple
Starting dynamic subtest: pipe-C-DP-1
Dynamic subtest pipe-C-DP-1: SUCCESS (0.536s)
Subtest background-color-purple: SUCCESS (0.538s)
Starting subtest: background-color-cyan
Starting dynamic subtest: pipe-C-DP-1
Dynamic subtest pipe-C-DP-1: SUCCESS (0.539s)
Subtest background-color-cyan: SUCCESS (0.541s)
Starting subtest: background-color-black
Starting dynamic subtest: pipe-C-DP-1
(kms_crtc_background_color:744) igt_pipe_crc-WARNING: Warning on condition all_zero in function crc_sanity_checks, file ../lib/igt_pipe_crc.c:475
(kms_crtc_background_color:744) igt_pipe_crc-WARNING: Suspicious CRC: All values are 0.
(kms_crtc_background_color:744) igt_pipe_crc-WARNING: Warning on condition all_zero in function crc_sanity_checks, file ../lib/igt_pipe_crc.c:475
(kms_crtc_background_color:744) igt_pipe_crc-WARNING: Suspicious CRC: All values are 0.
Dynamic subtest pipe-C-DP-1: SUCCESS (0.535s)
Subtest background-color-black: SUCCESS (0.537s)
Starting subtest: background-color-white
Starting dynamic subtest: pipe-C-DP-1
Dynamic subtest pipe-C-DP-1: SUCCESS (0.540s)
Subtest background-color-white: SUCCESS (0.542s)
---
 lib/igt_kms.c                     |   1 +
 lib/igt_kms.h                     |   3 +-
 tests/kms_crtc_background_color.c | 139 ++++++++++++++++++++++++++++++++++++++
 tests/meson.build                 |   1 +
 4 files changed, 143 insertions(+), 1 deletion(-)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 9208c8dbfc86..7c0848865038 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -705,6 +705,7 @@ const char * const igt_plane_prop_names[IGT_NUM_PLANE_PROPS] = {
 };
 
 const char * const igt_crtc_prop_names[IGT_NUM_CRTC_PROPS] = {
+	[IGT_CRTC_BACKGROUND] = "BACKGROUND_COLOR",
 	[IGT_CRTC_CTM] = "CTM",
 	[IGT_CRTC_GAMMA_LUT] = "GAMMA_LUT",
 	[IGT_CRTC_GAMMA_LUT_SIZE] = "GAMMA_LUT_SIZE",
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index eff76f0de0b3..a19f8d126a8d 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -156,7 +156,8 @@ void kmstest_restore_vt_mode(void);
 void kmstest_set_vt_text_mode(void);
 
 enum igt_atomic_crtc_properties {
-       IGT_CRTC_CTM = 0,
+       IGT_CRTC_BACKGROUND = 0,
+       IGT_CRTC_CTM,
        IGT_CRTC_GAMMA_LUT,
        IGT_CRTC_GAMMA_LUT_SIZE,
        IGT_CRTC_DEGAMMA_LUT,
diff --git a/tests/kms_crtc_background_color.c b/tests/kms_crtc_background_color.c
new file mode 100644
index 000000000000..4e6d183b736d
--- /dev/null
+++ b/tests/kms_crtc_background_color.c
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright ? 2013,2014 Intel Corporation
+ * Copyright ? 2025 Collabora, Ltd.
+ */
+
+#include "igt.h"
+
+IGT_TEST_DESCRIPTION("Test crtc background color feature");
+
+typedef struct {
+	int drm_fd;
+	int debugfs;
+	igt_display_t display;
+} data_t;
+
+#define __DRM_ARGB64_PREP(c, shift, bpc)			\
+	(((__u64)(c) << (16 - (bpc)) & 0xffffU) << (shift))
+
+#define DRM_ARGB64_PREP_BPC(alpha, red, green, blue, bpc)	\
+	(__DRM_ARGB64_PREP(alpha, 48, bpc) |			\
+	 __DRM_ARGB64_PREP(red,   32, bpc) |			\
+	 __DRM_ARGB64_PREP(green, 16, bpc) |			\
+	 __DRM_ARGB64_PREP(blue,   0, bpc))
+
+static void test_background(data_t *data, enum pipe pipe, igt_output_t *output,
+			    __u16 red, __u16 green, __u16 blue)
+{
+	igt_display_t *display = &data->display;
+	igt_crc_t plane_crc, bg_crc;
+	igt_pipe_crc_t *pipe_crc;
+	igt_plane_t *plane;
+	drmModeModeInfo *mode;
+	struct igt_fb fb;
+
+	igt_display_reset(display);
+
+	igt_output_set_pipe(output, pipe);
+	mode = igt_output_get_mode(output);
+
+	plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
+
+	/* Fill the primary plane and set the background to the same color */
+	igt_create_color_fb(data->drm_fd,
+			    mode->hdisplay, mode->vdisplay,
+			    DRM_FORMAT_XRGB8888,
+			    DRM_FORMAT_MOD_NONE,
+			    (double)red / 0xffff,
+			    (double)green / 0xffff,
+			    (double)blue / 0xffff,
+			    &fb);
+
+	igt_plane_set_fb(plane, &fb);
+	igt_pipe_set_prop_value(&data->display, pipe, IGT_CRTC_BACKGROUND,
+				DRM_ARGB64_PREP_BPC(0xffff, red, green, blue, 8));
+	igt_display_commit2(&data->display, COMMIT_ATOMIC);
+
+	pipe_crc = igt_pipe_crc_new(data->drm_fd, pipe, IGT_PIPE_CRC_SOURCE_AUTO);
+	igt_pipe_crc_collect_crc(pipe_crc, &plane_crc);
+
+	/* Turn off the primary plane so that only the background is visible */
+	igt_plane_set_fb(plane, NULL);
+	igt_display_commit2(&data->display, COMMIT_ATOMIC);
+	igt_pipe_crc_collect_crc(pipe_crc, &bg_crc);
+
+	/*
+	 * The test assumes hardware is able to generate valid CRCs when setting
+	 * the background color. Some platforms, e.g. Intel, might require at
+	 * least one plane to be visible before reading the pipe-level ("dmux")
+	 * CRC. Other platforms, e.g. Rockchip, do not take background color
+	 * into account when computing CRC at CRTC level.
+	 * A possible workaround would be to use alternative CRC sources, e.g.
+	 * where computation is performed at encoder or sink level.
+	 */
+	igt_assert_crc_equal(&plane_crc, &bg_crc);
+
+	/* Clean-up */
+	igt_pipe_set_prop_value(&data->display, pipe, IGT_CRTC_BACKGROUND,
+				DRM_ARGB64_PREP_BPC(0xffff, 0, 0, 0, 8));
+	igt_pipe_crc_free(pipe_crc);
+	igt_output_set_pipe(output, PIPE_NONE);
+	igt_display_commit(display);
+	igt_remove_fb(data->drm_fd, &fb);
+}
+
+igt_main
+{
+	igt_output_t *output;
+	data_t data = {};
+	enum pipe pipe;
+	int i;
+
+	struct {
+		const char *color;
+		__u16 red;
+		__u16 green;
+		__u16 blue;
+	} tests[] = {
+		{ "red",    0xffff, 0x0000, 0x0000, },
+		{ "green",  0x0000, 0xffff, 0x0000, },
+		{ "blue",   0x0000, 0x0000, 0xffff, },
+		{ "yellow", 0xffff, 0xffff, 0x0000, },
+		{ "purple", 0xffff, 0x0000, 0xffff, },
+		{ "cyan",   0x0000, 0xffff, 0xffff, },
+		{ "black",  0x0000, 0x0000, 0x0000, },
+		{ "white",  0xffff, 0xffff, 0xffff, },
+	};
+
+	igt_fixture {
+		data.drm_fd = drm_open_driver_master(DRIVER_ANY);
+
+		kmstest_set_vt_graphics_mode();
+
+		igt_display_require(&data.display, data.drm_fd);
+		igt_display_require_output(&data.display);
+		igt_require_pipe_crc(data.drm_fd);
+
+		data.debugfs = igt_debugfs_dir(data.drm_fd);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(tests); i++) {
+		igt_describe_f("Test crtc background color %s", tests[i].color);
+		igt_subtest_with_dynamic_f("background-color-%s", tests[i].color) {
+			for_each_pipe_with_single_output(&data.display, pipe, output) {
+				igt_require(igt_pipe_has_prop(&data.display, pipe,
+							      IGT_CRTC_BACKGROUND));
+
+				igt_dynamic_f("pipe-%s-%s", kmstest_pipe_name(pipe), output->name)
+					test_background(&data, pipe, output, tests[i].red,
+							tests[i].green, tests[i].blue);
+			}
+		}
+	}
+
+	igt_fixture {
+		igt_display_fini(&data.display);
+		drm_close_driver(data.drm_fd);
+	}
+}
diff --git a/tests/meson.build b/tests/meson.build
index 9736f2338507..06827b41a00c 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -27,6 +27,7 @@ test_progs = [
 	'kms_color',
 	'kms_concurrent',
 	'kms_content_protection',
+	'kms_crtc_background_color',
 	'kms_cursor_crc',
 	'kms_cursor_edge_walk',
 	'kms_cursor_legacy',

---
base-commit: 862eb176244feac8ee711f381fe1be1fdc6a7ede
change-id: 20251110-crtc-bgcolor-f6ed9a58e0bf



From sebastian.reichel at collabora.com  Mon Nov 10 05:43:32 2025
From: sebastian.reichel at collabora.com (Sebastian Reichel)
Date: Mon, 10 Nov 2025 14:43:32 +0100
Subject: [PATCH v2 1/2] mmc: sdhci-of-dwcmshc: Add command queue support
 for rockchip SOCs
In-Reply-To: <abb4a253-6f4b-4547-a238-db6f60ee3244@intel.com>
References: <20251031-rockchip-emmc-cqe-support-v2-0-958171f5edad@collabora.com>
 <20251031-rockchip-emmc-cqe-support-v2-1-958171f5edad@collabora.com>
 <abb4a253-6f4b-4547-a238-db6f60ee3244@intel.com>
Message-ID: <hjxwedwtwksog67mz4unm4jita2q5vvp4vkdrtpznc6mllz7q4@7a7nn3c5l7fv>

Hi,

On Mon, Nov 10, 2025 at 09:58:24AM +0200, Adrian Hunter wrote:
> On 31/10/2025 17:58, Sebastian Reichel wrote:
> > This adds CQE support for the Rockchip RK3588 and RK3576 platform. To
> > be functional, the eMMC device-tree node must have a 'supports-cqe;'
> > flag property.
> > 
> > As the RK3576 device-tree has been upstreamed with the 'supports-cqe;'
> > property set by default, the kernel already tried to use CQE, which
> > results in system hang during suspend. This fixes the issue.
> > 
> > Co-developed-by: Yifeng Zhao <yifeng.zhao at rock-chips.com>
> > Signed-off-by: Yifeng Zhao <yifeng.zhao at rock-chips.com>
> > Signed-off-by: Sebastian Reichel <sebastian.reichel at collabora.com>
> 
> One question below, otherwise:
> 
> Acked-by: Adrian Hunter <adrian.hunter at intel.com>

Thanks,

[...]

> > @@ -687,6 +757,9 @@ static void rk35xx_sdhci_reset(struct sdhci_host *host, u8 mask)
> >  	}
> >  
> >  	sdhci_reset(host, mask);
> > +
> > +	/* Enable INTERNAL CLOCK */
> > +	sdhci_writel(host, MISC_INTCLK_EN | extra, DECMSHC_EMMC_MISC_CON);
> 
> rk35xx_sdhci_reset() is in sdhci_dwcmshc_rk35xx_ops.
> sdhci_dwcmshc_rk3576_pdata also uses sdhci_dwcmshc_rk35xx_ops but isn't
> supporting CQE ops.  Is this change OK for rk3576?

How did you come to the conclusion, that rk3576 does not support CQE
ops? Have you read the cover letter? :)

Greetings,

-- Sebastian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251110/388aa2c7/attachment.sig>

From cristian.ciocaltea at collabora.com  Mon Nov 10 06:22:21 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Mon, 10 Nov 2025 16:22:21 +0200
Subject: [PATCH v2 0/2] Introduce BACKGROUND_COLOR DRM CRTC property
In-Reply-To: <x33zabb5un2boben6r4qp3vvrgca5s37gmseespdwwbajumdxx@mcxe6or5p63m>
References: <20251013-rk3588-bgcolor-v2-0-25cc3810ba8c@collabora.com>
 <x33zabb5un2boben6r4qp3vvrgca5s37gmseespdwwbajumdxx@mcxe6or5p63m>
Message-ID: <0e7d78e0-36ee-4115-b224-dbf4bda87ede@collabora.com>

On 10/13/25 11:55 PM, Dmitry Baryshkov wrote:
> On Mon, Oct 13, 2025 at 09:27:17PM +0300, Cristian Ciocaltea wrote:
>> Some display controllers can be hardware-configured to present non-black
>> colors for pixels which are not covered by any plane (or are exposed
>> through transparent regions of higher planes).
>>
>> The first patch of the series introduces the BACKGROUND_COLOR DRM
>> property that can be attached to a CRTC via a dedicated helper function.
>> A 64-bit ARGB color value format is also defined and can be manipulated
>> with the help of a few utility macros.
> 
> 
> Please provide IGT tests. I'd at least check that using the
> BACKGROUND_COLOR results in the same CRC as then one when there is a
> plane covering the whole screen.

Done:

https://lore.kernel.org/all/20251110-crtc-bgcolor-v1-1-28669b692970 at collabora.com/

> Additional note. I see a value in having the CRTC property for the
> background colour. However it might be more flexible to reuse old
> proposal for solid fill planes ([1]) and instead implement the lowest
> Z-order plane supporting only solid fill colour as an image source.

Thanks for pointing this out.  Will keep it in mind as for now there is no
(immediate) plan to consider the alternative(s).


From dsimic at manjaro.org  Mon Nov 10 06:29:15 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Mon, 10 Nov 2025 15:29:15 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH 2/2] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= Make eeprom read-only for Radxa ROCK 5A
In-Reply-To: <51135107D357A73A+50c2300d-7cc0-4f0d-99e7-8b67c0e43dff@radxa.com>
References: <20251110035455.839863-1-naoki@radxa.com>
 <20251110035455.839863-2-naoki@radxa.com>
 <36843804-433a-5c0c-4961-451b44d70bc4@manjaro.org>
 <38861A00B4F4BA62+e3221913-43e5-4335-9aaf-9b9eed5834ac@radxa.com>
 <65f17890-c052-f303-4731-f882946df1f1@manjaro.org> <51135107D357A73A+50c2300d-7cc0-4f0d-99e7-8b67c0e43dff@radxa.com>
Message-ID: <4135cb30-25f0-b202-765c-7343e38e10ac@manjaro.org>

Hello Naoki,

On Monday, November 10, 2025 09:03 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> On 11/10/25 16:38, Dragan Simic wrote:
> > On Monday, November 10, 2025 08:05 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> >> arm64: dts: rockchip: Make eeprom read-only for Radxa ROCK 3C/5A/5C
> >>
> >> Make the EEPROM[1][2][3] read-only. Board-specific data written to the
> >> EEPROM at the factory includes, but is not limited to, the SKU (~
> >> product name), BOM version (~ board version), and MAC address.
> > 
> > Thanks for the improvements!  I'd just suggest that the opening
> > sentence above is rewritten like this:
> > 
> >    Make the BL24C16 EEPROM chips found on Radxa ROCK 3C, 5A and
> >    5C SBCs [1][2][3] read-only, because they contain factory-
> >    programmed data that isn't supposed to be modified by the end
> >    users.
> > 
> > This would also be perfect timing for Radxa to officially release
> > the layout of the board-specific data that goes into these EPROM
> > chips, so the data can actually be used.
> 
>   https://github.com/radxa/u-boot/blob/next-dev-v2024.10/drivers/misc/radxa-i2c-eeprom.c
> 
> The actual data in the EEPROMs of my boards has some content 
> inconsistencies with the code descriptions, but the format is 
> consistent. The SKU, BOM, and MAC mentioned previously should be available.

I see, thanks.  I'm wondering could U-Boot's drivers/misc/nvmem.c be
used instead.  It seems like the driver linked above includes quite
a lot of code that's already present elsewhere in U-Boot.



From robh at kernel.org  Mon Nov 10 06:34:36 2025
From: robh at kernel.org (Rob Herring (Arm))
Date: Mon, 10 Nov 2025 08:34:36 -0600
Subject: [RFC PATCH] arm64: dts: rockchip: Fix microSD card detect for
 Radxa ROCK 5 ITX
In-Reply-To: <20251110030036.825150-1-naoki@radxa.com>
References: <20251110030036.825150-1-naoki@radxa.com>
Message-ID: <176278493435.154671.16126556415107681599.robh@kernel.org>


On Mon, 10 Nov 2025 03:00:36 +0000, FUKAUMI Naoki wrote:
> Due to the discussion about cd-gpios and sdmmmc_det pin
> functionality[1], it would be better to use cd-gpios for now.
> 
> [1] https://lore.kernel.org/linux-rockchip/20240912152538.1.I858c2a0bf83606c8b59ba1ab6944978a398d2ac5 at changeid/T/#u
> 
> Fixes: 31390eb8ffbf2 ("arm64: dts: rockchip: add ROCK 5 ITX board")
> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> ---
>  arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts | 9 ++++++++-
>  1 file changed, 8 insertions(+), 1 deletion(-)
> 


My bot found new DTB warnings on the .dts files added or changed in this
series.

Some warnings may be from an existing SoC .dtsi. Or perhaps the warnings
are fixed by another series. Ultimately, it is up to the platform
maintainer whether these warnings are acceptable or not. No need to reply
unless the platform maintainer has comments.

If you already ran DT checks and didn't see these error(s), then
make sure dt-schema is up to date:

  pip3 install dtschema --upgrade


This patch series was applied (using b4) to base:
 Base: attempting to guess base-commit...
 Base: tags/next-20251107 (exact match)
 Base: tags/next-20251107 (use --merge-base to override)

If this is not the correct base, please add 'base-commit' tag
(or use b4 which does this automatically)

New warnings running 'make CHECK_DTBS=y for arch/arm64/boot/dts/rockchip/' for 20251110030036.825150-1-naoki at radxa.com:

arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dtb: mmc: sdmmc-det-gpio: {'rockchip,pins': [[0, 4, 0, 270]], 'phandle': 145} is not of type 'array'
	from schema $id: http://devicetree.org/schemas/gpio/gpio-consumer.yaml







From dsimic at manjaro.org  Mon Nov 10 06:37:42 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Mon, 10 Nov 2025 15:37:42 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH 2/2] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= Make eeprom read-only for Radxa ROCK 5A
In-Reply-To: <8934442FCE2020A5+855829eb-e783-4aa5-b4a1-13b0a519c46d@radxa.com>
References: <20251110035455.839863-1-naoki@radxa.com>
 <20251110035455.839863-2-naoki@radxa.com>
 <36843804-433a-5c0c-4961-451b44d70bc4@manjaro.org>
 <38861A00B4F4BA62+e3221913-43e5-4335-9aaf-9b9eed5834ac@radxa.com>
 <65f17890-c052-f303-4731-f882946df1f1@manjaro.org> <8934442FCE2020A5+855829eb-e783-4aa5-b4a1-13b0a519c46d@radxa.com>
Message-ID: <06218e17-0bbc-9606-46b4-9a50d1177170@manjaro.org>

On Monday, November 10, 2025 10:44 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> On 11/10/25 16:38, Dragan Simic wrote:
> (snip)>>> Additionally, it would make sense to squash this patch and your
> >>> other patch that addresses the ROCK 5C together.  They're very
> >>> similar and having them together in a single commit might actually
> >>> help the people browsing the repository understand it better.
> >>
> >> I'll drop eeprom patch from ROCK 5C v7 patch series, and squash eeprom
> >> patches for ROCK 3C/5A/5C.
> > 
> > Thanks!
> 
> I'm preparing a patch series for Radxa ROCK 5A and I just remembered 
> that the eeprom node in 5a.dts is totally incorrect. The eeprom is on 
> i2c0, not on i2c2.
> 
> I'm planning to include this eeprom fix as a part of the patch series 
> for 5A.

You're right, and I managed to miss that during my review. :/

It would be good if you'd prepare and send a separate, two-patch
series with just the I2C bus fix for the ROCK 5A and the squashed
patch that makes the EEPROMs read-only on three boards.  Reviewing
and accepting large changes split into smaller portions is always
easier.



From naoki at radxa.com  Mon Nov 10 06:47:05 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Mon, 10 Nov 2025 23:47:05 +0900
Subject: [PATCH 2/2] arm64: dts: rockchip: Make eeprom read-only for Radxa
 ROCK 5A
In-Reply-To: <06218e17-0bbc-9606-46b4-9a50d1177170@manjaro.org>
References: <20251110035455.839863-1-naoki@radxa.com>
 <20251110035455.839863-2-naoki@radxa.com>
 <36843804-433a-5c0c-4961-451b44d70bc4@manjaro.org>
 <38861A00B4F4BA62+e3221913-43e5-4335-9aaf-9b9eed5834ac@radxa.com>
 <65f17890-c052-f303-4731-f882946df1f1@manjaro.org>
 <8934442FCE2020A5+855829eb-e783-4aa5-b4a1-13b0a519c46d@radxa.com>
 <06218e17-0bbc-9606-46b4-9a50d1177170@manjaro.org>
Message-ID: <8FF67CE920D32716+348efd12-16df-48aa-880c-61805f0ffe15@radxa.com>

Hi Dragan,

On 11/10/25 23:37, Dragan Simic wrote:
> On Monday, November 10, 2025 10:44 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
>> On 11/10/25 16:38, Dragan Simic wrote:
>> (snip)>>> Additionally, it would make sense to squash this patch and your
>>>>> other patch that addresses the ROCK 5C together.  They're very
>>>>> similar and having them together in a single commit might actually
>>>>> help the people browsing the repository understand it better.
>>>>
>>>> I'll drop eeprom patch from ROCK 5C v7 patch series, and squash eeprom
>>>> patches for ROCK 3C/5A/5C.
>>>
>>> Thanks!
>>
>> I'm preparing a patch series for Radxa ROCK 5A and I just remembered
>> that the eeprom node in 5a.dts is totally incorrect. The eeprom is on
>> i2c0, not on i2c2.
>>
>> I'm planning to include this eeprom fix as a part of the patch series
>> for 5A.
> 
> You're right, and I managed to miss that during my review. :/
> 
> It would be good if you'd prepare and send a separate, two-patch
> series with just the I2C bus fix for the ROCK 5A and the squashed
> patch that makes the EEPROMs read-only on three boards.  Reviewing
> and accepting large changes split into smaller portions is always
> easier.

I see. I'll do it first.

Thank you very much for your advice!

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.



From naoki at radxa.com  Mon Nov 10 07:21:20 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Tue, 11 Nov 2025 00:21:20 +0900
Subject: [RESEND] Re: [PATCH] PCI: dw-rockchip: Skip waiting for link up
In-Reply-To: <aRHdeVCY3rRmxe80@ryzen>
References: <aQ9FWEuW47L8YOxC@ryzen>
 <55EB0E5F655F3AFC+136b89fd-98d4-42af-a99d-a0bb05cc93f3@radxa.com>
 <aRCI5kG16_1erMME@ryzen>
 <F8B2B6FA2884D69A+b7da13f2-0ffb-4308-b1ba-0549bc461be8@radxa.com>
 <780a4209-f89f-43a9-9364-331d3b77e61e@rock-chips.com>
 <4487DA40249CC821+19232169-a096-4737-bc6a-5cec9592d65f@radxa.com>
 <363d6b4d-c999-43d4-866e-880ef7d0dec3@rock-chips.com>
 <0C31787C387488ED+fd39bfe6-0844-4a87-bf48-675dd6d6a2df@radxa.com>
 <dc932773-af5b-4af7-a0d0-8cc72dfbd3c7@rock-chips.com>
 <aRHb4S40a7ZUDop1@ryzen> <aRHdeVCY3rRmxe80@ryzen>
Message-ID: <7A613E8E5A3767C6+84d31db2-074e-49aa-8e82-bfb78632d2fa@radxa.com>

Hi Shawn, Mani, Niklas,

I'm testing your patches on ROCK 5A/5C, but the behavior is 
inconsistent. Sometimes it works, sometimes it doesn't, and sometimes I 
get an oops. I'm a bit confused, so I'll try again tomorrow.

BTW, do you have any idea about this oops?

[    1.680251] Unable to handle kernel NULL pointer dereference at 
virtual address 0000000000000080
[    1.681039] Mem abort info:
[    1.681294]   ESR = 0x0000000096000004
[    1.681627]   EC = 0x25: DABT (current EL), IL = 32 bits
[    1.682101]   SET = 0, FnV = 0
[    1.682382]   EA = 0, S1PTW = 0
[    1.682662]   FSC = 0x04: level 0 translation fault
[    1.683119] Data abort info:
[    1.683381]   ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
[    1.683869]   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
[    1.684324]   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[    1.684798] user pgtable: 4k pages, 48-bit VAs, pgdp=000000005630d000
[    1.685374] [0000000000000080] pgd=0000000000000000, p4d=0000000000000000
[    1.685983] Internal error: Oops: 0000000096000004 [#1]  SMP
[    1.686483] Modules linked in: phy_rockchip_usbdp typec 
phy_rockchip_naneng_combphy phy_rockchip_samsung_hdptx dwmac_rk 
stmmac_platform stmmac pcs_xpcs rockchipdrm dw_hdmi_qp analogix_dp 
dw_hdmi dw_mipi_dsi drm_dp_aux_bus drm_display_helper cec drm_client_lib 
drm_dma_helper drm_kms_helper drm backlight
[    1.688881] CPU: 0 UID: 0 PID: 171 Comm: irq/87-pcie-sys Tainted: G 
      W           6.18.0-rc5-dirty #2 PREEMPT
[    1.689801] Tainted: [W]=WARN
[    1.690066] Hardware name: radxa Radxa ROCK 5C/Radxa ROCK 5C, BIOS 
2025.10-00012-g0c3aff620204-dirty 10/01/2025
[    1.690952] pstate: 60400009 (nZCv daif +PAN -UAO -TCO -DIT -SSBS 
BTYPE=--)
[    1.691567] pc : of_pci_add_properties+0x284/0x4c4
[    1.692000] lr : of_pci_add_properties+0x264/0x4c4
[    1.692426] sp : ffff8000813fbbf0
[    1.692722] x29: ffff8000813fbc40 x28: ffffcfffe906b3b8 x27: 
ffffcfffeb95b1d0
[    1.693358] x26: ffff000001236980 x25: ffff00007452ceac x24: 
ffff000008844600
[    1.693993] x23: ffff00007452ce00 x22: ffff0000073b3a00 x21: 
ffff00000045db10
[    1.694628] x20: ffff00000057c000 x19: 0000000000000000 x18: 
00000000ffffffff
[    1.695264] x17: 0000000000000000 x16: 0000000000000000 x15: 
ffff8000813fba70
[    1.695898] x14: ffff000000c355b8 x13: ffff000000c355b6 x12: 
0000000000000000
[    1.696533] x11: 00333634353d4d55 x10: 000000000000002c x9 : 
0000000000000000
[    1.697168] x8 : ffff00007479c800 x7 : 0000000000000000 x6 : 
0000000000696370
[    1.697803] x5 : 0000000000000000 x4 : 0000000000000002 x3 : 
ffff8000813fbc20
[    1.698439] x2 : ffffcfffeabc6ef0 x1 : ffff0000073b3a00 x0 : 
0000000000000000
[    1.699074] Call trace:
[    1.699293]  of_pci_add_properties+0x284/0x4c4 (P)
[    1.699723]  of_pci_make_dev_node+0xd8/0x150
[    1.700109]  pci_bus_add_device+0x138/0x168
[    1.700485]  pci_bus_add_devices+0x3c/0x88
[    1.700853]  pci_bus_add_devices+0x68/0x88
[    1.701220]  pci_rescan_bus+0x30/0x44
[    1.701551]  rockchip_pcie_rc_sys_irq_thread+0xb8/0xd0
[    1.702010]  irq_thread_fn+0x2c/0xa8
[    1.702333]  irq_thread+0x168/0x320
[    1.702648]  kthread+0x12c/0x204
[    1.702941]  ret_from_fork+0x10/0x20
[    1.703267] Code: aa1603e1 f000abc2 d2800044 913bc042 (f94040a0)

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

On 11/10/25 21:41, Niklas Cassel wrote:
> On Mon, Nov 10, 2025 at 01:34:41PM +0100, Niklas Cassel wrote:
>> @@ -672,15 +705,13 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
>>   	if (!pp->use_linkup_irq)
>>   		/* Ignore errors, the link may come up later */
>>   		dw_pcie_wait_for_link(pci);
>> -
>> -	ret = pci_host_probe(bridge);
>> -	if (ret)
>> -		goto err_stop_link;
>> -
>> -	if (pp->ops->post_init)
>> -		pp->ops->post_init(pp);
>> -
>> -	dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
>> +	else
>> +		/*
>> +		 * For platforms with Link Up IRQ, initial scan will be done
>> +		 * on first Link Up IRQ.
>> +		 */
>> +		if (dw_pcie_host_initial_scan(pp))
>> +			goto err_stop_link;
> 
> Oops.. this condition was inverted, what I meant was:
> 
> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> index e92513c5bda5..0e04c1d6d260 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -565,6 +565,39 @@ static int dw_pcie_host_get_resources(struct dw_pcie_rp *pp)
>   	return 0;
>   }
>   
> +static int dw_pcie_host_initial_scan(struct dw_pcie_rp *pp)
> +{
> +	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> +	struct pci_host_bridge *bridge = pp->bridge;
> +	int ret;
> +
> +	ret = pci_host_probe(bridge);
> +	if (ret)
> +		return ret;
> +
> +	if (pp->ops->post_init)
> +		pp->ops->post_init(pp);
> +
> +	dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
> +
> +	return 0;
> +}
> +
> +void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp)
> +{
> +	if (!pp->initial_linkup_irq_done) {
> +		if (dw_pcie_host_initial_scan(pp)) {
> +			//TODO: cleanup
> +		}
> +		pp->initial_linkup_irq_done = true;
> +	} else {
> +		/* Rescan the bus to enumerate endpoint devices */
> +		pci_lock_rescan_remove();
> +		pci_rescan_bus(pp->bridge->bus);
> +		pci_unlock_rescan_remove();
> +	}
> +}
> +
>   int dw_pcie_host_init(struct dw_pcie_rp *pp)
>   {
>   	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> @@ -669,18 +702,17 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
>   	 * If there is no Link Up IRQ, we should not bypass the delay
>   	 * because that would require users to manually rescan for devices.
>   	 */
> -	if (!pp->use_linkup_irq)
> +	if (!pp->use_linkup_irq) {
>   		/* Ignore errors, the link may come up later */
>   		dw_pcie_wait_for_link(pci);
>   
> -	ret = pci_host_probe(bridge);
> -	if (ret)
> -		goto err_stop_link;
> -
> -	if (pp->ops->post_init)
> -		pp->ops->post_init(pp);
> -
> -	dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
> +		/*
> +		 * For platforms with Link Up IRQ, initial scan will be done
> +		 * on first Link Up IRQ.
> +		 */
> +		if (dw_pcie_host_initial_scan(pp))
> +			goto err_stop_link;
> +	}
>   
>   	return 0;
>   
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> index e995f692a1ec..a31bd93490dc 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -427,6 +427,7 @@ struct dw_pcie_rp {
>   	int			msg_atu_index;
>   	struct resource		*msg_res;
>   	bool			use_linkup_irq;
> +	bool			initial_linkup_irq_done;
>   	struct pci_eq_presets	presets;
>   	struct pci_config_window *cfg;
>   	bool			ecam_enabled;
> @@ -807,6 +808,7 @@ void dw_pcie_msi_init(struct dw_pcie_rp *pp);
>   int dw_pcie_msi_host_init(struct dw_pcie_rp *pp);
>   void dw_pcie_free_msi(struct dw_pcie_rp *pp);
>   int dw_pcie_setup_rc(struct dw_pcie_rp *pp);
> +void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp);
>   int dw_pcie_host_init(struct dw_pcie_rp *pp);
>   void dw_pcie_host_deinit(struct dw_pcie_rp *pp);
>   int dw_pcie_allocate_domains(struct dw_pcie_rp *pp);
> @@ -844,6 +846,9 @@ static inline int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
>   	return 0;
>   }
>   
> +static inline void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp)
> +{ }
> +
>   static inline int dw_pcie_host_init(struct dw_pcie_rp *pp)
>   {
>   	return 0;
> diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> index 8a882dcd1e4e..042e5845bdd6 100644
> --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> @@ -468,10 +468,7 @@ static irqreturn_t rockchip_pcie_rc_sys_irq_thread(int irq, void *arg)
>   		if (rockchip_pcie_link_up(pci)) {
>   			msleep(PCIE_RESET_CONFIG_WAIT_MS);
>   			dev_dbg(dev, "Received Link up event. Starting enumeration!\n");
> -			/* Rescan the bus to enumerate endpoint devices */
> -			pci_lock_rescan_remove();
> -			pci_rescan_bus(pp->bridge->bus);
> -			pci_unlock_rescan_remove();
> +			dw_pcie_handle_link_up_irq(pp);
>   		}
>   	}
>   
> 



From mani at kernel.org  Mon Nov 10 07:37:58 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Mon, 10 Nov 2025 21:07:58 +0530
Subject: [RESEND] Re: [PATCH] PCI: dw-rockchip: Skip waiting for link up
In-Reply-To: <7A613E8E5A3767C6+84d31db2-074e-49aa-8e82-bfb78632d2fa@radxa.com>
References: <aRCI5kG16_1erMME@ryzen>
 <F8B2B6FA2884D69A+b7da13f2-0ffb-4308-b1ba-0549bc461be8@radxa.com>
 <780a4209-f89f-43a9-9364-331d3b77e61e@rock-chips.com>
 <4487DA40249CC821+19232169-a096-4737-bc6a-5cec9592d65f@radxa.com>
 <363d6b4d-c999-43d4-866e-880ef7d0dec3@rock-chips.com>
 <0C31787C387488ED+fd39bfe6-0844-4a87-bf48-675dd6d6a2df@radxa.com>
 <dc932773-af5b-4af7-a0d0-8cc72dfbd3c7@rock-chips.com>
 <aRHb4S40a7ZUDop1@ryzen>
 <aRHdeVCY3rRmxe80@ryzen>
 <7A613E8E5A3767C6+84d31db2-074e-49aa-8e82-bfb78632d2fa@radxa.com>
Message-ID: <wnrtofgggs5d7y42ps4ujp3h54nuiszfkmoor6hdz2vlpbvkys@d4nre55j6nam>

On Tue, Nov 11, 2025 at 12:21:20AM +0900, FUKAUMI Naoki wrote:
> Hi Shawn, Mani, Niklas,
> 
> I'm testing your patches on ROCK 5A/5C, but the behavior is inconsistent.
> Sometimes it works, sometimes it doesn't, and sometimes I get an oops. I'm a
> bit confused, so I'll try again tomorrow.
> 
> BTW, do you have any idea about this oops?
> 

I don't know why this is happening, but looks like it is coming from
CONFIG_PCI_DYNAMIC_OF_NODES. You can unset it and give it a try.

- Mani

> [    1.680251] Unable to handle kernel NULL pointer dereference at virtual
> address 0000000000000080
> [    1.681039] Mem abort info:
> [    1.681294]   ESR = 0x0000000096000004
> [    1.681627]   EC = 0x25: DABT (current EL), IL = 32 bits
> [    1.682101]   SET = 0, FnV = 0
> [    1.682382]   EA = 0, S1PTW = 0
> [    1.682662]   FSC = 0x04: level 0 translation fault
> [    1.683119] Data abort info:
> [    1.683381]   ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
> [    1.683869]   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
> [    1.684324]   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
> [    1.684798] user pgtable: 4k pages, 48-bit VAs, pgdp=000000005630d000
> [    1.685374] [0000000000000080] pgd=0000000000000000, p4d=0000000000000000
> [    1.685983] Internal error: Oops: 0000000096000004 [#1]  SMP
> [    1.686483] Modules linked in: phy_rockchip_usbdp typec
> phy_rockchip_naneng_combphy phy_rockchip_samsung_hdptx dwmac_rk
> stmmac_platform stmmac pcs_xpcs rockchipdrm dw_hdmi_qp analogix_dp dw_hdmi
> dw_mipi_dsi drm_dp_aux_bus drm_display_helper cec drm_client_lib
> drm_dma_helper drm_kms_helper drm backlight
> [    1.688881] CPU: 0 UID: 0 PID: 171 Comm: irq/87-pcie-sys Tainted: G
> W           6.18.0-rc5-dirty #2 PREEMPT
> [    1.689801] Tainted: [W]=WARN
> [    1.690066] Hardware name: radxa Radxa ROCK 5C/Radxa ROCK 5C, BIOS
> 2025.10-00012-g0c3aff620204-dirty 10/01/2025
> [    1.690952] pstate: 60400009 (nZCv daif +PAN -UAO -TCO -DIT -SSBS
> BTYPE=--)
> [    1.691567] pc : of_pci_add_properties+0x284/0x4c4
> [    1.692000] lr : of_pci_add_properties+0x264/0x4c4
> [    1.692426] sp : ffff8000813fbbf0
> [    1.692722] x29: ffff8000813fbc40 x28: ffffcfffe906b3b8 x27:
> ffffcfffeb95b1d0
> [    1.693358] x26: ffff000001236980 x25: ffff00007452ceac x24:
> ffff000008844600
> [    1.693993] x23: ffff00007452ce00 x22: ffff0000073b3a00 x21:
> ffff00000045db10
> [    1.694628] x20: ffff00000057c000 x19: 0000000000000000 x18:
> 00000000ffffffff
> [    1.695264] x17: 0000000000000000 x16: 0000000000000000 x15:
> ffff8000813fba70
> [    1.695898] x14: ffff000000c355b8 x13: ffff000000c355b6 x12:
> 0000000000000000
> [    1.696533] x11: 00333634353d4d55 x10: 000000000000002c x9 :
> 0000000000000000
> [    1.697168] x8 : ffff00007479c800 x7 : 0000000000000000 x6 :
> 0000000000696370
> [    1.697803] x5 : 0000000000000000 x4 : 0000000000000002 x3 :
> ffff8000813fbc20
> [    1.698439] x2 : ffffcfffeabc6ef0 x1 : ffff0000073b3a00 x0 :
> 0000000000000000
> [    1.699074] Call trace:
> [    1.699293]  of_pci_add_properties+0x284/0x4c4 (P)
> [    1.699723]  of_pci_make_dev_node+0xd8/0x150
> [    1.700109]  pci_bus_add_device+0x138/0x168
> [    1.700485]  pci_bus_add_devices+0x3c/0x88
> [    1.700853]  pci_bus_add_devices+0x68/0x88
> [    1.701220]  pci_rescan_bus+0x30/0x44
> [    1.701551]  rockchip_pcie_rc_sys_irq_thread+0xb8/0xd0
> [    1.702010]  irq_thread_fn+0x2c/0xa8
> [    1.702333]  irq_thread+0x168/0x320
> [    1.702648]  kthread+0x12c/0x204
> [    1.702941]  ret_from_fork+0x10/0x20
> [    1.703267] Code: aa1603e1 f000abc2 d2800044 913bc042 (f94040a0)
> 
> Best regards,
> 
> --
> FUKAUMI Naoki
> Radxa Computer (Shenzhen) Co., Ltd.
> 
> On 11/10/25 21:41, Niklas Cassel wrote:
> > On Mon, Nov 10, 2025 at 01:34:41PM +0100, Niklas Cassel wrote:
> > > @@ -672,15 +705,13 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
> > >   	if (!pp->use_linkup_irq)
> > >   		/* Ignore errors, the link may come up later */
> > >   		dw_pcie_wait_for_link(pci);
> > > -
> > > -	ret = pci_host_probe(bridge);
> > > -	if (ret)
> > > -		goto err_stop_link;
> > > -
> > > -	if (pp->ops->post_init)
> > > -		pp->ops->post_init(pp);
> > > -
> > > -	dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
> > > +	else
> > > +		/*
> > > +		 * For platforms with Link Up IRQ, initial scan will be done
> > > +		 * on first Link Up IRQ.
> > > +		 */
> > > +		if (dw_pcie_host_initial_scan(pp))
> > > +			goto err_stop_link;
> > 
> > Oops.. this condition was inverted, what I meant was:
> > 
> > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> > index e92513c5bda5..0e04c1d6d260 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > @@ -565,6 +565,39 @@ static int dw_pcie_host_get_resources(struct dw_pcie_rp *pp)
> >   	return 0;
> >   }
> > +static int dw_pcie_host_initial_scan(struct dw_pcie_rp *pp)
> > +{
> > +	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > +	struct pci_host_bridge *bridge = pp->bridge;
> > +	int ret;
> > +
> > +	ret = pci_host_probe(bridge);
> > +	if (ret)
> > +		return ret;
> > +
> > +	if (pp->ops->post_init)
> > +		pp->ops->post_init(pp);
> > +
> > +	dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
> > +
> > +	return 0;
> > +}
> > +
> > +void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp)
> > +{
> > +	if (!pp->initial_linkup_irq_done) {
> > +		if (dw_pcie_host_initial_scan(pp)) {
> > +			//TODO: cleanup
> > +		}
> > +		pp->initial_linkup_irq_done = true;
> > +	} else {
> > +		/* Rescan the bus to enumerate endpoint devices */
> > +		pci_lock_rescan_remove();
> > +		pci_rescan_bus(pp->bridge->bus);
> > +		pci_unlock_rescan_remove();
> > +	}
> > +}
> > +
> >   int dw_pcie_host_init(struct dw_pcie_rp *pp)
> >   {
> >   	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > @@ -669,18 +702,17 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
> >   	 * If there is no Link Up IRQ, we should not bypass the delay
> >   	 * because that would require users to manually rescan for devices.
> >   	 */
> > -	if (!pp->use_linkup_irq)
> > +	if (!pp->use_linkup_irq) {
> >   		/* Ignore errors, the link may come up later */
> >   		dw_pcie_wait_for_link(pci);
> > -	ret = pci_host_probe(bridge);
> > -	if (ret)
> > -		goto err_stop_link;
> > -
> > -	if (pp->ops->post_init)
> > -		pp->ops->post_init(pp);
> > -
> > -	dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
> > +		/*
> > +		 * For platforms with Link Up IRQ, initial scan will be done
> > +		 * on first Link Up IRQ.
> > +		 */
> > +		if (dw_pcie_host_initial_scan(pp))
> > +			goto err_stop_link;
> > +	}
> >   	return 0;
> > diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> > index e995f692a1ec..a31bd93490dc 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware.h
> > +++ b/drivers/pci/controller/dwc/pcie-designware.h
> > @@ -427,6 +427,7 @@ struct dw_pcie_rp {
> >   	int			msg_atu_index;
> >   	struct resource		*msg_res;
> >   	bool			use_linkup_irq;
> > +	bool			initial_linkup_irq_done;
> >   	struct pci_eq_presets	presets;
> >   	struct pci_config_window *cfg;
> >   	bool			ecam_enabled;
> > @@ -807,6 +808,7 @@ void dw_pcie_msi_init(struct dw_pcie_rp *pp);
> >   int dw_pcie_msi_host_init(struct dw_pcie_rp *pp);
> >   void dw_pcie_free_msi(struct dw_pcie_rp *pp);
> >   int dw_pcie_setup_rc(struct dw_pcie_rp *pp);
> > +void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp);
> >   int dw_pcie_host_init(struct dw_pcie_rp *pp);
> >   void dw_pcie_host_deinit(struct dw_pcie_rp *pp);
> >   int dw_pcie_allocate_domains(struct dw_pcie_rp *pp);
> > @@ -844,6 +846,9 @@ static inline int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
> >   	return 0;
> >   }
> > +static inline void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp)
> > +{ }
> > +
> >   static inline int dw_pcie_host_init(struct dw_pcie_rp *pp)
> >   {
> >   	return 0;
> > diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> > index 8a882dcd1e4e..042e5845bdd6 100644
> > --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> > +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> > @@ -468,10 +468,7 @@ static irqreturn_t rockchip_pcie_rc_sys_irq_thread(int irq, void *arg)
> >   		if (rockchip_pcie_link_up(pci)) {
> >   			msleep(PCIE_RESET_CONFIG_WAIT_MS);
> >   			dev_dbg(dev, "Received Link up event. Starting enumeration!\n");
> > -			/* Rescan the bus to enumerate endpoint devices */
> > -			pci_lock_rescan_remove();
> > -			pci_rescan_bus(pp->bridge->bus);
> > -			pci_unlock_rescan_remove();
> > +			dw_pcie_handle_link_up_irq(pp);
> >   		}
> >   	}
> > 
> 

-- 
????????? ????????


From mani at kernel.org  Mon Nov 10 07:53:02 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Mon, 10 Nov 2025 21:23:02 +0530
Subject: [RESEND] Re: [PATCH] PCI: dw-rockchip: Skip waiting for link up
In-Reply-To: <aRHb4S40a7ZUDop1@ryzen>
References: <aQ9FWEuW47L8YOxC@ryzen>
 <55EB0E5F655F3AFC+136b89fd-98d4-42af-a99d-a0bb05cc93f3@radxa.com>
 <aRCI5kG16_1erMME@ryzen>
 <F8B2B6FA2884D69A+b7da13f2-0ffb-4308-b1ba-0549bc461be8@radxa.com>
 <780a4209-f89f-43a9-9364-331d3b77e61e@rock-chips.com>
 <4487DA40249CC821+19232169-a096-4737-bc6a-5cec9592d65f@radxa.com>
 <363d6b4d-c999-43d4-866e-880ef7d0dec3@rock-chips.com>
 <0C31787C387488ED+fd39bfe6-0844-4a87-bf48-675dd6d6a2df@radxa.com>
 <dc932773-af5b-4af7-a0d0-8cc72dfbd3c7@rock-chips.com>
 <aRHb4S40a7ZUDop1@ryzen>
Message-ID: <2n3wamm3txxc6xbmvf3nnrvaqpgsck3w4a6omxnhex3mqeujib@2tb4svn5d3z6>

On Mon, Nov 10, 2025 at 01:34:41PM +0100, Niklas Cassel wrote:
> On Mon, Nov 10, 2025 at 06:15:33PM +0800, Shawn Lin wrote:
> > > 
> > > Could you try PCIe 2.0 slot on your board?
> > 
> > I did, it doesn't work on PCIe 2.0 slot. From the PA, I could see
> > the link is still in training during pci_host_probe() is called.
> > Add some delay before pci_rescan_bus() in pcie-dw-rockchip doesn't
> > help. But the below change should work as we delayed pci_host_probe().
> > 
> > --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> > +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> > @@ -236,6 +236,8 @@ static int rockchip_pcie_start_link(struct dw_pcie *pci)
> >         msleep(PCIE_T_PVPERL_MS);
> >         gpiod_set_value_cansleep(rockchip->rst_gpio, 1);
> > 
> > +       msleep(50);
> > +
> >         return 0;
> > 
> > Otherwise we got:
> > 
> > [    0.841518] pci_bus 0003:33: busn_res: can not insert [bus 33-31] under
> > [bus 32-31] (conflicts with (null) [bus 32-31])
> > [    0.842596] pci_bus 0003:33: busn_res: [bus 33-31] end is updated to 33
> > [    0.843184] pci_bus 0003:33: busn_res: can not insert [bus 33] under [bus
> > 32-31] (conflicts with (null) [bus 32-31])
> > [    0.844120] pci 0003:32:00.0: devices behind bridge are unusable because
> > [bus 33] cannot be assigned for them
> > [    0.845229] pci_bus 0003:34: busn_res: can not insert [bus 34-31] under
> > [bus 32-31] (conflicts with (null) [bus 32-31])
> > [    0.846309] pci_bus 0003:34: busn_res: [bus 34-31] end is updated to 34
> > [    0.846898] pci_bus 0003:34: busn_res: can not insert [bus 34] under [bus
> > 32-31] (conflicts with (null) [bus 32-31])
> > [    0.847833] pci 0003:32:06.0: devices behind bridge are unusable because
> > [bus 34] cannot be assigned for them
> > [    0.848923] pci_bus 0003:35: busn_res: can not insert [bus 35-31] under
> > [bus 32-31] (conflicts with (null) [bus 32-31])
> > [    0.850014] pci_bus 0003:35: busn_res: [bus 35-31] end is updated to 35
> > [    0.850605] pci_bus 0003:35: busn_res: can not insert [bus 35] under [bus
> > 32-31] (conflicts with (null) [bus 32-31])
> > [    0.851540] pci 0003:32:0e.0: devices behind bridge are unusable because
> > [bus 35] cannot be assigned for them
> > [    0.852424] pci_bus 0003:32: busn_res: [bus 32-31] end is updated to 35
> > [    0.853028] pci_bus 0003:32: busn_res: can not insert [bus 32-35] under
> > [bus 31] (conflicts with (null) [bus 31])
> > [    0.853184] hub 3-0:1.0: USB hub found
> > [    0.853931] pci 0003:31:00.0: devices behind bridge are unusable because
> > [bus 32-35] cannot be assigned for them
> > [    0.854262] hub 3-0:1.0: 1 port detected
> > [    0.855144] pcieport 0003:30:00.0: bridge has subordinate 31 but max busn
> > 35
> > [    0.855722] hub 4-0:1.0: USB hub found
> > [    0.856109] pci 0003:32:00.0: PCI bridge to [bus 33]
> > [    0.856939] pci 0003:32:06.0: PCI bridge to [bus 34]
> > [    0.857133] hub 4-0:1.0: 1 port detected
> > [    0.857430] pci 0003:32:0e.0: PCI bridge to [bus 35]
> > [    0.858236] pci 0003:31:00.0: PCI bridge to [bus 32-35]
> 
> Mani,
> 
> while I see the idea behind your suggested hack:
>  
> +       if (pdev->vendor == 0x1d87 && pdev->device == 0x3588) {
> +               pdev->is_hotplug_bridge = pdev->is_pciehp = 1;
> +               return;
> +       }
> 
> 
> Considering what Shawn says, that the switch gets enumerated properly
> if we simply add a msleep() in ->start_link(), which will be called
> by dw_pcie_host_init() before pci_host_probe() is called...
> 

Yes, that delay probably gives enough time for the link up IRQ to kick in before
the initial bus scan happens.

> ...we already have a delay in the link up IRQ handler, before calling
> pci_rescan_bus().
> 

That delay won't help in this case.

> So, I think that the problem is that we are unconditionally calling
> pci_host_probe() in dw_pcie_host_init(), even for platforms that have
> a link-up IRQ.
> 
> 
> I think a better solution would be something like:
> 

This solution will work as long as the PCIe device is powered ON before
start_link(). For CEM and M.2 Key M connectors, the host controller can power
manage the components. But for other specifications/keys requiring custom power
management, a separate driver would be needed.

That's why I suggested using pwrctrl framework as it can satisfy both usecases.
However, as I said, it needs a bit of rework and I'm close to submitting it.

But until that gets merged, either we need to revert your link up IRQ change or
have the below patch. IMO, the revert seems simple.

- Mani

> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> index e92513c5bda5..42d987ddab7d 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -565,6 +565,39 @@ static int dw_pcie_host_get_resources(struct dw_pcie_rp *pp)
>  	return 0;
>  }
>  
> +static int dw_pcie_host_initial_scan(struct dw_pcie_rp *pp)
> +{
> +	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> +	struct pci_host_bridge *bridge = pp->bridge;
> +	int ret;
> +
> +	ret = pci_host_probe(bridge);
> +	if (ret)
> +		return ret;
> +
> +	if (pp->ops->post_init)
> +		pp->ops->post_init(pp);
> +
> +	dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
> +
> +	return 0;
> +}
> +
> +void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp)
> +{
> +	if (!pp->initial_linkup_irq_done) {
> +		if (dw_pcie_host_initial_scan(pp)) {
> +			//TODO: cleanup
> +		}
> +		pp->initial_linkup_irq_done = true;
> +	} else {
> +		/* Rescan the bus to enumerate endpoint devices */
> +		pci_lock_rescan_remove();
> +		pci_rescan_bus(pp->bridge->bus);
> +		pci_unlock_rescan_remove();
> +	}
> +}
> +
>  int dw_pcie_host_init(struct dw_pcie_rp *pp)
>  {
>  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> @@ -672,15 +705,13 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
>  	if (!pp->use_linkup_irq)
>  		/* Ignore errors, the link may come up later */
>  		dw_pcie_wait_for_link(pci);
> -
> -	ret = pci_host_probe(bridge);
> -	if (ret)
> -		goto err_stop_link;
> -
> -	if (pp->ops->post_init)
> -		pp->ops->post_init(pp);
> -
> -	dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
> +	else
> +		/*
> +		 * For platforms with Link Up IRQ, initial scan will be done
> +		 * on first Link Up IRQ.
> +		 */
> +		if (dw_pcie_host_initial_scan(pp))
> +			goto err_stop_link;
>  
>  	return 0;
>  
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> index e995f692a1ec..a31bd93490dc 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -427,6 +427,7 @@ struct dw_pcie_rp {
>  	int			msg_atu_index;
>  	struct resource		*msg_res;
>  	bool			use_linkup_irq;
> +	bool			initial_linkup_irq_done;
>  	struct pci_eq_presets	presets;
>  	struct pci_config_window *cfg;
>  	bool			ecam_enabled;
> @@ -807,6 +808,7 @@ void dw_pcie_msi_init(struct dw_pcie_rp *pp);
>  int dw_pcie_msi_host_init(struct dw_pcie_rp *pp);
>  void dw_pcie_free_msi(struct dw_pcie_rp *pp);
>  int dw_pcie_setup_rc(struct dw_pcie_rp *pp);
> +void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp);
>  int dw_pcie_host_init(struct dw_pcie_rp *pp);
>  void dw_pcie_host_deinit(struct dw_pcie_rp *pp);
>  int dw_pcie_allocate_domains(struct dw_pcie_rp *pp);
> @@ -844,6 +846,9 @@ static inline int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
>  	return 0;
>  }
>  
> +static inline void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp)
> +{ }
> +
>  static inline int dw_pcie_host_init(struct dw_pcie_rp *pp)
>  {
>  	return 0;
> diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> index 8a882dcd1e4e..042e5845bdd6 100644
> --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> @@ -468,10 +468,7 @@ static irqreturn_t rockchip_pcie_rc_sys_irq_thread(int irq, void *arg)
>  		if (rockchip_pcie_link_up(pci)) {
>  			msleep(PCIE_RESET_CONFIG_WAIT_MS);
>  			dev_dbg(dev, "Received Link up event. Starting enumeration!\n");
> -			/* Rescan the bus to enumerate endpoint devices */
> -			pci_lock_rescan_remove();
> -			pci_rescan_bus(pp->bridge->bus);
> -			pci_unlock_rescan_remove();
> +			dw_pcie_handle_link_up_irq(pp);
>  		}
>  	}
>  
> 
> 
> 
> 
> What do you think?
> 
> 
> 
> Kind regards,
> Niklas

-- 
????????? ????????


From adrian.hunter at intel.com  Mon Nov 10 08:50:33 2025
From: adrian.hunter at intel.com (Adrian Hunter)
Date: Mon, 10 Nov 2025 18:50:33 +0200
Subject: [PATCH v2 1/2] mmc: sdhci-of-dwcmshc: Add command queue support
 for rockchip SOCs
In-Reply-To: <hjxwedwtwksog67mz4unm4jita2q5vvp4vkdrtpznc6mllz7q4@7a7nn3c5l7fv>
References: <20251031-rockchip-emmc-cqe-support-v2-0-958171f5edad@collabora.com>
 <20251031-rockchip-emmc-cqe-support-v2-1-958171f5edad@collabora.com>
 <abb4a253-6f4b-4547-a238-db6f60ee3244@intel.com>
 <hjxwedwtwksog67mz4unm4jita2q5vvp4vkdrtpznc6mllz7q4@7a7nn3c5l7fv>
Message-ID: <01949bc9-4873-498b-ac7d-f008393ccc4c@intel.com>

On 10/11/2025 15:43, Sebastian Reichel wrote:
> Hi,
> 
> On Mon, Nov 10, 2025 at 09:58:24AM +0200, Adrian Hunter wrote:
>> On 31/10/2025 17:58, Sebastian Reichel wrote:
>>> This adds CQE support for the Rockchip RK3588 and RK3576 platform. To
>>> be functional, the eMMC device-tree node must have a 'supports-cqe;'
>>> flag property.
>>>
>>> As the RK3576 device-tree has been upstreamed with the 'supports-cqe;'
>>> property set by default, the kernel already tried to use CQE, which
>>> results in system hang during suspend. This fixes the issue.
>>>
>>> Co-developed-by: Yifeng Zhao <yifeng.zhao at rock-chips.com>
>>> Signed-off-by: Yifeng Zhao <yifeng.zhao at rock-chips.com>
>>> Signed-off-by: Sebastian Reichel <sebastian.reichel at collabora.com>
>>
>> One question below, otherwise:
>>
>> Acked-by: Adrian Hunter <adrian.hunter at intel.com>
> 
> Thanks,
> 
> [...]
> 
>>> @@ -687,6 +757,9 @@ static void rk35xx_sdhci_reset(struct sdhci_host *host, u8 mask)
>>>  	}
>>>  
>>>  	sdhci_reset(host, mask);
>>> +
>>> +	/* Enable INTERNAL CLOCK */
>>> +	sdhci_writel(host, MISC_INTCLK_EN | extra, DECMSHC_EMMC_MISC_CON);
>>
>> rk35xx_sdhci_reset() is in sdhci_dwcmshc_rk35xx_ops.
>> sdhci_dwcmshc_rk3576_pdata also uses sdhci_dwcmshc_rk35xx_ops but isn't
>> supporting CQE ops.  Is this change OK for rk3576?
> 
> How did you come to the conclusion, that rk3576 does not support CQE
> ops? Have you read the cover letter? :)

Just saw that sdhci_dwcmshc_rk35xx_pdata has:

	.cqhci_host_ops = &rk35xx_cqhci_ops

but sdhci_dwcmshc_rk3576_pdata does not.  So it uses the
default dwcmshc_cqhci_ops then. Ok.



From duwe at lst.de  Mon Nov 10 10:11:53 2025
From: duwe at lst.de (Torsten Duwe)
Date: Mon, 10 Nov 2025 19:11:53 +0100 (CET)
Subject: [PATCH] devicetree rk3588: enable HDMI audio on Rock 5 ITX
Message-ID: <20251110181153.CC62B6732A@verein.lst.de>

The Rock 5 ITX only needs enablement for 2 nodes in order to send audio
on HDMI1, the connector closer to the 12V barrel jack and farther from
S/PDIF.  It is sufficient to declare the audio injection as okay, and
to activate I2S6.

Note that for the other HDMI output it is not that trivial, as the video
data there originates from the SoC's DisplayPort output DP1 and is only
converted to HDMI in U7 (an RA620).

Signed-off-by: Torsten Duwe <duwe at lst.de>

---
 arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts |    9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/src/arm64/rockchip/rk3588-rock-5-itx.dts b/src/arm64/rockchip/rk3588-rock-5-itx.dts
index bc8140883d..c824727cf4 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
@@ -345,6 +345,10 @@
 	};
 };
 
+&hdmi1_sound {
+	status = "okay";
+};
+
 &hdptxphy1 {
 	status = "okay";
 };
@@ -546,6 +550,11 @@
 	};
 };
 
+/* HDMI1 ("HDMI TX1 8K") audio */
+&i2s6_8ch {
+	status = "okay";
+};
+
 &package_thermal {
 	polling-delay = <1000>;
 


From cassel at kernel.org  Mon Nov 10 11:59:08 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Mon, 10 Nov 2025 20:59:08 +0100
Subject: [RESEND] Re: [PATCH] PCI: dw-rockchip: Skip waiting for link up
In-Reply-To: <2n3wamm3txxc6xbmvf3nnrvaqpgsck3w4a6omxnhex3mqeujib@2tb4svn5d3z6>
References: <55EB0E5F655F3AFC+136b89fd-98d4-42af-a99d-a0bb05cc93f3@radxa.com>
 <aRCI5kG16_1erMME@ryzen>
 <F8B2B6FA2884D69A+b7da13f2-0ffb-4308-b1ba-0549bc461be8@radxa.com>
 <780a4209-f89f-43a9-9364-331d3b77e61e@rock-chips.com>
 <4487DA40249CC821+19232169-a096-4737-bc6a-5cec9592d65f@radxa.com>
 <363d6b4d-c999-43d4-866e-880ef7d0dec3@rock-chips.com>
 <0C31787C387488ED+fd39bfe6-0844-4a87-bf48-675dd6d6a2df@radxa.com>
 <dc932773-af5b-4af7-a0d0-8cc72dfbd3c7@rock-chips.com>
 <aRHb4S40a7ZUDop1@ryzen>
 <2n3wamm3txxc6xbmvf3nnrvaqpgsck3w4a6omxnhex3mqeujib@2tb4svn5d3z6>
Message-ID: <aRJEDEEJr9Ic-RKN@fedora>

On Mon, Nov 10, 2025 at 09:23:02PM +0530, Manivannan Sadhasivam wrote:
> > 
> > Considering what Shawn says, that the switch gets enumerated properly
> > if we simply add a msleep() in ->start_link(), which will be called
> > by dw_pcie_host_init() before pci_host_probe() is called...
> > 
> 
> Yes, that delay probably gives enough time for the link up IRQ to kick in before
> the initial bus scan happens.

I think that the problem is that even for platforms with link up IRQ,
we will always do:
1) dw_pcie_start_link() (if (!dw_pcie_link_up()))
2) pci_host_probe() from dw_pcie_host_init(), this will enumerate the bus
3) pci_rescan_bus() from the Link Up IRQ handler

Thus, in 2, when enumerating the bus, without performing any of the delays
mandated by the PCIe spec, it still seems possible to detect a device (it
must have been really quick to initialize), and to communicate with that
device, however since we have not performed the delays mandated by the spec,
it appears that the device might not yet behave properly.

Hence my suggestion to never call pci_host_probe() in dw_pcie_host_init()
for platforms with Link Up IRQ.

At least for pcie-dw-rockchip.c, we only unmask the Link Up IRQ after
dw_pcie_host_init() has returned, so I think that your theory: that Shawn's
suggested delay causes the Link Up IRQ to kick in before the initial bus
scan, is incorrect. (Since the IRQ should not be able to trigger until
dw_pcie_host_init() has returned.)


> 
> > ...we already have a delay in the link up IRQ handler, before calling
> > pci_rescan_bus().
> > 
> 
> That delay won't help in this case.

Sure, I was just saying that even though Shawn's patch made things work,
it seems incorrect, as we do not want to add "the same delay" that we
already have in the Link Up IRQ. (The delay in the Link Up IRQ should be
the only one.)


> > I think a better solution would be something like:

(snip)

> This solution will work as long as the PCIe device is powered ON before
> start_link(). For CEM and M.2 Key M connectors, the host controller can power
> manage the components. But for other specifications/keys requiring custom power
> management, a separate driver would be needed.
> 
> That's why I suggested using pwrctrl framework as it can satisfy both usecases.
> However, as I said, it needs a bit of rework and I'm close to submitting it.
> 
> But until that gets merged, either we need to revert your link up IRQ change or
> have the below patch. IMO, the revert seems simple.

Using pwrctrl framework once it can handle this use case sounds good to me.

FUKAUMI, could you please send a revert of the two patches?


Kind regards,
Niklas


From naoki at radxa.com  Mon Nov 10 14:14:23 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Tue, 11 Nov 2025 07:14:23 +0900
Subject: [RESEND] Re: [PATCH] PCI: dw-rockchip: Skip waiting for link up
In-Reply-To: <aRJEDEEJr9Ic-RKN@fedora>
References: <55EB0E5F655F3AFC+136b89fd-98d4-42af-a99d-a0bb05cc93f3@radxa.com>
 <aRCI5kG16_1erMME@ryzen>
 <F8B2B6FA2884D69A+b7da13f2-0ffb-4308-b1ba-0549bc461be8@radxa.com>
 <780a4209-f89f-43a9-9364-331d3b77e61e@rock-chips.com>
 <4487DA40249CC821+19232169-a096-4737-bc6a-5cec9592d65f@radxa.com>
 <363d6b4d-c999-43d4-866e-880ef7d0dec3@rock-chips.com>
 <0C31787C387488ED+fd39bfe6-0844-4a87-bf48-675dd6d6a2df@radxa.com>
 <dc932773-af5b-4af7-a0d0-8cc72dfbd3c7@rock-chips.com>
 <aRHb4S40a7ZUDop1@ryzen>
 <2n3wamm3txxc6xbmvf3nnrvaqpgsck3w4a6omxnhex3mqeujib@2tb4svn5d3z6>
 <aRJEDEEJr9Ic-RKN@fedora>
Message-ID: <326A5CF08811110E+7785bc1e-6245-453d-9312-1b5726e7aed1@radxa.com>

Hi Niklas,

On 11/11/25 04:59, Niklas Cassel wrote:
> On Mon, Nov 10, 2025 at 09:23:02PM +0530, Manivannan Sadhasivam wrote:
>>>
>>> Considering what Shawn says, that the switch gets enumerated properly
>>> if we simply add a msleep() in ->start_link(), which will be called
>>> by dw_pcie_host_init() before pci_host_probe() is called...
>>>
>>
>> Yes, that delay probably gives enough time for the link up IRQ to kick in before
>> the initial bus scan happens.
> 
> I think that the problem is that even for platforms with link up IRQ,
> we will always do:
> 1) dw_pcie_start_link() (if (!dw_pcie_link_up()))
> 2) pci_host_probe() from dw_pcie_host_init(), this will enumerate the bus
> 3) pci_rescan_bus() from the Link Up IRQ handler
> 
> Thus, in 2, when enumerating the bus, without performing any of the delays
> mandated by the PCIe spec, it still seems possible to detect a device (it
> must have been really quick to initialize), and to communicate with that
> device, however since we have not performed the delays mandated by the spec,
> it appears that the device might not yet behave properly.
> 
> Hence my suggestion to never call pci_host_probe() in dw_pcie_host_init()
> for platforms with Link Up IRQ.
> 
> At least for pcie-dw-rockchip.c, we only unmask the Link Up IRQ after
> dw_pcie_host_init() has returned, so I think that your theory: that Shawn's
> suggested delay causes the Link Up IRQ to kick in before the initial bus
> scan, is incorrect. (Since the IRQ should not be able to trigger until
> dw_pcie_host_init() has returned.)
> 
> 
>>
>>> ...we already have a delay in the link up IRQ handler, before calling
>>> pci_rescan_bus().
>>>
>>
>> That delay won't help in this case.
> 
> Sure, I was just saying that even though Shawn's patch made things work,
> it seems incorrect, as we do not want to add "the same delay" that we
> already have in the Link Up IRQ. (The delay in the Link Up IRQ should be
> the only one.)
> 
> 
>>> I think a better solution would be something like:
> 
> (snip)
> 
>> This solution will work as long as the PCIe device is powered ON before
>> start_link(). For CEM and M.2 Key M connectors, the host controller can power
>> manage the components. But for other specifications/keys requiring custom power
>> management, a separate driver would be needed.
>>
>> That's why I suggested using pwrctrl framework as it can satisfy both usecases.
>> However, as I said, it needs a bit of rework and I'm close to submitting it.
>>
>> But until that gets merged, either we need to revert your link up IRQ change or
>> have the below patch. IMO, the revert seems simple.
> 
> Using pwrctrl framework once it can handle this use case sounds good to me.
> 
> FUKAUMI, could you please send a revert of the two patches?

Well, I cannot write a detailed explanation...

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> Kind regards,
> Niklas
> 




From linus.walleij at linaro.org  Mon Nov 10 14:24:52 2025
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 10 Nov 2025 23:24:52 +0100
Subject: [PATCH v1 0/3] pinctrl: rockchip: Add RK3506 pinctrl support
In-Reply-To: <20251104021223.2375116-1-ye.zhang@rock-chips.com>
References: <20251104021223.2375116-1-ye.zhang@rock-chips.com>
Message-ID: <CACRpkdaR=_K-hewNne2fPN=RKu7iyOe0gLYhMEBfQVvemJJuoQ@mail.gmail.com>

On Tue, Nov 4, 2025 at 3:12?AM Ye Zhang <ye.zhang at rock-chips.com> wrote:

> This series adds pinctrl support for the Rockchip RK3506 SoC.
>
> The series includes:
> - RK3506 pinctrl driver implementation
> - RMIO (Rockchip Matrix I/O) support for RK3506
>
> Ye Zhang (3):
>   dt-bindings: pinctrl: Add rk3506 pinctrl support
>   pinctrl: rockchip: Add rk3506 pinctrl support

Since we have consensus on these two patches I applied them!

>   pinctrl: rockchip: add rk3506 rmio support

Now you only need to discuss this with Heiko and iterate it.

Yours,
Linus Walleij


From laurent.pinchart at ideasonboard.com  Mon Nov 10 16:06:27 2025
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Tue, 11 Nov 2025 02:06:27 +0200
Subject: [PATCH v14 00/18] media: rockchip: add a driver for the rockchip
 camera interface
In-Reply-To: <b89746e1-4574-4b65-af69-c533576ed185@collabora.com>
References: <20240220-rk3568-vicap-v14-0-b38b6da0fc80@collabora.com>
 <aQ4tJg8r_j4NyKhv@kekkonen.localdomain>
 <074cd08e-0412-49f9-8dd9-b1f96eb11717@collabora.com>
 <20251107185441.GG5558@pendragon.ideasonboard.com>
 <13c43edb-9592-4779-a39a-7856bb0f964d@collabora.com>
 <aRGlvQRVoQs0WjyA@kekkonen.localdomain>
 <b89746e1-4574-4b65-af69-c533576ed185@collabora.com>
Message-ID: <20251111000627.GA30837@pendragon.ideasonboard.com>

On Mon, Nov 10, 2025 at 11:29:57AM +0100, Michael Riesch wrote:
> On 11/10/25 09:43, Sakari Ailus wrote:
> > On Fri, Nov 07, 2025 at 09:51:37PM +0100, Michael Riesch wrote:
> >> On 11/7/25 19:54, Laurent Pinchart wrote:
> >>> On Fri, Nov 07, 2025 at 07:41:59PM +0100, Michael Riesch wrote:
> >>>> On 11/7/25 18:32, Sakari Ailus wrote:
> >>>>> On Fri, Oct 24, 2025 at 02:51:29PM +0200, Michael Riesch via B4 Relay wrote:
> >>>>>> Habidere,
> >>>>>>
> >>>>>> This series introduces support for the Rockchip Camera Interface (CIF),
> >>>>>> which is featured in many Rockchip SoCs in different variations.
> >>>>>> For example, the PX30 Video Input Processor (VIP) is able to receive
> >>>>>> video data via the Digital Video Port (DVP, a parallel data interface)
> >>>>>> and transfer it into system memory using a double-buffering mechanism
> >>>>>> called ping-pong mode.
> >>>>>> The RK3568 Video Capture (VICAP) unit, on the other hand, features a
> >>>>>> DVP and a MIPI CSI-2 receiver that can receive video data independently
> >>>>>> (both using the ping-pong scheme).
> >>>>>> The different variants may have additional features, such as scaling
> >>>>>> and/or cropping.
> >>>>>> Finally, the RK3588 VICAP unit constitutes an essential piece of the
> >>>>>> camera interface with one DVP, six MIPI CSI-2 receivers, scale/crop
> >>>>>> units, and a data path multiplexer (to scaler units, to ISP, ...).
> >>>>>
> >>>>> I understand both RK3568 and RK3588 include an ISP. Do you have insight on
> >>>>> how would this work, should the support for the ISP be added later on?
> >>>>
> >>>> Short answer: Yes and yes.
> >>>>
> >>>> Long answer:
> >>>>
> >>>> The patch series at hand adds support for the PX30 VIP and the RK3568
> >>>> VICAP. I cannot really say something about the PX30, but on the RK3568
> >>>> VICAP and ISP are orthogonal (the ISP features its own MIPI CSI-2
> >>>> receiver, different from that introduced in this series). Thus, ISP
> >>>> support can be introduced anytime (whenever someone is motivated ;-)).
> >>>
> >>> Won't they both be connected to the same sensor though, and probably the
> >>> same D-PHY in the SoC ? They don't seem entirely separate to me.
> >>
> >> The MIPI CSI-2 DPHY is shared, indeed. Thus, they *maybe technically
> >> could be* connected to the same sensor, but I don't know whether that
> >> works and fail to see why anyone would to such a thing (if it is about
> >> raw capture, the MIPI CSI-2 receiver in the ISP can do that on its own).
> >>
> >> The DPHY can be operated in split mode, with two lanes for VICAP and two
> >> lanes for ISP. This is not implemented yet, but can be done at a later
> >> stage on PHY level (not media related). In this case, ISP and VICAP can
> >> receive data from different subdevices via CSI-2.
> > 
> > The two would be part of the same media graph in that case and as there are
> > two CSI-2 receivers and a single PHY, the PHY would probably need to have a
> > sub-device as well, to allow link configuration to be used to select where
> > the PHY is connected.
> > 
> > I don't think we have such a setup elsewhere, and supporting this would
> > require changes in the MC framework.
> 
> What follows is a response that also addresses issues raised during our
> off-list discussion.
> 
> First of all, I agree with you that the RK3568 HW is "a bit special" (to
> say the least) in that regard. Let's have an outlook to newer SoCs, such
> as the RK3588: Here, the MIPI CSI-2 DPHYs (there are two of them) with
> their split mode are present as well, but the assignment is fixed. For
> example, the RK3588 VICAP has six MIPI CSI-2 receiver units and six MIPI
> CSI-2 capture units. Units 1 and 2 handle a different MIPI PHY, units 3
> and 5 handle the DPHYs (without split mode), units 4 and/or 6 are active
> whenever DPHY 1 and/or 2 is in split mode.
> 
> I would model this by adding support for more than one (logical) PHYs
> (phy-cells = <1>;) and assigning the logical PHYs to the MIPI CSI-2
> receivers. There is not really a possibility to route anything at this
> point (routing is done in a MUX unit that takes the different MIPI CSI-2
> receivers as inputs).
> 
> Now back to the peculiar RK3568 situation: By default the split mode of
> the DPHY is off and both VICAP and ISP are able to receive the same data
> (from up to four lanes) with their MIPI CSI-2 receivers (not sure
> whether both can be active at the same time, though).

A common use case for capturing data from the same sensor through both
ISP and VICAP would be routing image data to the ISP and embedded data
to VICAP. Assuming the hardware is able to do this, there will be users
interested in this feature.

> There are two bits
> in the GRF that define the lanes that ISP and VICAP receive in split
> mode (lane 0/1 or lane 2/3). Not sure whether these bits are supposed to
> be changed during runtime.
> 
> I would suggest modelling this on PHY level in DT, e.g., by passing
> reasonable properties to the dphy node, such as
>     rockchip,dphy-split-mode;

Split mode should indeed be conveyed through DT, as it's a property of
the hardware.

>     rockchip,dphy-split-invert;
> where the former activates the split mode and assigns lanes 0/1 to the
> ISP and lanes 2/3 to the VICAP, and the latter inverts this assignment
> (lanes 2/3 to the ISP and lanes 0/1 to the VICAP). This would facilitate
> the reasonable use cases with reasonable effort.

This I'm less convinced about. The routing should be dynamic.

How do you envision the connections to the CSI-2 sources to be modelled
in DT ? We need ports and endpoints, and data-lanes properties. Where
would those reside on the RK3568 side ?

> Otherwise, to keep it perfectly general and most flexible and
> everything, we would have to introduce another subdevice indeed, which
> would be active on the RK3568 exclusively. Therefore, I don't see that
> the PHY driver introduces this subdevice, but a specialized (syscon?)
> MUX driver that deals with the RK3568 GRF bits. Something like this
> 
>                            |----------------------|     |-------------|
>  Sensor A --- /2 lanes --- | lane 0/1      to ISP | --- | ISP MIPI RX |
>                            |                      |     |-------------|
>                            |                      |
>                            |                      |     |-------------|
>  Sensor B --- /2 lanes --- | lane 2/3    to VICAP | --- |VICAP MIPI RX|
>                            |----------------------|     |-------------|
> 
> But IMHO this will be too much effort for corner use case that I doubt
> anyone will actually use.
> 
> What do you think:
>  - Let's keep the PHYs out of V4L2/MC, ok?
>  - Let's model the reasonable use cases with device tree properties in
>    the dphy DT node, ok?

I think the routing should be dynamic.

> > How does the media graph look like for the device at the moment?
> 
> Please take a look at the media graph in the documentation patch (PATCH
> v14 01/18). This is without the ISP, but gives an overview of what the
> RK3568 VICAP is capable of.
> 
> Best regards,
> Michael
> 
> >> BTW the ISP is able to process the data captured by VICAP, but
> >> apparently this includes a RAM round trip (VICAP captures to memory, ISP
> >> operates in mem2mem mode).
> >>
> >>> A block diagram that shows connections between the CSI-2 pins, D-PHY,
> >>> CSI-2 receivers, VICAP and ISP could help.
> >>>
> >>>> Once this patch series is merged, I'll push out changes that introduce
> >>>> support for the RK3588 VICAP. We can discuss the integration of any
> >>>> RK3588 ISP in this scope then -- and there may be some things to discuss
> >>>> as there the VICAP and the ISP(s) are directly connected by means of a
> >>>> MUX unit in the VICAP.
> >>>>
> >>>> Alright?

-- 
Regards,

Laurent Pinchart


From shawn.lin at rock-chips.com  Mon Nov 10 17:11:34 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Tue, 11 Nov 2025 09:11:34 +0800
Subject: [RESEND] Re: [PATCH] PCI: dw-rockchip: Skip waiting for link up
In-Reply-To: <2n3wamm3txxc6xbmvf3nnrvaqpgsck3w4a6omxnhex3mqeujib@2tb4svn5d3z6>
References: <aQ9FWEuW47L8YOxC@ryzen>
 <55EB0E5F655F3AFC+136b89fd-98d4-42af-a99d-a0bb05cc93f3@radxa.com>
 <aRCI5kG16_1erMME@ryzen>
 <F8B2B6FA2884D69A+b7da13f2-0ffb-4308-b1ba-0549bc461be8@radxa.com>
 <780a4209-f89f-43a9-9364-331d3b77e61e@rock-chips.com>
 <4487DA40249CC821+19232169-a096-4737-bc6a-5cec9592d65f@radxa.com>
 <363d6b4d-c999-43d4-866e-880ef7d0dec3@rock-chips.com>
 <0C31787C387488ED+fd39bfe6-0844-4a87-bf48-675dd6d6a2df@radxa.com>
 <dc932773-af5b-4af7-a0d0-8cc72dfbd3c7@rock-chips.com>
 <aRHb4S40a7ZUDop1@ryzen>
 <2n3wamm3txxc6xbmvf3nnrvaqpgsck3w4a6omxnhex3mqeujib@2tb4svn5d3z6>
Message-ID: <20685424-9097-4993-a60d-61c7f7a74b5f@rock-chips.com>

Hi Mani

? 2025/11/10 ??? 23:53, Manivannan Sadhasivam ??:
> On Mon, Nov 10, 2025 at 01:34:41PM +0100, Niklas Cassel wrote:
>> On Mon, Nov 10, 2025 at 06:15:33PM +0800, Shawn Lin wrote:
>>>>
>>>> Could you try PCIe 2.0 slot on your board?
>>>
>>> I did, it doesn't work on PCIe 2.0 slot. From the PA, I could see
>>> the link is still in training during pci_host_probe() is called.
>>> Add some delay before pci_rescan_bus() in pcie-dw-rockchip doesn't
>>> help. But the below change should work as we delayed pci_host_probe().
>>>
>>> --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
>>> +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
>>> @@ -236,6 +236,8 @@ static int rockchip_pcie_start_link(struct dw_pcie *pci)
>>>          msleep(PCIE_T_PVPERL_MS);
>>>          gpiod_set_value_cansleep(rockchip->rst_gpio, 1);
>>>
>>> +       msleep(50);
>>> +
>>>          return 0;
>>>
>>> Otherwise we got:
>>>
>>> [    0.841518] pci_bus 0003:33: busn_res: can not insert [bus 33-31] under
>>> [bus 32-31] (conflicts with (null) [bus 32-31])
>>> [    0.842596] pci_bus 0003:33: busn_res: [bus 33-31] end is updated to 33
>>> [    0.843184] pci_bus 0003:33: busn_res: can not insert [bus 33] under [bus
>>> 32-31] (conflicts with (null) [bus 32-31])
>>> [    0.844120] pci 0003:32:00.0: devices behind bridge are unusable because
>>> [bus 33] cannot be assigned for them
>>> [    0.845229] pci_bus 0003:34: busn_res: can not insert [bus 34-31] under
>>> [bus 32-31] (conflicts with (null) [bus 32-31])
>>> [    0.846309] pci_bus 0003:34: busn_res: [bus 34-31] end is updated to 34
>>> [    0.846898] pci_bus 0003:34: busn_res: can not insert [bus 34] under [bus
>>> 32-31] (conflicts with (null) [bus 32-31])
>>> [    0.847833] pci 0003:32:06.0: devices behind bridge are unusable because
>>> [bus 34] cannot be assigned for them
>>> [    0.848923] pci_bus 0003:35: busn_res: can not insert [bus 35-31] under
>>> [bus 32-31] (conflicts with (null) [bus 32-31])
>>> [    0.850014] pci_bus 0003:35: busn_res: [bus 35-31] end is updated to 35
>>> [    0.850605] pci_bus 0003:35: busn_res: can not insert [bus 35] under [bus
>>> 32-31] (conflicts with (null) [bus 32-31])
>>> [    0.851540] pci 0003:32:0e.0: devices behind bridge are unusable because
>>> [bus 35] cannot be assigned for them
>>> [    0.852424] pci_bus 0003:32: busn_res: [bus 32-31] end is updated to 35
>>> [    0.853028] pci_bus 0003:32: busn_res: can not insert [bus 32-35] under
>>> [bus 31] (conflicts with (null) [bus 31])
>>> [    0.853184] hub 3-0:1.0: USB hub found
>>> [    0.853931] pci 0003:31:00.0: devices behind bridge are unusable because
>>> [bus 32-35] cannot be assigned for them
>>> [    0.854262] hub 3-0:1.0: 1 port detected
>>> [    0.855144] pcieport 0003:30:00.0: bridge has subordinate 31 but max busn
>>> 35
>>> [    0.855722] hub 4-0:1.0: USB hub found
>>> [    0.856109] pci 0003:32:00.0: PCI bridge to [bus 33]
>>> [    0.856939] pci 0003:32:06.0: PCI bridge to [bus 34]
>>> [    0.857133] hub 4-0:1.0: 1 port detected
>>> [    0.857430] pci 0003:32:0e.0: PCI bridge to [bus 35]
>>> [    0.858236] pci 0003:31:00.0: PCI bridge to [bus 32-35]
>>
>> Mani,
>>
>> while I see the idea behind your suggested hack:
>>   
>> +       if (pdev->vendor == 0x1d87 && pdev->device == 0x3588) {
>> +               pdev->is_hotplug_bridge = pdev->is_pciehp = 1;
>> +               return;
>> +       }
>>
>>
>> Considering what Shawn says, that the switch gets enumerated properly
>> if we simply add a msleep() in ->start_link(), which will be called
>> by dw_pcie_host_init() before pci_host_probe() is called...
>>
> 
> Yes, that delay probably gives enough time for the link up IRQ to kick in before
> the initial bus scan happens.
> 
>> ...we already have a delay in the link up IRQ handler, before calling
>> pci_rescan_bus().
>>
> 
> That delay won't help in this case.
> 
>> So, I think that the problem is that we are unconditionally calling
>> pci_host_probe() in dw_pcie_host_init(), even for platforms that have
>> a link-up IRQ.
>>
>>
>> I think a better solution would be something like:
>>
> 
> This solution will work as long as the PCIe device is powered ON before
> start_link(). For CEM and M.2 Key M connectors, the host controller can power
> manage the components. But for other specifications/keys requiring custom power
> management, a separate driver would be needed.
> 

My test environment is a PCIe2.0 x1 CEM slot and a PCIe3.0 x4 CEM slot.
The power supply for slots are controlled by pcie-dw-rockchip, far
earlier than staring to link. From this point, I would expect the result
is consistent, both worked or both failed. But, the result for these two
slots is different, PCIe2.0 slot didn't work but PCIe3.0 slot worked.

After checking with PA, with gpio-input-tigger's help, I could see
PCIe2.0 is still in tranning with thet switch, during pci_host_probe()
is called. This is the only difference I could see then, so as a debug I
add a delay to postpone the pci_host_probe() to make sure the link will
be finished on background.

So this's true if I added the delay, the pci_host_probe?? will see the
switch and the following devices. So your analysis of extented bus makes
sense. But pwrctrl seems helpless here, as we sure power-on the slot
before star_link().

> That's why I suggested using pwrctrl framework as it can satisfy both usecases.
> However, as I said, it needs a bit of rework and I'm close to submitting it.
> 
> But until that gets merged, either we need to revert your link up IRQ change or
> have the below patch. IMO, the revert seems simple.
> 
> - Mani
> 
>> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
>> index e92513c5bda5..42d987ddab7d 100644
>> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
>> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
>> @@ -565,6 +565,39 @@ static int dw_pcie_host_get_resources(struct dw_pcie_rp *pp)
>>   	return 0;
>>   }
>>   
>> +static int dw_pcie_host_initial_scan(struct dw_pcie_rp *pp)
>> +{
>> +	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
>> +	struct pci_host_bridge *bridge = pp->bridge;
>> +	int ret;
>> +
>> +	ret = pci_host_probe(bridge);
>> +	if (ret)
>> +		return ret;
>> +
>> +	if (pp->ops->post_init)
>> +		pp->ops->post_init(pp);
>> +
>> +	dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
>> +
>> +	return 0;
>> +}
>> +
>> +void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp)
>> +{
>> +	if (!pp->initial_linkup_irq_done) {
>> +		if (dw_pcie_host_initial_scan(pp)) {
>> +			//TODO: cleanup
>> +		}
>> +		pp->initial_linkup_irq_done = true;
>> +	} else {
>> +		/* Rescan the bus to enumerate endpoint devices */
>> +		pci_lock_rescan_remove();
>> +		pci_rescan_bus(pp->bridge->bus);
>> +		pci_unlock_rescan_remove();
>> +	}
>> +}
>> +
>>   int dw_pcie_host_init(struct dw_pcie_rp *pp)
>>   {
>>   	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
>> @@ -672,15 +705,13 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
>>   	if (!pp->use_linkup_irq)
>>   		/* Ignore errors, the link may come up later */
>>   		dw_pcie_wait_for_link(pci);
>> -
>> -	ret = pci_host_probe(bridge);
>> -	if (ret)
>> -		goto err_stop_link;
>> -
>> -	if (pp->ops->post_init)
>> -		pp->ops->post_init(pp);
>> -
>> -	dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
>> +	else
>> +		/*
>> +		 * For platforms with Link Up IRQ, initial scan will be done
>> +		 * on first Link Up IRQ.
>> +		 */
>> +		if (dw_pcie_host_initial_scan(pp))
>> +			goto err_stop_link;
>>   
>>   	return 0;
>>   
>> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
>> index e995f692a1ec..a31bd93490dc 100644
>> --- a/drivers/pci/controller/dwc/pcie-designware.h
>> +++ b/drivers/pci/controller/dwc/pcie-designware.h
>> @@ -427,6 +427,7 @@ struct dw_pcie_rp {
>>   	int			msg_atu_index;
>>   	struct resource		*msg_res;
>>   	bool			use_linkup_irq;
>> +	bool			initial_linkup_irq_done;
>>   	struct pci_eq_presets	presets;
>>   	struct pci_config_window *cfg;
>>   	bool			ecam_enabled;
>> @@ -807,6 +808,7 @@ void dw_pcie_msi_init(struct dw_pcie_rp *pp);
>>   int dw_pcie_msi_host_init(struct dw_pcie_rp *pp);
>>   void dw_pcie_free_msi(struct dw_pcie_rp *pp);
>>   int dw_pcie_setup_rc(struct dw_pcie_rp *pp);
>> +void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp);
>>   int dw_pcie_host_init(struct dw_pcie_rp *pp);
>>   void dw_pcie_host_deinit(struct dw_pcie_rp *pp);
>>   int dw_pcie_allocate_domains(struct dw_pcie_rp *pp);
>> @@ -844,6 +846,9 @@ static inline int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
>>   	return 0;
>>   }
>>   
>> +static inline void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp)
>> +{ }
>> +
>>   static inline int dw_pcie_host_init(struct dw_pcie_rp *pp)
>>   {
>>   	return 0;
>> diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
>> index 8a882dcd1e4e..042e5845bdd6 100644
>> --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
>> +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
>> @@ -468,10 +468,7 @@ static irqreturn_t rockchip_pcie_rc_sys_irq_thread(int irq, void *arg)
>>   		if (rockchip_pcie_link_up(pci)) {
>>   			msleep(PCIE_RESET_CONFIG_WAIT_MS);
>>   			dev_dbg(dev, "Received Link up event. Starting enumeration!\n");
>> -			/* Rescan the bus to enumerate endpoint devices */
>> -			pci_lock_rescan_remove();
>> -			pci_rescan_bus(pp->bridge->bus);
>> -			pci_unlock_rescan_remove();
>> +			dw_pcie_handle_link_up_irq(pp);
>>   		}
>>   	}
>>   
>>
>>
>>
>>
>> What do you think?
>>
>>
>>
>> Kind regards,
>> Niklas
> 



From naoki at radxa.com  Mon Nov 10 18:09:42 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Tue, 11 Nov 2025 11:09:42 +0900
Subject: [RESEND] Re: [PATCH] PCI: dw-rockchip: Skip waiting for link up
In-Reply-To: <aRJEDEEJr9Ic-RKN@fedora>
References: <55EB0E5F655F3AFC+136b89fd-98d4-42af-a99d-a0bb05cc93f3@radxa.com>
 <aRCI5kG16_1erMME@ryzen>
 <F8B2B6FA2884D69A+b7da13f2-0ffb-4308-b1ba-0549bc461be8@radxa.com>
 <780a4209-f89f-43a9-9364-331d3b77e61e@rock-chips.com>
 <4487DA40249CC821+19232169-a096-4737-bc6a-5cec9592d65f@radxa.com>
 <363d6b4d-c999-43d4-866e-880ef7d0dec3@rock-chips.com>
 <0C31787C387488ED+fd39bfe6-0844-4a87-bf48-675dd6d6a2df@radxa.com>
 <dc932773-af5b-4af7-a0d0-8cc72dfbd3c7@rock-chips.com>
 <aRHb4S40a7ZUDop1@ryzen>
 <2n3wamm3txxc6xbmvf3nnrvaqpgsck3w4a6omxnhex3mqeujib@2tb4svn5d3z6>
 <aRJEDEEJr9Ic-RKN@fedora>
Message-ID: <B721C8A516FDB604+a04b38d3-64ec-423f-9e4c-040c8d2aec76@radxa.com>

On 11/11/25 04:59, Niklas Cassel wrote:
> On Mon, Nov 10, 2025 at 09:23:02PM +0530, Manivannan Sadhasivam wrote:
>>>
>>> Considering what Shawn says, that the switch gets enumerated properly
>>> if we simply add a msleep() in ->start_link(), which will be called
>>> by dw_pcie_host_init() before pci_host_probe() is called...
>>>
>>
>> Yes, that delay probably gives enough time for the link up IRQ to kick in before
>> the initial bus scan happens.
> 
> I think that the problem is that even for platforms with link up IRQ,
> we will always do:
> 1) dw_pcie_start_link() (if (!dw_pcie_link_up()))
> 2) pci_host_probe() from dw_pcie_host_init(), this will enumerate the bus
> 3) pci_rescan_bus() from the Link Up IRQ handler
> 
> Thus, in 2, when enumerating the bus, without performing any of the delays
> mandated by the PCIe spec, it still seems possible to detect a device (it
> must have been really quick to initialize), and to communicate with that
> device, however since we have not performed the delays mandated by the spec,
> it appears that the device might not yet behave properly.
> 
> Hence my suggestion to never call pci_host_probe() in dw_pcie_host_init()
> for platforms with Link Up IRQ.
> 
> At least for pcie-dw-rockchip.c, we only unmask the Link Up IRQ after
> dw_pcie_host_init() has returned, so I think that your theory: that Shawn's
> suggested delay causes the Link Up IRQ to kick in before the initial bus
> scan, is incorrect. (Since the IRQ should not be able to trigger until
> dw_pcie_host_init() has returned.)
> 
> 
>>
>>> ...we already have a delay in the link up IRQ handler, before calling
>>> pci_rescan_bus().
>>>
>>
>> That delay won't help in this case.
> 
> Sure, I was just saying that even though Shawn's patch made things work,
> it seems incorrect, as we do not want to add "the same delay" that we
> already have in the Link Up IRQ. (The delay in the Link Up IRQ should be
> the only one.)
> 
> 
>>> I think a better solution would be something like:
> 
> (snip)
> 
>> This solution will work as long as the PCIe device is powered ON before
>> start_link(). For CEM and M.2 Key M connectors, the host controller can power
>> manage the components. But for other specifications/keys requiring custom power
>> management, a separate driver would be needed.
>>
>> That's why I suggested using pwrctrl framework as it can satisfy both usecases.
>> However, as I said, it needs a bit of rework and I'm close to submitting it.
>>
>> But until that gets merged, either we need to revert your link up IRQ change or
>> have the below patch. IMO, the revert seems simple.
> 
> Using pwrctrl framework once it can handle this use case sounds good to me.
> 
> FUKAUMI, could you please send a revert of the two patches?

Leaving the commit message aside, I'm currently testing with a revert of 
the two patches.

Vanilla v6.18-rc5, CONFIG_PCI_DYNAMIC_OF_NODES=y, revert ec9fd499b9c6, 
revert 0e0b45ab5d77.

It works stably on the ROCK 5A. The link speed is 2Gb/s.

The ROCK 5C is unstable. It initially worked with a link speed of 4Gb/s, 
but eventually started showing kernel oops. The dts files for the 5A and 
5C are compatible and interchangeable, but even using the 5A's dts on 
the 5C, the operation remains unstable.

I plan to thoroughly investigate the ROCK 5C's behavior on v6.13, but 
for now, I believe reverting the two patches is the correct action.

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> Kind regards,
> Niklas
> 




From zhangqing at rock-chips.com  Mon Nov 10 18:57:33 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Tue, 11 Nov 2025 10:57:33 +0800
Subject: [PATCH v7 0/5] clk: rockchip: Add clock controller for the
Message-ID: <20251111025738.869847-1-zhangqing@rock-chips.com>

Add yaml and dt-bindings for the RV1126B and RK3506.
RK3506 depend on patches 1/5, so it is merged and submitted.

Change in V7:
[PATCH v7 1/5]: No change
[PATCH v7 2/5]: Redefine clk id(start at 0), drop RESETN for reset id.
[PATCH v7 3/5]: Drop RESETN for reset id.
[PATCH v7 4/5]: Fix "description: |", drop RESETN for reset id.
[PATCH v7 5/5]: Drop RESETN for reset id.

Change in V6:
Drop pvtpll, others no change.
There are many questions about pvtpll and have some dependency issues.
They will be submitted separately later.

Change in V5:
[PATCH v5 1/7]: No change
[PATCH v5 2/7]: No change
[PATCH v5 3/7]: Drop RV1126B_GRF_SOC_STATUS0
[PATCH v5 4/7]: Drop syscon
[PATCH v5 5/7]: No change
[PATCH v5 6/7]: Add clocks and clock-names, fix id define
[PATCH v5 7/7]: Drop RK3506_GRF_SOC_STATUS

Change in V4:
[PATCH v4 1/7]: No change
[PATCH v4 2/7]: remove label
[PATCH v4 3/7]: No change
[PATCH v4 4/7]: remove label,fix order
[PATCH v4 5/7]: No change
[PATCH v4 6/7]: Add yaml and dt-bindings for the RK3506
[PATCH v4 7/7]: Add clock controller for the RK3506

Change in V3:
[PATCH v3 1/5]: No change
[PATCH v3 2/5]: Fix define error
[PATCH v3 3/5]: update driver,fix errir
[PATCH v3 4/5]: fix error
[PATCH v3 5/5]: No change

Change in V2:
[PATCH v2 1/5]: update commit message, rename v2 to multi_pll
[PATCH v2 2/5]: Modify DT binding headers license
[PATCH v2 3/5]: update driver
[PATCH v2 4/5]: fix error
[PATCH v2 5/5]: update commit message

Elaine Zhang (4):
  clk: rockchip: Implement rockchip_clk_register_armclk_multi_pll()
  dt-bindings: clock, reset: Add support for rv1126b
  clk: rockchip: Add clock controller for the RV1126B
  clk: rockchip: Add clock and reset driver for RK3506

Finley Xiao (1):
  dt-bindings: clock: rockchip: Add RK3506 clock and reset unit

 .../bindings/clock/rockchip,rk3506-cru.yaml   |   51 +
 .../bindings/clock/rockchip,rv1126b-cru.yaml  |   52 +
 drivers/clk/rockchip/Kconfig                  |   14 +
 drivers/clk/rockchip/Makefile                 |    2 +
 drivers/clk/rockchip/clk-cpu.c                |  165 +++
 drivers/clk/rockchip/clk-rk3506.c             |  869 +++++++++++++
 drivers/clk/rockchip/clk-rv1126b.c            | 1103 +++++++++++++++++
 drivers/clk/rockchip/clk.c                    |   24 +
 drivers/clk/rockchip/clk.h                    |   96 ++
 drivers/clk/rockchip/rst-rk3506.c             |  226 ++++
 drivers/clk/rockchip/rst-rv1126b.c            |  444 +++++++
 .../dt-bindings/clock/rockchip,rk3506-cru.h   |  285 +++++
 .../dt-bindings/clock/rockchip,rv1126b-cru.h  |  392 ++++++
 .../dt-bindings/reset/rockchip,rk3506-cru.h   |  211 ++++
 .../dt-bindings/reset/rockchip,rv1126b-cru.h  |  405 ++++++
 15 files changed, 4339 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rv1126b-cru.yaml
 create mode 100644 drivers/clk/rockchip/clk-rk3506.c
 create mode 100644 drivers/clk/rockchip/clk-rv1126b.c
 create mode 100644 drivers/clk/rockchip/rst-rk3506.c
 create mode 100644 drivers/clk/rockchip/rst-rv1126b.c
 create mode 100644 include/dt-bindings/clock/rockchip,rk3506-cru.h
 create mode 100644 include/dt-bindings/clock/rockchip,rv1126b-cru.h
 create mode 100644 include/dt-bindings/reset/rockchip,rk3506-cru.h
 create mode 100644 include/dt-bindings/reset/rockchip,rv1126b-cru.h


base-commit: fb0a581e0696ccd994e27287941a2a25c58b2ccd
-- 
2.34.1



From zhangqing at rock-chips.com  Mon Nov 10 18:57:34 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Tue, 11 Nov 2025 10:57:34 +0800
Subject: [PATCH v7 1/5] clk: rockchip: Implement rockchip_clk_register_armclk_multi_pll()
In-Reply-To: <20251111025738.869847-1-zhangqing@rock-chips.com>
References: <20251111025738.869847-1-zhangqing@rock-chips.com>
Message-ID: <20251111025738.869847-2-zhangqing@rock-chips.com>

The current path will have an independent PLL(LPLL\BPLL)
exclusively for the CPU to use.
As follows:

            |-\
    --lpll--|  \
            |mux|--[gate]--[div]--clk_core--
    --gpll--|  /
            |-/

The new chip does not have a dedicated PLL for the cpu;
it is distributed nearby from the common PLL.
If there are special frequency requirements that require the
use of pvtpll, explanations will be submitted later.

The clock path of new soc CPU simplified as follows:

    --gpll--|--\
            |   \
            |    \
            |     \
   --v0pll--| mux |--[gate]--[div]--clk_core--
            |     /
            |    /
   --v1pll--|   /
            |--/

Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
---
 drivers/clk/rockchip/clk-cpu.c | 165 +++++++++++++++++++++++++++++++++
 drivers/clk/rockchip/clk.c     |  24 +++++
 drivers/clk/rockchip/clk.h     |  15 +++
 3 files changed, 204 insertions(+)

diff --git a/drivers/clk/rockchip/clk-cpu.c b/drivers/clk/rockchip/clk-cpu.c
index dcc9dcb597ae..6e91a3041a03 100644
--- a/drivers/clk/rockchip/clk-cpu.c
+++ b/drivers/clk/rockchip/clk-cpu.c
@@ -396,3 +396,168 @@ struct clk *rockchip_clk_register_cpuclk(const char *name,
 	kfree(cpuclk);
 	return ERR_PTR(ret);
 }
+
+static int rockchip_cpuclk_multi_pll_pre_rate_change(struct rockchip_cpuclk *cpuclk,
+						     struct clk_notifier_data *ndata)
+{
+	unsigned long new_rate = roundup(ndata->new_rate, 1000);
+	const struct rockchip_cpuclk_rate_table *rate;
+	unsigned long flags;
+
+	rate = rockchip_get_cpuclk_settings(cpuclk, new_rate);
+	if (!rate) {
+		pr_err("%s: Invalid rate : %lu for cpuclk\n",
+		       __func__, new_rate);
+		return -EINVAL;
+	}
+
+	if (new_rate > ndata->old_rate) {
+		spin_lock_irqsave(cpuclk->lock, flags);
+		rockchip_cpuclk_set_dividers(cpuclk, rate);
+		spin_unlock_irqrestore(cpuclk->lock, flags);
+	}
+
+	return 0;
+}
+
+static int rockchip_cpuclk_multi_pll_post_rate_change(struct rockchip_cpuclk *cpuclk,
+						      struct clk_notifier_data *ndata)
+{
+	unsigned long new_rate = roundup(ndata->new_rate, 1000);
+	const struct rockchip_cpuclk_rate_table *rate;
+	unsigned long flags;
+
+	rate = rockchip_get_cpuclk_settings(cpuclk, new_rate);
+	if (!rate) {
+		pr_err("%s: Invalid rate : %lu for cpuclk\n",
+		       __func__, new_rate);
+		return -EINVAL;
+	}
+
+	if (new_rate < ndata->old_rate) {
+		spin_lock_irqsave(cpuclk->lock, flags);
+		rockchip_cpuclk_set_dividers(cpuclk, rate);
+		spin_unlock_irqrestore(cpuclk->lock, flags);
+	}
+
+	return 0;
+}
+
+static int rockchip_cpuclk_multi_pll_notifier_cb(struct notifier_block *nb,
+						 unsigned long event, void *data)
+{
+	struct clk_notifier_data *ndata = data;
+	struct rockchip_cpuclk *cpuclk = to_rockchip_cpuclk_nb(nb);
+	int ret = 0;
+
+	pr_debug("%s: event %lu, old_rate %lu, new_rate: %lu\n",
+		 __func__, event, ndata->old_rate, ndata->new_rate);
+	if (event == PRE_RATE_CHANGE)
+		ret = rockchip_cpuclk_multi_pll_pre_rate_change(cpuclk, ndata);
+	else if (event == POST_RATE_CHANGE)
+		ret = rockchip_cpuclk_multi_pll_post_rate_change(cpuclk, ndata);
+
+	return notifier_from_errno(ret);
+}
+
+struct clk *rockchip_clk_register_cpuclk_multi_pll(const char *name,
+						   const char *const *parent_names,
+						   u8 num_parents, void __iomem *base,
+						   int muxdiv_offset, u8 mux_shift,
+						   u8 mux_width, u8 mux_flags,
+						   int div_offset, u8 div_shift,
+						   u8 div_width, u8 div_flags,
+						   unsigned long flags, spinlock_t *lock,
+						   const struct rockchip_cpuclk_rate_table *rates,
+						   int nrates)
+{
+	struct rockchip_cpuclk *cpuclk;
+	struct clk_hw *hw;
+	struct clk_mux *mux = NULL;
+	struct clk_divider *div = NULL;
+	const struct clk_ops *mux_ops = NULL, *div_ops = NULL;
+	int ret;
+
+	if (num_parents > 1) {
+		mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+		if (!mux)
+			return ERR_PTR(-ENOMEM);
+
+		mux->reg = base + muxdiv_offset;
+		mux->shift = mux_shift;
+		mux->mask = BIT(mux_width) - 1;
+		mux->flags = mux_flags;
+		mux->lock = lock;
+		mux_ops = (mux_flags & CLK_MUX_READ_ONLY) ? &clk_mux_ro_ops
+							: &clk_mux_ops;
+	}
+
+	if (div_width > 0) {
+		div = kzalloc(sizeof(*div), GFP_KERNEL);
+		if (!div) {
+			ret = -ENOMEM;
+			goto free_mux;
+		}
+
+		div->flags = div_flags;
+		if (div_offset)
+			div->reg = base + div_offset;
+		else
+			div->reg = base + muxdiv_offset;
+		div->shift = div_shift;
+		div->width = div_width;
+		div->lock = lock;
+		div_ops = (div_flags & CLK_DIVIDER_READ_ONLY)
+						? &clk_divider_ro_ops
+						: &clk_divider_ops;
+	}
+
+	hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
+				       mux ? &mux->hw : NULL, mux_ops,
+				       div ? &div->hw : NULL, div_ops,
+				       NULL, NULL, flags);
+	if (IS_ERR(hw)) {
+		ret = PTR_ERR(hw);
+		goto free_div;
+	}
+
+	cpuclk = kzalloc(sizeof(*cpuclk), GFP_KERNEL);
+	if (!cpuclk) {
+		ret = -ENOMEM;
+		goto unregister_clk;
+	}
+
+	cpuclk->reg_base = base;
+	cpuclk->lock = lock;
+	cpuclk->clk_nb.notifier_call = rockchip_cpuclk_multi_pll_notifier_cb;
+	ret = clk_notifier_register(hw->clk, &cpuclk->clk_nb);
+	if (ret) {
+		pr_err("%s: failed to register clock notifier for %s\n",
+		       __func__, name);
+		goto free_cpuclk;
+	}
+
+	if (nrates > 0) {
+		cpuclk->rate_count = nrates;
+		cpuclk->rate_table = kmemdup(rates,
+					     sizeof(*rates) * nrates,
+					     GFP_KERNEL);
+		if (!cpuclk->rate_table) {
+			ret = -ENOMEM;
+			goto free_cpuclk;
+		}
+	}
+
+	return hw->clk;
+
+free_cpuclk:
+	kfree(cpuclk);
+unregister_clk:
+	clk_hw_unregister_composite(hw);
+free_div:
+	kfree(div);
+free_mux:
+	kfree(mux);
+
+	return ERR_PTR(ret);
+}
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
index 19caf26c991b..2601df3b1066 100644
--- a/drivers/clk/rockchip/clk.c
+++ b/drivers/clk/rockchip/clk.c
@@ -722,6 +722,30 @@ void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
 }
 EXPORT_SYMBOL_GPL(rockchip_clk_register_armclk);
 
+void rockchip_clk_register_armclk_multi_pll(struct rockchip_clk_provider *ctx,
+					    struct rockchip_clk_branch *list,
+					    const struct rockchip_cpuclk_rate_table *rates,
+					    int nrates)
+{
+	struct clk *clk;
+
+	clk = rockchip_clk_register_cpuclk_multi_pll(list->name, list->parent_names,
+						     list->num_parents, ctx->reg_base,
+						     list->muxdiv_offset, list->mux_shift,
+						     list->mux_width, list->mux_flags,
+						     list->div_offset, list->div_shift,
+						     list->div_width, list->div_flags,
+						     list->flags, &ctx->lock, rates, nrates);
+	if (IS_ERR(clk)) {
+		pr_err("%s: failed to register clock %s: %ld\n",
+		       __func__, list->name, PTR_ERR(clk));
+		return;
+	}
+
+	rockchip_clk_set_lookup(ctx, clk, list->id);
+}
+EXPORT_SYMBOL_GPL(rockchip_clk_register_armclk_multi_pll);
+
 void rockchip_clk_protect_critical(const char *const clocks[],
 				   int nclocks)
 {
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index 7c5e74c7a2e2..23653a942403 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -622,6 +622,17 @@ struct clk *rockchip_clk_register_cpuclk(const char *name,
 			const struct rockchip_cpuclk_rate_table *rates,
 			int nrates, void __iomem *reg_base, spinlock_t *lock);
 
+struct clk *rockchip_clk_register_cpuclk_multi_pll(const char *name,
+						   const char *const *parent_names,
+						   u8 num_parents, void __iomem *base,
+						   int muxdiv_offset, u8 mux_shift,
+						   u8 mux_width, u8 mux_flags,
+						   int div_offset, u8 div_shift,
+						   u8 div_width, u8 div_flags,
+						   unsigned long flags, spinlock_t *lock,
+						   const struct rockchip_cpuclk_rate_table *rates,
+						   int nrates);
+
 struct clk *rockchip_clk_register_mmc(const char *name,
 				const char *const *parent_names, u8 num_parents,
 				void __iomem *reg,
@@ -1208,6 +1219,10 @@ void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
 			const struct rockchip_cpuclk_reg_data *reg_data,
 			const struct rockchip_cpuclk_rate_table *rates,
 			int nrates);
+void rockchip_clk_register_armclk_multi_pll(struct rockchip_clk_provider *ctx,
+					    struct rockchip_clk_branch *list,
+					    const struct rockchip_cpuclk_rate_table *rates,
+					    int nrates);
 void rockchip_clk_protect_critical(const char *const clocks[], int nclocks);
 void rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx,
 					unsigned int reg, void (*cb)(void));
-- 
2.34.1



From zhangqing at rock-chips.com  Mon Nov 10 18:57:35 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Tue, 11 Nov 2025 10:57:35 +0800
Subject: [PATCH v7 2/5] dt-bindings: clock, reset: Add support for rv1126b
In-Reply-To: <20251111025738.869847-1-zhangqing@rock-chips.com>
References: <20251111025738.869847-1-zhangqing@rock-chips.com>
Message-ID: <20251111025738.869847-3-zhangqing@rock-chips.com>

Add clock and reset ID defines for rv1126b.
Also add documentation for the rv1126b CRU core.

Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
Acked-by: Conor Dooley <conor.dooley at microchip.com>
---
 .../bindings/clock/rockchip,rv1126b-cru.yaml  |  52 +++
 .../dt-bindings/clock/rockchip,rv1126b-cru.h  | 392 +++++++++++++++++
 .../dt-bindings/reset/rockchip,rv1126b-cru.h  | 405 ++++++++++++++++++
 3 files changed, 849 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rv1126b-cru.yaml
 create mode 100644 include/dt-bindings/clock/rockchip,rv1126b-cru.h
 create mode 100644 include/dt-bindings/reset/rockchip,rv1126b-cru.h

diff --git a/Documentation/devicetree/bindings/clock/rockchip,rv1126b-cru.yaml b/Documentation/devicetree/bindings/clock/rockchip,rv1126b-cru.yaml
new file mode 100644
index 000000000000..04b0a5c51e4e
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/rockchip,rv1126b-cru.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/rockchip,rv1126b-cru.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip RV1126B Clock and Reset Unit
+
+maintainers:
+  - Elaine Zhang <zhangqing at rock-chips.com>
+  - Heiko Stuebner <heiko at sntech.de>
+
+description:
+  The rv1126b clock controller generates the clock and also implements a
+  reset controller for SoC peripherals.
+
+properties:
+  compatible:
+    enum:
+      - rockchip,rv1126b-cru
+
+  reg:
+    maxItems: 1
+
+  "#clock-cells":
+    const: 1
+
+  "#reset-cells":
+    const: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    const: xin24m
+
+required:
+  - compatible
+  - reg
+  - "#clock-cells"
+  - "#reset-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller at 20000000 {
+      compatible = "rockchip,rv1126b-cru";
+      reg = <0x20000000 0xc0000>;
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+    };
diff --git a/include/dt-bindings/clock/rockchip,rv1126b-cru.h b/include/dt-bindings/clock/rockchip,rv1126b-cru.h
new file mode 100644
index 000000000000..721d50a1419f
--- /dev/null
+++ b/include/dt-bindings/clock/rockchip,rv1126b-cru.h
@@ -0,0 +1,392 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/*
+ * Copyright (c) 2025 Rockchip Electronics Co., Ltd.
+ * Author: Elaine Zhang <zhangqing at rock-chips.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RV1126B_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_RV1126B_H
+
+/* pll clocks */
+#define PLL_GPLL				0
+#define PLL_CPLL				1
+#define PLL_AUPLL				2
+#define ARMCLK					3
+#define SCLK_DDR				4
+
+/* clk (clocks) */
+#define CLK_CPLL_DIV20				5
+#define CLK_CPLL_DIV10				6
+#define CLK_CPLL_DIV8				7
+#define CLK_GPLL_DIV8				8
+#define CLK_GPLL_DIV6				9
+#define CLK_GPLL_DIV4				10
+#define CLK_CPLL_DIV3				11
+#define CLK_GPLL_DIV3				12
+#define CLK_CPLL_DIV2				13
+#define CLK_GPLL_DIV2				14
+#define CLK_CM_FRAC0				15
+#define CLK_CM_FRAC1				16
+#define CLK_CM_FRAC2				17
+#define CLK_UART_FRAC0				18
+#define CLK_UART_FRAC1				19
+#define CLK_AUDIO_FRAC0				20
+#define CLK_AUDIO_FRAC1				21
+#define CLK_AUDIO_INT0				22
+#define CLK_AUDIO_INT1				23
+#define SCLK_UART0_SRC				24
+#define SCLK_UART1				25
+#define SCLK_UART2				26
+#define SCLK_UART3				27
+#define SCLK_UART4				28
+#define SCLK_UART5				29
+#define SCLK_UART6				30
+#define SCLK_UART7				31
+#define MCLK_SAI0				32
+#define MCLK_SAI1				33
+#define MCLK_SAI2				34
+#define MCLK_PDM				35
+#define CLKOUT_PDM				36
+#define MCLK_ASRC0				37
+#define MCLK_ASRC1				38
+#define MCLK_ASRC2				39
+#define MCLK_ASRC3				40
+#define CLK_ASRC0				41
+#define CLK_ASRC1				42
+#define CLK_CORE_PLL				43
+#define CLK_NPU_PLL				44
+#define CLK_VEPU_PLL				45
+#define CLK_ISP_PLL				46
+#define CLK_AISP_PLL				47
+#define CLK_SARADC0_SRC				48
+#define CLK_SARADC1_SRC				49
+#define CLK_SARADC2_SRC				50
+#define HCLK_NPU_ROOT				51
+#define PCLK_NPU_ROOT				52
+#define ACLK_VEPU_ROOT				53
+#define HCLK_VEPU_ROOT				54
+#define PCLK_VEPU_ROOT				55
+#define CLK_CORE_RGA_SRC			56
+#define ACLK_GMAC_ROOT				57
+#define ACLK_VI_ROOT				58
+#define HCLK_VI_ROOT				59
+#define PCLK_VI_ROOT				60
+#define DCLK_VICAP_ROOT				61
+#define CLK_SYS_DSMC_ROOT			62
+#define ACLK_VDO_ROOT				63
+#define ACLK_RKVDEC_ROOT			64
+#define HCLK_VDO_ROOT				65
+#define PCLK_VDO_ROOT				66
+#define DCLK_OOC_SRC				67
+#define DCLK_VOP				68
+#define DCLK_DECOM_SRC				69
+#define PCLK_DDR_ROOT				70
+#define ACLK_SYSMEM_SRC				71
+#define ACLK_TOP_ROOT				72
+#define ACLK_BUS_ROOT				73
+#define HCLK_BUS_ROOT				74
+#define PCLK_BUS_ROOT				75
+#define CCLK_SDMMC0				76
+#define CCLK_SDMMC1				77
+#define CCLK_EMMC				78
+#define SCLK_2X_FSPI0				79
+#define CLK_GMAC_PTP_REF_SRC			80
+#define CLK_GMAC_125M				81
+#define CLK_TIMER_ROOT				82
+#define TCLK_WDT_NS_SRC				83
+#define TCLK_WDT_S_SRC				84
+#define TCLK_WDT_HPMCU				85
+#define CLK_CAN0				86
+#define CLK_CAN1				87
+#define PCLK_PERI_ROOT				88
+#define ACLK_PERI_ROOT				89
+#define CLK_I2C_BUS_SRC				90
+#define CLK_SPI0				91
+#define CLK_SPI1				92
+#define BUSCLK_PMU_SRC				93
+#define CLK_PWM0				94
+#define CLK_PWM2				95
+#define CLK_PWM3				96
+#define CLK_PKA_RKCE_SRC			97
+#define ACLK_RKCE_SRC				98
+#define ACLK_VCP_ROOT				99
+#define HCLK_VCP_ROOT				100
+#define PCLK_VCP_ROOT				101
+#define CLK_CORE_FEC_SRC			102
+#define CLK_CORE_AVSP_SRC			103
+#define CLK_50M_GMAC_IOBUF_VI			104
+#define PCLK_TOP_ROOT				105
+#define CLK_MIPI0_OUT2IO			106
+#define CLK_MIPI1_OUT2IO			107
+#define CLK_MIPI2_OUT2IO			108
+#define CLK_MIPI3_OUT2IO			109
+#define CLK_CIF_OUT2IO				110
+#define CLK_MAC_OUT2IO				111
+#define MCLK_SAI0_OUT2IO			112
+#define MCLK_SAI1_OUT2IO			113
+#define MCLK_SAI2_OUT2IO			114
+#define CLK_CM_FRAC0_SRC			115
+#define CLK_CM_FRAC1_SRC			116
+#define CLK_CM_FRAC2_SRC			117
+#define CLK_UART_FRAC0_SRC			118
+#define CLK_UART_FRAC1_SRC			119
+#define CLK_AUDIO_FRAC0_SRC			120
+#define CLK_AUDIO_FRAC1_SRC			121
+#define ACLK_NPU_ROOT				122
+#define HCLK_RKNN				123
+#define ACLK_RKNN				124
+#define PCLK_GPIO3				125
+#define DBCLK_GPIO3				126
+#define PCLK_IOC_VCCIO3				127
+#define PCLK_SARADC0				128
+#define CLK_SARADC0				129
+#define HCLK_SDMMC1				130
+#define HCLK_VEPU				131
+#define ACLK_VEPU				132
+#define CLK_CORE_VEPU				133
+#define HCLK_FEC				134
+#define ACLK_FEC				135
+#define CLK_CORE_FEC				136
+#define HCLK_AVSP				137
+#define ACLK_AVSP				138
+#define BUSCLK_PMU1_ROOT			139
+#define HCLK_AISP				140
+#define ACLK_AISP				141
+#define CLK_CORE_AISP				142
+#define CLK_CORE_ISP_ROOT			143
+#define PCLK_DSMC				144
+#define ACLK_DSMC				145
+#define HCLK_CAN0				146
+#define HCLK_CAN1				147
+#define PCLK_GPIO2				148
+#define DBCLK_GPIO2				149
+#define PCLK_GPIO4				150
+#define DBCLK_GPIO4				151
+#define PCLK_GPIO5				152
+#define DBCLK_GPIO5				153
+#define PCLK_GPIO6				154
+#define DBCLK_GPIO6				155
+#define PCLK_GPIO7				156
+#define DBCLK_GPIO7				157
+#define PCLK_IOC_VCCIO2				158
+#define PCLK_IOC_VCCIO4				159
+#define PCLK_IOC_VCCIO5				160
+#define PCLK_IOC_VCCIO6				161
+#define PCLK_IOC_VCCIO7				162
+#define HCLK_ISP				163
+#define ACLK_ISP				164
+#define CLK_CORE_ISP				165
+#define HCLK_VICAP				166
+#define ACLK_VICAP				167
+#define DCLK_VICAP				168
+#define ISP0CLK_VICAP				169
+#define HCLK_VPSS				170
+#define ACLK_VPSS				171
+#define CLK_CORE_VPSS				172
+#define PCLK_CSI2HOST0				173
+#define DCLK_CSI2HOST0				174
+#define PCLK_CSI2HOST1				175
+#define DCLK_CSI2HOST1				176
+#define PCLK_CSI2HOST2				177
+#define DCLK_CSI2HOST2				178
+#define PCLK_CSI2HOST3				179
+#define DCLK_CSI2HOST3				180
+#define HCLK_SDMMC0				181
+#define ACLK_GMAC				182
+#define PCLK_GMAC				183
+#define CLK_GMAC_PTP_REF			184
+#define PCLK_CSIPHY0				185
+#define PCLK_CSIPHY1				186
+#define PCLK_MACPHY				187
+#define PCLK_SARADC1				188
+#define CLK_SARADC1				189
+#define PCLK_SARADC2				190
+#define CLK_SARADC2				191
+#define ACLK_RKVDEC				192
+#define HCLK_RKVDEC				193
+#define CLK_HEVC_CA_RKVDEC			194
+#define ACLK_VOP				195
+#define HCLK_VOP				196
+#define HCLK_RKJPEG				197
+#define ACLK_RKJPEG				198
+#define ACLK_RKMMU_DECOM			199
+#define HCLK_RKMMU_DECOM			200
+#define DCLK_DECOM				201
+#define ACLK_DECOM				202
+#define PCLK_DECOM				203
+#define PCLK_MIPI_DSI				204
+#define PCLK_DSIPHY				205
+#define ACLK_OOC				206
+#define ACLK_SYSMEM				207
+#define PCLK_DDRC				208
+#define PCLK_DDRMON				209
+#define CLK_TIMER_DDRMON			210
+#define PCLK_DFICTRL				211
+#define PCLK_DDRPHY				212
+#define PCLK_DMA2DDR				213
+#define CLK_RCOSC_SRC				214
+#define BUSCLK_PMU_MUX				215
+#define BUSCLK_PMU_ROOT				216
+#define PCLK_PMU				217
+#define CLK_XIN_RC_DIV				218
+#define CLK_32K					219
+#define PCLK_PMU_GPIO0				220
+#define DBCLK_PMU_GPIO0				221
+#define PCLK_PMU_HP_TIMER			222
+#define CLK_PMU_HP_TIMER			223
+#define CLK_PMU_32K_HP_TIMER			224
+#define PCLK_PWM1				225
+#define CLK_PWM1				226
+#define CLK_OSC_PWM1				227
+#define CLK_RC_PWM1				228
+#define CLK_FREQ_PWM1				229
+#define CLK_COUNTER_PWM1			230
+#define PCLK_I2C2				231
+#define CLK_I2C2				232
+#define PCLK_UART0				233
+#define SCLK_UART0				234
+#define PCLK_RCOSC_CTRL				235
+#define CLK_OSC_RCOSC_CTRL			236
+#define CLK_REF_RCOSC_CTRL			237
+#define PCLK_IOC_PMUIO0				238
+#define CLK_REFOUT				239
+#define CLK_PREROLL				240
+#define CLK_PREROLL_32K				241
+#define HCLK_PMU_SRAM				242
+#define PCLK_WDT_LPMCU				243
+#define TCLK_WDT_LPMCU				244
+#define CLK_LPMCU				245
+#define CLK_LPMCU_RTC				246
+#define PCLK_LPMCU_MAILBOX			247
+#define HCLK_OOC				248
+#define PCLK_SPI2AHB				249
+#define HCLK_SPI2AHB				250
+#define HCLK_FSPI1				251
+#define HCLK_XIP_FSPI1				252
+#define SCLK_1X_FSPI1				253
+#define PCLK_IOC_PMUIO1				254
+#define PCLK_AUDIO_ADC_PMU			255
+#define MCLK_AUDIO_ADC_PMU			256
+#define MCLK_AUDIO_ADC_DIV4_PMU			257
+#define MCLK_LPSAI				258
+#define ACLK_GIC400				259
+#define PCLK_WDT_NS				260
+#define TCLK_WDT_NS				261
+#define PCLK_WDT_HPMCU				262
+#define HCLK_CACHE				263
+#define PCLK_HPMCU_MAILBOX			264
+#define PCLK_HPMCU_INTMUX			265
+#define CLK_HPMCU				266
+#define CLK_HPMCU_RTC				267
+#define PCLK_RKDMA				268
+#define ACLK_RKDMA				269
+#define PCLK_DCF				270
+#define ACLK_DCF				271
+#define HCLK_RGA				272
+#define ACLK_RGA				273
+#define CLK_CORE_RGA				274
+#define PCLK_TIMER				275
+#define CLK_TIMER0				276
+#define CLK_TIMER1				277
+#define CLK_TIMER2				278
+#define CLK_TIMER3				279
+#define CLK_TIMER4				280
+#define CLK_TIMER5				281
+#define PCLK_I2C0				282
+#define CLK_I2C0				283
+#define PCLK_I2C1				284
+#define CLK_I2C1				285
+#define PCLK_I2C3				286
+#define CLK_I2C3				287
+#define PCLK_I2C4				288
+#define CLK_I2C4				289
+#define PCLK_I2C5				290
+#define CLK_I2C5				291
+#define PCLK_SPI0				292
+#define PCLK_SPI1				293
+#define PCLK_PWM0				294
+#define CLK_OSC_PWM0				295
+#define CLK_RC_PWM0				296
+#define PCLK_PWM2				297
+#define CLK_OSC_PWM2				298
+#define CLK_RC_PWM2				299
+#define PCLK_PWM3				300
+#define CLK_OSC_PWM3				301
+#define CLK_RC_PWM3				302
+#define PCLK_UART1				303
+#define PCLK_UART2				304
+#define PCLK_UART3				305
+#define PCLK_UART4				306
+#define PCLK_UART5				307
+#define PCLK_UART6				308
+#define PCLK_UART7				309
+#define PCLK_TSADC				310
+#define CLK_TSADC				311
+#define HCLK_SAI0				312
+#define HCLK_SAI1				313
+#define HCLK_SAI2				314
+#define HCLK_RKDSM				315
+#define MCLK_RKDSM				316
+#define HCLK_PDM				317
+#define HCLK_ASRC0				318
+#define HCLK_ASRC1				319
+#define PCLK_AUDIO_ADC_BUS			320
+#define MCLK_AUDIO_ADC_BUS			321
+#define MCLK_AUDIO_ADC_DIV4_BUS			322
+#define PCLK_RKCE				323
+#define HCLK_NS_RKCE				324
+#define PCLK_OTPC_NS				325
+#define CLK_SBPI_OTPC_NS			326
+#define CLK_USER_OTPC_NS			327
+#define CLK_OTPC_ARB				328
+#define PCLK_OTP_MASK				329
+#define CLK_TSADC_PHYCTRL			330
+#define LRCK_SRC_ASRC0				331
+#define LRCK_DST_ASRC0				332
+#define LRCK_SRC_ASRC1				333
+#define LRCK_DST_ASRC1				334
+#define PCLK_KEY_READER				335
+#define ACLK_NSRKCE				336
+#define CLK_PKA_NSRKCE				337
+#define PCLK_RTC_ROOT				338
+#define PCLK_GPIO1				339
+#define DBCLK_GPIO1				340
+#define PCLK_IOC_VCCIO1				341
+#define ACLK_USB3OTG				342
+#define CLK_REF_USB3OTG				343
+#define CLK_SUSPEND_USB3OTG			344
+#define HCLK_USB2HOST				345
+#define HCLK_ARB_USB2HOST			346
+#define PCLK_RTC_TEST				347
+#define HCLK_EMMC				348
+#define HCLK_FSPI0				349
+#define HCLK_XIP_FSPI0				350
+#define PCLK_PIPEPHY				351
+#define PCLK_USB2PHY				352
+#define CLK_REF_PIPEPHY_CPLL_SRC		353
+#define CLK_REF_PIPEPHY				354
+#define HCLK_VPSL				355
+#define ACLK_VPSL				356
+#define CLK_CORE_VPSL				357
+#define CLK_MACPHY				358
+#define HCLK_RKRNG_NS				359
+#define HCLK_RKRNG_S_NS				360
+#define CLK_AISP_PLL_SRC			361
+
+/* secure clks */
+#define CLK_USER_OTPC_S				362
+#define CLK_SBPI_OTPC_S				363
+#define PCLK_OTPC_S				364
+#define PCLK_KEY_READER_S			365
+#define HCLK_KL_RKCE_S				366
+#define HCLK_RKCE_S				367
+#define PCLK_WDT_S				368
+#define TCLK_WDT_S				369
+#define CLK_STIMER0				370
+#define CLK_STIMER1				371
+#define PLK_STIMER				372
+#define HCLK_RKRNG_S				373
+#define CLK_PKA_RKCE_S				374
+#define ACLK_RKCE_S				375
+
+#endif
diff --git a/include/dt-bindings/reset/rockchip,rv1126b-cru.h b/include/dt-bindings/reset/rockchip,rv1126b-cru.h
new file mode 100644
index 000000000000..a7712db319d0
--- /dev/null
+++ b/include/dt-bindings/reset/rockchip,rv1126b-cru.h
@@ -0,0 +1,405 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/*
+ * Copyright (c) 2025 Rockchip Electronics Co., Ltd.
+ * Author: Elaine Zhang <zhangqing at rock-chips.com>
+ */
+
+#ifndef _DT_BINDINGS_RESET_ROCKCHIP_RV1126B_H
+#define _DT_BINDINGS_RESET_ROCKCHIP_RV1126B_H
+
+/* ==========================list all of reset fields id=========================== */
+/* TOPCRU-->SOFTRST_CON00 */
+
+/* TOPCRU-->SOFTRST_CON15 */
+#define SRST_P_CRU				0
+#define SRST_P_CRU_BIU				1
+
+/* BUSCRU-->SOFTRST_CON00 */
+#define SRST_A_TOP_BIU				2
+#define SRST_A_RKCE_BIU				3
+#define SRST_A_BUS_BIU				4
+#define SRST_H_BUS_BIU				5
+#define SRST_P_BUS_BIU				6
+#define SRST_P_CRU_BUS				7
+#define SRST_P_SYS_GRF				8
+#define SRST_H_BOOTROM				9
+#define SRST_A_GIC400				10
+#define SRST_A_SPINLOCK				11
+#define SRST_P_WDT_NS				12
+#define SRST_T_WDT_NS				13
+
+/* BUSCRU-->SOFTRST_CON01 */
+#define SRST_P_WDT_HPMCU			14
+#define SRST_T_WDT_HPMCU			15
+#define SRST_H_CACHE				16
+#define SRST_P_HPMCU_MAILBOX			17
+#define SRST_P_HPMCU_INTMUX			18
+#define SRST_HPMCU_FULL_CLUSTER			19
+#define SRST_HPMCU_PWUP				20
+#define SRST_HPMCU_ONLY_CORE			21
+#define SRST_T_HPMCU_JTAG			22
+#define SRST_P_RKDMA				23
+#define SRST_A_RKDMA				24
+
+/* BUSCRU-->SOFTRST_CON02 */
+#define SRST_P_DCF				25
+#define SRST_A_DCF				26
+#define SRST_H_RGA				27
+#define SRST_A_RGA				28
+#define SRST_CORE_RGA				29
+#define SRST_P_TIMER				30
+#define SRST_TIMER0				31
+#define SRST_TIMER1				32
+#define SRST_TIMER2				33
+#define SRST_TIMER3				34
+#define SRST_TIMER4				35
+#define SRST_TIMER5				36
+#define SRST_A_RKCE				37
+#define SRST_PKA_RKCE				38
+#define SRST_H_RKRNG_S				39
+#define SRST_H_RKRNG_NS				40
+
+/* BUSCRU-->SOFTRST_CON03 */
+#define SRST_P_I2C0				41
+#define SRST_I2C0				42
+#define SRST_P_I2C1				43
+#define SRST_I2C1				44
+#define SRST_P_I2C3				45
+#define SRST_I2C3				46
+#define SRST_P_I2C4				47
+#define SRST_I2C4				48
+#define SRST_P_I2C5				49
+#define SRST_I2C5				50
+#define SRST_P_SPI0				51
+#define SRST_SPI0				52
+#define SRST_P_SPI1				53
+#define SRST_SPI1				54
+
+/* BUSCRU-->SOFTRST_CON04 */
+#define SRST_P_PWM0				55
+#define SRST_PWM0				56
+#define SRST_P_PWM2				57
+#define SRST_PWM2				58
+#define SRST_P_PWM3				59
+#define SRST_PWM3				60
+
+/* BUSCRU-->SOFTRST_CON05 */
+#define SRST_P_UART1				61
+#define SRST_S_UART1				62
+#define SRST_P_UART2				63
+#define SRST_S_UART2				64
+#define SRST_P_UART3				65
+#define SRST_S_UART3				66
+#define SRST_P_UART4				67
+#define SRST_S_UART4				68
+#define SRST_P_UART5				69
+#define SRST_S_UART5				70
+#define SRST_P_UART6				71
+#define SRST_S_UART6				72
+#define SRST_P_UART7				73
+#define SRST_S_UART7				74
+
+/* BUSCRU-->SOFTRST_CON06 */
+#define SRST_P_TSADC				75
+#define SRST_TSADC				76
+#define SRST_H_SAI0				77
+#define SRST_M_SAI0				78
+#define SRST_H_SAI1				79
+#define SRST_M_SAI1				80
+#define SRST_H_SAI2				81
+#define SRST_M_SAI2				82
+#define SRST_H_RKDSM				83
+#define SRST_M_RKDSM				84
+#define SRST_H_PDM				85
+#define SRST_M_PDM				86
+#define SRST_PDM				87
+
+/* BUSCRU-->SOFTRST_CON07 */
+#define SRST_H_ASRC0				88
+#define SRST_ASRC0				89
+#define SRST_H_ASRC1				90
+#define SRST_ASRC1				91
+#define SRST_P_AUDIO_ADC_BUS			92
+#define SRST_M_AUDIO_ADC_BUS			93
+#define SRST_P_RKCE				94
+#define SRST_H_NS_RKCE				95
+#define SRST_P_OTPC_NS				96
+#define SRST_SBPI_OTPC_NS			97
+#define SRST_USER_OTPC_NS			98
+#define SRST_OTPC_ARB				99
+#define SRST_P_OTP_MASK				100
+
+/* PERICRU-->SOFTRST_CON00 */
+#define SRST_A_PERI_BIU				101
+#define SRST_P_PERI_BIU				102
+#define SRST_P_RTC_BIU				103
+#define SRST_P_CRU_PERI				104
+#define SRST_P_PERI_GRF				105
+#define SRST_P_GPIO1				106
+#define SRST_DB_GPIO1				107
+#define SRST_P_IOC_VCCIO1			108
+#define SRST_A_USB3OTG				109
+#define SRST_H_USB2HOST				110
+#define SRST_H_ARB_USB2HOST			111
+#define SRST_P_RTC_TEST				112
+
+/* PERICRU-->SOFTRST_CON01 */
+#define SRST_H_EMMC				113
+#define SRST_H_FSPI0				114
+#define SRST_H_XIP_FSPI0			115
+#define SRST_S_2X_FSPI0				116
+#define SRST_UTMI_USB2HOST			117
+#define SRST_REF_PIPEPHY			118
+#define SRST_P_PIPEPHY				119
+#define SRST_P_PIPEPHY_GRF			120
+#define SRST_P_USB2PHY				121
+#define SRST_POR_USB2PHY			122
+#define SRST_OTG_USB2PHY			123
+#define SRST_HOST_USB2PHY			124
+
+/* CORECRU-->SOFTRST_CON00 */
+#define SRST_REF_PVTPLL_CORE			125
+#define SRST_NCOREPORESET0			126
+#define SRST_NCORESET0				127
+#define SRST_NCOREPORESET1			128
+#define SRST_NCORESET1				129
+#define SRST_NCOREPORESET2			130
+#define SRST_NCORESET2				131
+#define SRST_NCOREPORESET3			132
+#define SRST_NCORESET3				133
+#define SRST_NDBGRESET				134
+#define SRST_NL2RESET				135
+
+/* CORECRU-->SOFTRST_CON01 */
+#define SRST_A_CORE_BIU				136
+#define SRST_P_CORE_BIU				137
+#define SRST_H_CORE_BIU				138
+#define SRST_P_DBG				139
+#define SRST_POT_DBG				140
+#define SRST_NT_DBG				141
+#define SRST_P_CORE_PVTPLL			142
+#define SRST_P_CRU_CORE				143
+#define SRST_P_CORE_GRF				144
+#define SRST_P_DFT2APB				145
+
+/* PMUCRU-->SOFTRST_CON00 */
+#define SRST_H_PMU_BIU				146
+#define SRST_P_PMU_GPIO0			147
+#define SRST_DB_PMU_GPIO0			148
+#define SRST_P_PMU_HP_TIMER			149
+#define SRST_PMU_HP_TIMER			150
+#define SRST_PMU_32K_HP_TIMER			151
+
+/* PMUCRU-->SOFTRST_CON01 */
+#define SRST_P_PWM1				152
+#define SRST_PWM1				153
+#define SRST_P_I2C2				154
+#define SRST_I2C2				155
+#define SRST_P_UART0				156
+#define SRST_S_UART0				157
+
+/* PMUCRU-->SOFTRST_CON02 */
+#define SRST_P_RCOSC_CTRL			158
+#define SRST_REF_RCOSC_CTRL			159
+#define SRST_P_IOC_PMUIO0			160
+#define SRST_P_CRU_PMU				161
+#define SRST_P_PMU_GRF				162
+#define SRST_PREROLL				163
+#define SRST_PREROLL_32K			164
+#define SRST_H_PMU_SRAM				165
+
+/* PMUCRU-->SOFTRST_CON03 */
+#define SRST_P_WDT_LPMCU			166
+#define SRST_T_WDT_LPMCU			167
+#define SRST_LPMCU_FULL_CLUSTER			168
+#define SRST_LPMCU_PWUP				169
+#define SRST_LPMCU_ONLY_CORE			170
+#define SRST_T_LPMCU_JTAG			171
+#define SRST_P_LPMCU_MAILBOX			172
+
+/* PMU1CRU-->SOFTRST_CON00 */
+#define SRST_P_SPI2AHB				173
+#define SRST_H_SPI2AHB				174
+#define SRST_H_FSPI1				175
+#define SRST_H_XIP_FSPI1			176
+#define SRST_S_1X_FSPI1				177
+#define SRST_P_IOC_PMUIO1			178
+#define SRST_P_CRU_PMU1				179
+#define SRST_P_AUDIO_ADC_PMU			180
+#define SRST_M_AUDIO_ADC_PMU			181
+#define SRST_H_PMU1_BIU				182
+
+/* PMU1CRU-->SOFTRST_CON01 */
+#define SRST_P_LPDMA				183
+#define SRST_A_LPDMA				184
+#define SRST_H_LPSAI				185
+#define SRST_M_LPSAI				186
+#define SRST_P_AOA_TDD				187
+#define SRST_P_AOA_FE				188
+#define SRST_P_AOA_AAD				189
+#define SRST_P_AOA_APB				190
+#define SRST_P_AOA_SRAM				191
+
+/* DDRCRU-->SOFTRST_CON00 */
+#define SRST_P_DDR_BIU				192
+#define SRST_P_DDRC				193
+#define SRST_P_DDRMON				194
+#define SRST_TIMER_DDRMON			195
+#define SRST_P_DFICTRL				196
+#define SRST_P_DDR_GRF				197
+#define SRST_P_CRU_DDR				198
+#define SRST_P_DDRPHY				199
+#define SRST_P_DMA2DDR				200
+
+/* SUBDDRCRU-->SOFTRST_CON00 */
+#define SRST_A_SYSMEM_BIU			201
+#define SRST_A_SYSMEM				202
+#define SRST_A_DDR_BIU				203
+#define SRST_A_DDRSCH0_CPU			204
+#define SRST_A_DDRSCH1_NPU			205
+#define SRST_A_DDRSCH2_POE			206
+#define SRST_A_DDRSCH3_VI			207
+#define SRST_CORE_DDRC				208
+#define SRST_DDRMON				209
+#define SRST_DFICTRL				210
+#define SRST_RS					211
+#define SRST_A_DMA2DDR				212
+#define SRST_DDRPHY				213
+
+/* VICRU-->SOFTRST_CON00 */
+#define SRST_REF_PVTPLL_ISP			214
+#define SRST_A_GMAC_BIU				215
+#define SRST_A_VI_BIU				216
+#define SRST_H_VI_BIU				217
+#define SRST_P_VI_BIU				218
+#define SRST_P_CRU_VI				219
+#define SRST_P_VI_GRF				220
+#define SRST_P_VI_PVTPLL			221
+#define SRST_P_DSMC				222
+#define SRST_A_DSMC				223
+#define SRST_H_CAN0				224
+#define SRST_CAN0				225
+#define SRST_H_CAN1				226
+#define SRST_CAN1				227
+
+/* VICRU-->SOFTRST_CON01 */
+#define SRST_P_GPIO2				228
+#define SRST_DB_GPIO2				229
+#define SRST_P_GPIO4				230
+#define SRST_DB_GPIO4				231
+#define SRST_P_GPIO5				232
+#define SRST_DB_GPIO5				233
+#define SRST_P_GPIO6				234
+#define SRST_DB_GPIO6				235
+#define SRST_P_GPIO7				236
+#define SRST_DB_GPIO7				237
+#define SRST_P_IOC_VCCIO2			238
+#define SRST_P_IOC_VCCIO4			239
+#define SRST_P_IOC_VCCIO5			240
+#define SRST_P_IOC_VCCIO6			241
+#define SRST_P_IOC_VCCIO7			242
+
+/* VICRU-->SOFTRST_CON02 */
+#define SRST_CORE_ISP				243
+#define SRST_H_VICAP				244
+#define SRST_A_VICAP				245
+#define SRST_D_VICAP				246
+#define SRST_ISP0_VICAP				247
+#define SRST_CORE_VPSS				248
+#define SRST_CORE_VPSL				249
+#define SRST_P_CSI2HOST0			250
+#define SRST_P_CSI2HOST1			251
+#define SRST_P_CSI2HOST2			252
+#define SRST_P_CSI2HOST3			253
+#define SRST_H_SDMMC0				254
+#define SRST_A_GMAC				255
+#define SRST_P_CSIPHY0				256
+#define SRST_P_CSIPHY1				257
+
+/* VICRU-->SOFTRST_CON03 */
+#define SRST_P_MACPHY				258
+#define SRST_MACPHY				259
+#define SRST_P_SARADC1				260
+#define SRST_SARADC1				261
+#define SRST_P_SARADC2				262
+#define SRST_SARADC2				263
+
+/* VEPUCRU-->SOFTRST_CON00 */
+#define SRST_REF_PVTPLL_VEPU			264
+#define SRST_A_VEPU_BIU				265
+#define SRST_H_VEPU_BIU				266
+#define SRST_P_VEPU_BIU				267
+#define SRST_P_CRU_VEPU				268
+#define SRST_P_VEPU_GRF				269
+#define SRST_P_GPIO3				270
+#define SRST_DB_GPIO3				271
+#define SRST_P_IOC_VCCIO3			272
+#define SRST_P_SARADC0				273
+#define SRST_SARADC0				274
+#define SRST_H_SDMMC1				275
+
+/* VEPUCRU-->SOFTRST_CON01 */
+#define SRST_P_VEPU_PVTPLL			276
+#define SRST_H_VEPU				277
+#define SRST_A_VEPU				278
+#define SRST_CORE_VEPU				279
+
+/* NPUCRU-->SOFTRST_CON00 */
+#define SRST_REF_PVTPLL_NPU			280
+#define SRST_A_NPU_BIU				281
+#define SRST_H_NPU_BIU				282
+#define SRST_P_NPU_BIU				283
+#define SRST_P_CRU_NPU				284
+#define SRST_P_NPU_GRF				285
+#define SRST_P_NPU_PVTPLL			286
+#define SRST_H_RKNN				287
+#define SRST_A_RKNN				288
+
+/* VDOCRU-->SOFTRST_CON00 */
+#define SRST_A_RKVDEC_BIU			289
+#define SRST_A_VDO_BIU				290
+#define SRST_H_VDO_BIU				291
+#define SRST_P_VDO_BIU				292
+#define SRST_P_CRU_VDO				293
+#define SRST_P_VDO_GRF				294
+#define SRST_A_RKVDEC				295
+#define SRST_H_RKVDEC				296
+#define SRST_HEVC_CA_RKVDEC			297
+#define SRST_A_VOP				298
+#define SRST_H_VOP				299
+#define SRST_D_VOP				300
+#define SRST_A_OOC				301
+#define SRST_H_OOC				302
+#define SRST_D_OOC				303
+
+/* VDOCRU-->SOFTRST_CON01 */
+#define SRST_H_RKJPEG				304
+#define SRST_A_RKJPEG				305
+#define SRST_A_RKMMU_DECOM			306
+#define SRST_H_RKMMU_DECOM			307
+#define SRST_D_DECOM				308
+#define SRST_A_DECOM				309
+#define SRST_P_DECOM				310
+#define SRST_P_MIPI_DSI				311
+#define SRST_P_DSIPHY				312
+
+/* VCPCRU-->SOFTRST_CON00 */
+#define SRST_REF_PVTPLL_VCP			313
+#define SRST_A_VCP_BIU				314
+#define SRST_H_VCP_BIU				315
+#define SRST_P_VCP_BIU				316
+#define SRST_P_CRU_VCP				317
+#define SRST_P_VCP_GRF				318
+#define SRST_P_VCP_PVTPLL			319
+#define SRST_A_AISP_BIU				320
+#define SRST_H_AISP_BIU				321
+#define SRST_CORE_AISP				322
+
+/* VCPCRU-->SOFTRST_CON01 */
+#define SRST_H_FEC				323
+#define SRST_A_FEC				324
+#define SRST_CORE_FEC				325
+#define SRST_H_AVSP				326
+#define SRST_A_AVSP				327
+
+#endif
-- 
2.34.1



From zhangqing at rock-chips.com  Mon Nov 10 18:57:36 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Tue, 11 Nov 2025 10:57:36 +0800
Subject: [PATCH v7 3/5] clk: rockchip: Add clock controller for the RV1126B
In-Reply-To: <20251111025738.869847-1-zhangqing@rock-chips.com>
References: <20251111025738.869847-1-zhangqing@rock-chips.com>
Message-ID: <20251111025738.869847-4-zhangqing@rock-chips.com>

Add the clock and reset tree definitions for the new
rv1126b SoC.

Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
---
 drivers/clk/rockchip/Kconfig       |    7 +
 drivers/clk/rockchip/Makefile      |    1 +
 drivers/clk/rockchip/clk-rv1126b.c | 1103 ++++++++++++++++++++++++++++
 drivers/clk/rockchip/clk.h         |   68 ++
 drivers/clk/rockchip/rst-rv1126b.c |  444 +++++++++++
 5 files changed, 1623 insertions(+)
 create mode 100644 drivers/clk/rockchip/clk-rv1126b.c
 create mode 100644 drivers/clk/rockchip/rst-rv1126b.c

diff --git a/drivers/clk/rockchip/Kconfig b/drivers/clk/rockchip/Kconfig
index febb7944f34b..e1ea0a098ca9 100644
--- a/drivers/clk/rockchip/Kconfig
+++ b/drivers/clk/rockchip/Kconfig
@@ -30,6 +30,13 @@ config CLK_RV1126
 	help
 	  Build the driver for RV1126 Clock Driver.
 
+config CLK_RV1126B
+	bool "Rockchip RV1126B clock controller support"
+	depends on ARM64 || COMPILE_TEST
+	default y
+	help
+	  Build the driver for RV1126B Clock Driver.
+
 config CLK_RK3036
 	bool "Rockchip RK3036 clock controller support"
 	depends on ARM || COMPILE_TEST
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index c281a9738d9f..82b4b29ad036 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -20,6 +20,7 @@ clk-rockchip-$(CONFIG_RESET_CONTROLLER) += softrst.o
 obj-$(CONFIG_CLK_PX30)          += clk-px30.o
 obj-$(CONFIG_CLK_RV110X)        += clk-rv1108.o
 obj-$(CONFIG_CLK_RV1126)        += clk-rv1126.o
+obj-$(CONFIG_CLK_RV1126B)	+= clk-rv1126b.o rst-rv1126b.o
 obj-$(CONFIG_CLK_RK3036)        += clk-rk3036.o
 obj-$(CONFIG_CLK_RK312X)        += clk-rk3128.o
 obj-$(CONFIG_CLK_RK3188)        += clk-rk3188.o
diff --git a/drivers/clk/rockchip/clk-rv1126b.c b/drivers/clk/rockchip/clk-rv1126b.c
new file mode 100644
index 000000000000..2e7ea28649fc
--- /dev/null
+++ b/drivers/clk/rockchip/clk-rv1126b.c
@@ -0,0 +1,1103 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2024 Rockchip Electronics Co., Ltd.
+ * Author: Elaine Zhang <zhangqing at rock-chips.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/syscore_ops.h>
+#include <dt-bindings/clock/rockchip,rv1126b-cru.h>
+#include "clk.h"
+
+#define RV1126B_FRAC_MAX_PRATE		1200000000
+
+#define PVTPLL_SRC_SEL_PVTPLL		(BIT(0) | BIT(16))
+
+enum rv1126b_plls {
+	gpll, cpll, aupll, dpll
+};
+
+static struct rockchip_pll_rate_table rv1126b_pll_rates[] = {
+	/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
+	RK3036_PLL_RATE(1200000000, 1, 100, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1179648000, 1, 49, 1, 1, 0, 2550137),
+	RK3036_PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0),
+	RK3036_PLL_RATE(993484800, 1, 41, 1, 1, 0, 6630355),
+	RK3036_PLL_RATE(983040000, 1, 40, 1, 1, 0, 16106127),
+	RK3036_PLL_RATE(903168000, 1, 75, 2, 1, 0, 4429185),
+	{ /* sentinel */ },
+};
+
+#define RV1126B_DIV_ACLK_CORE_MASK	0x1f
+#define RV1126B_DIV_ACLK_CORE_SHIFT	0
+#define RV1126B_DIV_PCLK_CORE_MASK	0x1f
+#define RV1126B_DIV_PCLK_CORE_SHIFT	8
+#define RV1126B_CORE_SEL_MASK		0x1
+#define RV1126B_CORE_SEL_SHIFT		1
+
+#define RV1126B_CLKSEL0(_aclk_core)						\
+{										\
+	.reg = RV1126B_CORECLKSEL_CON(2),					\
+	.val = HIWORD_UPDATE(_aclk_core - 1, RV1126B_DIV_ACLK_CORE_MASK,	\
+			     RV1126B_DIV_ACLK_CORE_SHIFT),			\
+}
+
+#define RV1126B_CLKSEL1(_pclk_dbg)						\
+{										\
+	.reg = RV1126B_CORECLKSEL_CON(2),					\
+	.val = HIWORD_UPDATE(_pclk_dbg - 1, RV1126B_DIV_PCLK_CORE_MASK,		\
+			     RV1126B_DIV_PCLK_CORE_SHIFT),			\
+}
+
+#define RV1126B_CPUCLK_RATE(_prate, _aclk_core, _pclk_dbg)			\
+{										\
+	.prate = _prate,							\
+	.divs = {								\
+		RV1126B_CLKSEL0(_aclk_core),					\
+		RV1126B_CLKSEL1(_pclk_dbg),					\
+	},									\
+}
+
+static struct rockchip_cpuclk_rate_table rv1126b_cpuclk_rates[] __initdata = {
+	RV1126B_CPUCLK_RATE(1608000000, 4, 10),
+	RV1126B_CPUCLK_RATE(1512000000, 4, 10),
+	RV1126B_CPUCLK_RATE(1416000000, 4, 10),
+	RV1126B_CPUCLK_RATE(1296000000, 3, 10),
+	RV1126B_CPUCLK_RATE(1200000000, 3, 10),
+	RV1126B_CPUCLK_RATE(1188000000, 3, 8),
+	RV1126B_CPUCLK_RATE(1104000000, 2, 8),
+	RV1126B_CPUCLK_RATE(1008000000, 2, 8),
+	RV1126B_CPUCLK_RATE(816000000, 2, 6),
+	RV1126B_CPUCLK_RATE(600000000, 2, 4),
+	RV1126B_CPUCLK_RATE(594000000, 2, 4),
+	RV1126B_CPUCLK_RATE(408000000, 1, 3),
+	RV1126B_CPUCLK_RATE(396000000, 1, 3),
+};
+
+PNAME(mux_pll_p)			= { "xin24m" };
+PNAME(mux_gpll_cpll_p)			= { "gpll", "cpll" };
+PNAME(mux_gpll_aupll_p)			= { "gpll", "aupll" };
+PNAME(mux_gpll_aupll_cpll_p)		= { "gpll", "aupll", "cpll" };
+PNAME(mux_gpll_cpll_24m_p)		= { "gpll", "cpll", "xin24m" };
+PNAME(mux_cpll_24m_p)			= { "cpll", "xin24m" };
+PNAME(mux_24m_gpll_aupll_cpll_p)	= { "xin24m", "gpll", "aupll", "cpll" };
+PNAME(mux_24m_gpll_cpll_p)		= { "xin24m", "gpll", "cpll" };
+PNAME(mux_24m_gpll_aupll_p)		= { "xin24m", "gpll", "aupll" };
+PNAME(mux_sclk_uart_src_p)		= { "xin24m", "clk_cm_frac0", "clk_cm_frac1", "clk_cm_frac2",
+					    "clk_uart_frac0", "clk_uart_frac1" };
+PNAME(mclk_sai0_src_p)			= { "xin24m", "clk_cm_frac0", "clk_cm_frac1", "clk_cm_frac2",
+					    "clk_audio_frac0", "clk_audio_frac1", "clk_audio_int0", "clk_audio_int1", "mclk_sai0_from_io" };
+PNAME(mclk_sai1_src_p)			= { "xin24m", "clk_cm_frac0", "clk_cm_frac1", "clk_cm_frac2", "clk_audio_frac0",
+					    "clk_audio_frac1", "clk_audio_int0", "clk_audio_int1", "mclk_sai1_from_io" };
+PNAME(mclk_sai2_src_p)			= { "xin24m", "clk_cm_frac0", "clk_cm_frac1", "clk_cm_frac2", "clk_audio_frac0",
+					    "clk_audio_frac1", "clk_audio_int0", "clk_audio_int1", "mclk_sai2_from_io" };
+PNAME(mux_sai_src_p)			= { "xin24m", "clk_cm_frac0", "clk_cm_frac1", "clk_cm_frac2", "clk_audio_frac0",
+					    "clk_audio_frac1", "clk_audio_int0", "clk_audio_int1", "mclk_sai0_from_io",
+					    "mclk_sai1_from_io", "mclk_sai2_from_io"};
+PNAME(mux_100m_24m_p)			= { "clk_cpll_div10", "xin24m" };
+PNAME(mux_200m_24m_p)			= { "clk_gpll_div6", "xin24m" };
+PNAME(mux_500m_400m_200m_p)		= { "clk_cpll_div2", "clk_gpll_div3", "clk_gpll_div6" };
+PNAME(mux_300m_200m_p)			= { "clk_gpll_div4", "clk_gpll_div6" };
+PNAME(mux_500m_400m_300m_p)		= { "clk_cpll_div2", "clk_gpll_div3", "clk_gpll_div4" };
+PNAME(mux_333m_200m_p)			= { "clk_cpll_div3", "clk_gpll_div6" };
+PNAME(mux_600m_400m_200m_p)		= { "clk_gpll_div2", "clk_gpll_div3", "clk_gpll_div6" };
+PNAME(mux_400m_300m_200m_p)		= { "clk_gpll_div3", "clk_gpll_div4", "clk_gpll_div6" };
+PNAME(mux_200m_100m_p)			= { "clk_gpll_div6", "clk_cpll_div10" };
+PNAME(mux_200m_100m_50m_24m_p)		= { "clk_gpll_div6", "clk_cpll_div10", "clk_cpll_div20", "xin24m" };
+PNAME(mux_600m_24m_p)			= { "clk_gpll_div2", "xin24m" };
+PNAME(mux_armclk_p)			= { "clk_core_pll", "clk_core_pvtpll" };
+PNAME(aclk_npu_root_p)			= { "clk_npu_pll", "clk_npu_pvtpll" };
+PNAME(clk_saradc0_p)			= { "clk_saradc0_src", "clk_saradc0_rcosc_io" };
+PNAME(clk_core_vepu_p)			= { "clk_vepu_pll", "clk_vepu_pvtpll" };
+PNAME(clk_core_fec_p)			= { "clk_core_fec_src", "clk_vcp_pvtpll" };
+PNAME(clk_core_aisp_p)			= { "clk_aisp_pll", "clk_vcp_pvtpll" };
+PNAME(clk_core_isp_root_p)		= { "clk_isp_pll", "clk_isp_pvtpll" };
+PNAME(clk_gmac_ptp_ref_p)		= { "clk_gmac_ptp_ref_src", "clk_gmac_ptp_from_io" };
+PNAME(clk_saradc1_p)			= { "clk_saradc1_src", "clk_saradc1_rcosc_io" };
+PNAME(clk_saradc2_p)			= { "clk_saradc2_src", "clk_saradc2_rcosc_io" };
+PNAME(clk_rcosc_src_p)			= { "xin24m", "clk_rcosc", "clk_rcosc_div2", "clk_rcosc_div3", "clk_rcosc_div4" };
+PNAME(busclk_pmu_mux_p)			= { "clk_cpll_div10", "clk_rcosc_src" };
+PNAME(clk_xin_rc_div_p)			= { "xin24m", "clk_rcosc_src" };
+PNAME(clk_32k_p)			= { "clk_xin_rc_div", "clk_32k_rtc", "clk_32k_io" };
+PNAME(mux_24m_32k_p)			= { "xin24m", "clk_32k" };
+PNAME(mux_24m_rcosc_buspmu_p)		= { "xin24m", "clk_rcosc_src", "busclk_pmu_src" };
+PNAME(mux_24m_rcosc_buspmu_32k_p)	= { "xin24m", "clk_rcosc_src", "busclk_pmu_src", "clk_32k" };
+PNAME(sclk_uart0_p)			= { "sclk_uart0_src", "xin24m", "clk_rcosc_src" };
+PNAME(clk_osc_rcosc_ctrl_p)		= { "clk_rcosc_src", "clk_testout_out" };
+PNAME(lrck_src_asrc_p)			= { "mclk_asrc0", "mclk_asrc1", "mclk_asrc2", "mclk_asrc3",
+					    "fs_inter_from_sai0", "fs_inter_from_sai1", "fs_inter_from_sai2", "clkout_pdm"};
+PNAME(clk_ref_pipephy_p)		= { "clk_ref_pipephy_cpll_src", "xin24m" };
+PNAME(clk_timer0_parents_p)		= { "clk_timer_root", "mclk_sai0_from_io", "sclk_sai0_from_io" };
+PNAME(clk_timer1_parents_p)		= { "clk_timer_root", "mclk_sai1_from_io", "sclk_sai1_from_io" };
+PNAME(clk_timer2_parents_p)		= { "clk_timer_root", "mclk_sai2_from_io", "sclk_sai2_from_io" };
+PNAME(clk_timer3_parents_p)		= { "clk_timer_root", "mclk_asrc0", "mclk_asrc1" };
+PNAME(clk_timer4_parents_p)		= { "clk_timer_root", "mclk_asrc2", "mclk_asrc3" };
+PNAME(clk_macphy_p)			= { "xin24m", "clk_cpll_div20" };
+PNAME(clk_cpll_div10_p)			= { "gpll", "clk_aisp_pll_src" };
+
+static struct rockchip_pll_clock rv1126b_pll_clks[] __initdata = {
+	[gpll] = PLL(pll_rk3328, PLL_GPLL, "gpll", mux_pll_p,
+		     CLK_IS_CRITICAL, RV1126B_PLL_CON(8),
+		     RV1126B_MODE_CON, 2, 10, 0, rv1126b_pll_rates),
+	[aupll] = PLL(pll_rk3328, PLL_AUPLL, "aupll", mux_pll_p,
+		     CLK_IS_CRITICAL, RV1126B_PLL_CON(0),
+		     RV1126B_MODE_CON, 0, 10, 0, rv1126b_pll_rates),
+	[cpll] = PLL(pll_rk3328, PLL_CPLL, "cpll", mux_pll_p,
+		     CLK_IS_CRITICAL, RV1126B_PERIPLL_CON(0),
+		     RV1126B_MODE_CON, 4, 10, 0, rv1126b_pll_rates),
+	[dpll] = PLL(pll_rk3328, 0, "dpll", mux_pll_p,
+		     CLK_IS_CRITICAL, RV1126B_SUBDDRPLL_CON(0),
+		     RV1126B_MODE_CON, 2, 10, 0, rv1126b_pll_rates),
+};
+
+#define MFLAGS CLK_MUX_HIWORD_MASK
+#define DFLAGS CLK_DIVIDER_HIWORD_MASK
+#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
+
+static struct rockchip_clk_branch rv1126b_rcdiv_pmu_fracmux __initdata =
+	MUX(CLK_32K, "clk_32k", clk_32k_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
+			RV1126B_PMUCLKSEL_CON(2), 1, 2, MFLAGS);
+
+static struct rockchip_clk_branch rv1126b_clk_branches[] __initdata = {
+
+	FACTOR(0, "clk_rcosc_div2", "clk_rcosc", 0, 1, 2),
+	FACTOR(0, "clk_rcosc_div3", "clk_rcosc", 0, 1, 3),
+	FACTOR(0, "clk_rcosc_div4", "clk_rcosc", 0, 1, 4),
+
+	/*       Clock Definition       */
+	COMPOSITE_NODIV(CLK_AISP_PLL_SRC, "clk_aisp_pll_src", mux_gpll_aupll_cpll_p, 0,
+			RV1126B_CLKSEL_CON(62), 4, 2, MFLAGS,
+			RV1126B_CLKGATE_CON(5), 4, GFLAGS),
+	DIV(CLK_AISP_PLL, "clk_aisp_pll", "clk_aisp_pll_src", 0,
+			RV1126B_CLKSEL_CON(62), 0, 3, DFLAGS),
+
+	COMPOSITE(CLK_CPLL_DIV10, "clk_cpll_div10", clk_cpll_div10_p, 0,
+			RV1126B_CLKSEL_CON(1), 15, 1, MFLAGS, 5, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(0), 1, GFLAGS),
+	COMPOSITE_NOMUX(CLK_CPLL_DIV20, "clk_cpll_div20", "cpll", 0,
+			RV1126B_CLKSEL_CON(1), 0, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(0), 0, GFLAGS),
+	COMPOSITE_NOMUX(CLK_CPLL_DIV8, "clk_cpll_div8", "cpll", 0,
+			RV1126B_CLKSEL_CON(1), 10, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(0), 2, GFLAGS),
+	COMPOSITE_NOMUX(CLK_GPLL_DIV8, "clk_gpll_div8", "gpll", 0,
+			RV1126B_CLKSEL_CON(2), 0, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(0), 3, GFLAGS),
+	COMPOSITE_NOMUX(CLK_GPLL_DIV6, "clk_gpll_div6", "gpll", 0,
+			RV1126B_CLKSEL_CON(2), 5, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(0), 4, GFLAGS),
+	COMPOSITE_NOMUX(CLK_GPLL_DIV4, "clk_gpll_div4", "gpll", 0,
+			RV1126B_CLKSEL_CON(2), 10, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(0), 5, GFLAGS),
+	COMPOSITE_NOMUX(CLK_CPLL_DIV3, "clk_cpll_div3", "cpll", 0,
+			RV1126B_CLKSEL_CON(3), 0, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(0), 6, GFLAGS),
+	COMPOSITE_NOMUX(CLK_GPLL_DIV3, "clk_gpll_div3", "gpll", 0,
+			RV1126B_CLKSEL_CON(3), 5, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(0), 7, GFLAGS),
+	COMPOSITE_NOMUX(CLK_CPLL_DIV2, "clk_cpll_div2", "cpll", 0,
+			RV1126B_CLKSEL_CON(3), 10, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(0), 8, GFLAGS),
+	COMPOSITE_NOMUX(CLK_GPLL_DIV2, "clk_gpll_div2", "gpll", 0,
+			RV1126B_CLKSEL_CON(4), 0, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(0), 9, GFLAGS),
+	MUX(CLK_CM_FRAC0_SRC, "clk_cm_frac0_src", mux_24m_gpll_aupll_cpll_p, 0,
+			RV1126B_CLKSEL_CON(10), 0, 2, MFLAGS),
+	COMPOSITE_FRAC(CLK_CM_FRAC0, "clk_cm_frac0", "clk_cm_frac0_src", 0,
+			RV1126B_CLKSEL_CON(25), 0,
+			RV1126B_CLKGATE_CON(1), 0, GFLAGS),
+	MUX(CLK_CM_FRAC1_SRC, "clk_cm_frac1_src", mux_24m_gpll_aupll_cpll_p, 0,
+			RV1126B_CLKSEL_CON(10), 2, 2, MFLAGS),
+	COMPOSITE_FRAC(CLK_CM_FRAC1, "clk_cm_frac1", "clk_cm_frac1_src", 0,
+			RV1126B_CLKSEL_CON(26), 0,
+			RV1126B_CLKGATE_CON(1), 1, GFLAGS),
+	MUX(CLK_CM_FRAC2_SRC, "clk_cm_frac2_src", mux_24m_gpll_aupll_cpll_p, 0,
+			RV1126B_CLKSEL_CON(10), 4, 2, MFLAGS),
+	COMPOSITE_FRAC(CLK_CM_FRAC2, "clk_cm_frac2", "clk_cm_frac2_src", 0,
+			RV1126B_CLKSEL_CON(27), 0,
+			RV1126B_CLKGATE_CON(1), 2, GFLAGS),
+	MUX(CLK_UART_FRAC0_SRC, "clk_uart_frac0_src", mux_24m_gpll_cpll_p, 0,
+			RV1126B_CLKSEL_CON(10), 6, 2, MFLAGS),
+	COMPOSITE_FRAC(CLK_UART_FRAC0, "clk_uart_frac0", "clk_uart_frac0_src", 0,
+			RV1126B_CLKSEL_CON(28), 0,
+			RV1126B_CLKGATE_CON(1), 3, GFLAGS),
+	MUX(CLK_UART_FRAC1_SRC, "clk_uart_frac1_src", mux_24m_gpll_cpll_p, 0,
+			RV1126B_CLKSEL_CON(10), 8, 2, MFLAGS),
+	COMPOSITE_FRAC(CLK_UART_FRAC1, "clk_uart_frac1", "clk_uart_frac1_src", 0,
+			RV1126B_CLKSEL_CON(29), 0,
+			RV1126B_CLKGATE_CON(1), 4, GFLAGS),
+	MUX(CLK_AUDIO_FRAC0_SRC, "clk_audio_frac0_src", mux_24m_gpll_aupll_p, 0,
+			RV1126B_CLKSEL_CON(10), 10, 2, MFLAGS),
+	COMPOSITE_FRAC(CLK_AUDIO_FRAC0, "clk_audio_frac0", "clk_audio_frac0_src", 0,
+			RV1126B_CLKSEL_CON(30), 0,
+			RV1126B_CLKGATE_CON(1), 5, GFLAGS),
+	MUX(CLK_AUDIO_FRAC1_SRC, "clk_audio_frac1_src", mux_24m_gpll_aupll_p, 0,
+			RV1126B_CLKSEL_CON(10), 12, 2, MFLAGS),
+	COMPOSITE_FRAC(CLK_AUDIO_FRAC1, "clk_audio_frac1", "clk_audio_frac1_src", 0,
+			RV1126B_CLKSEL_CON(31), 0,
+			RV1126B_CLKGATE_CON(1), 6, GFLAGS),
+	COMPOSITE(CLK_AUDIO_INT0, "clk_audio_int0", mux_24m_gpll_aupll_p, 0,
+			RV1126B_CLKSEL_CON(11), 6, 2, MFLAGS, 0, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(1), 7, GFLAGS),
+	COMPOSITE(CLK_AUDIO_INT1, "clk_audio_int1", mux_24m_gpll_aupll_p, 0,
+			RV1126B_CLKSEL_CON(11), 14, 2, MFLAGS, 8, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(1), 8, GFLAGS),
+	COMPOSITE(SCLK_UART0_SRC, "sclk_uart0_src", mux_sclk_uart_src_p, 0,
+			RV1126B_CLKSEL_CON(12), 5, 3, MFLAGS, 0, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(1), 9, GFLAGS),
+	COMPOSITE(SCLK_UART1, "sclk_uart1", mux_sclk_uart_src_p, 0,
+			RV1126B_CLKSEL_CON(12), 13, 3, MFLAGS, 8, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(1), 10, GFLAGS),
+	COMPOSITE(SCLK_UART2, "sclk_uart2", mux_sclk_uart_src_p, 0,
+			RV1126B_CLKSEL_CON(13), 5, 3, MFLAGS, 0, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(1), 11, GFLAGS),
+	COMPOSITE(SCLK_UART3, "sclk_uart3", mux_sclk_uart_src_p, 0,
+			RV1126B_CLKSEL_CON(13), 13, 3, MFLAGS, 8, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(1), 12, GFLAGS),
+	COMPOSITE(SCLK_UART4, "sclk_uart4", mux_sclk_uart_src_p, 0,
+			RV1126B_CLKSEL_CON(14), 5, 3, MFLAGS, 0, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(1), 13, GFLAGS),
+	COMPOSITE(SCLK_UART5, "sclk_uart5", mux_sclk_uart_src_p, 0,
+			RV1126B_CLKSEL_CON(14), 13, 3, MFLAGS, 8, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(1), 14, GFLAGS),
+	COMPOSITE(SCLK_UART6, "sclk_uart6", mux_sclk_uart_src_p, 0,
+			RV1126B_CLKSEL_CON(15), 5, 3, MFLAGS, 0, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(2), 0, GFLAGS),
+	COMPOSITE(SCLK_UART7, "sclk_uart7", mux_sclk_uart_src_p, 0,
+			RV1126B_CLKSEL_CON(15), 13, 3, MFLAGS, 8, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(2), 1, GFLAGS),
+	COMPOSITE(MCLK_SAI0, "mclk_sai0", mclk_sai0_src_p, 0,
+			RV1126B_CLKSEL_CON(16), 8, 4, MFLAGS, 0, 8, DFLAGS,
+			RV1126B_CLKGATE_CON(2), 2, GFLAGS),
+	COMPOSITE(MCLK_SAI1, "mclk_sai1", mclk_sai1_src_p, 0,
+			RV1126B_CLKSEL_CON(17), 8, 4, MFLAGS, 0, 8, DFLAGS,
+			RV1126B_CLKGATE_CON(2), 3, GFLAGS),
+	COMPOSITE(MCLK_SAI2, "mclk_sai2", mclk_sai2_src_p, 0,
+			RV1126B_CLKSEL_CON(18), 8, 4, MFLAGS, 0, 8, DFLAGS,
+			RV1126B_CLKGATE_CON(2), 4, GFLAGS),
+	COMPOSITE(MCLK_PDM, "mclk_pdm", mux_sai_src_p, 0,
+			RV1126B_CLKSEL_CON(19), 6, 4, MFLAGS, 0, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(2), 5, GFLAGS),
+	COMPOSITE_NOGATE(0, "clkout_pdm_src", mux_sai_src_p, 0,
+			RV1126B_CLKSEL_CON(20), 8, 4, MFLAGS, 0, 8, DFLAGS),
+	GATE(CLKOUT_PDM, "clkout_pdm", "clkout_pdm_src", 0,
+			RV1126B_CLKGATE_CON(2), 6, GFLAGS),
+	COMPOSITE_NODIV(MCLK_ASRC0, "mclk_asrc0", mux_sai_src_p, 0,
+			RV1126B_CLKSEL_CON(16), 12, 4, MFLAGS,
+			RV1126B_CLKGATE_CON(2), 7, GFLAGS),
+	COMPOSITE_NODIV(MCLK_ASRC1, "mclk_asrc1", mux_sai_src_p, 0,
+			RV1126B_CLKSEL_CON(17), 12, 4, MFLAGS,
+			RV1126B_CLKGATE_CON(2), 8, GFLAGS),
+	COMPOSITE_NODIV(MCLK_ASRC2, "mclk_asrc2", mux_sai_src_p, 0,
+			RV1126B_CLKSEL_CON(18), 12, 4, MFLAGS,
+			RV1126B_CLKGATE_CON(2), 9, GFLAGS),
+	COMPOSITE_NODIV(MCLK_ASRC3, "mclk_asrc3", mux_sai_src_p, 0,
+			RV1126B_CLKSEL_CON(19), 12, 4, MFLAGS,
+			RV1126B_CLKGATE_CON(2), 10, GFLAGS),
+	COMPOSITE(CLK_ASRC0, "clk_asrc0", mux_gpll_aupll_p, 0,
+			RV1126B_CLKSEL_CON(21), 6, 1, MFLAGS, 0, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(2), 11, GFLAGS),
+	COMPOSITE(CLK_ASRC1, "clk_asrc1", mux_gpll_aupll_p, 0,
+			RV1126B_CLKSEL_CON(21), 14, 1, MFLAGS, 8, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(2), 12, GFLAGS),
+	COMPOSITE_NOMUX(CLK_CORE_PLL, "clk_core_pll", "gpll", CLK_IS_CRITICAL,
+			RV1126B_CLKSEL_CON(60), 0, 3, DFLAGS,
+			RV1126B_CLKGATE_CON(5), 0, GFLAGS),
+	COMPOSITE_NOMUX(CLK_NPU_PLL, "clk_npu_pll", "gpll", CLK_IS_CRITICAL,
+			RV1126B_CLKSEL_CON(60), 6, 3, DFLAGS,
+			RV1126B_CLKGATE_CON(5), 1, GFLAGS),
+	COMPOSITE(CLK_VEPU_PLL, "clk_vepu_pll", mux_gpll_aupll_cpll_p, 0,
+			RV1126B_CLKSEL_CON(61), 4, 2, MFLAGS, 0, 3, DFLAGS,
+			RV1126B_CLKGATE_CON(5), 2, GFLAGS),
+	COMPOSITE(CLK_ISP_PLL, "clk_isp_pll", mux_gpll_aupll_cpll_p, 0,
+			RV1126B_CLKSEL_CON(61), 10, 2, MFLAGS, 6, 4, DFLAGS,
+			RV1126B_CLKGATE_CON(5), 3, GFLAGS),
+	COMPOSITE(CLK_SARADC0_SRC, "clk_saradc0_src", mux_200m_24m_p, 0,
+			RV1126B_CLKSEL_CON(63), 12, 1, MFLAGS, 0, 3, DFLAGS,
+			RV1126B_CLKGATE_CON(5), 6, GFLAGS),
+	COMPOSITE(CLK_SARADC1_SRC, "clk_saradc1_src", mux_200m_24m_p, 0,
+			RV1126B_CLKSEL_CON(63), 13, 1, MFLAGS, 4, 3, DFLAGS,
+			RV1126B_CLKGATE_CON(5), 7, GFLAGS),
+	COMPOSITE(CLK_SARADC2_SRC, "clk_saradc2_src", mux_200m_24m_p, 0,
+			RV1126B_CLKSEL_CON(63), 14, 1, MFLAGS, 8, 3, DFLAGS,
+			RV1126B_CLKGATE_CON(5), 8, GFLAGS),
+	GATE(HCLK_RKNN, "hclk_rknn", "clk_gpll_div8", CLK_IS_CRITICAL,
+			RV1126B_CLKGATE_CON(5), 10, GFLAGS),
+	GATE(PCLK_NPU_ROOT, "pclk_npu_root", "clk_cpll_div10", CLK_IS_CRITICAL,
+			RV1126B_CLKGATE_CON(5), 11, GFLAGS),
+	COMPOSITE_NODIV(ACLK_VEPU_ROOT, "aclk_vepu_root", mux_500m_400m_200m_p, CLK_IS_CRITICAL,
+			RV1126B_CLKSEL_CON(40), 0, 2, MFLAGS,
+			RV1126B_CLKGATE_CON(5), 12, GFLAGS),
+	GATE(HCLK_VEPU_ROOT, "hclk_vepu_root", "clk_gpll_div8", CLK_IS_CRITICAL,
+			RV1126B_CLKGATE_CON(5), 13, GFLAGS),
+	GATE(PCLK_VEPU_ROOT, "pclk_vepu_root", "clk_cpll_div10", 0,
+			RV1126B_CLKGATE_CON(5), 14, GFLAGS),
+	COMPOSITE(CLK_CORE_RGA_SRC, "clk_core_rga_src", mux_gpll_cpll_p, 0,
+			RV1126B_CLKSEL_CON(40), 5, 1, MFLAGS, 2, 3, DFLAGS,
+			RV1126B_CLKGATE_CON(6), 0, GFLAGS),
+	COMPOSITE_NODIV(ACLK_GMAC_ROOT, "aclk_gmac_root", mux_300m_200m_p, 0,
+			RV1126B_CLKSEL_CON(40), 6, 1, MFLAGS,
+			RV1126B_CLKGATE_CON(6), 1, GFLAGS),
+	COMPOSITE_NODIV(ACLK_VI_ROOT, "aclk_vi_root", mux_500m_400m_300m_p, CLK_IS_CRITICAL,
+			RV1126B_CLKSEL_CON(40), 7, 2, MFLAGS,
+			RV1126B_CLKGATE_CON(6), 2, GFLAGS),
+	GATE(HCLK_VI_ROOT, "hclk_vi_root", "clk_gpll_div8", CLK_IS_CRITICAL,
+			RV1126B_CLKGATE_CON(6), 3, GFLAGS),
+	GATE(PCLK_VI_ROOT, "pclk_vi_root", "clk_cpll_div10", CLK_IS_CRITICAL,
+			RV1126B_CLKGATE_CON(6), 4, GFLAGS),
+	COMPOSITE_NODIV(DCLK_VICAP_ROOT, "dclk_vicap_root", mux_333m_200m_p, 0,
+			RV1126B_CLKSEL_CON(42), 5, 1, MFLAGS,
+			RV1126B_CLKGATE_CON(6), 5, GFLAGS),
+	COMPOSITE(CLK_SYS_DSMC_ROOT, "clk_sys_dsmc_root", mux_24m_gpll_cpll_p, 0,
+			RV1126B_CLKSEL_CON(40), 14, 2, MFLAGS, 9, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(6), 6, GFLAGS),
+	COMPOSITE(ACLK_VDO_ROOT, "aclk_vdo_root", mux_gpll_cpll_p, CLK_IS_CRITICAL,
+			RV1126B_CLKSEL_CON(42), 4, 1, MFLAGS, 0, 4, DFLAGS,
+			RV1126B_CLKGATE_CON(6), 7, GFLAGS),
+	COMPOSITE(ACLK_RKVDEC_ROOT, "aclk_rkvdec_root", mux_gpll_cpll_p, 0,
+			RV1126B_CLKSEL_CON(42), 10, 1, MFLAGS, 6, 4, DFLAGS,
+			RV1126B_CLKGATE_CON(6), 8, GFLAGS),
+	GATE(HCLK_VDO_ROOT, "hclk_vdo_root", "clk_gpll_div8", CLK_IS_CRITICAL,
+			RV1126B_CLKGATE_CON(6), 9, GFLAGS),
+	GATE(PCLK_VDO_ROOT, "pclk_vdo_root", "clk_cpll_div10", CLK_IS_CRITICAL,
+			RV1126B_CLKGATE_CON(6), 10, GFLAGS),
+	COMPOSITE(DCLK_VOP, "dclk_vop", mux_gpll_cpll_p, 0,
+			RV1126B_CLKSEL_CON(43), 8, 1, MFLAGS, 0, 8, DFLAGS,
+			RV1126B_CLKGATE_CON(6), 12, GFLAGS),
+	COMPOSITE(DCLK_OOC_SRC, "dclk_ooc_src", mux_gpll_cpll_p, 0,
+			RV1126B_CLKSEL_CON(62), 7, 1, MFLAGS, 8, 8, DFLAGS,
+			RV1126B_CLKGATE_CON(6), 13, GFLAGS),
+	GATE(DCLK_DECOM_SRC, "dclk_decom_src", "clk_gpll_div3", 0,
+			RV1126B_CLKGATE_CON(6), 14, GFLAGS),
+	GATE(PCLK_DDR_ROOT, "pclk_ddr_root", "clk_cpll_div10", 0,
+			RV1126B_CLKGATE_CON(7), 0, GFLAGS),
+	COMPOSITE(ACLK_SYSMEM, "aclk_sysmem", mux_gpll_cpll_p, CLK_IS_CRITICAL,
+			RV1126B_CLKSEL_CON(44), 3, 1, MFLAGS, 0, 3, DFLAGS,
+			RV1126B_CLKGATE_CON(7), 1, GFLAGS),
+	COMPOSITE_NODIV(ACLK_TOP_ROOT, "aclk_top_root", mux_600m_400m_200m_p, CLK_IS_CRITICAL,
+			RV1126B_CLKSEL_CON(44), 6, 2, MFLAGS,
+			RV1126B_CLKGATE_CON(7), 3, GFLAGS),
+	COMPOSITE_NODIV(ACLK_BUS_ROOT, "aclk_bus_root", mux_400m_300m_200m_p, CLK_IS_CRITICAL,
+			RV1126B_CLKSEL_CON(44), 8, 2, MFLAGS,
+			RV1126B_CLKGATE_CON(7), 4, GFLAGS),
+	COMPOSITE_NODIV(HCLK_BUS_ROOT, "hclk_bus_root", mux_200m_100m_p, CLK_IS_CRITICAL,
+			RV1126B_CLKSEL_CON(44), 10, 1, MFLAGS,
+			RV1126B_CLKGATE_CON(7), 5, GFLAGS),
+	GATE(PCLK_BUS_ROOT, "pclk_bus_root", "clk_cpll_div10", CLK_IS_CRITICAL,
+			RV1126B_CLKGATE_CON(7), 6, GFLAGS),
+	COMPOSITE(CCLK_SDMMC0, "cclk_sdmmc0", mux_gpll_cpll_24m_p, 0,
+			RV1126B_CLKSEL_CON(45), 8, 2, MFLAGS, 0, 8, DFLAGS,
+			RV1126B_CLKGATE_CON(7), 7, GFLAGS),
+	COMPOSITE(CCLK_SDMMC1, "cclk_sdmmc1", mux_gpll_cpll_24m_p, 0,
+			RV1126B_CLKSEL_CON(46), 8, 2, MFLAGS, 0, 8, DFLAGS,
+			RV1126B_CLKGATE_CON(7), 8, GFLAGS),
+	COMPOSITE(CCLK_EMMC, "cclk_emmc", mux_gpll_cpll_24m_p, 0,
+			RV1126B_CLKSEL_CON(47), 8, 2, MFLAGS, 0, 8, DFLAGS,
+			RV1126B_CLKGATE_CON(7), 9, GFLAGS),
+	COMPOSITE(SCLK_2X_FSPI0, "sclk_2x_fspi0", mux_gpll_cpll_24m_p, 0,
+			RV1126B_CLKSEL_CON(48), 8, 2, MFLAGS, 0, 8, DFLAGS,
+			RV1126B_CLKGATE_CON(7), 10, GFLAGS),
+	COMPOSITE(CLK_GMAC_PTP_REF_SRC, "clk_gmac_ptp_ref_src", mux_cpll_24m_p, 0,
+			RV1126B_CLKSEL_CON(45), 10, 1, MFLAGS, 11, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(7), 11, GFLAGS),
+	GATE(CLK_GMAC_125M, "clk_gmac_125m", "clk_cpll_div8", 0,
+			RV1126B_CLKGATE_CON(7), 12, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER_ROOT, "clk_timer_root", mux_100m_24m_p, 0,
+			RV1126B_CLKSEL_CON(46), 11, 1, MFLAGS,
+			RV1126B_CLKGATE_CON(7), 13, GFLAGS),
+	COMPOSITE_NODIV(TCLK_WDT_NS_SRC, "tclk_wdt_ns_src", mux_100m_24m_p, 0,
+			RV1126B_CLKSEL_CON(46), 12, 1, MFLAGS,
+			RV1126B_CLKGATE_CON(8), 0, GFLAGS),
+	COMPOSITE_NODIV(TCLK_WDT_S_SRC, "tclk_wdt_s_src", mux_100m_24m_p, 0,
+			RV1126B_CLKSEL_CON(46), 13, 1, MFLAGS,
+			RV1126B_CLKGATE_CON(8), 1, GFLAGS),
+	COMPOSITE_NODIV(TCLK_WDT_HPMCU, "tclk_wdt_hpmcu", mux_100m_24m_p, 0,
+			RV1126B_CLKSEL_CON(46), 14, 1, MFLAGS,
+			RV1126B_CLKGATE_CON(8), 2, GFLAGS),
+	COMPOSITE(CLK_CAN0, "clk_can0", mux_gpll_cpll_24m_p, 0,
+			RV1126B_CLKSEL_CON(49), 6, 2, MFLAGS, 0, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(8), 4, GFLAGS),
+	COMPOSITE(CLK_CAN1, "clk_can1", mux_gpll_cpll_24m_p, 0,
+			RV1126B_CLKSEL_CON(49), 14, 2, MFLAGS, 8, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(8), 5, GFLAGS),
+	COMPOSITE_NODIV(PCLK_PERI_ROOT, "pclk_peri_root", mux_100m_24m_p, CLK_IS_CRITICAL,
+			RV1126B_CLKSEL_CON(47), 12, 1, MFLAGS,
+			RV1126B_CLKGATE_CON(8), 6, GFLAGS),
+	COMPOSITE_NODIV(ACLK_PERI_ROOT, "aclk_peri_root", mux_200m_24m_p, CLK_IS_CRITICAL,
+			RV1126B_CLKSEL_CON(47), 13, 1, MFLAGS,
+			RV1126B_CLKGATE_CON(8), 7, GFLAGS),
+	COMPOSITE_NODIV(CLK_I2C_BUS_SRC, "clk_i2c_bus_src", mux_200m_24m_p, 0,
+			RV1126B_CLKSEL_CON(50), 1, 1, MFLAGS,
+			RV1126B_CLKGATE_CON(8), 9, GFLAGS),
+	COMPOSITE_NODIV(CLK_SPI0, "clk_spi0", mux_200m_100m_50m_24m_p, 0,
+			RV1126B_CLKSEL_CON(50), 2, 2, MFLAGS,
+			RV1126B_CLKGATE_CON(8), 10, GFLAGS),
+	COMPOSITE_NODIV(CLK_SPI1, "clk_spi1", mux_200m_100m_50m_24m_p, 0,
+			RV1126B_CLKSEL_CON(50), 4, 2, MFLAGS,
+			RV1126B_CLKGATE_CON(8), 11, GFLAGS),
+	GATE(BUSCLK_PMU_SRC, "busclk_pmu_src", "clk_cpll_div10", CLK_IS_CRITICAL,
+			RV1126B_CLKGATE_CON(8), 12, GFLAGS),
+	COMPOSITE_NODIV(CLK_PWM0, "clk_pwm0", mux_100m_24m_p, 0,
+			RV1126B_CLKSEL_CON(50), 8, 1, MFLAGS,
+			RV1126B_CLKGATE_CON(9), 0, GFLAGS),
+	COMPOSITE_NODIV(CLK_PWM2, "clk_pwm2", mux_100m_24m_p, 0,
+			RV1126B_CLKSEL_CON(50), 10, 1, MFLAGS,
+			RV1126B_CLKGATE_CON(9), 2, GFLAGS),
+	COMPOSITE_NODIV(CLK_PWM3, "clk_pwm3", mux_100m_24m_p, 0,
+			RV1126B_CLKSEL_CON(50), 11, 1, MFLAGS,
+			RV1126B_CLKGATE_CON(9), 3, GFLAGS),
+	COMPOSITE_NODIV(CLK_PKA_RKCE_SRC, "clk_pka_rkce_src", mux_300m_200m_p, CLK_IS_CRITICAL,
+			RV1126B_CLKSEL_CON(50), 12, 1, MFLAGS,
+			RV1126B_CLKGATE_CON(9), 4, GFLAGS),
+	COMPOSITE_NODIV(ACLK_RKCE_SRC, "aclk_rkce_src", mux_200m_24m_p, CLK_IS_CRITICAL,
+			RV1126B_CLKSEL_CON(50), 13, 1, MFLAGS,
+			RV1126B_CLKGATE_CON(9), 5, GFLAGS),
+	COMPOSITE_NODIV(ACLK_VCP_ROOT, "aclk_vcp_root", mux_500m_400m_200m_p, CLK_IS_CRITICAL,
+			RV1126B_CLKSEL_CON(48), 12, 2, MFLAGS,
+			RV1126B_CLKGATE_CON(9), 6, GFLAGS),
+	GATE(HCLK_VCP_ROOT, "hclk_vcp_root", "clk_gpll_div8", CLK_IS_CRITICAL,
+			RV1126B_CLKGATE_CON(9), 7, GFLAGS),
+	GATE(PCLK_VCP_ROOT, "pclk_vcp_root", "clk_cpll_div10", CLK_IS_CRITICAL,
+			RV1126B_CLKGATE_CON(9), 8, GFLAGS),
+	COMPOSITE(CLK_CORE_FEC_SRC, "clk_core_fec_src", mux_gpll_cpll_p, 0,
+			RV1126B_CLKSEL_CON(51), 3, 1, MFLAGS, 0, 3, DFLAGS,
+			RV1126B_CLKGATE_CON(9), 9, GFLAGS),
+	GATE(CLK_50M_GMAC_IOBUF_VI, "clk_50m_gmac_iobuf_vi", "clk_cpll_div20", 0,
+			RV1126B_CLKGATE_CON(9), 11, GFLAGS),
+	GATE(PCLK_TOP_ROOT, "pclk_top_root", "clk_cpll_div10", CLK_IS_CRITICAL,
+			RV1126B_CLKGATE_CON(15), 0, GFLAGS),
+	COMPOSITE(CLK_MIPI0_OUT2IO, "clk_mipi0_out2io", mux_600m_24m_p, 0,
+			RV1126B_CLKSEL_CON(67), 11, 1, MFLAGS, 0, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(15), 3, GFLAGS),
+	COMPOSITE(CLK_MIPI1_OUT2IO, "clk_mipi1_out2io", mux_600m_24m_p, 0,
+			RV1126B_CLKSEL_CON(67), 12, 1, MFLAGS, 6, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(15), 4, GFLAGS),
+	COMPOSITE(CLK_MIPI2_OUT2IO, "clk_mipi2_out2io", mux_600m_24m_p, 0,
+			RV1126B_CLKSEL_CON(68), 11, 1, MFLAGS, 0, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(15), 5, GFLAGS),
+	COMPOSITE(CLK_MIPI3_OUT2IO, "clk_mipi3_out2io", mux_600m_24m_p, 0,
+			RV1126B_CLKSEL_CON(68), 12, 1, MFLAGS, 6, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(15), 6, GFLAGS),
+	COMPOSITE(CLK_CIF_OUT2IO, "clk_cif_out2io", mux_600m_24m_p, 0,
+			RV1126B_CLKSEL_CON(69), 5, 1, MFLAGS, 0, 5, DFLAGS,
+			RV1126B_CLKGATE_CON(15), 7, GFLAGS),
+	COMPOSITE(CLK_MAC_OUT2IO, "clk_mac_out2io", mux_gpll_cpll_24m_p, 0,
+			RV1126B_CLKSEL_CON(69), 6, 2, MFLAGS, 8, 7, DFLAGS,
+			RV1126B_CLKGATE_CON(15), 8, GFLAGS),
+	COMPOSITE_NOMUX(MCLK_SAI0_OUT2IO, "mclk_sai0_out2io", "mclk_sai0", CLK_SET_RATE_PARENT,
+			RV1126B_CLKSEL_CON(70), 0, 4, DFLAGS,
+			RV1126B_CLKGATE_CON(15), 9, GFLAGS),
+	COMPOSITE_NOMUX(MCLK_SAI1_OUT2IO, "mclk_sai1_out2io", "mclk_sai1", CLK_SET_RATE_PARENT,
+			RV1126B_CLKSEL_CON(70), 5, 4, DFLAGS,
+			RV1126B_CLKGATE_CON(15), 10, GFLAGS),
+	COMPOSITE_NOMUX(MCLK_SAI2_OUT2IO, "mclk_sai2_out2io", "mclk_sai2", CLK_SET_RATE_PARENT,
+			RV1126B_CLKSEL_CON(70), 10, 4, DFLAGS,
+			RV1126B_CLKGATE_CON(15), 11, GFLAGS),
+
+	/* pd _npu */
+	MUX(ACLK_RKNN, "aclk_rknn", aclk_npu_root_p, CLK_SET_RATE_PARENT,
+			RV1126B_NPUCLKSEL_CON(0), 1, 1, MFLAGS),
+
+	/* pd_vepu */
+	GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_vepu_root", 0,
+			RV1126B_VEPUCLKGATE_CON(0), 7, GFLAGS),
+	GATE(DBCLK_GPIO3, "dbclk_gpio3", "xin24m", 0,
+			RV1126B_VEPUCLKGATE_CON(0), 8, GFLAGS),
+	GATE(PCLK_IOC_VCCIO3, "pclk_ioc_vccio3", "pclk_vepu_root", CLK_IS_CRITICAL,
+			RV1126B_VEPUCLKGATE_CON(0), 9, GFLAGS),
+	GATE(PCLK_SARADC0, "pclk_saradc0", "pclk_vepu_root", 0,
+			RV1126B_VEPUCLKGATE_CON(0), 10, GFLAGS),
+	MUX(CLK_SARADC0, "clk_saradc0", clk_saradc0_p, CLK_SET_RATE_PARENT,
+			RV1126B_VEPUCLKSEL_CON(0), 2, 1, MFLAGS),
+	GATE(HCLK_SDMMC1, "hclk_sdmmc1", "hclk_vepu_root", 0,
+			RV1126B_VEPUCLKGATE_CON(0), 12, GFLAGS),
+	GATE(HCLK_VEPU, "hclk_vepu", "hclk_vepu_root", 0,
+			RV1126B_VEPUCLKGATE_CON(1), 1, GFLAGS),
+	GATE(ACLK_VEPU, "aclk_vepu", "aclk_vepu_root", 0,
+			RV1126B_VEPUCLKGATE_CON(1), 2, GFLAGS),
+	COMPOSITE_NODIV(CLK_CORE_VEPU, "clk_core_vepu", clk_core_vepu_p, CLK_SET_RATE_PARENT,
+			RV1126B_VEPUCLKSEL_CON(0), 1, 1, MFLAGS,
+			RV1126B_VEPUCLKGATE_CON(1), 3, GFLAGS),
+
+	/* pd_vcp */
+	GATE(HCLK_FEC, "hclk_fec", "hclk_vcp_root", 0,
+			RV1126B_VCPCLKGATE_CON(1), 0, GFLAGS),
+	GATE(ACLK_FEC, "aclk_fec", "aclk_vcp_root", 0,
+			RV1126B_VCPCLKGATE_CON(1), 1, GFLAGS),
+	COMPOSITE_NODIV(CLK_CORE_FEC, "clk_core_fec", clk_core_fec_p, CLK_SET_RATE_PARENT,
+			RV1126B_VCPCLKSEL_CON(0), 13, 1, MFLAGS,
+			RV1126B_VCPCLKGATE_CON(1), 2, GFLAGS),
+	GATE(HCLK_AVSP, "hclk_avsp", "hclk_vcp_root", 0,
+			RV1126B_VCPCLKGATE_CON(1), 3, GFLAGS),
+	GATE(ACLK_AVSP, "aclk_avsp", "aclk_vcp_root", 0,
+			RV1126B_VCPCLKGATE_CON(1), 4, GFLAGS),
+	GATE(HCLK_AISP, "hclk_aisp", "hclk_vcp_root", 0,
+			RV1126B_VCPCLKGATE_CON(0), 11, GFLAGS),
+	GATE(ACLK_AISP, "aclk_aisp", "aclk_vcp_root", 0,
+			RV1126B_VCPCLKGATE_CON(0), 12, GFLAGS),
+	COMPOSITE_NODIV(CLK_CORE_AISP, "clk_core_aisp", clk_core_aisp_p, CLK_SET_RATE_PARENT,
+			RV1126B_VCPCLKSEL_CON(0), 15, 1, MFLAGS,
+			RV1126B_VCPCLKGATE_CON(0), 13, GFLAGS),
+
+	/* pd_vi */
+	MUX(CLK_CORE_ISP_ROOT, "clk_core_isp_root", clk_core_isp_root_p, CLK_SET_RATE_PARENT,
+			RV1126B_VICLKSEL_CON(0), 1, 1, MFLAGS),
+	GATE(PCLK_DSMC, "pclk_dsmc", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(0), 8, GFLAGS),
+	GATE(ACLK_DSMC, "aclk_dsmc", "hclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(0), 9, GFLAGS),
+	GATE(HCLK_CAN0, "hclk_can0", "hclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(0), 10, GFLAGS),
+	GATE(HCLK_CAN1, "hclk_can1", "hclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(0), 11, GFLAGS),
+	GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(1), 0, GFLAGS),
+	GATE(DBCLK_GPIO2, "dbclk_gpio2", "xin24m", 0,
+			RV1126B_VICLKGATE_CON(1), 1, GFLAGS),
+	GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(1), 2, GFLAGS),
+	GATE(DBCLK_GPIO4, "dbclk_gpio4", "xin24m", 0,
+			RV1126B_VICLKGATE_CON(1), 3, GFLAGS),
+	GATE(PCLK_GPIO5, "pclk_gpio5", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(1), 4, GFLAGS),
+	GATE(DBCLK_GPIO5, "dbclk_gpio5", "xin24m", 0,
+			RV1126B_VICLKGATE_CON(1), 5, GFLAGS),
+	GATE(PCLK_GPIO6, "pclk_gpio6", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(1), 6, GFLAGS),
+	GATE(DBCLK_GPIO6, "dbclk_gpio6", "xin24m", 0,
+			RV1126B_VICLKGATE_CON(1), 7, GFLAGS),
+	GATE(PCLK_GPIO7, "pclk_gpio7", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(1), 8, GFLAGS),
+	GATE(DBCLK_GPIO7, "dbclk_gpio7", "xin24m", 0,
+			RV1126B_VICLKGATE_CON(1), 9, GFLAGS),
+	GATE(PCLK_IOC_VCCIO2, "pclk_ioc_vccio2", "pclk_vi_root", CLK_IS_CRITICAL,
+			RV1126B_VICLKGATE_CON(1), 10, GFLAGS),
+	GATE(PCLK_IOC_VCCIO4, "pclk_ioc_vccio4", "pclk_vi_root", CLK_IS_CRITICAL,
+			RV1126B_VICLKGATE_CON(1), 11, GFLAGS),
+	GATE(PCLK_IOC_VCCIO5, "pclk_ioc_vccio5", "pclk_vi_root", CLK_IS_CRITICAL,
+			RV1126B_VICLKGATE_CON(1), 12, GFLAGS),
+	GATE(PCLK_IOC_VCCIO6, "pclk_ioc_vccio6", "pclk_vi_root", CLK_IS_CRITICAL,
+			RV1126B_VICLKGATE_CON(1), 13, GFLAGS),
+	GATE(PCLK_IOC_VCCIO7, "pclk_ioc_vccio7", "pclk_vi_root", CLK_IS_CRITICAL,
+			RV1126B_VICLKGATE_CON(1), 14, GFLAGS),
+	GATE(HCLK_ISP, "hclk_isp", "hclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(2), 0, GFLAGS),
+	GATE(ACLK_ISP, "aclk_isp", "aclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(2), 1, GFLAGS),
+	GATE(CLK_CORE_ISP, "clk_core_isp", "clk_core_isp_root", 0,
+			RV1126B_VICLKGATE_CON(2), 2, GFLAGS),
+	GATE(HCLK_VICAP, "hclk_vicap", "hclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(2), 3, GFLAGS),
+	GATE(ACLK_VICAP, "aclk_vicap", "aclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(2), 4, GFLAGS),
+	GATE(DCLK_VICAP, "dclk_vicap", "dclk_vicap_root", 0,
+			RV1126B_VICLKGATE_CON(2), 5, GFLAGS),
+	GATE(ISP0CLK_VICAP, "isp0clk_vicap", "clk_core_isp_root", 0,
+			RV1126B_VICLKGATE_CON(2), 6, GFLAGS),
+	GATE(HCLK_VPSS, "hclk_vpss", "hclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(2), 7, GFLAGS),
+	GATE(ACLK_VPSS, "aclk_vpss", "aclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(2), 8, GFLAGS),
+	GATE(CLK_CORE_VPSS, "clk_core_vpss", "clk_core_isp_root", 0,
+			RV1126B_VICLKGATE_CON(2), 9, GFLAGS),
+	GATE(HCLK_VPSL, "hclk_vpsl", "hclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(2), 10, GFLAGS),
+	GATE(ACLK_VPSL, "aclk_vpsl", "aclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(2), 11, GFLAGS),
+	GATE(CLK_CORE_VPSL, "clk_core_vpsl", "clk_core_isp_root", 0,
+			RV1126B_VICLKGATE_CON(2), 12, GFLAGS),
+	GATE(PCLK_CSI2HOST0, "pclk_csi2host0", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(3), 0, GFLAGS),
+	GATE(DCLK_CSI2HOST0, "dclk_csi2host0", "dclk_vicap_root", 0,
+			RV1126B_VICLKGATE_CON(3), 1, GFLAGS),
+	GATE(PCLK_CSI2HOST1, "pclk_csi2host1", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(3), 2, GFLAGS),
+	GATE(DCLK_CSI2HOST1, "dclk_csi2host1", "dclk_vicap_root", 0,
+			RV1126B_VICLKGATE_CON(3), 3, GFLAGS),
+	GATE(PCLK_CSI2HOST2, "pclk_csi2host2", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(3), 4, GFLAGS),
+	GATE(DCLK_CSI2HOST2, "dclk_csi2host2", "dclk_vicap_root", 0,
+			RV1126B_VICLKGATE_CON(3), 5, GFLAGS),
+	GATE(PCLK_CSI2HOST3, "pclk_csi2host3", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(3), 6, GFLAGS),
+	GATE(DCLK_CSI2HOST3, "dclk_csi2host3", "dclk_vicap_root", 0,
+			RV1126B_VICLKGATE_CON(3), 7, GFLAGS),
+	GATE(HCLK_SDMMC0, "hclk_sdmmc0", "hclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(3), 8, GFLAGS),
+	GATE(ACLK_GMAC, "aclk_gmac", "aclk_gmac_root", 0,
+			RV1126B_VICLKGATE_CON(3), 9, GFLAGS),
+	GATE(PCLK_GMAC, "pclk_gmac", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(3), 10, GFLAGS),
+	MUX(CLK_GMAC_PTP_REF, "clk_gmac_ptp_ref", clk_gmac_ptp_ref_p, CLK_SET_RATE_PARENT,
+			RV1126B_VICLKSEL_CON(0), 14, 1, MFLAGS),
+	GATE(PCLK_CSIPHY0, "pclk_csiphy0", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(3), 11, GFLAGS),
+	GATE(PCLK_CSIPHY1, "pclk_csiphy1", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(3), 12, GFLAGS),
+	GATE(PCLK_MACPHY, "pclk_macphy", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(3), 13, GFLAGS),
+	GATE(PCLK_SARADC1, "pclk_saradc1", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(4), 0, GFLAGS),
+	MUX(CLK_SARADC1, "clk_saradc1", clk_saradc1_p, CLK_SET_RATE_PARENT,
+			RV1126B_VICLKSEL_CON(0), 2, 1, MFLAGS),
+	GATE(PCLK_SARADC2, "pclk_saradc2", "pclk_vi_root", 0,
+			RV1126B_VICLKGATE_CON(4), 2, GFLAGS),
+	MUX(CLK_SARADC2, "clk_saradc2", clk_saradc2_p, CLK_SET_RATE_PARENT,
+			RV1126B_VICLKSEL_CON(0), 3, 1, MFLAGS),
+	COMPOSITE_NODIV(CLK_MACPHY, "clk_macphy", clk_macphy_p, 0,
+			RV1126B_VICLKSEL_CON(1), 1, 1, MFLAGS,
+			RV1126B_VICLKGATE_CON(0), 12, GFLAGS),
+
+	/* pd_vdo */
+	GATE(ACLK_RKVDEC, "aclk_rkvdec", "aclk_rkvdec_root", 0,
+			RV1126B_VDOCLKGATE_CON(0), 7, GFLAGS),
+	GATE(HCLK_RKVDEC, "hclk_rkvdec", "hclk_vdo_root", 0,
+			RV1126B_VDOCLKGATE_CON(0), 8, GFLAGS),
+	GATE(CLK_HEVC_CA_RKVDEC, "clk_hevc_ca_rkvdec", "aclk_rkvdec_root", 0,
+			RV1126B_VDOCLKGATE_CON(0), 9, GFLAGS),
+	GATE(ACLK_VOP, "aclk_vop", "aclk_vdo_root", 0,
+			RV1126B_VDOCLKGATE_CON(0), 10, GFLAGS),
+	GATE(HCLK_VOP, "hclk_vop", "hclk_vdo_root", 0,
+			RV1126B_VDOCLKGATE_CON(0), 11, GFLAGS),
+	GATE(ACLK_OOC, "aclk_ooc", "aclk_vdo_root", 0,
+			RV1126B_VDOCLKGATE_CON(0), 13, GFLAGS),
+	GATE(HCLK_OOC, "hclk_ooc", "hclk_vdo_root", 0,
+			RV1126B_VDOCLKGATE_CON(0), 14, GFLAGS),
+	GATE(HCLK_RKJPEG, "hclk_rkjpeg", "hclk_vdo_root", 0,
+			RV1126B_VDOCLKGATE_CON(1), 3, GFLAGS),
+	GATE(ACLK_RKJPEG, "aclk_rkjpeg", "aclk_vdo_root", 0,
+			RV1126B_VDOCLKGATE_CON(1), 4, GFLAGS),
+	GATE(ACLK_RKMMU_DECOM, "aclk_rkmmu_decom", "aclk_vdo_root", 0,
+			RV1126B_VDOCLKGATE_CON(1), 5, GFLAGS),
+	GATE(HCLK_RKMMU_DECOM, "hclk_rkmmu_decom", "hclk_vdo_root", 0,
+			RV1126B_VDOCLKGATE_CON(1), 6, GFLAGS),
+	GATE(DCLK_DECOM, "dclk_decom", "dclk_decom_src", 0,
+			RV1126B_VDOCLKGATE_CON(1), 8, GFLAGS),
+	GATE(ACLK_DECOM, "aclk_decom", "aclk_vdo_root", 0,
+			RV1126B_VDOCLKGATE_CON(1), 9, GFLAGS),
+	GATE(PCLK_DECOM, "pclk_decom", "pclk_vdo_root", 0,
+			RV1126B_VDOCLKGATE_CON(1), 10, GFLAGS),
+	GATE(PCLK_MIPI_DSI, "pclk_mipi_dsi", "pclk_vdo_root", 0,
+			RV1126B_VDOCLKGATE_CON(1), 12, GFLAGS),
+	GATE(PCLK_DSIPHY, "pclk_dsiphy", "pclk_vdo_root", 0,
+			RV1126B_VDOCLKGATE_CON(1), 13, GFLAGS),
+
+	/* pd_ddr */
+	GATE(PCLK_DDRC, "pclk_ddrc", "pclk_ddr_root", CLK_IS_CRITICAL,
+			RV1126B_DDRCLKGATE_CON(0), 2, GFLAGS),
+	GATE(PCLK_DDRMON, "pclk_ddrmon", "pclk_ddr_root", CLK_IS_CRITICAL,
+			RV1126B_DDRCLKGATE_CON(0), 3, GFLAGS),
+	GATE(CLK_TIMER_DDRMON, "clk_timer_ddrmon", "xin24m", 0,
+			RV1126B_DDRCLKGATE_CON(0), 4, GFLAGS),
+	GATE(PCLK_DFICTRL, "pclk_dfictrl", "pclk_ddr_root", CLK_IS_CRITICAL,
+			RV1126B_DDRCLKGATE_CON(0), 5, GFLAGS),
+	GATE(PCLK_DDRPHY, "pclk_ddrphy", "pclk_ddr_root", CLK_IS_CRITICAL,
+			RV1126B_DDRCLKGATE_CON(0), 8, GFLAGS),
+	GATE(PCLK_DMA2DDR, "pclk_dma2ddr", "pclk_ddr_root", CLK_IS_CRITICAL,
+			RV1126B_DDRCLKGATE_CON(0), 9, GFLAGS),
+
+	/* pd_pmu*/
+	COMPOSITE_NODIV(CLK_RCOSC_SRC, "clk_rcosc_src", clk_rcosc_src_p, 0,
+			RV1126B_PMUCLKSEL_CON(1), 0, 3, MFLAGS,
+			RV1126B_PMUCLKGATE_CON(0), 0, GFLAGS),
+	COMPOSITE_NOGATE(BUSCLK_PMU_MUX, "busclk_pmu_mux", busclk_pmu_mux_p, 0,
+			RV1126B_PMUCLKSEL_CON(1), 3, 1, MFLAGS, 4, 2, DFLAGS),
+	GATE(BUSCLK_PMU_ROOT, "busclk_pmu_root", "busclk_pmu_mux", 0,
+			RV1126B_PMUCLKGATE_CON(0), 1, GFLAGS),
+	GATE(BUSCLK_PMU1_ROOT, "busclk_pmu1_root", "busclk_pmu_mux", CLK_IS_CRITICAL,
+			RV1126B_PMUCLKGATE_CON(3), 11, GFLAGS),
+	GATE(PCLK_PMU, "pclk_pmu", "busclk_pmu_root", CLK_IS_CRITICAL,
+			RV1126B_PMUCLKGATE_CON(0), 6, GFLAGS),
+	MUX(0, "xin_rc_src", clk_xin_rc_div_p, 0,
+			RV1126B_PMUCLKSEL_CON(2), 0, 1, MFLAGS),
+	COMPOSITE_FRACMUX_NOGATE(CLK_XIN_RC_DIV, "clk_xin_rc_div", "xin_rc_src", CLK_SET_RATE_PARENT,
+			RV1126B_PMUCLKSEL_CON(8), 0,
+			&rv1126b_rcdiv_pmu_fracmux),
+	GATE(PCLK_PMU_GPIO0, "pclk_pmu_gpio0", "busclk_pmu_root", 0,
+			RV1126B_PMUCLKGATE_CON(0), 7, GFLAGS),
+	COMPOSITE_NODIV(DBCLK_PMU_GPIO0, "dbclk_pmu_gpio0", mux_24m_32k_p, 0,
+			RV1126B_PMUCLKSEL_CON(2), 4, 1, MFLAGS,
+			RV1126B_PMUCLKGATE_CON(0), 8, GFLAGS),
+	GATE(PCLK_PMU_HP_TIMER, "pclk_pmu_hp_timer", "busclk_pmu_root", CLK_IS_CRITICAL,
+			RV1126B_PMUCLKGATE_CON(0), 10, GFLAGS),
+	COMPOSITE(CLK_PMU_HP_TIMER, "clk_pmu_hp_timer", mux_cpll_24m_p, CLK_IS_CRITICAL,
+			RV1126B_PMUCLKSEL_CON(1), 13, 1, MFLAGS, 8, 5, DFLAGS,
+			RV1126B_PMUCLKGATE_CON(0), 11, GFLAGS),
+	GATE(CLK_PMU_32K_HP_TIMER, "clk_pmu_32k_hp_timer", "clk_32k", CLK_IS_CRITICAL,
+			RV1126B_PMUCLKGATE_CON(0), 13, GFLAGS),
+	GATE(PCLK_PWM1, "pclk_pwm1", "busclk_pmu_root", 0,
+			RV1126B_PMUCLKGATE_CON(1), 0, GFLAGS),
+	COMPOSITE(CLK_PWM1, "clk_pwm1", mux_24m_rcosc_buspmu_p, 0,
+			RV1126B_PMUCLKSEL_CON(2), 8, 2, MFLAGS, 6, 2, DFLAGS,
+			RV1126B_PMUCLKGATE_CON(1), 1, GFLAGS),
+	GATE(CLK_OSC_PWM1, "clk_osc_pwm1", "xin24m", 0,
+			RV1126B_PMUCLKGATE_CON(1), 2, GFLAGS),
+	GATE(CLK_RC_PWM1, "clk_rc_pwm1", "clk_32k", 0,
+			RV1126B_PMUCLKGATE_CON(1), 3, GFLAGS),
+	GATE(PCLK_I2C2, "pclk_i2c2", "busclk_pmu_root", 0,
+			RV1126B_PMUCLKGATE_CON(1), 6, GFLAGS),
+	COMPOSITE(CLK_I2C2, "clk_i2c2", mux_24m_rcosc_buspmu_p, 0,
+			RV1126B_PMUCLKSEL_CON(2), 14, 2, MFLAGS, 12, 2, DFLAGS,
+			RV1126B_PMUCLKGATE_CON(1), 7, GFLAGS),
+	GATE(PCLK_UART0, "pclk_uart0", "busclk_pmu_root", 0,
+			RV1126B_PMUCLKGATE_CON(1), 8, GFLAGS),
+	COMPOSITE_NODIV(SCLK_UART0, "sclk_uart0", sclk_uart0_p, CLK_SET_RATE_PARENT,
+			RV1126B_PMUCLKSEL_CON(3), 0, 2, MFLAGS,
+			RV1126B_PMUCLKGATE_CON(1), 11, GFLAGS),
+	GATE(PCLK_RCOSC_CTRL, "pclk_rcosc_ctrl", "busclk_pmu_root", CLK_IS_CRITICAL,
+			RV1126B_PMUCLKGATE_CON(2), 0, GFLAGS),
+	COMPOSITE_NODIV(CLK_OSC_RCOSC_CTRL, "clk_osc_rcosc_ctrl", clk_osc_rcosc_ctrl_p, CLK_IS_CRITICAL,
+			RV1126B_PMUCLKSEL_CON(3), 2, 1, MFLAGS,
+			RV1126B_PMUCLKGATE_CON(2), 1, GFLAGS),
+	GATE(CLK_REF_RCOSC_CTRL, "clk_ref_rcosc_ctrl", "xin24m", CLK_IS_CRITICAL,
+			RV1126B_PMUCLKGATE_CON(2), 2, GFLAGS),
+	GATE(PCLK_IOC_PMUIO0, "pclk_ioc_pmuio0", "busclk_pmu_root", CLK_IS_CRITICAL,
+			RV1126B_PMUCLKGATE_CON(2), 3, GFLAGS),
+	GATE(CLK_REFOUT, "clk_refout", "xin24m", 0,
+			RV1126B_PMUCLKGATE_CON(2), 6, GFLAGS),
+	GATE(CLK_PREROLL, "clk_preroll", "busclk_pmu_root", 0,
+			RV1126B_PMUCLKGATE_CON(2), 7, GFLAGS),
+	GATE(CLK_PREROLL_32K, "clk_preroll_32k", "clk_32k", 0,
+			RV1126B_PMUCLKGATE_CON(2), 8, GFLAGS),
+	GATE(HCLK_PMU_SRAM, "hclk_pmu_sram", "busclk_pmu_root", CLK_IS_CRITICAL,
+			RV1126B_PMUCLKGATE_CON(2), 9, GFLAGS),
+	GATE(PCLK_WDT_LPMCU, "pclk_wdt_lpmcu", "busclk_pmu_root", 0,
+			RV1126B_PMUCLKGATE_CON(3), 0, GFLAGS),
+	COMPOSITE_NODIV(TCLK_WDT_LPMCU, "tclk_wdt_lpmcu", mux_24m_rcosc_buspmu_32k_p, 0,
+			RV1126B_PMUCLKSEL_CON(3), 6, 2, MFLAGS,
+			RV1126B_PMUCLKGATE_CON(3), 1, GFLAGS),
+	GATE(CLK_LPMCU, "clk_lpmcu", "busclk_pmu_root", 0,
+			RV1126B_PMUCLKGATE_CON(3), 2, GFLAGS),
+	GATE(CLK_LPMCU_RTC, "clk_lpmcu_rtc", "xin24m", 0,
+			RV1126B_PMUCLKGATE_CON(3), 3, GFLAGS),
+	GATE(PCLK_LPMCU_MAILBOX, "pclk_lpmcu_mailbox", "busclk_pmu_root", 0,
+			RV1126B_PMUCLKGATE_CON(3), 4, GFLAGS),
+
+	/* pd_pmu1 */
+	GATE(PCLK_SPI2AHB, "pclk_spi2ahb", "busclk_pmu_root", 0,
+			RV1126B_PMU1CLKGATE_CON(0), 0, GFLAGS),
+	GATE(HCLK_SPI2AHB, "hclk_spi2ahb", "busclk_pmu_root", 0,
+			RV1126B_PMU1CLKGATE_CON(0), 1, GFLAGS),
+	GATE(HCLK_FSPI1, "hclk_fspi1", "busclk_pmu_root", 0,
+			RV1126B_PMU1CLKGATE_CON(0), 2, GFLAGS),
+	GATE(HCLK_XIP_FSPI1, "hclk_xip_fspi1", "busclk_pmu_root", 0,
+			RV1126B_PMU1CLKGATE_CON(0), 3, GFLAGS),
+	COMPOSITE(SCLK_1X_FSPI1, "sclk_1x_fspi1", mux_24m_rcosc_buspmu_p, 0,
+			RV1126B_PMU1CLKSEL_CON(0), 0, 2, MFLAGS, 2, 3, DFLAGS,
+			RV1126B_PMU1CLKGATE_CON(0), 4, GFLAGS),
+	GATE(PCLK_IOC_PMUIO1, "pclk_ioc_pmuio1", "busclk_pmu_root", CLK_IS_CRITICAL,
+			RV1126B_PMU1CLKGATE_CON(0), 5, GFLAGS),
+	GATE(PCLK_AUDIO_ADC_PMU, "pclk_audio_adc_pmu", "busclk_pmu_root", 0,
+			RV1126B_PMU1CLKGATE_CON(0), 8, GFLAGS),
+
+	COMPOSITE(MCLK_LPSAI, "mclk_lpsai", mux_24m_rcosc_buspmu_p, 0,
+			RV1126B_PMU1CLKSEL_CON(0), 6, 2, MFLAGS, 8, 5, DFLAGS,
+			RV1126B_PMU1CLKGATE_CON(1), 3, GFLAGS),
+	GATE(MCLK_AUDIO_ADC_PMU, "mclk_audio_adc_pmu", "mclk_lpsai", CLK_IS_CRITICAL,
+			RV1126B_PMU1CLKGATE_CON(0), 9, GFLAGS),
+	FACTOR(MCLK_AUDIO_ADC_DIV4_PMU, "mclk_audio_adc_div4_pmu", "mclk_audio_adc_pmu", 0, 1, 4),
+
+	/* pd_bus */
+	GATE(ACLK_GIC400, "aclk_gic400", "hclk_bus_root", CLK_IS_CRITICAL,
+			RV1126B_BUSCLKGATE_CON(0), 8, GFLAGS),
+	GATE(PCLK_WDT_NS, "pclk_wdt_ns", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(0), 10, GFLAGS),
+	GATE(TCLK_WDT_NS, "tclk_wdt_ns", "tclk_wdt_ns_src", 0,
+			RV1126B_BUSCLKGATE_CON(0), 11, GFLAGS),
+	GATE(PCLK_WDT_HPMCU, "pclk_wdt_hpmcu", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(1), 0, GFLAGS),
+	GATE(HCLK_CACHE, "hclk_cache", "aclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(1), 2, GFLAGS),
+	GATE(PCLK_HPMCU_MAILBOX, "pclk_hpmcu_mailbox", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(1), 3, GFLAGS),
+	GATE(PCLK_HPMCU_INTMUX, "pclk_hpmcu_intmux", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(1), 4, GFLAGS),
+	GATE(CLK_HPMCU, "clk_hpmcu", "aclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(1), 5, GFLAGS),
+	GATE(CLK_HPMCU_RTC, "clk_hpmcu_rtc", "xin24m", 0,
+			RV1126B_BUSCLKGATE_CON(1), 10, GFLAGS),
+	GATE(PCLK_RKDMA, "pclk_rkdma", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(1), 11, GFLAGS),
+	GATE(ACLK_RKDMA, "aclk_rkdma", "aclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(1), 12, GFLAGS),
+	GATE(PCLK_DCF, "pclk_dcf", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(2), 0, GFLAGS),
+	GATE(ACLK_DCF, "aclk_dcf", "aclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(2), 1, GFLAGS),
+	GATE(HCLK_RGA, "hclk_rga", "hclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(2), 2, GFLAGS),
+	GATE(ACLK_RGA, "aclk_rga", "aclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(2), 3, GFLAGS),
+	GATE(CLK_CORE_RGA, "clk_core_rga", "clk_core_rga_src", 0,
+			RV1126B_BUSCLKGATE_CON(2), 4, GFLAGS),
+	GATE(PCLK_TIMER, "pclk_timer", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(2), 5, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0, "clk_timer0", clk_timer0_parents_p, 0,
+			RV1126B_BUSCLKSEL_CON(2), 0, 2, MFLAGS,
+			RV1126B_BUSCLKGATE_CON(2), 6, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER1, "clk_timer1", clk_timer1_parents_p, 0,
+			RV1126B_BUSCLKSEL_CON(2), 2, 2, MFLAGS,
+			RV1126B_BUSCLKGATE_CON(2), 7, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER2, "clk_timer2", clk_timer2_parents_p, 0,
+			RV1126B_BUSCLKSEL_CON(2), 4, 2, MFLAGS,
+			RV1126B_BUSCLKGATE_CON(2), 8, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER3, "clk_timer3", clk_timer3_parents_p, 0,
+			RV1126B_BUSCLKSEL_CON(2), 6, 2, MFLAGS,
+			RV1126B_BUSCLKGATE_CON(2), 9, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER4, "clk_timer4", clk_timer4_parents_p, 0,
+			RV1126B_BUSCLKSEL_CON(2), 8, 2, MFLAGS,
+			RV1126B_BUSCLKGATE_CON(2), 10, GFLAGS),
+	GATE(HCLK_RKRNG_S_NS, "hclk_rkrng_s_ns", "hclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(2), 14, GFLAGS),
+	GATE(HCLK_RKRNG_NS, "hclk_rkrng_ns", "hclk_rkrng_s_ns", 0,
+			RV1126B_BUSCLKGATE_CON(2), 15, GFLAGS),
+	GATE(CLK_TIMER5, "clk_timer5", "clk_timer_root", CLK_IS_CRITICAL,
+			RV1126B_BUSCLKGATE_CON(2), 11, GFLAGS),
+	GATE(PCLK_I2C0, "pclk_i2c0", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(3), 0, GFLAGS),
+	GATE(CLK_I2C0, "clk_i2c0", "clk_i2c_bus_src", 0,
+			RV1126B_BUSCLKGATE_CON(3), 1, GFLAGS),
+	GATE(PCLK_I2C1, "pclk_i2c1", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(3), 2, GFLAGS),
+	GATE(CLK_I2C1, "clk_i2c1", "clk_i2c_bus_src", 0,
+			RV1126B_BUSCLKGATE_CON(3), 3, GFLAGS),
+	GATE(PCLK_I2C3, "pclk_i2c3", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(3), 4, GFLAGS),
+	GATE(CLK_I2C3, "clk_i2c3", "clk_i2c_bus_src", 0,
+			RV1126B_BUSCLKGATE_CON(3), 5, GFLAGS),
+	GATE(PCLK_I2C4, "pclk_i2c4", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(3), 6, GFLAGS),
+	GATE(CLK_I2C4, "clk_i2c4", "clk_i2c_bus_src", 0,
+			RV1126B_BUSCLKGATE_CON(3), 7, GFLAGS),
+	GATE(PCLK_I2C5, "pclk_i2c5", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(3), 8, GFLAGS),
+	GATE(CLK_I2C5, "clk_i2c5", "clk_i2c_bus_src", 0,
+			RV1126B_BUSCLKGATE_CON(3), 9, GFLAGS),
+	GATE(PCLK_SPI0, "pclk_spi0", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(3), 10, GFLAGS),
+	GATE(PCLK_SPI1, "pclk_spi1", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(3), 12, GFLAGS),
+	GATE(PCLK_PWM0, "pclk_pwm0", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(4), 0, GFLAGS),
+	GATE(CLK_OSC_PWM0, "clk_osc_pwm0", "xin24m", 0,
+			RV1126B_BUSCLKGATE_CON(4), 1, GFLAGS),
+	GATE(CLK_RC_PWM0, "clk_rc_pwm0", "xin24m", 0,
+			RV1126B_BUSCLKGATE_CON(4), 2, GFLAGS),
+	GATE(PCLK_PWM2, "pclk_pwm2", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(4), 3, GFLAGS),
+	GATE(CLK_OSC_PWM2, "clk_osc_pwm2", "xin24m", 0,
+			RV1126B_BUSCLKGATE_CON(4), 4, GFLAGS),
+	GATE(CLK_RC_PWM2, "clk_rc_pwm2", "xin24m", 0,
+			RV1126B_BUSCLKGATE_CON(4), 5, GFLAGS),
+	GATE(PCLK_PWM3, "pclk_pwm3", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(4), 6, GFLAGS),
+	GATE(CLK_OSC_PWM3, "clk_osc_pwm3", "xin24m", 0,
+			RV1126B_BUSCLKGATE_CON(4), 7, GFLAGS),
+	GATE(CLK_RC_PWM3, "clk_rc_pwm3", "xin24m", 0,
+			RV1126B_BUSCLKGATE_CON(4), 8, GFLAGS),
+	GATE(PCLK_UART1, "pclk_uart1", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(4), 9, GFLAGS),
+	GATE(PCLK_UART2, "pclk_uart2", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(4), 10, GFLAGS),
+	GATE(PCLK_UART3, "pclk_uart3", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(4), 11, GFLAGS),
+	GATE(PCLK_UART4, "pclk_uart4", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(4), 12, GFLAGS),
+	GATE(PCLK_UART5, "pclk_uart5", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(4), 13, GFLAGS),
+	GATE(PCLK_UART6, "pclk_uart6", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(4), 14, GFLAGS),
+	GATE(PCLK_UART7, "pclk_uart7", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(4), 15, GFLAGS),
+	GATE(PCLK_TSADC, "pclk_tsadc", "pclk_bus_root", CLK_IS_CRITICAL,
+			RV1126B_BUSCLKGATE_CON(5), 0, GFLAGS),
+	GATE(CLK_TSADC, "clk_tsadc", "xin24m", CLK_IS_CRITICAL,
+			RV1126B_BUSCLKGATE_CON(5), 1, GFLAGS),
+	GATE(HCLK_SAI0, "hclk_sai0", "hclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(5), 2, GFLAGS),
+	GATE(HCLK_SAI1, "hclk_sai1", "hclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(5), 4, GFLAGS),
+	GATE(HCLK_SAI2, "hclk_sai2", "hclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(5), 6, GFLAGS),
+	GATE(HCLK_RKDSM, "hclk_rkdsm", "hclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(5), 8, GFLAGS),
+	GATE(MCLK_RKDSM, "mclk_rkdsm", "mclk_sai2", 0,
+			RV1126B_BUSCLKGATE_CON(5), 9, GFLAGS),
+	GATE(HCLK_PDM, "hclk_pdm", "hclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(5), 10, GFLAGS),
+	GATE(HCLK_ASRC0, "hclk_asrc0", "hclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(5), 11, GFLAGS),
+	GATE(HCLK_ASRC1, "hclk_asrc1", "hclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(5), 12, GFLAGS),
+	GATE(PCLK_AUDIO_ADC_BUS, "pclk_audio_adc_bus", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(5), 13, GFLAGS),
+	GATE(MCLK_AUDIO_ADC_BUS, "mclk_audio_adc_bus", "mclk_sai2", 0,
+			RV1126B_BUSCLKGATE_CON(5), 14, GFLAGS),
+	FACTOR(MCLK_AUDIO_ADC_DIV4_BUS, "mclk_audio_adc_div4_bus", "mclk_audio_adc_bus", 0, 1, 4),
+	GATE(PCLK_RKCE, "pclk_rkce", "pclk_bus_root", CLK_IS_CRITICAL,
+			RV1126B_BUSCLKGATE_CON(6), 0, GFLAGS),
+	GATE(HCLK_NS_RKCE, "hclk_ns_rkce", "hclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(6), 1, GFLAGS),
+	GATE(PCLK_OTPC_NS, "pclk_otpc_ns", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(6), 2, GFLAGS),
+	GATE(CLK_SBPI_OTPC_NS, "clk_sbpi_otpc_ns", "xin24m", 0,
+			RV1126B_BUSCLKGATE_CON(6), 3, GFLAGS),
+	COMPOSITE_NOMUX(CLK_USER_OTPC_NS, "clk_user_otpc_ns", "xin24m", 0,
+			RV1126B_BUSCLKSEL_CON(2), 12, 3, DFLAGS,
+			RV1126B_BUSCLKGATE_CON(6), 4, GFLAGS),
+	GATE(PCLK_OTP_MASK, "pclk_otp_mask", "pclk_bus_root", 0,
+			RV1126B_BUSCLKGATE_CON(6), 6, GFLAGS),
+	GATE(CLK_TSADC_PHYCTRL, "clk_tsadc_phyctrl", "xin24m", CLK_IS_CRITICAL,
+			RV1126B_BUSCLKGATE_CON(6), 8, GFLAGS),
+	MUX(LRCK_SRC_ASRC0, "lrck_src_asrc0", lrck_src_asrc_p, 0,
+			RV1126B_BUSCLKSEL_CON(3), 0, 3, MFLAGS),
+	MUX(LRCK_DST_ASRC0, "lrck_dst_asrc0", lrck_src_asrc_p, 0,
+			RV1126B_BUSCLKSEL_CON(3), 4, 3, MFLAGS),
+	MUX(LRCK_SRC_ASRC1, "lrck_src_asrc1", lrck_src_asrc_p, 0,
+			RV1126B_BUSCLKSEL_CON(3), 8, 3, MFLAGS),
+	MUX(LRCK_DST_ASRC1, "lrck_dst_asrc1", lrck_src_asrc_p, 0,
+			RV1126B_BUSCLKSEL_CON(3), 12, 3, MFLAGS),
+	GATE(ACLK_NSRKCE, "aclk_nsrkce", "aclk_rkce_src", 0,
+			RV1126B_BUSCLKGATE_CON(2), 12, GFLAGS),
+	GATE(CLK_PKA_NSRKCE, "clk_pka_nsrkce", "clk_pka_rkce_src", 0,
+			RV1126B_BUSCLKGATE_CON(2), 13, GFLAGS),
+
+	/* pd_peri */
+	DIV(PCLK_RTC_ROOT, "pclk_rtc_root", "pclk_peri_root", 0,
+			RV1126B_PERICLKSEL_CON(0), 0, 2, DFLAGS),
+	GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_peri_root", 0,
+			RV1126B_PERICLKGATE_CON(0), 5, GFLAGS),
+	GATE(DBCLK_GPIO1, "dbclk_gpio1", "xin24m", 0,
+			RV1126B_PERICLKGATE_CON(0), 6, GFLAGS),
+	GATE(PCLK_IOC_VCCIO1, "pclk_ioc_vccio1", "pclk_peri_root", CLK_IS_CRITICAL,
+			RV1126B_PERICLKGATE_CON(0), 7, GFLAGS),
+	GATE(ACLK_USB3OTG, "aclk_usb3otg", "aclk_peri_root", 0,
+			RV1126B_PERICLKGATE_CON(0), 8, GFLAGS),
+	GATE(CLK_REF_USB3OTG, "clk_ref_usb3otg", "xin24m", 0,
+			RV1126B_PERICLKGATE_CON(0), 9, GFLAGS),
+	GATE(CLK_SUSPEND_USB3OTG, "clk_suspend_usb3otg", "xin24m", 0,
+			RV1126B_PERICLKGATE_CON(0), 10, GFLAGS),
+	GATE(HCLK_USB2HOST, "hclk_usb2host", "aclk_peri_root", 0,
+			RV1126B_PERICLKGATE_CON(0), 11, GFLAGS),
+	GATE(HCLK_ARB_USB2HOST, "hclk_arb_usb2host", "aclk_peri_root", 0,
+			RV1126B_PERICLKGATE_CON(0), 12, GFLAGS),
+	GATE(PCLK_RTC_TEST, "pclk_rtc_test", "pclk_rtc_root", 0,
+			RV1126B_PERICLKGATE_CON(0), 13, GFLAGS),
+	GATE(HCLK_EMMC, "hclk_emmc", "aclk_peri_root", 0,
+			RV1126B_PERICLKGATE_CON(1), 0, GFLAGS),
+	GATE(HCLK_FSPI0, "hclk_fspi0", "aclk_peri_root", 0,
+			RV1126B_PERICLKGATE_CON(1), 1, GFLAGS),
+	GATE(HCLK_XIP_FSPI0, "hclk_xip_fspi0", "aclk_peri_root", 0,
+			RV1126B_PERICLKGATE_CON(1), 2, GFLAGS),
+	GATE(PCLK_PIPEPHY, "pclk_pipephy", "pclk_peri_root", 0,
+			RV1126B_PERICLKGATE_CON(1), 8, GFLAGS),
+	GATE(PCLK_USB2PHY, "pclk_usb2phy", "pclk_peri_root", 0,
+			RV1126B_PERICLKGATE_CON(1), 10, GFLAGS),
+	COMPOSITE_NOMUX(CLK_REF_PIPEPHY_CPLL_SRC, "clk_ref_pipephy_cpll_src", "cpll", 0,
+			RV1126B_PERICLKSEL_CON(1), 0, 6, DFLAGS,
+			RV1126B_PERICLKGATE_CON(1), 14, GFLAGS),
+	MUX(CLK_REF_PIPEPHY, "clk_ref_pipephy", clk_ref_pipephy_p, 0,
+			RV1126B_PERICLKSEL_CON(1), 12, 1, MFLAGS),
+};
+
+static struct rockchip_clk_branch rv1126b_armclk __initdata =
+	MUX(ARMCLK, "armclk", mux_armclk_p, CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
+			RV1126B_CORECLKSEL_CON(0), 1, 1, MFLAGS);
+
+static void __init rv1126b_clk_init(struct device_node *np)
+{
+	struct rockchip_clk_provider *ctx;
+	void __iomem *reg_base;
+	unsigned long clk_nr_clks;
+
+	clk_nr_clks = rockchip_clk_find_max_clk_id(rv1126b_clk_branches,
+						   ARRAY_SIZE(rv1126b_clk_branches)) + 1;
+
+	reg_base = of_iomap(np, 0);
+	if (!reg_base) {
+		pr_err("%s: could not map cru region\n", __func__);
+		return;
+	}
+
+	ctx = rockchip_clk_init(np, reg_base, clk_nr_clks);
+	if (IS_ERR(ctx)) {
+		pr_err("%s: rockchip clk init failed\n", __func__);
+		iounmap(reg_base);
+		return;
+	}
+
+	rockchip_clk_register_plls(ctx, rv1126b_pll_clks,
+				   ARRAY_SIZE(rv1126b_pll_clks),
+				   0);
+
+	rockchip_clk_register_branches(ctx, rv1126b_clk_branches,
+				       ARRAY_SIZE(rv1126b_clk_branches));
+
+	rockchip_clk_register_armclk_multi_pll(ctx, &rv1126b_armclk,
+					       rv1126b_cpuclk_rates,
+					       ARRAY_SIZE(rv1126b_cpuclk_rates));
+
+	rv1126b_rst_init(np, reg_base);
+
+	rockchip_register_restart_notifier(ctx, RV1126B_GLB_SRST_FST, NULL);
+
+	rockchip_clk_of_add_provider(np, ctx);
+
+	/* pvtpll src init */
+	writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RV1126B_CORECLKSEL_CON(0));
+	writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RV1126B_NPUCLKSEL_CON(0));
+	writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RV1126B_VICLKSEL_CON(0));
+	writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RV1126B_VEPUCLKSEL_CON(0));
+	writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RV1126B_VCPCLKSEL_CON(0));
+}
+
+CLK_OF_DECLARE(rv1126b_cru, "rockchip,rv1126b-cru", rv1126b_clk_init);
+
+struct clk_rv1126b_inits {
+	void (*inits)(struct device_node *np);
+};
+
+static const struct clk_rv1126b_inits clk_rv1126b_init = {
+	.inits = rv1126b_clk_init,
+};
+
+static const struct of_device_id clk_rv1126b_match_table[] = {
+	{
+		.compatible = "rockchip,rv1126b-cru",
+		.data = &clk_rv1126b_init,
+	},
+	{ }
+};
+
+static int clk_rv1126b_probe(struct platform_device *pdev)
+{
+	const struct clk_rv1126b_inits *init_data;
+	struct device *dev = &pdev->dev;
+
+	init_data = device_get_match_data(dev);
+	if (!init_data)
+		return -EINVAL;
+
+	if (init_data->inits)
+		init_data->inits(dev->of_node);
+
+	return 0;
+}
+
+static struct platform_driver clk_rv1126b_driver = {
+	.probe		= clk_rv1126b_probe,
+	.driver		= {
+		.name	= "clk-rv1126b",
+		.of_match_table = clk_rv1126b_match_table,
+		.suppress_bind_attrs = true,
+	},
+};
+builtin_platform_driver_probe(clk_rv1126b_driver, clk_rv1126b_probe);
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index 23653a942403..87f09320b942 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -99,6 +99,73 @@ struct clk;
 #define RV1126_EMMC_CON0		0x450
 #define RV1126_EMMC_CON1		0x454
 
+#define RV1126B_TOPCRU_BASE		0x0
+#define RV1126B_BUSCRU_BASE		0x10000
+#define RV1126B_PERICRU_BASE		0x20000
+#define RV1126B_CORECRU_BASE		0x30000
+#define RV1126B_PMUCRU_BASE		0x40000
+#define RV1126B_PMU1CRU_BASE		0x50000
+#define RV1126B_DDRCRU_BASE		0x60000
+#define RV1126B_SUBDDRCRU_BASE		0x68000
+#define RV1126B_VICRU_BASE		0x70000
+#define RV1126B_VEPUCRU_BASE		0x80000
+#define RV1126B_NPUCRU_BASE		0x90000
+#define RV1126B_VDOCRU_BASE		0xA0000
+#define RV1126B_VCPCRU_BASE		0xB0000
+
+#define RV1126B_PLL_CON(x)		((x) * 0x4 + RV1126B_TOPCRU_BASE)
+#define RV1126B_MODE_CON		(0x280 + RV1126B_TOPCRU_BASE)
+#define RV1126B_CLKSEL_CON(x)		((x) * 0x4 + 0x300 + RV1126B_TOPCRU_BASE)
+#define RV1126B_CLKGATE_CON(x)		((x) * 0x4 + 0x800 + RV1126B_TOPCRU_BASE)
+#define RV1126B_SOFTRST_CON(x)		((x) * 0x4 + 0xa00 + RV1126B_TOPCRU_BASE)
+#define RV1126B_GLB_SRST_FST		(0xc08 + RV1126B_TOPCRU_BASE)
+#define RV1126B_GLB_SRST_SND		(0xc0c + RV1126B_TOPCRU_BASE)
+#define RV1126B_CLK_CM_FRAC0_DIV_H	(0xcc0 + RV1126B_TOPCRU_BASE)
+#define RV1126B_CLK_CM_FRAC1_DIV_H	(0xcc4 + RV1126B_TOPCRU_BASE)
+#define RV1126B_CLK_CM_FRAC2_DIV_H	(0xcc8 + RV1126B_TOPCRU_BASE)
+#define RV1126B_CLK_UART_FRAC0_DIV_H	(0xccc + RV1126B_TOPCRU_BASE)
+#define RV1126B_CLK_UART_FRAC1_DIV_H	(0xcd0 + RV1126B_TOPCRU_BASE)
+#define RV1126B_CLK_AUDIO_FRAC0_DIV_H	(0xcd4 + RV1126B_TOPCRU_BASE)
+#define RV1126B_CLK_AUDIO_FRAC1_DIV_H	(0xcd8 + RV1126B_TOPCRU_BASE)
+#define RV1126B_BUSCLKSEL_CON(x)	((x) * 0x4 + 0x300 + RV1126B_BUSCRU_BASE)
+#define RV1126B_BUSCLKGATE_CON(x)	((x) * 0x4 + 0x800 + RV1126B_BUSCRU_BASE)
+#define RV1126B_BUSSOFTRST_CON(x)	((x) * 0x4 + 0xa00 + RV1126B_BUSCRU_BASE)
+#define RV1126B_PERIPLL_CON(x)		((x) * 0x4 + RV1126B_PERICRU_BASE)
+#define RV1126B_PERICLKSEL_CON(x)	((x) * 0x4 + 0x300 + RV1126B_PERICRU_BASE)
+#define RV1126B_PERICLKGATE_CON(x)	((x) * 0x4 + 0x800 + RV1126B_PERICRU_BASE)
+#define RV1126B_PERISOFTRST_CON(x)	((x) * 0x4 + 0xa00 + RV1126B_PERICRU_BASE)
+#define RV1126B_CORECLKSEL_CON(x)	((x) * 0x4 + 0x300 + RV1126B_CORECRU_BASE)
+#define RV1126B_CORECLKGATE_CON(x)	((x) * 0x4 + 0x800 + RV1126B_CORECRU_BASE)
+#define RV1126B_CORESOFTRST_CON(x)	((x) * 0x4 + 0xa00 + RV1126B_CORECRU_BASE)
+#define RV1126B_PMUCLKSEL_CON(x)	((x) * 0x4 + 0x300 + RV1126B_PMUCRU_BASE)
+#define RV1126B_PMUCLKGATE_CON(x)	((x) * 0x4 + 0x800 + RV1126B_PMUCRU_BASE)
+#define RV1126B_PMUSOFTRST_CON(x)	((x) * 0x4 + 0xa00 + RV1126B_PMUCRU_BASE)
+#define RV1126B_PMU1CLKSEL_CON(x)	((x) * 0x4 + 0x300 + RV1126B_PMU1CRU_BASE)
+#define RV1126B_PMU1CLKGATE_CON(x)	((x) * 0x4 + 0x800 + RV1126B_PMU1CRU_BASE)
+#define RV1126B_PMU1SOFTRST_CON(x)	((x) * 0x4 + 0xa00 + RV1126B_PMU1CRU_BASE)
+#define RV1126B_DDRCLKSEL_CON(x)	((x) * 0x4 + 0x300 + RV1126B_DDRCRU_BASE)
+#define RV1126B_DDRCLKGATE_CON(x)	((x) * 0x4 + 0x800 + RV1126B_DDRCRU_BASE)
+#define RV1126B_DDRSOFTRST_CON(x)	((x) * 0x4 + 0xa00 + RV1126B_DDRCRU_BASE)
+#define RV1126B_SUBDDRPLL_CON(x)	((x) * 0x4 + RV1126B_SUBDDRCRU_BASE)
+#define RV1126B_SUBDDRCLKSEL_CON(x)	((x) * 0x4 + 0x300 + RV1126B_SUBDDRCRU_BASE)
+#define RV1126B_SUBDDRCLKGATE_CON(x)	((x) * 0x4 + 0x800 + RV1126B_SUBDDRCRU_BASE)
+#define RV1126B_SUBDDRSOFTRST_CON(x)	((x) * 0x4 + 0xa00 + RV1126B_SUBDDRCRU_BASE)
+#define RV1126B_VICLKSEL_CON(x)		((x) * 0x4 + 0x300 + RV1126B_VICRU_BASE)
+#define RV1126B_VICLKGATE_CON(x)	((x) * 0x4 + 0x800 + RV1126B_VICRU_BASE)
+#define RV1126B_VISOFTRST_CON(x)	((x) * 0x4 + 0xa00 + RV1126B_VICRU_BASE)
+#define RV1126B_VEPUCLKSEL_CON(x)	((x) * 0x4 + 0x300 + RV1126B_VEPUCRU_BASE)
+#define RV1126B_VEPUCLKGATE_CON(x)	((x) * 0x4 + 0x800 + RV1126B_VEPUCRU_BASE)
+#define RV1126B_VEPUSOFTRST_CON(x)	((x) * 0x4 + 0xa00 + RV1126B_VEPUCRU_BASE)
+#define RV1126B_NPUCLKSEL_CON(x)	((x) * 0x4 + 0x300 + RV1126B_NPUCRU_BASE)
+#define RV1126B_NPUCLKGATE_CON(x)	((x) * 0x4 + 0x800 + RV1126B_NPUCRU_BASE)
+#define RV1126B_NPUSOFTRST_CON(x)	((x) * 0x4 + 0xa00 + RV1126B_NPUCRU_BASE)
+#define RV1126B_VDOCLKSEL_CON(x)	((x) * 0x4 + 0x300 + RV1126B_VDOCRU_BASE)
+#define RV1126B_VDOCLKGATE_CON(x)	((x) * 0x4 + 0x800 + RV1126B_VDOCRU_BASE)
+#define RV1126B_VDOSOFTRST_CON(x)	((x) * 0x4 + 0xa00 + RV1126B_VDOCRU_BASE)
+#define RV1126B_VCPCLKSEL_CON(x)	((x) * 0x4 + 0x300 + RV1126B_VCPCRU_BASE)
+#define RV1126B_VCPCLKGATE_CON(x)	((x) * 0x4 + 0x800 + RV1126B_VCPCRU_BASE)
+#define RV1126B_VCPSOFTRST_CON(x)	((x) * 0x4 + 0xa00 + RV1126B_VCPCRU_BASE)
+
 #define RK2928_PLL_CON(x)		((x) * 0x4)
 #define RK2928_MODE_CON		0x40
 #define RK2928_CLKSEL_CON(x)	((x) * 0x4 + 0x44)
@@ -1261,6 +1328,7 @@ static inline void rockchip_register_softrst(struct device_node *np,
 	return rockchip_register_softrst_lut(np, NULL, num_regs, base, flags);
 }
 
+void rv1126b_rst_init(struct device_node *np, void __iomem *reg_base);
 void rk3528_rst_init(struct device_node *np, void __iomem *reg_base);
 void rk3562_rst_init(struct device_node *np, void __iomem *reg_base);
 void rk3576_rst_init(struct device_node *np, void __iomem *reg_base);
diff --git a/drivers/clk/rockchip/rst-rv1126b.c b/drivers/clk/rockchip/rst-rv1126b.c
new file mode 100644
index 000000000000..a6c6d35c59a8
--- /dev/null
+++ b/drivers/clk/rockchip/rst-rv1126b.c
@@ -0,0 +1,444 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2025 Rockchip Electronics Co., Ltd.
+ * Author: Elaine Zhang <zhangqing at rock-chips.com>
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <dt-bindings/reset/rockchip,rv1126b-cru.h>
+#include "clk.h"
+
+/* 0x20000000 + 0x0A00 */
+#define TOPCRU_RESET_OFFSET(id, reg, bit) [id] = (0x0 * 4 + reg * 16 + bit)
+/* 0x20010000 + 0x0A00 */
+#define BUSCRU_RESET_OFFSET(id, reg, bit) [id] = (0x10000 * 4 + reg * 16 + bit)
+/* 0x20020000 + 0x0A00 */
+#define PERICRU_RESET_OFFSET(id, reg, bit) [id] = (0x20000 * 4 + reg * 16 + bit)
+/* 0x20030000 + 0x0A00 */
+#define CORECRU_RESET_OFFSET(id, reg, bit) [id] = (0x30000 * 4 + reg * 16 + bit)
+/* 0x20040000 + 0x0A00 */
+#define PMUCRU_RESET_OFFSET(id, reg, bit) [id] = (0x40000 * 4 + reg * 16 + bit)
+/* 0x20050000 + 0x0A00 */
+#define PMU1CRU_RESET_OFFSET(id, reg, bit) [id] = (0x50000 * 4 + reg * 16 + bit)
+/* 0x20060000 + 0x0A00 */
+#define DDRCRU_RESET_OFFSET(id, reg, bit) [id] = (0x60000 * 4 + reg * 16 + bit)
+/* 0x20068000 + 0x0A00 */
+#define SUBDDRCRU_RESET_OFFSET(id, reg, bit) [id] = (0x68000 * 4 + reg * 16 + bit)
+/* 0x20070000 + 0x0A00 */
+#define VICRU_RESET_OFFSET(id, reg, bit) [id] = (0x70000 * 4 + reg * 16 + bit)
+/* 0x20080000 + 0x0A00 */
+#define VEPUCRU_RESET_OFFSET(id, reg, bit) [id] = (0x80000 * 4 + reg * 16 + bit)
+/* 0x20090000 + 0x0A00 */
+#define NPUCRU_RESET_OFFSET(id, reg, bit) [id] = (0x90000 * 4 + reg * 16 + bit)
+/* 0x200A0000 + 0x0A00 */
+#define VDOCRU_RESET_OFFSET(id, reg, bit) [id] = (0xA0000 * 4 + reg * 16 + bit)
+/* 0x200B0000 + 0x0A00 */
+#define VCPCRU_RESET_OFFSET(id, reg, bit) [id] = (0xB0000 * 4 + reg * 16 + bit)
+
+/* =================mapping table for reset ID to register offset================== */
+static const int rv1126b_register_offset[] = {
+	/* TOPCRU-->SOFTRST_CON00 */
+
+	/* TOPCRU-->SOFTRST_CON15 */
+	TOPCRU_RESET_OFFSET(SRST_P_CRU, 15, 1),
+	TOPCRU_RESET_OFFSET(SRST_P_CRU_BIU, 15, 2),
+
+	/* BUSCRU-->SOFTRST_CON00 */
+	BUSCRU_RESET_OFFSET(SRST_A_TOP_BIU, 0, 0),
+	BUSCRU_RESET_OFFSET(SRST_A_RKCE_BIU, 0, 1),
+	BUSCRU_RESET_OFFSET(SRST_A_BUS_BIU, 0, 2),
+	BUSCRU_RESET_OFFSET(SRST_H_BUS_BIU, 0, 3),
+	BUSCRU_RESET_OFFSET(SRST_P_BUS_BIU, 0, 4),
+	BUSCRU_RESET_OFFSET(SRST_P_CRU_BUS, 0, 5),
+	BUSCRU_RESET_OFFSET(SRST_P_SYS_GRF, 0, 6),
+	BUSCRU_RESET_OFFSET(SRST_H_BOOTROM, 0, 7),
+	BUSCRU_RESET_OFFSET(SRST_A_GIC400, 0, 8),
+	BUSCRU_RESET_OFFSET(SRST_A_SPINLOCK, 0, 9),
+	BUSCRU_RESET_OFFSET(SRST_P_WDT_NS, 0, 10),
+	BUSCRU_RESET_OFFSET(SRST_T_WDT_NS, 0, 11),
+
+	/* BUSCRU-->SOFTRST_CON01 */
+	BUSCRU_RESET_OFFSET(SRST_P_WDT_HPMCU, 1, 0),
+	BUSCRU_RESET_OFFSET(SRST_T_WDT_HPMCU, 1, 1),
+	BUSCRU_RESET_OFFSET(SRST_H_CACHE, 1, 2),
+	BUSCRU_RESET_OFFSET(SRST_P_HPMCU_MAILBOX, 1, 3),
+	BUSCRU_RESET_OFFSET(SRST_P_HPMCU_INTMUX, 1, 4),
+	BUSCRU_RESET_OFFSET(SRST_HPMCU_FULL_CLUSTER, 1, 5),
+	BUSCRU_RESET_OFFSET(SRST_HPMCU_PWUP, 1, 6),
+	BUSCRU_RESET_OFFSET(SRST_HPMCU_ONLY_CORE, 1, 7),
+	BUSCRU_RESET_OFFSET(SRST_T_HPMCU_JTAG, 1, 8),
+	BUSCRU_RESET_OFFSET(SRST_P_RKDMA, 1, 11),
+	BUSCRU_RESET_OFFSET(SRST_A_RKDMA, 1, 12),
+
+	/* BUSCRU-->SOFTRST_CON02 */
+	BUSCRU_RESET_OFFSET(SRST_P_DCF, 2, 0),
+	BUSCRU_RESET_OFFSET(SRST_A_DCF, 2, 1),
+	BUSCRU_RESET_OFFSET(SRST_H_RGA, 2, 2),
+	BUSCRU_RESET_OFFSET(SRST_A_RGA, 2, 3),
+	BUSCRU_RESET_OFFSET(SRST_CORE_RGA, 2, 4),
+	BUSCRU_RESET_OFFSET(SRST_P_TIMER, 2, 5),
+	BUSCRU_RESET_OFFSET(SRST_TIMER0, 2, 6),
+	BUSCRU_RESET_OFFSET(SRST_TIMER1, 2, 7),
+	BUSCRU_RESET_OFFSET(SRST_TIMER2, 2, 8),
+	BUSCRU_RESET_OFFSET(SRST_TIMER3, 2, 9),
+	BUSCRU_RESET_OFFSET(SRST_TIMER4, 2, 10),
+	BUSCRU_RESET_OFFSET(SRST_TIMER5, 2, 11),
+	BUSCRU_RESET_OFFSET(SRST_A_RKCE, 2, 12),
+	BUSCRU_RESET_OFFSET(SRST_PKA_RKCE, 2, 13),
+	BUSCRU_RESET_OFFSET(SRST_H_RKRNG_S, 2, 14),
+	BUSCRU_RESET_OFFSET(SRST_H_RKRNG_NS, 2, 15),
+
+	/* BUSCRU-->SOFTRST_CON03 */
+	BUSCRU_RESET_OFFSET(SRST_P_I2C0, 3, 0),
+	BUSCRU_RESET_OFFSET(SRST_I2C0, 3, 1),
+	BUSCRU_RESET_OFFSET(SRST_P_I2C1, 3, 2),
+	BUSCRU_RESET_OFFSET(SRST_I2C1, 3, 3),
+	BUSCRU_RESET_OFFSET(SRST_P_I2C3, 3, 4),
+	BUSCRU_RESET_OFFSET(SRST_I2C3, 3, 5),
+	BUSCRU_RESET_OFFSET(SRST_P_I2C4, 3, 6),
+	BUSCRU_RESET_OFFSET(SRST_I2C4, 3, 7),
+	BUSCRU_RESET_OFFSET(SRST_P_I2C5, 3, 8),
+	BUSCRU_RESET_OFFSET(SRST_I2C5, 3, 9),
+	BUSCRU_RESET_OFFSET(SRST_P_SPI0, 3, 10),
+	BUSCRU_RESET_OFFSET(SRST_SPI0, 3, 11),
+	BUSCRU_RESET_OFFSET(SRST_P_SPI1, 3, 12),
+	BUSCRU_RESET_OFFSET(SRST_SPI1, 3, 13),
+
+	/* BUSCRU-->SOFTRST_CON04 */
+	BUSCRU_RESET_OFFSET(SRST_P_PWM0, 4, 0),
+	BUSCRU_RESET_OFFSET(SRST_PWM0, 4, 1),
+	BUSCRU_RESET_OFFSET(SRST_P_PWM2, 4, 4),
+	BUSCRU_RESET_OFFSET(SRST_PWM2, 4, 5),
+	BUSCRU_RESET_OFFSET(SRST_P_PWM3, 4, 8),
+	BUSCRU_RESET_OFFSET(SRST_PWM3, 4, 9),
+
+	/* BUSCRU-->SOFTRST_CON05 */
+	BUSCRU_RESET_OFFSET(SRST_P_UART1, 5, 0),
+	BUSCRU_RESET_OFFSET(SRST_S_UART1, 5, 1),
+	BUSCRU_RESET_OFFSET(SRST_P_UART2, 5, 2),
+	BUSCRU_RESET_OFFSET(SRST_S_UART2, 5, 3),
+	BUSCRU_RESET_OFFSET(SRST_P_UART3, 5, 4),
+	BUSCRU_RESET_OFFSET(SRST_S_UART3, 5, 5),
+	BUSCRU_RESET_OFFSET(SRST_P_UART4, 5, 6),
+	BUSCRU_RESET_OFFSET(SRST_S_UART4, 5, 7),
+	BUSCRU_RESET_OFFSET(SRST_P_UART5, 5, 8),
+	BUSCRU_RESET_OFFSET(SRST_S_UART5, 5, 9),
+	BUSCRU_RESET_OFFSET(SRST_P_UART6, 5, 10),
+	BUSCRU_RESET_OFFSET(SRST_S_UART6, 5, 11),
+	BUSCRU_RESET_OFFSET(SRST_P_UART7, 5, 12),
+	BUSCRU_RESET_OFFSET(SRST_S_UART7, 5, 13),
+
+	/* BUSCRU-->SOFTRST_CON06 */
+	BUSCRU_RESET_OFFSET(SRST_P_TSADC, 6, 0),
+	BUSCRU_RESET_OFFSET(SRST_TSADC, 6, 1),
+	BUSCRU_RESET_OFFSET(SRST_H_SAI0, 6, 2),
+	BUSCRU_RESET_OFFSET(SRST_M_SAI0, 6, 3),
+	BUSCRU_RESET_OFFSET(SRST_H_SAI1, 6, 4),
+	BUSCRU_RESET_OFFSET(SRST_M_SAI1, 6, 5),
+	BUSCRU_RESET_OFFSET(SRST_H_SAI2, 6, 6),
+	BUSCRU_RESET_OFFSET(SRST_M_SAI2, 6, 7),
+	BUSCRU_RESET_OFFSET(SRST_H_RKDSM, 6, 8),
+	BUSCRU_RESET_OFFSET(SRST_M_RKDSM, 6, 9),
+	BUSCRU_RESET_OFFSET(SRST_H_PDM, 6, 10),
+	BUSCRU_RESET_OFFSET(SRST_M_PDM, 6, 11),
+	BUSCRU_RESET_OFFSET(SRST_PDM, 6, 12),
+
+	/* BUSCRU-->SOFTRST_CON07 */
+	BUSCRU_RESET_OFFSET(SRST_H_ASRC0, 7, 0),
+	BUSCRU_RESET_OFFSET(SRST_ASRC0, 7, 1),
+	BUSCRU_RESET_OFFSET(SRST_H_ASRC1, 7, 2),
+	BUSCRU_RESET_OFFSET(SRST_ASRC1, 7, 3),
+	BUSCRU_RESET_OFFSET(SRST_P_AUDIO_ADC_BUS, 7, 4),
+	BUSCRU_RESET_OFFSET(SRST_M_AUDIO_ADC_BUS, 7, 5),
+	BUSCRU_RESET_OFFSET(SRST_P_RKCE, 7, 6),
+	BUSCRU_RESET_OFFSET(SRST_H_NS_RKCE, 7, 7),
+	BUSCRU_RESET_OFFSET(SRST_P_OTPC_NS, 7, 8),
+	BUSCRU_RESET_OFFSET(SRST_SBPI_OTPC_NS, 7, 9),
+	BUSCRU_RESET_OFFSET(SRST_USER_OTPC_NS, 7, 10),
+	BUSCRU_RESET_OFFSET(SRST_OTPC_ARB, 7, 11),
+	BUSCRU_RESET_OFFSET(SRST_P_OTP_MASK, 7, 12),
+
+	/* PERICRU-->SOFTRST_CON00 */
+	PERICRU_RESET_OFFSET(SRST_A_PERI_BIU, 0, 0),
+	PERICRU_RESET_OFFSET(SRST_P_PERI_BIU, 0, 1),
+	PERICRU_RESET_OFFSET(SRST_P_RTC_BIU, 0, 2),
+	PERICRU_RESET_OFFSET(SRST_P_CRU_PERI, 0, 3),
+	PERICRU_RESET_OFFSET(SRST_P_PERI_GRF, 0, 4),
+	PERICRU_RESET_OFFSET(SRST_P_GPIO1, 0, 5),
+	PERICRU_RESET_OFFSET(SRST_DB_GPIO1, 0, 6),
+	PERICRU_RESET_OFFSET(SRST_P_IOC_VCCIO1, 0, 7),
+	PERICRU_RESET_OFFSET(SRST_A_USB3OTG, 0, 8),
+	PERICRU_RESET_OFFSET(SRST_H_USB2HOST, 0, 11),
+	PERICRU_RESET_OFFSET(SRST_H_ARB_USB2HOST, 0, 12),
+	PERICRU_RESET_OFFSET(SRST_P_RTC_TEST, 0, 13),
+
+	/* PERICRU-->SOFTRST_CON01 */
+	PERICRU_RESET_OFFSET(SRST_H_EMMC, 1, 0),
+	PERICRU_RESET_OFFSET(SRST_H_FSPI0, 1, 1),
+	PERICRU_RESET_OFFSET(SRST_H_XIP_FSPI0, 1, 2),
+	PERICRU_RESET_OFFSET(SRST_S_2X_FSPI0, 1, 3),
+	PERICRU_RESET_OFFSET(SRST_UTMI_USB2HOST, 1, 5),
+	PERICRU_RESET_OFFSET(SRST_REF_PIPEPHY, 1, 7),
+	PERICRU_RESET_OFFSET(SRST_P_PIPEPHY, 1, 8),
+	PERICRU_RESET_OFFSET(SRST_P_PIPEPHY_GRF, 1, 9),
+	PERICRU_RESET_OFFSET(SRST_P_USB2PHY, 1, 10),
+	PERICRU_RESET_OFFSET(SRST_POR_USB2PHY, 1, 11),
+	PERICRU_RESET_OFFSET(SRST_OTG_USB2PHY, 1, 12),
+	PERICRU_RESET_OFFSET(SRST_HOST_USB2PHY, 1, 13),
+
+	/* CORECRU-->SOFTRST_CON00 */
+	CORECRU_RESET_OFFSET(SRST_REF_PVTPLL_CORE, 0, 0),
+	CORECRU_RESET_OFFSET(SRST_NCOREPORESET0, 0, 1),
+	CORECRU_RESET_OFFSET(SRST_NCORESET0, 0, 2),
+	CORECRU_RESET_OFFSET(SRST_NCOREPORESET1, 0, 3),
+	CORECRU_RESET_OFFSET(SRST_NCORESET1, 0, 4),
+	CORECRU_RESET_OFFSET(SRST_NCOREPORESET2, 0, 5),
+	CORECRU_RESET_OFFSET(SRST_NCORESET2, 0, 6),
+	CORECRU_RESET_OFFSET(SRST_NCOREPORESET3, 0, 7),
+	CORECRU_RESET_OFFSET(SRST_NCORESET3, 0, 8),
+	CORECRU_RESET_OFFSET(SRST_NDBGRESET, 0, 9),
+	CORECRU_RESET_OFFSET(SRST_NL2RESET, 0, 10),
+
+	/* CORECRU-->SOFTRST_CON01 */
+	CORECRU_RESET_OFFSET(SRST_A_CORE_BIU, 1, 0),
+	CORECRU_RESET_OFFSET(SRST_P_CORE_BIU, 1, 1),
+	CORECRU_RESET_OFFSET(SRST_H_CORE_BIU, 1, 2),
+	CORECRU_RESET_OFFSET(SRST_P_DBG, 1, 3),
+	CORECRU_RESET_OFFSET(SRST_POT_DBG, 1, 4),
+	CORECRU_RESET_OFFSET(SRST_NT_DBG, 1, 5),
+	CORECRU_RESET_OFFSET(SRST_P_CORE_PVTPLL, 1, 6),
+	CORECRU_RESET_OFFSET(SRST_P_CRU_CORE, 1, 7),
+	CORECRU_RESET_OFFSET(SRST_P_CORE_GRF, 1, 8),
+	CORECRU_RESET_OFFSET(SRST_P_DFT2APB, 1, 10),
+
+	/* PMUCRU-->SOFTRST_CON00 */
+	PMUCRU_RESET_OFFSET(SRST_H_PMU_BIU, 0, 0),
+	PMUCRU_RESET_OFFSET(SRST_P_PMU_GPIO0, 0, 7),
+	PMUCRU_RESET_OFFSET(SRST_DB_PMU_GPIO0, 0, 8),
+	PMUCRU_RESET_OFFSET(SRST_P_PMU_HP_TIMER, 0, 10),
+	PMUCRU_RESET_OFFSET(SRST_PMU_HP_TIMER, 0, 11),
+	PMUCRU_RESET_OFFSET(SRST_PMU_32K_HP_TIMER, 0, 12),
+
+	/* PMUCRU-->SOFTRST_CON01 */
+	PMUCRU_RESET_OFFSET(SRST_P_PWM1, 1, 0),
+	PMUCRU_RESET_OFFSET(SRST_PWM1, 1, 1),
+	PMUCRU_RESET_OFFSET(SRST_P_I2C2, 1, 2),
+	PMUCRU_RESET_OFFSET(SRST_I2C2, 1, 3),
+	PMUCRU_RESET_OFFSET(SRST_P_UART0, 1, 4),
+	PMUCRU_RESET_OFFSET(SRST_S_UART0, 1, 5),
+
+	/* PMUCRU-->SOFTRST_CON02 */
+	PMUCRU_RESET_OFFSET(SRST_P_RCOSC_CTRL, 2, 0),
+	PMUCRU_RESET_OFFSET(SRST_REF_RCOSC_CTRL, 2, 2),
+	PMUCRU_RESET_OFFSET(SRST_P_IOC_PMUIO0, 2, 3),
+	PMUCRU_RESET_OFFSET(SRST_P_CRU_PMU, 2, 4),
+	PMUCRU_RESET_OFFSET(SRST_P_PMU_GRF, 2, 5),
+	PMUCRU_RESET_OFFSET(SRST_PREROLL, 2, 7),
+	PMUCRU_RESET_OFFSET(SRST_PREROLL_32K, 2, 8),
+	PMUCRU_RESET_OFFSET(SRST_H_PMU_SRAM, 2, 9),
+
+	/* PMUCRU-->SOFTRST_CON03 */
+	PMUCRU_RESET_OFFSET(SRST_P_WDT_LPMCU, 3, 0),
+	PMUCRU_RESET_OFFSET(SRST_T_WDT_LPMCU, 3, 1),
+	PMUCRU_RESET_OFFSET(SRST_LPMCU_FULL_CLUSTER, 3, 2),
+	PMUCRU_RESET_OFFSET(SRST_LPMCU_PWUP, 3, 3),
+	PMUCRU_RESET_OFFSET(SRST_LPMCU_ONLY_CORE, 3, 4),
+	PMUCRU_RESET_OFFSET(SRST_T_LPMCU_JTAG, 3, 5),
+	PMUCRU_RESET_OFFSET(SRST_P_LPMCU_MAILBOX, 3, 6),
+
+	/* PMU1CRU-->SOFTRST_CON00 */
+	PMU1CRU_RESET_OFFSET(SRST_P_SPI2AHB, 0, 0),
+	PMU1CRU_RESET_OFFSET(SRST_H_SPI2AHB, 0, 1),
+	PMU1CRU_RESET_OFFSET(SRST_H_FSPI1, 0, 2),
+	PMU1CRU_RESET_OFFSET(SRST_H_XIP_FSPI1, 0, 3),
+	PMU1CRU_RESET_OFFSET(SRST_S_1X_FSPI1, 0, 4),
+	PMU1CRU_RESET_OFFSET(SRST_P_IOC_PMUIO1, 0, 5),
+	PMU1CRU_RESET_OFFSET(SRST_P_CRU_PMU1, 0, 6),
+	PMU1CRU_RESET_OFFSET(SRST_P_AUDIO_ADC_PMU, 0, 7),
+	PMU1CRU_RESET_OFFSET(SRST_M_AUDIO_ADC_PMU, 0, 8),
+	PMU1CRU_RESET_OFFSET(SRST_H_PMU1_BIU, 0, 9),
+
+	/* PMU1CRU-->SOFTRST_CON01 */
+	PMU1CRU_RESET_OFFSET(SRST_P_LPDMA, 1, 0),
+	PMU1CRU_RESET_OFFSET(SRST_A_LPDMA, 1, 1),
+	PMU1CRU_RESET_OFFSET(SRST_H_LPSAI, 1, 2),
+	PMU1CRU_RESET_OFFSET(SRST_M_LPSAI, 1, 3),
+	PMU1CRU_RESET_OFFSET(SRST_P_AOA_TDD, 1, 4),
+	PMU1CRU_RESET_OFFSET(SRST_P_AOA_FE, 1, 5),
+	PMU1CRU_RESET_OFFSET(SRST_P_AOA_AAD, 1, 6),
+	PMU1CRU_RESET_OFFSET(SRST_P_AOA_APB, 1, 7),
+	PMU1CRU_RESET_OFFSET(SRST_P_AOA_SRAM, 1, 8),
+
+	/* DDRCRU-->SOFTRST_CON00 */
+	DDRCRU_RESET_OFFSET(SRST_P_DDR_BIU, 0, 1),
+	DDRCRU_RESET_OFFSET(SRST_P_DDRC, 0, 2),
+	DDRCRU_RESET_OFFSET(SRST_P_DDRMON, 0, 3),
+	DDRCRU_RESET_OFFSET(SRST_TIMER_DDRMON, 0, 4),
+	DDRCRU_RESET_OFFSET(SRST_P_DFICTRL, 0, 5),
+	DDRCRU_RESET_OFFSET(SRST_P_DDR_GRF, 0, 6),
+	DDRCRU_RESET_OFFSET(SRST_P_CRU_DDR, 0, 7),
+	DDRCRU_RESET_OFFSET(SRST_P_DDRPHY, 0, 8),
+	DDRCRU_RESET_OFFSET(SRST_P_DMA2DDR, 0, 9),
+
+	/* SUBDDRCRU-->SOFTRST_CON00 */
+	SUBDDRCRU_RESET_OFFSET(SRST_A_SYSMEM_BIU, 0, 0),
+	SUBDDRCRU_RESET_OFFSET(SRST_A_SYSMEM, 0, 1),
+	SUBDDRCRU_RESET_OFFSET(SRST_A_DDR_BIU, 0, 2),
+	SUBDDRCRU_RESET_OFFSET(SRST_A_DDRSCH0_CPU, 0, 3),
+	SUBDDRCRU_RESET_OFFSET(SRST_A_DDRSCH1_NPU, 0, 4),
+	SUBDDRCRU_RESET_OFFSET(SRST_A_DDRSCH2_POE, 0, 5),
+	SUBDDRCRU_RESET_OFFSET(SRST_A_DDRSCH3_VI, 0, 6),
+	SUBDDRCRU_RESET_OFFSET(SRST_CORE_DDRC, 0, 7),
+	SUBDDRCRU_RESET_OFFSET(SRST_DDRMON, 0, 8),
+	SUBDDRCRU_RESET_OFFSET(SRST_DFICTRL, 0, 9),
+	SUBDDRCRU_RESET_OFFSET(SRST_RS, 0, 11),
+	SUBDDRCRU_RESET_OFFSET(SRST_A_DMA2DDR, 0, 12),
+	SUBDDRCRU_RESET_OFFSET(SRST_DDRPHY, 0, 13),
+
+	/* VICRU-->SOFTRST_CON00 */
+	VICRU_RESET_OFFSET(SRST_REF_PVTPLL_ISP, 0, 0),
+	VICRU_RESET_OFFSET(SRST_A_GMAC_BIU, 0, 1),
+	VICRU_RESET_OFFSET(SRST_A_VI_BIU, 0, 2),
+	VICRU_RESET_OFFSET(SRST_H_VI_BIU, 0, 3),
+	VICRU_RESET_OFFSET(SRST_P_VI_BIU, 0, 4),
+	VICRU_RESET_OFFSET(SRST_P_CRU_VI, 0, 5),
+	VICRU_RESET_OFFSET(SRST_P_VI_GRF, 0, 6),
+	VICRU_RESET_OFFSET(SRST_P_VI_PVTPLL, 0, 7),
+	VICRU_RESET_OFFSET(SRST_P_DSMC, 0, 8),
+	VICRU_RESET_OFFSET(SRST_A_DSMC, 0, 9),
+	VICRU_RESET_OFFSET(SRST_H_CAN0, 0, 10),
+	VICRU_RESET_OFFSET(SRST_CAN0, 0, 11),
+	VICRU_RESET_OFFSET(SRST_H_CAN1, 0, 12),
+	VICRU_RESET_OFFSET(SRST_CAN1, 0, 13),
+
+	/* VICRU-->SOFTRST_CON01 */
+	VICRU_RESET_OFFSET(SRST_P_GPIO2, 1, 0),
+	VICRU_RESET_OFFSET(SRST_DB_GPIO2, 1, 1),
+	VICRU_RESET_OFFSET(SRST_P_GPIO4, 1, 2),
+	VICRU_RESET_OFFSET(SRST_DB_GPIO4, 1, 3),
+	VICRU_RESET_OFFSET(SRST_P_GPIO5, 1, 4),
+	VICRU_RESET_OFFSET(SRST_DB_GPIO5, 1, 5),
+	VICRU_RESET_OFFSET(SRST_P_GPIO6, 1, 6),
+	VICRU_RESET_OFFSET(SRST_DB_GPIO6, 1, 7),
+	VICRU_RESET_OFFSET(SRST_P_GPIO7, 1, 8),
+	VICRU_RESET_OFFSET(SRST_DB_GPIO7, 1, 9),
+	VICRU_RESET_OFFSET(SRST_P_IOC_VCCIO2, 1, 10),
+	VICRU_RESET_OFFSET(SRST_P_IOC_VCCIO4, 1, 11),
+	VICRU_RESET_OFFSET(SRST_P_IOC_VCCIO5, 1, 12),
+	VICRU_RESET_OFFSET(SRST_P_IOC_VCCIO6, 1, 13),
+	VICRU_RESET_OFFSET(SRST_P_IOC_VCCIO7, 1, 14),
+
+	/* VICRU-->SOFTRST_CON02 */
+	VICRU_RESET_OFFSET(SRST_CORE_ISP, 2, 0),
+	VICRU_RESET_OFFSET(SRST_H_VICAP, 2, 1),
+	VICRU_RESET_OFFSET(SRST_A_VICAP, 2, 2),
+	VICRU_RESET_OFFSET(SRST_D_VICAP, 2, 3),
+	VICRU_RESET_OFFSET(SRST_ISP0_VICAP, 2, 4),
+	VICRU_RESET_OFFSET(SRST_CORE_VPSS, 2, 5),
+	VICRU_RESET_OFFSET(SRST_CORE_VPSL, 2, 6),
+	VICRU_RESET_OFFSET(SRST_P_CSI2HOST0, 2, 7),
+	VICRU_RESET_OFFSET(SRST_P_CSI2HOST1, 2, 8),
+	VICRU_RESET_OFFSET(SRST_P_CSI2HOST2, 2, 9),
+	VICRU_RESET_OFFSET(SRST_P_CSI2HOST3, 2, 10),
+	VICRU_RESET_OFFSET(SRST_H_SDMMC0, 2, 11),
+	VICRU_RESET_OFFSET(SRST_A_GMAC, 2, 12),
+	VICRU_RESET_OFFSET(SRST_P_CSIPHY0, 2, 13),
+	VICRU_RESET_OFFSET(SRST_P_CSIPHY1, 2, 14),
+
+	/* VICRU-->SOFTRST_CON03 */
+	VICRU_RESET_OFFSET(SRST_P_MACPHY, 3, 0),
+	VICRU_RESET_OFFSET(SRST_MACPHY, 3, 1),
+	VICRU_RESET_OFFSET(SRST_P_SARADC1, 3, 2),
+	VICRU_RESET_OFFSET(SRST_SARADC1, 3, 3),
+	VICRU_RESET_OFFSET(SRST_P_SARADC2, 3, 5),
+	VICRU_RESET_OFFSET(SRST_SARADC2, 3, 6),
+
+	/* VEPUCRU-->SOFTRST_CON00 */
+	VEPUCRU_RESET_OFFSET(SRST_REF_PVTPLL_VEPU, 0, 0),
+	VEPUCRU_RESET_OFFSET(SRST_A_VEPU_BIU, 0, 1),
+	VEPUCRU_RESET_OFFSET(SRST_H_VEPU_BIU, 0, 2),
+	VEPUCRU_RESET_OFFSET(SRST_P_VEPU_BIU, 0, 3),
+	VEPUCRU_RESET_OFFSET(SRST_P_CRU_VEPU, 0, 4),
+	VEPUCRU_RESET_OFFSET(SRST_P_VEPU_GRF, 0, 5),
+	VEPUCRU_RESET_OFFSET(SRST_P_GPIO3, 0, 7),
+	VEPUCRU_RESET_OFFSET(SRST_DB_GPIO3, 0, 8),
+	VEPUCRU_RESET_OFFSET(SRST_P_IOC_VCCIO3, 0, 9),
+	VEPUCRU_RESET_OFFSET(SRST_P_SARADC0, 0, 10),
+	VEPUCRU_RESET_OFFSET(SRST_SARADC0, 0, 11),
+	VEPUCRU_RESET_OFFSET(SRST_H_SDMMC1, 0, 13),
+
+	/* VEPUCRU-->SOFTRST_CON01 */
+	VEPUCRU_RESET_OFFSET(SRST_P_VEPU_PVTPLL, 1, 0),
+	VEPUCRU_RESET_OFFSET(SRST_H_VEPU, 1, 1),
+	VEPUCRU_RESET_OFFSET(SRST_A_VEPU, 1, 2),
+	VEPUCRU_RESET_OFFSET(SRST_CORE_VEPU, 1, 3),
+
+	/* NPUCRU-->SOFTRST_CON00 */
+	NPUCRU_RESET_OFFSET(SRST_REF_PVTPLL_NPU, 0, 0),
+	NPUCRU_RESET_OFFSET(SRST_A_NPU_BIU, 0, 2),
+	NPUCRU_RESET_OFFSET(SRST_H_NPU_BIU, 0, 3),
+	NPUCRU_RESET_OFFSET(SRST_P_NPU_BIU, 0, 4),
+	NPUCRU_RESET_OFFSET(SRST_P_CRU_NPU, 0, 5),
+	NPUCRU_RESET_OFFSET(SRST_P_NPU_GRF, 0, 6),
+	NPUCRU_RESET_OFFSET(SRST_P_NPU_PVTPLL, 0, 8),
+	NPUCRU_RESET_OFFSET(SRST_H_RKNN, 0, 9),
+	NPUCRU_RESET_OFFSET(SRST_A_RKNN, 0, 10),
+
+	/* VDOCRU-->SOFTRST_CON00 */
+	VDOCRU_RESET_OFFSET(SRST_A_RKVDEC_BIU, 0, 0),
+	VDOCRU_RESET_OFFSET(SRST_A_VDO_BIU, 0, 1),
+	VDOCRU_RESET_OFFSET(SRST_H_VDO_BIU, 0, 3),
+	VDOCRU_RESET_OFFSET(SRST_P_VDO_BIU, 0, 4),
+	VDOCRU_RESET_OFFSET(SRST_P_CRU_VDO, 0, 5),
+	VDOCRU_RESET_OFFSET(SRST_P_VDO_GRF, 0, 6),
+	VDOCRU_RESET_OFFSET(SRST_A_RKVDEC, 0, 7),
+	VDOCRU_RESET_OFFSET(SRST_H_RKVDEC, 0, 8),
+	VDOCRU_RESET_OFFSET(SRST_HEVC_CA_RKVDEC, 0, 9),
+	VDOCRU_RESET_OFFSET(SRST_A_VOP, 0, 10),
+	VDOCRU_RESET_OFFSET(SRST_H_VOP, 0, 11),
+	VDOCRU_RESET_OFFSET(SRST_D_VOP, 0, 12),
+	VDOCRU_RESET_OFFSET(SRST_A_OOC, 0, 13),
+	VDOCRU_RESET_OFFSET(SRST_H_OOC, 0, 14),
+	VDOCRU_RESET_OFFSET(SRST_D_OOC, 0, 15),
+
+	/* VDOCRU-->SOFTRST_CON01 */
+	VDOCRU_RESET_OFFSET(SRST_H_RKJPEG, 1, 3),
+	VDOCRU_RESET_OFFSET(SRST_A_RKJPEG, 1, 4),
+	VDOCRU_RESET_OFFSET(SRST_A_RKMMU_DECOM, 1, 5),
+	VDOCRU_RESET_OFFSET(SRST_H_RKMMU_DECOM, 1, 6),
+	VDOCRU_RESET_OFFSET(SRST_D_DECOM, 1, 8),
+	VDOCRU_RESET_OFFSET(SRST_A_DECOM, 1, 9),
+	VDOCRU_RESET_OFFSET(SRST_P_DECOM, 1, 10),
+	VDOCRU_RESET_OFFSET(SRST_P_MIPI_DSI, 1, 12),
+	VDOCRU_RESET_OFFSET(SRST_P_DSIPHY, 1, 13),
+
+	/* VCPCRU-->SOFTRST_CON00 */
+	VCPCRU_RESET_OFFSET(SRST_REF_PVTPLL_VCP, 0, 0),
+	VCPCRU_RESET_OFFSET(SRST_A_VCP_BIU, 0, 1),
+	VCPCRU_RESET_OFFSET(SRST_H_VCP_BIU, 0, 2),
+	VCPCRU_RESET_OFFSET(SRST_P_VCP_BIU, 0, 3),
+	VCPCRU_RESET_OFFSET(SRST_P_CRU_VCP, 0, 4),
+	VCPCRU_RESET_OFFSET(SRST_P_VCP_GRF, 0, 5),
+	VCPCRU_RESET_OFFSET(SRST_P_VCP_PVTPLL, 0, 7),
+	VCPCRU_RESET_OFFSET(SRST_A_AISP_BIU, 0, 8),
+	VCPCRU_RESET_OFFSET(SRST_H_AISP_BIU, 0, 9),
+	VCPCRU_RESET_OFFSET(SRST_CORE_AISP, 0, 13),
+
+	/* VCPCRU-->SOFTRST_CON01 */
+	VCPCRU_RESET_OFFSET(SRST_H_FEC, 1, 0),
+	VCPCRU_RESET_OFFSET(SRST_A_FEC, 1, 1),
+	VCPCRU_RESET_OFFSET(SRST_CORE_FEC, 1, 2),
+	VCPCRU_RESET_OFFSET(SRST_H_AVSP, 1, 3),
+	VCPCRU_RESET_OFFSET(SRST_A_AVSP, 1, 4),
+};
+
+void rv1126b_rst_init(struct device_node *np, void __iomem *reg_base)
+{
+	rockchip_register_softrst_lut(np,
+				      rv1126b_register_offset,
+				      ARRAY_SIZE(rv1126b_register_offset),
+				      reg_base + RV1126B_SOFTRST_CON(0),
+				      ROCKCHIP_SOFTRST_HIWORD_MASK);
+}
+
-- 
2.34.1



From zhangqing at rock-chips.com  Mon Nov 10 18:57:37 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Tue, 11 Nov 2025 10:57:37 +0800
Subject: [PATCH v7 4/5] dt-bindings: clock: rockchip: Add RK3506 clock and reset unit
In-Reply-To: <20251111025738.869847-1-zhangqing@rock-chips.com>
References: <20251111025738.869847-1-zhangqing@rock-chips.com>
Message-ID: <20251111025738.869847-5-zhangqing@rock-chips.com>

From: Finley Xiao <finley.xiao at rock-chips.com>

Add device tree bindings for clock and reset unit on RK3506 SoC.
Add clock and reset IDs for RK3506 SoC.

Signed-off-by: Finley Xiao <finley.xiao at rock-chips.com>
Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
---
 .../bindings/clock/rockchip,rk3506-cru.yaml   |  51 ++++
 .../dt-bindings/clock/rockchip,rk3506-cru.h   | 285 ++++++++++++++++++
 .../dt-bindings/reset/rockchip,rk3506-cru.h   | 211 +++++++++++++
 3 files changed, 547 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
 create mode 100644 include/dt-bindings/clock/rockchip,rk3506-cru.h
 create mode 100644 include/dt-bindings/reset/rockchip,rk3506-cru.h

diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml b/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
new file mode 100644
index 000000000000..34bb45f2f227
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/rockchip,rk3506-cru.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip RK3506 Clock and Reset Unit (CRU)
+
+maintainers:
+  - Finley Xiao <finley.xiao at rock-chips.com>
+  - Heiko Stuebner <heiko at sntech.de>
+
+description:
+  The RK3506 CRU generates the clock and also implements reset for SoC
+  peripherals.
+
+properties:
+  compatible:
+    const: rockchip,rk3506-cru
+
+  reg:
+    maxItems: 1
+
+  "#clock-cells":
+    const: 1
+
+  "#reset-cells":
+    const: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    const: xin24m
+
+required:
+  - compatible
+  - reg
+  - "#clock-cells"
+  - "#reset-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller at ff9a0000 {
+      compatible = "rockchip,rk3506-cru";
+      reg = <0xff9a0000 0x20000>;
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+    };
diff --git a/include/dt-bindings/clock/rockchip,rk3506-cru.h b/include/dt-bindings/clock/rockchip,rk3506-cru.h
new file mode 100644
index 000000000000..71d7dda23cc9
--- /dev/null
+++ b/include/dt-bindings/clock/rockchip,rk3506-cru.h
@@ -0,0 +1,285 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2023-2025 Rockchip Electronics Co., Ltd.
+ * Author: Finley Xiao <finley.xiao at rock-chips.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3506_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_RK3506_H
+
+/* cru plls */
+#define PLL_GPLL			0
+#define PLL_V0PLL			1
+#define PLL_V1PLL			2
+
+/* cru-clocks indices */
+#define ARMCLK				3
+#define CLK_DDR				4
+#define XIN24M_GATE			5
+#define CLK_GPLL_GATE			6
+#define CLK_V0PLL_GATE			7
+#define CLK_V1PLL_GATE			8
+#define CLK_GPLL_DIV			9
+#define CLK_GPLL_DIV_100M		10
+#define CLK_V0PLL_DIV			11
+#define CLK_V1PLL_DIV			12
+#define CLK_INT_VOICE_MATRIX0		13
+#define CLK_INT_VOICE_MATRIX1		14
+#define CLK_INT_VOICE_MATRIX2		15
+#define CLK_FRAC_UART_MATRIX0_MUX	16
+#define CLK_FRAC_UART_MATRIX1_MUX	17
+#define CLK_FRAC_VOICE_MATRIX0_MUX	18
+#define CLK_FRAC_VOICE_MATRIX1_MUX	19
+#define CLK_FRAC_COMMON_MATRIX0_MUX	20
+#define CLK_FRAC_COMMON_MATRIX1_MUX	21
+#define CLK_FRAC_COMMON_MATRIX2_MUX	22
+#define CLK_FRAC_UART_MATRIX0		23
+#define CLK_FRAC_UART_MATRIX1		24
+#define CLK_FRAC_VOICE_MATRIX0		25
+#define CLK_FRAC_VOICE_MATRIX1		26
+#define CLK_FRAC_COMMON_MATRIX0		27
+#define CLK_FRAC_COMMON_MATRIX1		28
+#define CLK_FRAC_COMMON_MATRIX2		29
+#define CLK_REF_USBPHY_TOP		30
+#define CLK_REF_DPHY_TOP		31
+#define ACLK_CORE_ROOT			32
+#define PCLK_CORE_ROOT			33
+#define PCLK_DBG			34
+#define PCLK_CORE_GRF			35
+#define PCLK_CORE_CRU			36
+#define CLK_CORE_EMA_DETECT		37
+#define CLK_REF_PVTPLL_CORE		38
+#define PCLK_GPIO1			39
+#define DBCLK_GPIO1			40
+#define ACLK_CORE_PERI_ROOT		41
+#define HCLK_CORE_PERI_ROOT		42
+#define PCLK_CORE_PERI_ROOT		43
+#define CLK_DSMC			44
+#define ACLK_DSMC			45
+#define PCLK_DSMC			46
+#define CLK_FLEXBUS_TX			47
+#define CLK_FLEXBUS_RX			48
+#define ACLK_FLEXBUS			49
+#define HCLK_FLEXBUS			50
+#define ACLK_DSMC_SLV			51
+#define HCLK_DSMC_SLV			52
+#define ACLK_BUS_ROOT			53
+#define HCLK_BUS_ROOT			54
+#define PCLK_BUS_ROOT			55
+#define ACLK_SYSRAM			56
+#define HCLK_SYSRAM			57
+#define ACLK_DMAC0			58
+#define ACLK_DMAC1			59
+#define HCLK_M0				60
+#define PCLK_BUS_GRF			61
+#define PCLK_TIMER			62
+#define CLK_TIMER0_CH0			63
+#define CLK_TIMER0_CH1			64
+#define CLK_TIMER0_CH2			65
+#define CLK_TIMER0_CH3			66
+#define CLK_TIMER0_CH4			67
+#define CLK_TIMER0_CH5			68
+#define PCLK_WDT0			69
+#define TCLK_WDT0			70
+#define PCLK_WDT1			71
+#define TCLK_WDT1			72
+#define PCLK_MAILBOX			73
+#define PCLK_INTMUX			74
+#define PCLK_SPINLOCK			75
+#define PCLK_DDRC			76
+#define HCLK_DDRPHY			77
+#define PCLK_DDRMON			78
+#define CLK_DDRMON_OSC			79
+#define PCLK_STDBY			80
+#define HCLK_USBOTG0			81
+#define HCLK_USBOTG0_PMU		82
+#define CLK_USBOTG0_ADP			83
+#define HCLK_USBOTG1			84
+#define HCLK_USBOTG1_PMU		85
+#define CLK_USBOTG1_ADP			86
+#define PCLK_USBPHY			87
+#define ACLK_DMA2DDR			88
+#define PCLK_DMA2DDR			89
+#define STCLK_M0			90
+#define CLK_DDRPHY			91
+#define CLK_DDRC_SRC			92
+#define ACLK_DDRC_0			93
+#define ACLK_DDRC_1			94
+#define CLK_DDRC			95
+#define CLK_DDRMON			96
+#define HCLK_LSPERI_ROOT		97
+#define PCLK_LSPERI_ROOT		98
+#define PCLK_UART0			99
+#define PCLK_UART1			100
+#define PCLK_UART2			101
+#define PCLK_UART3			102
+#define PCLK_UART4			103
+#define SCLK_UART0			104
+#define SCLK_UART1			105
+#define SCLK_UART2			106
+#define SCLK_UART3			107
+#define SCLK_UART4			108
+#define PCLK_I2C0			109
+#define CLK_I2C0			110
+#define PCLK_I2C1			111
+#define CLK_I2C1			112
+#define PCLK_I2C2			113
+#define CLK_I2C2			114
+#define PCLK_PWM1			115
+#define CLK_PWM1			116
+#define CLK_OSC_PWM1			117
+#define CLK_RC_PWM1			118
+#define CLK_FREQ_PWM1			119
+#define CLK_COUNTER_PWM1		120
+#define PCLK_SPI0			121
+#define CLK_SPI0			122
+#define PCLK_SPI1			123
+#define CLK_SPI1			124
+#define PCLK_GPIO2			125
+#define DBCLK_GPIO2			126
+#define PCLK_GPIO3			127
+#define DBCLK_GPIO3			128
+#define PCLK_GPIO4			129
+#define DBCLK_GPIO4			130
+#define HCLK_CAN0			131
+#define CLK_CAN0			132
+#define HCLK_CAN1			133
+#define CLK_CAN1			134
+#define HCLK_PDM			135
+#define MCLK_PDM			136
+#define CLKOUT_PDM			137
+#define MCLK_SPDIFTX			138
+#define HCLK_SPDIFTX			139
+#define HCLK_SPDIFRX			140
+#define MCLK_SPDIFRX			141
+#define MCLK_SAI0			142
+#define HCLK_SAI0			143
+#define MCLK_OUT_SAI0			144
+#define MCLK_SAI1			145
+#define HCLK_SAI1			146
+#define MCLK_OUT_SAI1			147
+#define HCLK_ASRC0			148
+#define CLK_ASRC0			149
+#define HCLK_ASRC1			150
+#define CLK_ASRC1			151
+#define PCLK_CRU			152
+#define PCLK_PMU_ROOT			153
+#define MCLK_ASRC0			154
+#define MCLK_ASRC1			155
+#define MCLK_ASRC2			156
+#define MCLK_ASRC3			157
+#define LRCK_ASRC0_SRC			158
+#define LRCK_ASRC0_DST			159
+#define LRCK_ASRC1_SRC			160
+#define LRCK_ASRC1_DST			161
+#define ACLK_HSPERI_ROOT		162
+#define HCLK_HSPERI_ROOT		163
+#define PCLK_HSPERI_ROOT		164
+#define CCLK_SRC_SDMMC			165
+#define HCLK_SDMMC			166
+#define HCLK_FSPI			167
+#define SCLK_FSPI			168
+#define PCLK_SPI2			169
+#define ACLK_MAC0			170
+#define ACLK_MAC1			171
+#define PCLK_MAC0			172
+#define PCLK_MAC1			173
+#define CLK_MAC_ROOT			174
+#define CLK_MAC0			175
+#define CLK_MAC1			176
+#define MCLK_SAI2			177
+#define HCLK_SAI2			178
+#define MCLK_OUT_SAI2			179
+#define MCLK_SAI3_SRC			180
+#define HCLK_SAI3			181
+#define MCLK_SAI3			182
+#define MCLK_OUT_SAI3			183
+#define MCLK_SAI4_SRC			184
+#define HCLK_SAI4			185
+#define MCLK_SAI4			186
+#define HCLK_DSM			187
+#define MCLK_DSM			188
+#define PCLK_AUDIO_ADC			189
+#define MCLK_AUDIO_ADC			190
+#define MCLK_AUDIO_ADC_DIV4		191
+#define PCLK_SARADC			192
+#define CLK_SARADC			193
+#define PCLK_OTPC_NS			194
+#define CLK_SBPI_OTPC_NS		195
+#define CLK_USER_OTPC_NS		196
+#define PCLK_UART5			197
+#define SCLK_UART5			198
+#define PCLK_GPIO234_IOC		199
+#define CLK_MAC_PTP_ROOT		200
+#define CLK_MAC0_PTP			201
+#define CLK_MAC1_PTP			202
+#define CLK_SPI2			203
+#define ACLK_VIO_ROOT			204
+#define HCLK_VIO_ROOT			205
+#define PCLK_VIO_ROOT			206
+#define HCLK_RGA			207
+#define ACLK_RGA			208
+#define CLK_CORE_RGA			209
+#define ACLK_VOP			210
+#define HCLK_VOP			211
+#define DCLK_VOP			212
+#define PCLK_DPHY			213
+#define PCLK_DSI_HOST			214
+#define PCLK_TSADC			215
+#define CLK_TSADC			216
+#define CLK_TSADC_TSEN			217
+#define PCLK_GPIO1_IOC			218
+#define PCLK_OTPC_S			219
+#define CLK_SBPI_OTPC_S			220
+#define CLK_USER_OTPC_S			221
+#define PCLK_OTP_MASK			222
+#define PCLK_KEYREADER			223
+#define HCLK_BOOTROM			224
+#define PCLK_DDR_SERVICE		225
+#define HCLK_CRYPTO_S			226
+#define HCLK_KEYLAD			227
+#define CLK_CORE_CRYPTO			228
+#define CLK_PKA_CRYPTO			229
+#define CLK_CORE_CRYPTO_S		230
+#define CLK_PKA_CRYPTO_S		231
+#define ACLK_CRYPTO_S			232
+#define HCLK_RNG_S			233
+#define CLK_CORE_CRYPTO_NS		234
+#define CLK_PKA_CRYPTO_NS		235
+#define ACLK_CRYPTO_NS			236
+#define HCLK_CRYPTO_NS			237
+#define HCLK_RNG			238
+#define CLK_PMU				239
+#define PCLK_PMU			240
+#define CLK_PMU_32K			241
+#define PCLK_PMU_CRU			242
+#define PCLK_PMU_GRF			243
+#define PCLK_GPIO0_IOC			244
+#define PCLK_GPIO0			245
+#define DBCLK_GPIO0			246
+#define PCLK_GPIO1_SHADOW		247
+#define DBCLK_GPIO1_SHADOW		248
+#define PCLK_PMU_HP_TIMER		249
+#define CLK_PMU_HP_TIMER		250
+#define CLK_PMU_HP_TIMER_32K		251
+#define PCLK_PWM0			252
+#define CLK_PWM0			253
+#define CLK_OSC_PWM0			254
+#define CLK_RC_PWM0			255
+#define CLK_MAC_OUT			256
+#define CLK_REF_OUT0			257
+#define CLK_REF_OUT1			258
+#define CLK_32K_FRAC			259
+#define CLK_32K_RC			260
+#define CLK_32K				261
+#define CLK_32K_PMU			262
+#define PCLK_TOUCH_KEY			263
+#define CLK_TOUCH_KEY			264
+#define CLK_REF_PHY_PLL			265
+#define CLK_REF_PHY_PMU_MUX		266
+#define CLK_WIFI_OUT			267
+#define CLK_V0PLL_REF			268
+#define CLK_V1PLL_REF			269
+#define CLK_32K_FRAC_MUX		270
+
+#endif
diff --git a/include/dt-bindings/reset/rockchip,rk3506-cru.h b/include/dt-bindings/reset/rockchip,rk3506-cru.h
new file mode 100644
index 000000000000..31c0d4aa410f
--- /dev/null
+++ b/include/dt-bindings/reset/rockchip,rk3506-cru.h
@@ -0,0 +1,211 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2023-2025 Rockchip Electronics Co., Ltd.
+ * Author: Finley Xiao <finley.xiao at rock-chips.com>
+ */
+
+#ifndef _DT_BINDINGS_REST_ROCKCHIP_RK3506_H
+#define _DT_BINDINGS_REST_ROCKCHIP_RK3506_H
+
+/* CRU-->SOFTRST_CON00 */
+#define SRST_NCOREPORESET0_AC	0
+#define SRST_NCOREPORESET1_AC	1
+#define SRST_NCOREPORESET2_AC	2
+#define SRST_NCORESET0_AC	3
+#define SRST_NCORESET1_AC	4
+#define SRST_NCORESET2_AC	5
+#define SRST_NL2RESET_AC	6
+#define SRST_A_CORE_BIU_AC	7
+#define SRST_H_M0_AC		8
+
+/* CRU-->SOFTRST_CON02 */
+#define SRST_NDBGRESET		9
+#define SRST_P_CORE_BIU		10
+#define SRST_PMU		11
+
+/* CRU-->SOFTRST_CON03 */
+#define SRST_P_DBG		12
+#define SRST_POT_DBG		13
+#define SRST_P_CORE_GRF		14
+#define SRST_CORE_EMA_DETECT	15
+#define SRST_REF_PVTPLL_CORE	16
+#define SRST_P_GPIO1		17
+#define SRST_DB_GPIO1		18
+
+/* CRU-->SOFTRST_CON04 */
+#define SRST_A_CORE_PERI_BIU	19
+#define SRST_A_DSMC		20
+#define SRST_P_DSMC		21
+#define SRST_FLEXBUS		22
+#define SRST_A_FLEXBUS		23
+#define SRST_H_FLEXBUS		24
+#define SRST_A_DSMC_SLV		25
+#define SRST_H_DSMC_SLV		26
+#define SRST_DSMC_SLV		27
+
+/* CRU-->SOFTRST_CON05 */
+#define SRST_A_BUS_BIU		28
+#define SRST_H_BUS_BIU		29
+#define SRST_P_BUS_BIU		30
+#define SRST_A_SYSRAM		31
+#define SRST_H_SYSRAM		32
+#define SRST_A_DMAC0		33
+#define SRST_A_DMAC1		34
+#define SRST_H_M0		35
+#define SRST_M0_JTAG		36
+#define SRST_H_CRYPTO		37
+
+/* CRU-->SOFTRST_CON06 */
+#define SRST_H_RNG		38
+#define SRST_P_BUS_GRF		39
+#define SRST_P_TIMER0		40
+#define SRST_TIMER0_CH0		41
+#define SRST_TIMER0_CH1		42
+#define SRST_TIMER0_CH2		43
+#define SRST_TIMER0_CH3		44
+#define SRST_TIMER0_CH4		45
+#define SRST_TIMER0_CH5		46
+#define SRST_P_WDT0		47
+#define SRST_T_WDT0		48
+#define SRST_P_WDT1		49
+#define SRST_T_WDT1		50
+#define SRST_P_MAILBOX		51
+#define SRST_P_INTMUX		52
+#define SRST_P_SPINLOCK		53
+
+/* CRU-->SOFTRST_CON07 */
+#define SRST_P_DDRC		54
+#define SRST_H_DDRPHY		55
+#define SRST_P_DDRMON		56
+#define SRST_DDRMON_OSC		57
+#define SRST_P_DDR_LPC		58
+#define SRST_H_USBOTG0		59
+#define SRST_USBOTG0_ADP	60
+#define SRST_H_USBOTG1		61
+#define SRST_USBOTG1_ADP	62
+#define SRST_P_USBPHY		63
+#define SRST_USBPHY_POR		64
+#define SRST_USBPHY_OTG0	65
+#define SRST_USBPHY_OTG1	66
+
+/* CRU-->SOFTRST_CON08 */
+#define SRST_A_DMA2DDR		67
+#define SRST_P_DMA2DDR		68
+
+/* CRU-->SOFTRST_CON09 */
+#define SRST_USBOTG0_UTMI	69
+#define SRST_USBOTG1_UTMI	70
+
+/* CRU-->SOFTRST_CON10 */
+#define SRST_A_DDRC_0		71
+#define SRST_A_DDRC_1		72
+#define SRST_A_DDR_BIU		73
+#define SRST_DDRC		74
+#define SRST_DDRMON		75
+
+/* CRU-->SOFTRST_CON11 */
+#define SRST_H_LSPERI_BIU	76
+#define SRST_P_UART0		77
+#define SRST_P_UART1		78
+#define SRST_P_UART2		79
+#define SRST_P_UART3		80
+#define SRST_P_UART4		81
+#define SRST_UART0		82
+#define SRST_UART1		83
+#define SRST_UART2		84
+#define SRST_UART3		85
+#define SRST_UART4		86
+#define SRST_P_I2C0		87
+#define SRST_I2C0		88
+
+/* CRU-->SOFTRST_CON12 */
+#define SRST_P_I2C1		89
+#define SRST_I2C1		90
+#define SRST_P_I2C2		91
+#define SRST_I2C2		92
+#define SRST_P_PWM1		93
+#define SRST_PWM1		94
+#define SRST_P_SPI0		95
+#define SRST_SPI0		96
+#define SRST_P_SPI1		97
+#define SRST_SPI1		98
+#define SRST_P_GPIO2		99
+#define SRST_DB_GPIO2		100
+
+/* CRU-->SOFTRST_CON13 */
+#define SRST_P_GPIO3		101
+#define SRST_DB_GPIO3		102
+#define SRST_P_GPIO4		103
+#define SRST_DB_GPIO4		104
+#define SRST_H_CAN0		105
+#define SRST_CAN0		106
+#define SRST_H_CAN1		107
+#define SRST_CAN1		108
+#define SRST_H_PDM		109
+#define SRST_M_PDM		110
+#define SRST_PDM		111
+#define SRST_SPDIFTX		112
+#define SRST_H_SPDIFTX		113
+#define SRST_H_SPDIFRX		114
+#define SRST_SPDIFRX		115
+#define SRST_M_SAI0		116
+
+/* CRU-->SOFTRST_CON14 */
+#define SRST_H_SAI0		117
+#define SRST_M_SAI1		118
+#define SRST_H_SAI1		119
+#define SRST_H_ASRC0		120
+#define SRST_ASRC0		121
+#define SRST_H_ASRC1		122
+#define SRST_ASRC1		123
+
+/* CRU-->SOFTRST_CON17 */
+#define SRST_H_HSPERI_BIU	124
+#define SRST_H_SDMMC		125
+#define SRST_H_FSPI		126
+#define SRST_S_FSPI		127
+#define SRST_P_SPI2		128
+#define SRST_A_MAC0		129
+#define SRST_A_MAC1		130
+
+/* CRU-->SOFTRST_CON18 */
+#define SRST_M_SAI2		131
+#define SRST_H_SAI2		132
+#define SRST_H_SAI3		133
+#define SRST_M_SAI3		134
+#define SRST_H_SAI4		135
+#define SRST_M_SAI4		136
+#define SRST_H_DSM		137
+#define SRST_M_DSM		138
+#define SRST_P_AUDIO_ADC	139
+#define SRST_M_AUDIO_ADC	140
+
+/* CRU-->SOFTRST_CON19 */
+#define SRST_P_SARADC		141
+#define SRST_SARADC		142
+#define SRST_SARADC_PHY		143
+#define SRST_P_OTPC_NS		144
+#define SRST_SBPI_OTPC_NS	145
+#define SRST_USER_OTPC_NS	146
+#define SRST_P_UART5		147
+#define SRST_UART5		148
+#define SRST_P_GPIO234_IOC	149
+
+/* CRU-->SOFTRST_CON21 */
+#define SRST_A_VIO_BIU		150
+#define SRST_H_VIO_BIU		151
+#define SRST_H_RGA		152
+#define SRST_A_RGA		153
+#define SRST_CORE_RGA		154
+#define SRST_A_VOP		155
+#define SRST_H_VOP		156
+#define SRST_VOP		157
+#define SRST_P_DPHY		158
+#define SRST_P_DSI_HOST		159
+#define SRST_P_TSADC		160
+#define SRST_TSADC		161
+
+/* CRU-->SOFTRST_CON22 */
+#define SRST_P_GPIO1_IOC	162
+
+#endif
-- 
2.34.1



From zhangqing at rock-chips.com  Mon Nov 10 18:57:38 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Tue, 11 Nov 2025 10:57:38 +0800
Subject: [PATCH v7 5/5] clk: rockchip: Add clock and reset driver for RK3506
In-Reply-To: <20251111025738.869847-1-zhangqing@rock-chips.com>
References: <20251111025738.869847-1-zhangqing@rock-chips.com>
Message-ID: <20251111025738.869847-6-zhangqing@rock-chips.com>

Add the clock and reset tree definitions for the new
RK3506 SoC.

Signed-off-by: Finley Xiao <finley.xiao at rock-chips.com>
Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
---
 drivers/clk/rockchip/Kconfig      |   7 +
 drivers/clk/rockchip/Makefile     |   1 +
 drivers/clk/rockchip/clk-rk3506.c | 869 ++++++++++++++++++++++++++++++
 drivers/clk/rockchip/clk.h        |  13 +
 drivers/clk/rockchip/rst-rk3506.c | 226 ++++++++
 5 files changed, 1116 insertions(+)
 create mode 100644 drivers/clk/rockchip/clk-rk3506.c
 create mode 100644 drivers/clk/rockchip/rst-rk3506.c

diff --git a/drivers/clk/rockchip/Kconfig b/drivers/clk/rockchip/Kconfig
index e1ea0a098ca9..5cf1e0fd6fb3 100644
--- a/drivers/clk/rockchip/Kconfig
+++ b/drivers/clk/rockchip/Kconfig
@@ -100,6 +100,13 @@ config CLK_RK3399
 	help
 	  Build the driver for RK3399 Clock Driver.
 
+config CLK_RK3506
+	bool "Rockchip RK3506 clock controller support"
+	depends on ARM || COMPILE_TEST
+	default y
+	help
+	  Build the driver for RK3506 Clock Driver.
+
 config CLK_RK3528
 	bool "Rockchip RK3528 clock controller support"
 	depends on ARM64 || COMPILE_TEST
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index 82b4b29ad036..4d8cbb2044c7 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_CLK_RK3308)        += clk-rk3308.o
 obj-$(CONFIG_CLK_RK3328)        += clk-rk3328.o
 obj-$(CONFIG_CLK_RK3368)        += clk-rk3368.o
 obj-$(CONFIG_CLK_RK3399)        += clk-rk3399.o
+obj-$(CONFIG_CLK_RK3506)	+= clk-rk3506.o rst-rk3506.o
 obj-$(CONFIG_CLK_RK3528)	+= clk-rk3528.o rst-rk3528.o
 obj-$(CONFIG_CLK_RK3562)	+= clk-rk3562.o rst-rk3562.o
 obj-$(CONFIG_CLK_RK3568)	+= clk-rk3568.o
diff --git a/drivers/clk/rockchip/clk-rk3506.c b/drivers/clk/rockchip/clk-rk3506.c
new file mode 100644
index 000000000000..dd59bd60382e
--- /dev/null
+++ b/drivers/clk/rockchip/clk-rk3506.c
@@ -0,0 +1,869 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023-2025 Rockchip Electronics Co., Ltd.
+ * Author: Finley Xiao <finley.xiao at rock-chips.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/syscore_ops.h>
+#include <dt-bindings/clock/rockchip,rk3506-cru.h>
+#include "clk.h"
+
+#define PVTPLL_SRC_SEL_PVTPLL		(BIT(7) | BIT(23))
+
+enum rk3506_plls {
+	gpll, v0pll, v1pll,
+};
+
+/*
+ * [FRAC PLL]: GPLL, V0PLL, V1PLL
+ *   - VCO Frequency: 950MHz to 3800MHZ
+ *   - Output Frequency: 19MHz to 3800MHZ
+ *   - refdiv: 1 to 63 (Int Mode), 1 to 2 (Frac Mode)
+ *   - fbdiv: 16 to 3800 (Int Mode), 20 to 380 (Frac Mode)
+ *   - post1div: 1 to 7
+ *   - post2div: 1 to 7
+ */
+static struct rockchip_pll_rate_table rk3506_pll_rates[] = {
+	/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
+	RK3036_PLL_RATE(1896000000, 1, 79, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1800000000, 1, 75, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1704000000, 1, 71, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1512000000, 1, 63, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1350000000, 4, 225, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1179648000, 1, 49, 1, 1, 0, 2550137),
+	RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1000000000, 3, 125, 1, 1, 1, 0),
+	RK3036_PLL_RATE(993484800, 1, 41, 1, 1, 0, 6630355),
+	RK3036_PLL_RATE(983040000, 1, 40, 1, 1, 0, 16106127),
+	RK3036_PLL_RATE(960000000, 1, 80, 2, 1, 1, 0),
+	RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0),
+	RK3036_PLL_RATE(903168000, 1, 75, 2, 1, 0, 4429185),
+	RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
+	RK3036_PLL_RATE(800000000, 3, 200, 2, 1, 1, 0),
+	RK3036_PLL_RATE(600000000, 1, 50, 2, 1, 1, 0),
+	RK3036_PLL_RATE(594000000, 2, 99, 2, 1, 1, 0),
+	RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0),
+	RK3036_PLL_RATE(312000000, 1, 78, 6, 1, 1, 0),
+	RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0),
+	RK3036_PLL_RATE(96000000, 1, 48, 6, 2, 1, 0),
+	{ /* sentinel */ },
+};
+
+#define RK3506_DIV_ACLK_CORE_MASK	0xf
+#define RK3506_DIV_ACLK_CORE_SHIFT	9
+#define RK3506_DIV_PCLK_CORE_MASK	0xf
+#define RK3506_DIV_PCLK_CORE_SHIFT	0
+
+#define RK3506_CLKSEL15(_aclk_core_div)					\
+{									\
+	.reg = RK3506_CLKSEL_CON(15),					\
+	.val = HIWORD_UPDATE(_aclk_core_div, RK3506_DIV_ACLK_CORE_MASK,	\
+			     RK3506_DIV_ACLK_CORE_SHIFT),		\
+}
+
+#define RK3506_CLKSEL16(_pclk_core_div)					\
+{									\
+	.reg = RK3506_CLKSEL_CON(16),					\
+	.val = HIWORD_UPDATE(_pclk_core_div, RK3506_DIV_PCLK_CORE_MASK,	\
+			     RK3506_DIV_PCLK_CORE_SHIFT),		\
+}
+
+/* SIGN-OFF: aclk_core: 500M, pclk_core: 125M, */
+#define RK3506_CPUCLK_RATE(_prate, _aclk_core_div, _pclk_core_div)	\
+{									\
+	.prate = _prate,						\
+	.divs = {							\
+		RK3506_CLKSEL15(_aclk_core_div),			\
+		RK3506_CLKSEL16(_pclk_core_div),			\
+	},								\
+}
+
+static struct rockchip_cpuclk_rate_table rk3506_cpuclk_rates[] __initdata = {
+	RK3506_CPUCLK_RATE(1608000000, 3, 12),
+	RK3506_CPUCLK_RATE(1512000000, 3, 12),
+	RK3506_CPUCLK_RATE(1416000000, 2, 11),
+	RK3506_CPUCLK_RATE(1296000000, 2, 10),
+	RK3506_CPUCLK_RATE(1200000000, 2, 9),
+	RK3506_CPUCLK_RATE(1179648000, 2, 9),
+	RK3506_CPUCLK_RATE(1008000000, 1, 7),
+	RK3506_CPUCLK_RATE(903168000, 1, 7),
+	RK3506_CPUCLK_RATE(800000000, 1, 6),
+	RK3506_CPUCLK_RATE(750000000, 1, 5),
+	RK3506_CPUCLK_RATE(589824000, 1, 4),
+	RK3506_CPUCLK_RATE(400000000, 1, 3),
+	RK3506_CPUCLK_RATE(200000000, 1, 1),
+};
+
+PNAME(mux_pll_p)				= { "xin24m" };
+PNAME(gpll_v0pll_v1pll_parents_p)		= { "gpll", "v0pll", "v1pll" };
+PNAME(gpll_v0pll_v1pll_g_parents_p)		= { "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate" };
+PNAME(gpll_v0pll_v1pll_div_parents_p)		= { "clk_gpll_div", "clk_v0pll_div", "clk_v1pll_div" };
+PNAME(xin24m_gpll_v0pll_v1pll_g_parents_p)	= { "xin24m", "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate" };
+PNAME(xin24m_g_gpll_v0pll_v1pll_g_parents_p)	= { "xin24m_gate", "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate" };
+PNAME(xin24m_g_gpll_v0pll_v1pll_div_parents_p)	= { "xin24m_gate", "clk_gpll_div", "clk_v0pll_div", "clk_v1pll_div" };
+PNAME(xin24m_400k_32k_parents_p)		= { "xin24m", "clk_rc", "clk_32k" };
+PNAME(clk_frac_uart_matrix0_mux_parents_p)	= { "xin24m", "gpll", "clk_v0pll_gate", "clk_v1pll_gate" };
+PNAME(clk_timer0_parents_p)			= { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai0_mclk_in", "sai0_sclk_in" };
+PNAME(clk_timer1_parents_p)			= { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai1_mclk_in", "sai1_sclk_in" };
+PNAME(clk_timer2_parents_p)			= { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai2_mclk_in", "sai2_sclk_in" };
+PNAME(clk_timer3_parents_p)			= { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai3_mclk_in", "sai3_sclk_in" };
+PNAME(clk_timer4_parents_p)			= { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "mclk_asrc0" };
+PNAME(clk_timer5_parents_p)			= { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "mclk_asrc1" };
+PNAME(sclk_uart_parents_p)			= { "xin24m", "clk_gpll_gate", "clk_v0pll_gate", "clk_frac_uart_matrix0", "clk_frac_uart_matrix1",
+						    "clk_frac_common_matrix0", "clk_frac_common_matrix1", "clk_frac_common_matrix2" };
+PNAME(clk_mac_ptp_root_parents_p)		= { "gpll", "v0pll", "v1pll" };
+PNAME(clk_pwm_parents_p)			= { "clk_rc", "sai0_mclk_in", "sai1_mclk_in", "sai2_mclk_in", "sai3_mclk_in", "sai0_sclk_in", "sai1_sclk_in",
+						    "sai2_sclk_in", "sai3_sclk_in", "mclk_asrc0", "mclk_asrc1" };
+PNAME(clk_can_parents_p)			= { "xin24m", "gpll", "clk_v0pll_gate", "clk_v1pll_gate", "clk_frac_voice_matrix1",
+						    "clk_frac_common_matrix0", "clk_frac_common_matrix1", "clk_frac_common_matrix2" };
+PNAME(clk_pdm_parents_p)			= { "xin24m_gate", "clk_int_voice_matrix0", "clk_int_voice_matrix1", "clk_int_voice_matrix2",
+						    "clk_frac_voice_matrix0", "clk_frac_voice_matrix1", "clk_frac_common_matrix0", "clk_frac_common_matrix1",
+						    "clk_frac_common_matrix2", "sai0_mclk_in", "sai1_mclk_in", "sai2_mclk_in", "sai3_mclk_in", "clk_gpll_div" };
+PNAME(mclk_sai_asrc_parents_p)			= { "xin24m_gate", "clk_int_voice_matrix0", "clk_int_voice_matrix1", "clk_int_voice_matrix2",
+						    "clk_frac_voice_matrix0", "clk_frac_voice_matrix1", "clk_frac_common_matrix0", "clk_frac_common_matrix1",
+						    "clk_frac_common_matrix2", "sai0_mclk_in", "sai1_mclk_in", "sai2_mclk_in", "sai3_mclk_in" };
+PNAME(lrck_asrc_parents_p)			= { "mclk_asrc0", "mclk_asrc1", "mclk_asrc2", "mclk_asrc3", "mclk_spdiftx", "clk_spdifrx_to_asrc", "clkout_pdm",
+						    "sai0_fs", "sai1_fs", "sai2_fs", "sai3_fs", "sai4_fs" };
+PNAME(cclk_src_sdmmc_parents_p)			= { "xin24m_gate", "gpll", "clk_v0pll_gate", "clk_v1pll_gate" };
+PNAME(dclk_vop_parents_p)			= { "xin24m_gate", "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate", "dummy_vop_dclk",
+						    "dummy_vop_dclk", "dummy_vop_dclk", "dummy_vop_dclk" };
+PNAME(dbclk_gpio0_parents_p)			= { "xin24m", "clk_rc", "clk_32k_pmu" };
+PNAME(clk_pmu_hp_timer_parents_p)		= { "xin24m", "gpll_div_100m", "clk_core_pvtpll" };
+PNAME(clk_ref_out_parents_p)			= { "xin24m", "gpll", "v0pll", "v1pll" };
+PNAME(clk_32k_frac_parents_p)			= { "xin24m", "v0pll", "v1pll", "clk_rc" };
+PNAME(clk_32k_parents_p)			= { "xin32k", "clk_32k_rc", "clk_32k_frac" };
+PNAME(clk_ref_phy_pmu_mux_parents_p)		= { "xin24m", "clk_ref_phy_pll" };
+PNAME(clk_vpll_ref_parents_p)			= { "xin24m", "clk_pll_ref_io" };
+PNAME(mux_armclk_p)				= { "armclk_pll", "clk_core_pvtpll" };
+
+#define MFLAGS CLK_MUX_HIWORD_MASK
+#define DFLAGS CLK_DIVIDER_HIWORD_MASK
+#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
+
+static struct rockchip_pll_clock rk3506_pll_clks[] __initdata = {
+	[gpll] = PLL(pll_rk3328, PLL_GPLL, "gpll", mux_pll_p,
+		     CLK_IS_CRITICAL, RK3506_PLL_CON(0),
+		     RK3506_MODE_CON, 0, 2, 0, rk3506_pll_rates),
+	[v0pll] = PLL(pll_rk3328, PLL_V0PLL, "v0pll", mux_pll_p,
+		     CLK_IS_CRITICAL, RK3506_PLL_CON(8),
+		     RK3506_MODE_CON, 2, 0, 0, rk3506_pll_rates),
+	[v1pll] = PLL(pll_rk3328, PLL_V1PLL, "v1pll", mux_pll_p,
+		     CLK_IS_CRITICAL, RK3506_PLL_CON(16),
+		     RK3506_MODE_CON, 4, 1, 0, rk3506_pll_rates),
+};
+
+static struct rockchip_clk_branch rk3506_armclk __initdata =
+	MUX(ARMCLK, "armclk", mux_armclk_p, CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
+			RK3506_CLKSEL_CON(15), 8, 1, MFLAGS);
+
+static struct rockchip_clk_branch rk3506_clk_branches[] __initdata = {
+	/*
+	 * CRU Clock-Architecture
+	 */
+	/* top */
+	GATE(XIN24M_GATE, "xin24m_gate", "xin24m", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(0), 1, GFLAGS),
+	GATE(CLK_GPLL_GATE, "clk_gpll_gate", "gpll", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(0), 2, GFLAGS),
+	GATE(CLK_V0PLL_GATE, "clk_v0pll_gate", "v0pll", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(0), 3, GFLAGS),
+	GATE(CLK_V1PLL_GATE, "clk_v1pll_gate", "v1pll", 0,
+			RK3506_CLKGATE_CON(0), 4, GFLAGS),
+	COMPOSITE_NOMUX(CLK_GPLL_DIV, "clk_gpll_div", "clk_gpll_gate", CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(0), 6, 4, DFLAGS,
+			RK3506_CLKGATE_CON(0), 5, GFLAGS),
+	COMPOSITE_NOMUX(CLK_GPLL_DIV_100M, "clk_gpll_div_100m", "clk_gpll_div", 0,
+			RK3506_CLKSEL_CON(0), 10, 4, DFLAGS,
+			RK3506_CLKGATE_CON(0), 6, GFLAGS),
+	COMPOSITE_NOMUX(CLK_V0PLL_DIV, "clk_v0pll_div", "clk_v0pll_gate", CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(1), 0, 4, DFLAGS,
+			RK3506_CLKGATE_CON(0), 7, GFLAGS),
+	COMPOSITE_NOMUX(CLK_V1PLL_DIV, "clk_v1pll_div", "clk_v1pll_gate", 0,
+			RK3506_CLKSEL_CON(1), 4, 4, DFLAGS,
+			RK3506_CLKGATE_CON(0), 8, GFLAGS),
+	COMPOSITE_NOMUX(CLK_INT_VOICE_MATRIX0, "clk_int_voice_matrix0", "clk_v0pll_gate", 0,
+			RK3506_CLKSEL_CON(1), 8, 5, DFLAGS,
+			RK3506_CLKGATE_CON(0), 9, GFLAGS),
+	COMPOSITE_NOMUX(CLK_INT_VOICE_MATRIX1, "clk_int_voice_matrix1", "clk_v1pll_gate", 0,
+			RK3506_CLKSEL_CON(2), 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(0), 10, GFLAGS),
+	COMPOSITE_NOMUX(CLK_INT_VOICE_MATRIX2, "clk_int_voice_matrix2", "clk_v0pll_gate", 0,
+			RK3506_CLKSEL_CON(2), 5, 5, DFLAGS,
+			RK3506_CLKGATE_CON(0), 11, GFLAGS),
+	MUX(CLK_FRAC_UART_MATRIX0_MUX, "clk_frac_uart_matrix0_mux", clk_frac_uart_matrix0_mux_parents_p, 0,
+			RK3506_CLKSEL_CON(3), 9, 2, MFLAGS),
+	MUX(CLK_FRAC_UART_MATRIX1_MUX, "clk_frac_uart_matrix1_mux", xin24m_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(3), 11, 2, MFLAGS),
+	MUX(CLK_FRAC_VOICE_MATRIX0_MUX, "clk_frac_voice_matrix0_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(3), 13, 2, MFLAGS),
+	MUX(CLK_FRAC_VOICE_MATRIX1_MUX, "clk_frac_voice_matrix1_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(4), 0, 2, MFLAGS),
+	MUX(CLK_FRAC_COMMON_MATRIX0_MUX, "clk_frac_common_matrix0_mux", xin24m_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(4), 2, 2, MFLAGS),
+	MUX(CLK_FRAC_COMMON_MATRIX1_MUX, "clk_frac_common_matrix1_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(4), 4, 2, MFLAGS),
+	MUX(CLK_FRAC_COMMON_MATRIX2_MUX, "clk_frac_common_matrix2_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(4), 6, 2, MFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_UART_MATRIX0, "clk_frac_uart_matrix0", "clk_frac_uart_matrix0_mux", 0,
+			RK3506_CLKSEL_CON(5), 0,
+			RK3506_CLKGATE_CON(0), 13, GFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_UART_MATRIX1, "clk_frac_uart_matrix1", "clk_frac_uart_matrix1_mux", 0,
+			RK3506_CLKSEL_CON(6), 0,
+			RK3506_CLKGATE_CON(0), 14, GFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_VOICE_MATRIX0, "clk_frac_voice_matrix0", "clk_frac_voice_matrix0_mux", 0,
+			RK3506_CLKSEL_CON(7), 0,
+			RK3506_CLKGATE_CON(0), 15, GFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_VOICE_MATRIX1, "clk_frac_voice_matrix1", "clk_frac_voice_matrix1_mux", 0,
+			RK3506_CLKSEL_CON(9), 0,
+			RK3506_CLKGATE_CON(1), 0, GFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_COMMON_MATRIX0, "clk_frac_common_matrix0", "clk_frac_common_matrix0_mux", 0,
+			RK3506_CLKSEL_CON(11), 0,
+			RK3506_CLKGATE_CON(1), 1, GFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_COMMON_MATRIX1, "clk_frac_common_matrix1", "clk_frac_common_matrix1_mux", 0,
+			RK3506_CLKSEL_CON(12), 0,
+			RK3506_CLKGATE_CON(1), 2, GFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_COMMON_MATRIX2, "clk_frac_common_matrix2", "clk_frac_common_matrix2_mux", 0,
+			RK3506_CLKSEL_CON(13), 0,
+			RK3506_CLKGATE_CON(1), 3, GFLAGS),
+	GATE(CLK_REF_USBPHY_TOP, "clk_ref_usbphy_top", "xin24m", 0,
+			RK3506_CLKGATE_CON(1), 4, GFLAGS),
+	GATE(CLK_REF_DPHY_TOP, "clk_ref_dphy_top", "xin24m", 0,
+			RK3506_CLKGATE_CON(1), 5, GFLAGS),
+
+	/* core */
+	COMPOSITE_NOGATE(0, "armclk_pll", gpll_v0pll_v1pll_parents_p, CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(15), 5, 2, MFLAGS, 0, 5, DFLAGS),
+	COMPOSITE_NOMUX(ACLK_CORE_ROOT, "aclk_core_root", "armclk", CLK_IGNORE_UNUSED,
+			RK3506_CLKSEL_CON(15), 9, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
+			RK3506_CLKGATE_CON(2), 11, GFLAGS),
+	COMPOSITE_NOMUX(PCLK_CORE_ROOT, "pclk_core_root", "armclk", CLK_IGNORE_UNUSED,
+			RK3506_CLKSEL_CON(16), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
+			RK3506_CLKGATE_CON(2), 12, GFLAGS),
+	GATE(PCLK_DBG, "pclk_dbg", "pclk_core_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(3), 1, GFLAGS),
+	GATE(PCLK_CORE_GRF, "pclk_core_grf", "pclk_core_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(3), 4, GFLAGS),
+	GATE(PCLK_CORE_CRU, "pclk_core_cru", "pclk_core_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(3), 5, GFLAGS),
+	GATE(CLK_CORE_EMA_DETECT, "clk_core_ema_detect", "xin24m_gate", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(3), 6, GFLAGS),
+	GATE(PCLK_GPIO1, "pclk_gpio1", "aclk_core_root", 0,
+			RK3506_CLKGATE_CON(3), 8, GFLAGS),
+	GATE(DBCLK_GPIO1, "dbclk_gpio1", "xin24m_gate", 0,
+			RK3506_CLKGATE_CON(3), 9, GFLAGS),
+
+	/* core peri */
+	COMPOSITE(ACLK_CORE_PERI_ROOT, "aclk_core_peri_root", gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(18), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(4), 0, GFLAGS),
+	GATE(HCLK_CORE_PERI_ROOT, "hclk_core_peri_root", "aclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 1, GFLAGS),
+	GATE(PCLK_CORE_PERI_ROOT, "pclk_core_peri_root", "aclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 2, GFLAGS),
+	COMPOSITE(CLK_DSMC, "clk_dsmc", xin24m_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(18), 12, 2, MFLAGS, 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(4), 4, GFLAGS),
+	GATE(ACLK_DSMC, "aclk_dsmc", "aclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 5, GFLAGS),
+	GATE(PCLK_DSMC, "pclk_dsmc", "pclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 6, GFLAGS),
+	COMPOSITE(CLK_FLEXBUS_TX, "clk_flexbus_tx", xin24m_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(19), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(4), 7, GFLAGS),
+	COMPOSITE(CLK_FLEXBUS_RX, "clk_flexbus_rx", xin24m_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(19), 12, 2, MFLAGS, 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(4), 8, GFLAGS),
+	GATE(ACLK_FLEXBUS, "aclk_flexbus", "aclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 9, GFLAGS),
+	GATE(HCLK_FLEXBUS, "hclk_flexbus", "hclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 10, GFLAGS),
+	GATE(ACLK_DSMC_SLV, "aclk_dsmc_slv", "aclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 11, GFLAGS),
+	GATE(HCLK_DSMC_SLV, "hclk_dsmc_slv", "hclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 12, GFLAGS),
+
+	/* bus */
+	COMPOSITE(ACLK_BUS_ROOT, "aclk_bus_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(21), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(5), 0, GFLAGS),
+	COMPOSITE(HCLK_BUS_ROOT, "hclk_bus_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(21), 12, 2, MFLAGS, 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(5), 1, GFLAGS),
+	COMPOSITE(PCLK_BUS_ROOT, "pclk_bus_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(22), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(5), 2, GFLAGS),
+	GATE(ACLK_SYSRAM, "aclk_sysram", "aclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(5), 6, GFLAGS),
+	GATE(HCLK_SYSRAM, "hclk_sysram", "aclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(5), 7, GFLAGS),
+	GATE(ACLK_DMAC0, "aclk_dmac0", "aclk_bus_root", 0,
+			RK3506_CLKGATE_CON(5), 8, GFLAGS),
+	GATE(ACLK_DMAC1, "aclk_dmac1", "aclk_bus_root", 0,
+			RK3506_CLKGATE_CON(5), 9, GFLAGS),
+	GATE(HCLK_M0, "hclk_m0", "aclk_bus_root", 0,
+			RK3506_CLKGATE_CON(5), 10, GFLAGS),
+	GATE(ACLK_CRYPTO_NS, "aclk_crypto_ns", "aclk_bus_root", 0,
+			RK3506_CLKGATE_CON(5), 14, GFLAGS),
+	GATE(HCLK_CRYPTO_NS, "hclk_crypto_ns", "hclk_bus_root", 0,
+			RK3506_CLKGATE_CON(5), 15, GFLAGS),
+	GATE(HCLK_RNG, "hclk_rng", "hclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 0, GFLAGS),
+	GATE(PCLK_BUS_GRF, "pclk_bus_grf", "pclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(6), 1, GFLAGS),
+	GATE(PCLK_TIMER, "pclk_timer", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 2, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0_CH0, "clk_timer0_ch0", clk_timer0_parents_p, 0,
+			RK3506_CLKSEL_CON(22), 7, 3, MFLAGS,
+			RK3506_CLKGATE_CON(6), 3, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0_CH1, "clk_timer0_ch1", clk_timer1_parents_p, 0,
+			RK3506_CLKSEL_CON(22), 10, 3, MFLAGS,
+			RK3506_CLKGATE_CON(6), 4, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0_CH2, "clk_timer0_ch2", clk_timer2_parents_p, 0,
+			RK3506_CLKSEL_CON(22), 13, 3, MFLAGS,
+			RK3506_CLKGATE_CON(6), 5, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0_CH3, "clk_timer0_ch3", clk_timer3_parents_p, 0,
+			RK3506_CLKSEL_CON(23), 0, 3, MFLAGS,
+			RK3506_CLKGATE_CON(6), 6, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0_CH4, "clk_timer0_ch4", clk_timer4_parents_p, 0,
+			RK3506_CLKSEL_CON(23), 3, 3, MFLAGS,
+			RK3506_CLKGATE_CON(6), 7, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0_CH5, "clk_timer0_ch5", clk_timer5_parents_p, 0,
+			RK3506_CLKSEL_CON(23), 6, 3, MFLAGS,
+			RK3506_CLKGATE_CON(6), 8, GFLAGS),
+	GATE(PCLK_WDT0, "pclk_wdt0", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 9, GFLAGS),
+	GATE(TCLK_WDT0, "tclk_wdt0", "xin24m_gate", 0,
+			RK3506_CLKGATE_CON(6), 10, GFLAGS),
+	GATE(PCLK_WDT1, "pclk_wdt1", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 11, GFLAGS),
+	GATE(TCLK_WDT1, "tclk_wdt1", "xin24m_gate", 0,
+			RK3506_CLKGATE_CON(6), 12, GFLAGS),
+	GATE(PCLK_MAILBOX, "pclk_mailbox", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 13, GFLAGS),
+	GATE(PCLK_INTMUX, "pclk_intmux", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 14, GFLAGS),
+	GATE(PCLK_SPINLOCK, "pclk_spinlock", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 15, GFLAGS),
+	GATE(PCLK_DDRC, "pclk_ddrc", "pclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(7), 0, GFLAGS),
+	GATE(HCLK_DDRPHY, "hclk_ddrphy", "hclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(7), 1, GFLAGS),
+	GATE(PCLK_DDRMON, "pclk_ddrmon", "pclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(7), 2, GFLAGS),
+	GATE(CLK_DDRMON_OSC, "clk_ddrmon_osc", "xin24m_gate", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(7), 3, GFLAGS),
+	GATE(PCLK_STDBY, "pclk_stdby", "pclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(7), 4, GFLAGS),
+	GATE(HCLK_USBOTG0, "hclk_usbotg0", "hclk_bus_root", 0,
+			RK3506_CLKGATE_CON(7), 5, GFLAGS),
+	GATE(HCLK_USBOTG0_PMU, "hclk_usbotg0_pmu", "hclk_bus_root", 0,
+			RK3506_CLKGATE_CON(7), 6, GFLAGS),
+	GATE(CLK_USBOTG0_ADP, "clk_usbotg0_adp", "clk_32k", 0,
+			RK3506_CLKGATE_CON(7), 7, GFLAGS),
+	GATE(HCLK_USBOTG1, "hclk_usbotg1", "hclk_bus_root", 0,
+			RK3506_CLKGATE_CON(7), 8, GFLAGS),
+	GATE(HCLK_USBOTG1_PMU, "hclk_usbotg1_pmu", "hclk_bus_root", 0,
+			RK3506_CLKGATE_CON(7), 9, GFLAGS),
+	GATE(CLK_USBOTG1_ADP, "clk_usbotg1_adp", "clk_32k", 0,
+			RK3506_CLKGATE_CON(7), 10, GFLAGS),
+	GATE(PCLK_USBPHY, "pclk_usbphy", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(7), 11, GFLAGS),
+	GATE(ACLK_DMA2DDR, "aclk_dma2ddr", "aclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(8), 0, GFLAGS),
+	GATE(PCLK_DMA2DDR, "pclk_dma2ddr", "pclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(8), 1, GFLAGS),
+	COMPOSITE_NOMUX(STCLK_M0, "stclk_m0", "xin24m_gate", 0,
+			RK3506_CLKSEL_CON(23), 9, 6, DFLAGS,
+			RK3506_CLKGATE_CON(8), 2, GFLAGS),
+	COMPOSITE(CLK_DDRPHY, "clk_ddrphy", gpll_v0pll_v1pll_parents_p, CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKSEL_CON(4), 4, 2, MFLAGS, 0, 4, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 10, GFLAGS),
+	FACTOR(CLK_DDRC_SRC, "clk_ddrc_src", "clk_ddrphy", 0, 1, 4),
+	GATE(ACLK_DDRC_0, "aclk_ddrc_0", "clk_ddrc_src", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(10), 0, GFLAGS),
+	GATE(ACLK_DDRC_1, "aclk_ddrc_1", "clk_ddrc_src", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(10), 1, GFLAGS),
+	GATE(CLK_DDRC, "clk_ddrc", "clk_ddrc_src", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(10), 3, GFLAGS),
+	GATE(CLK_DDRMON, "clk_ddrmon", "clk_ddrc_src", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(10), 4, GFLAGS),
+
+	/* ls peri */
+	COMPOSITE(HCLK_LSPERI_ROOT, "hclk_lsperi_root", gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(29), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(11), 0, GFLAGS),
+	GATE(PCLK_LSPERI_ROOT, "pclk_lsperi_root", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 1, GFLAGS),
+	GATE(PCLK_UART0, "pclk_uart0", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 4, GFLAGS),
+	GATE(PCLK_UART1, "pclk_uart1", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 5, GFLAGS),
+	GATE(PCLK_UART2, "pclk_uart2", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 6, GFLAGS),
+	GATE(PCLK_UART3, "pclk_uart3", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 7, GFLAGS),
+	GATE(PCLK_UART4, "pclk_uart4", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 8, GFLAGS),
+	COMPOSITE(SCLK_UART0, "sclk_uart0", sclk_uart_parents_p, 0,
+			RK3506_CLKSEL_CON(29), 12, 3, MFLAGS, 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(11), 9, GFLAGS),
+	COMPOSITE(SCLK_UART1, "sclk_uart1", sclk_uart_parents_p, 0,
+			RK3506_CLKSEL_CON(30), 5, 3, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(11), 10, GFLAGS),
+	COMPOSITE(SCLK_UART2, "sclk_uart2", sclk_uart_parents_p, 0,
+			RK3506_CLKSEL_CON(30), 13, 3, MFLAGS, 8, 5, DFLAGS,
+			RK3506_CLKGATE_CON(11), 11, GFLAGS),
+	COMPOSITE(SCLK_UART3, "sclk_uart3", sclk_uart_parents_p, 0,
+			RK3506_CLKSEL_CON(31), 5, 3, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(11), 12, GFLAGS),
+	COMPOSITE(SCLK_UART4, "sclk_uart4", sclk_uart_parents_p, 0,
+			RK3506_CLKSEL_CON(31), 13, 3, MFLAGS, 8, 5, DFLAGS,
+			RK3506_CLKGATE_CON(11), 13, GFLAGS),
+	GATE(PCLK_I2C0, "pclk_i2c0", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 14, GFLAGS),
+	COMPOSITE(CLK_I2C0, "clk_i2c0", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(32), 4, 2, MFLAGS, 0, 4, DFLAGS,
+			RK3506_CLKGATE_CON(11), 15, GFLAGS),
+	GATE(PCLK_I2C1, "pclk_i2c1", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(12), 0, GFLAGS),
+	COMPOSITE(CLK_I2C1, "clk_i2c1", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(32), 10, 2, MFLAGS, 6, 4, DFLAGS,
+			RK3506_CLKGATE_CON(12), 1, GFLAGS),
+	GATE(PCLK_I2C2, "pclk_i2c2", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(12), 2, GFLAGS),
+	COMPOSITE(CLK_I2C2, "clk_i2c2", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(33), 4, 2, MFLAGS, 0, 4, DFLAGS,
+			RK3506_CLKGATE_CON(12), 3, GFLAGS),
+	GATE(PCLK_PWM1, "pclk_pwm1", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(12), 4, GFLAGS),
+	COMPOSITE(CLK_PWM1, "clk_pwm1", gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(33), 10, 2, MFLAGS, 6, 4, DFLAGS,
+			RK3506_CLKGATE_CON(12), 5, GFLAGS),
+	GATE(CLK_OSC_PWM1, "clk_osc_pwm1", "xin24m", 0,
+			RK3506_CLKGATE_CON(12), 6, GFLAGS),
+	GATE(CLK_RC_PWM1, "clk_rc_pwm1", "clk_rc", 0,
+			RK3506_CLKGATE_CON(12), 7, GFLAGS),
+	COMPOSITE_NODIV(CLK_FREQ_PWM1, "clk_freq_pwm1", clk_pwm_parents_p, 0,
+			RK3506_CLKSEL_CON(33), 12, 4, MFLAGS,
+			RK3506_CLKGATE_CON(12), 8, GFLAGS),
+	COMPOSITE_NODIV(CLK_COUNTER_PWM1, "clk_counter_pwm1", clk_pwm_parents_p, 0,
+			RK3506_CLKSEL_CON(34), 0, 4, MFLAGS,
+			RK3506_CLKGATE_CON(12), 9, GFLAGS),
+	GATE(PCLK_SPI0, "pclk_spi0", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(12), 10, GFLAGS),
+	COMPOSITE(CLK_SPI0, "clk_spi0", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(34), 8, 2, MFLAGS, 4, 4, DFLAGS,
+			RK3506_CLKGATE_CON(12), 11, GFLAGS),
+	GATE(PCLK_SPI1, "pclk_spi1", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(12), 12, GFLAGS),
+	COMPOSITE(CLK_SPI1, "clk_spi1", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(34), 14, 2, MFLAGS, 10, 4, DFLAGS,
+			RK3506_CLKGATE_CON(12), 13, GFLAGS),
+	GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(12), 14, GFLAGS),
+	COMPOSITE_NODIV(DBCLK_GPIO2, "dbclk_gpio2", xin24m_400k_32k_parents_p, 0,
+			RK3506_CLKSEL_CON(35), 0, 2, MFLAGS,
+			RK3506_CLKGATE_CON(12), 15, GFLAGS),
+	GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 0, GFLAGS),
+	COMPOSITE_NODIV(DBCLK_GPIO3, "dbclk_gpio3", xin24m_400k_32k_parents_p, 0,
+			RK3506_CLKSEL_CON(35), 2, 2, MFLAGS,
+			RK3506_CLKGATE_CON(13), 1, GFLAGS),
+	GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 2, GFLAGS),
+	COMPOSITE_NODIV(DBCLK_GPIO4, "dbclk_gpio4", xin24m_400k_32k_parents_p, 0,
+			RK3506_CLKSEL_CON(35), 4, 2, MFLAGS,
+			RK3506_CLKGATE_CON(13), 3, GFLAGS),
+	GATE(HCLK_CAN0, "hclk_can0", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 4, GFLAGS),
+	COMPOSITE(CLK_CAN0, "clk_can0", clk_can_parents_p, 0,
+			RK3506_CLKSEL_CON(35), 11, 3, MFLAGS, 6, 5, DFLAGS,
+			RK3506_CLKGATE_CON(13), 5, GFLAGS),
+	GATE(HCLK_CAN1, "hclk_can1", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 6, GFLAGS),
+	COMPOSITE(CLK_CAN1, "clk_can1", clk_can_parents_p, 0,
+			RK3506_CLKSEL_CON(36), 5, 3, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(13), 7, GFLAGS),
+	GATE(HCLK_PDM, "hclk_pdm", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 8, GFLAGS),
+	COMPOSITE(MCLK_PDM, "mclk_pdm", clk_pdm_parents_p, 0,
+			RK3506_CLKSEL_CON(37), 5, 4, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(13), 9, GFLAGS),
+	COMPOSITE(CLKOUT_PDM, "clkout_pdm", clk_pdm_parents_p, 0,
+			RK3506_CLKSEL_CON(38), 10, 4, MFLAGS, 0, 10, DFLAGS,
+			RK3506_CLKGATE_CON(13), 10, GFLAGS),
+	COMPOSITE(MCLK_SPDIFTX, "mclk_spdiftx", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(39), 5, 4, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(13), 11, GFLAGS),
+	GATE(HCLK_SPDIFTX, "hclk_spdiftx", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 12, GFLAGS),
+	GATE(HCLK_SPDIFRX, "hclk_spdifrx", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 13, GFLAGS),
+	COMPOSITE(MCLK_SPDIFRX, "mclk_spdifrx", gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(39), 14, 2, MFLAGS, 9, 5, DFLAGS,
+			RK3506_CLKGATE_CON(13), 14, GFLAGS),
+	COMPOSITE(MCLK_SAI0, "mclk_sai0", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(40), 8, 4, MFLAGS, 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(13), 15, GFLAGS),
+	GATE(HCLK_SAI0, "hclk_sai0", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(14), 0, GFLAGS),
+	GATE(MCLK_OUT_SAI0, "mclk_out_sai0", "mclk_sai0", 0,
+			RK3506_CLKGATE_CON(14), 1, GFLAGS),
+	COMPOSITE(MCLK_SAI1, "mclk_sai1", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(41), 8, 4, MFLAGS, 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(14), 2, GFLAGS),
+	GATE(HCLK_SAI1, "hclk_sai1", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(14), 3, GFLAGS),
+	GATE(MCLK_OUT_SAI1, "mclk_out_sai1", "mclk_sai1", 0,
+			RK3506_CLKGATE_CON(14), 4, GFLAGS),
+	GATE(HCLK_ASRC0, "hclk_asrc0", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(14), 5, GFLAGS),
+	COMPOSITE(CLK_ASRC0, "clk_asrc0", gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(42), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(14), 6, GFLAGS),
+	GATE(HCLK_ASRC1, "hclk_asrc1", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(14), 7, GFLAGS),
+	COMPOSITE(CLK_ASRC1, "clk_asrc1", gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(42), 12, 2, MFLAGS, 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(14), 8, GFLAGS),
+	GATE(PCLK_CRU, "pclk_cru", "pclk_lsperi_root", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(14), 9, GFLAGS),
+	GATE(PCLK_PMU_ROOT, "pclk_pmu_root", "pclk_lsperi_root", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(14), 10, GFLAGS),
+	COMPOSITE_NODIV(MCLK_ASRC0, "mclk_asrc0", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(46), 0, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 0, GFLAGS),
+	COMPOSITE_NODIV(MCLK_ASRC1, "mclk_asrc1", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(46), 4, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 1, GFLAGS),
+	COMPOSITE_NODIV(MCLK_ASRC2, "mclk_asrc2", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(46), 8, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 2, GFLAGS),
+	COMPOSITE_NODIV(MCLK_ASRC3, "mclk_asrc3", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(46), 12, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 3, GFLAGS),
+	COMPOSITE_NODIV(LRCK_ASRC0_SRC, "lrck_asrc0_src", lrck_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(47), 0, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 4, GFLAGS),
+	COMPOSITE_NODIV(LRCK_ASRC0_DST, "lrck_asrc0_dst", lrck_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(47), 4, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 5, GFLAGS),
+	COMPOSITE_NODIV(LRCK_ASRC1_SRC, "lrck_asrc1_src", lrck_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(47), 8, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 6, GFLAGS),
+	COMPOSITE_NODIV(LRCK_ASRC1_DST, "lrck_asrc1_dst", lrck_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(47), 12, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 7, GFLAGS),
+
+	/* hs peri */
+	COMPOSITE(ACLK_HSPERI_ROOT, "aclk_hsperi_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(49), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(17), 0, GFLAGS),
+	GATE(HCLK_HSPERI_ROOT, "hclk_hsperi_root", "aclk_hsperi_root", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(17), 1, GFLAGS),
+	GATE(PCLK_HSPERI_ROOT, "pclk_hsperi_root", "hclk_hsperi_root", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(17), 2, GFLAGS),
+	COMPOSITE(CCLK_SRC_SDMMC, "cclk_src_sdmmc", cclk_src_sdmmc_parents_p, 0,
+			RK3506_CLKSEL_CON(49), 13, 2, MFLAGS, 7, 6, DFLAGS,
+			RK3506_CLKGATE_CON(17), 6, GFLAGS),
+	GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 7, GFLAGS),
+	GATE(HCLK_FSPI, "hclk_fspi", "hclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 8, GFLAGS),
+	COMPOSITE(SCLK_FSPI, "sclk_fspi", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(50), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(17), 9, GFLAGS),
+	GATE(PCLK_SPI2, "pclk_spi2", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 10, GFLAGS),
+	GATE(ACLK_MAC0, "aclk_mac0", "aclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 11, GFLAGS),
+	GATE(ACLK_MAC1, "aclk_mac1", "aclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 12, GFLAGS),
+	GATE(PCLK_MAC0, "pclk_mac0", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 13, GFLAGS),
+	GATE(PCLK_MAC1, "pclk_mac1", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 14, GFLAGS),
+	COMPOSITE_NOMUX(CLK_MAC_ROOT, "clk_mac_root", "gpll", 0,
+			RK3506_CLKSEL_CON(50), 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(17), 15, GFLAGS),
+	GATE(CLK_MAC0, "clk_mac0", "clk_mac_root", 0,
+			RK3506_CLKGATE_CON(18), 0, GFLAGS),
+	GATE(CLK_MAC1, "clk_mac1", "clk_mac_root", 0,
+			RK3506_CLKGATE_CON(18), 1, GFLAGS),
+	COMPOSITE(MCLK_SAI2, "mclk_sai2", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(51), 8, 4, MFLAGS, 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(18), 2, GFLAGS),
+	GATE(HCLK_SAI2, "hclk_sai2", "hclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(18), 3, GFLAGS),
+	GATE(MCLK_OUT_SAI2, "mclk_out_sai2", "mclk_sai2", 0,
+			RK3506_CLKGATE_CON(18), 4, GFLAGS),
+	COMPOSITE(MCLK_SAI3_SRC, "mclk_sai3_src", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(52), 8, 4, MFLAGS, 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(18), 5, GFLAGS),
+	GATE(HCLK_SAI3, "hclk_sai3", "hclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(18), 6, GFLAGS),
+	GATE(MCLK_SAI3, "mclk_sai3", "mclk_sai3_src", 0,
+			RK3506_CLKGATE_CON(18), 7, GFLAGS),
+	GATE(MCLK_OUT_SAI3, "mclk_out_sai3", "mclk_sai3_src", 0,
+			RK3506_CLKGATE_CON(18), 8, GFLAGS),
+	COMPOSITE(MCLK_SAI4_SRC, "mclk_sai4_src", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(53), 8, 4, MFLAGS, 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(18), 9, GFLAGS),
+	GATE(HCLK_SAI4, "hclk_sai4", "hclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(18), 10, GFLAGS),
+	GATE(MCLK_SAI4, "mclk_sai4", "mclk_sai4_src", 0,
+			RK3506_CLKGATE_CON(18), 11, GFLAGS),
+	GATE(HCLK_DSM, "hclk_dsm", "hclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(18), 12, GFLAGS),
+	GATE(MCLK_DSM, "mclk_dsm", "mclk_sai3_src", 0,
+			RK3506_CLKGATE_CON(18), 13, GFLAGS),
+	GATE(PCLK_AUDIO_ADC, "pclk_audio_adc", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(18), 14, GFLAGS),
+	GATE(MCLK_AUDIO_ADC, "mclk_audio_adc", "mclk_sai4_src", 0,
+			RK3506_CLKGATE_CON(18), 15, GFLAGS),
+	FACTOR(MCLK_AUDIO_ADC_DIV4, "mclk_audio_adc_div4", "mclk_audio_adc", 0, 1, 4),
+	GATE(PCLK_SARADC, "pclk_saradc", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(19), 0, GFLAGS),
+	COMPOSITE(CLK_SARADC, "clk_saradc", xin24m_400k_32k_parents_p, 0,
+			RK3506_CLKSEL_CON(54), 4, 2, MFLAGS, 0, 4, DFLAGS,
+			RK3506_CLKGATE_CON(19), 1, GFLAGS),
+	GATE(PCLK_OTPC_NS, "pclk_otpc_ns", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(19), 3, GFLAGS),
+	GATE(CLK_SBPI_OTPC_NS, "clk_sbpi_otpc_ns", "xin24m_gate", 0,
+			RK3506_CLKGATE_CON(19), 4, GFLAGS),
+	FACTOR(CLK_USER_OTPC_NS, "clk_user_otpc_ns", "clk_sbpi_otpc_ns", 0, 1, 2),
+	GATE(PCLK_UART5, "pclk_uart5", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(19), 6, GFLAGS),
+	COMPOSITE(SCLK_UART5, "sclk_uart5", sclk_uart_parents_p, 0,
+			RK3506_CLKSEL_CON(54), 11, 3, MFLAGS, 6, 5, DFLAGS,
+			RK3506_CLKGATE_CON(19), 7, GFLAGS),
+	GATE(PCLK_GPIO234_IOC, "pclk_gpio234_ioc", "pclk_hsperi_root", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(19), 8, GFLAGS),
+	COMPOSITE(CLK_MAC_PTP_ROOT, "clk_mac_ptp_root", clk_mac_ptp_root_parents_p, 0,
+			RK3506_CLKSEL_CON(55), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(19), 9, GFLAGS),
+	GATE(CLK_MAC0_PTP, "clk_mac0_ptp", "clk_mac_ptp_root", 0,
+			RK3506_CLKGATE_CON(19), 10, GFLAGS),
+	GATE(CLK_MAC1_PTP, "clk_mac1_ptp", "clk_mac_ptp_root", 0,
+			RK3506_CLKGATE_CON(19), 11, GFLAGS),
+	COMPOSITE(ACLK_VIO_ROOT, "aclk_vio_root", gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(58), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(21), 0, GFLAGS),
+	COMPOSITE(HCLK_VIO_ROOT, "hclk_vio_root", gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(58), 12, 2, MFLAGS, 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(21), 1, GFLAGS),
+	GATE(PCLK_VIO_ROOT, "pclk_vio_root", "hclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 2, GFLAGS),
+	GATE(HCLK_RGA, "hclk_rga", "hclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 6, GFLAGS),
+	GATE(ACLK_RGA, "aclk_rga", "aclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 7, GFLAGS),
+	COMPOSITE(CLK_CORE_RGA, "clk_core_rga", gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(59), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(21), 8, GFLAGS),
+	GATE(ACLK_VOP, "aclk_vop", "aclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 9, GFLAGS),
+	GATE(HCLK_VOP, "hclk_vop", "hclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 10, GFLAGS),
+	COMPOSITE(DCLK_VOP, "dclk_vop", dclk_vop_parents_p, 0,
+			RK3506_CLKSEL_CON(60), 8, 3, MFLAGS, 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(21), 11, GFLAGS),
+	GATE(PCLK_DPHY, "pclk_dphy", "pclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 12, GFLAGS),
+	GATE(PCLK_DSI_HOST, "pclk_dsi_host", "pclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 13, GFLAGS),
+	GATE(PCLK_TSADC, "pclk_tsadc", "pclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 14, GFLAGS),
+	COMPOSITE_NOMUX(CLK_TSADC, "clk_tsadc", "xin24m_gate", 0,
+			RK3506_CLKSEL_CON(61), 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(21), 15, GFLAGS),
+	COMPOSITE_NOMUX(CLK_TSADC_TSEN, "clk_tsadc_tsen", "xin24m_gate", 0,
+			RK3506_CLKSEL_CON(61), 8, 3, DFLAGS,
+			RK3506_CLKGATE_CON(22), 0, GFLAGS),
+	GATE(PCLK_GPIO1_IOC, "pclk_gpio1_ioc", "pclk_vio_root", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(22), 1, GFLAGS),
+
+	/* pmu */
+	GATE(CLK_PMU, "clk_pmu", "xin24m", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 1, GFLAGS),
+	GATE(PCLK_PMU, "pclk_pmu", "pclk_pmu_root", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 2, GFLAGS),
+	GATE(PCLK_PMU_CRU, "pclk_pmu_cru", "pclk_pmu_root", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 4, GFLAGS),
+	GATE(PCLK_PMU_GRF, "pclk_pmu_grf", "pclk_pmu_root", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 5, GFLAGS),
+	GATE(PCLK_GPIO0_IOC, "pclk_gpio0_ioc", "pclk_pmu_root", CLK_IS_CRITICAL,
+			RK3506_PMU_CLKGATE_CON(0), 7, GFLAGS),
+	GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pmu_root", 0,
+			RK3506_PMU_CLKGATE_CON(0), 8, GFLAGS),
+	COMPOSITE_NODIV(DBCLK_GPIO0, "dbclk_gpio0", dbclk_gpio0_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(0), 0, 2, MFLAGS,
+			RK3506_PMU_CLKGATE_CON(0), 9, GFLAGS),
+	GATE(PCLK_GPIO1_SHADOW, "pclk_gpio1_shadow", "pclk_pmu_root", 0,
+			RK3506_PMU_CLKGATE_CON(0), 10, GFLAGS),
+	COMPOSITE_NODIV(DBCLK_GPIO1_SHADOW, "dbclk_gpio1_shadow", dbclk_gpio0_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(0), 2, 2, MFLAGS,
+			RK3506_PMU_CLKGATE_CON(0), 11, GFLAGS),
+	GATE(PCLK_PMU_HP_TIMER, "pclk_pmu_hp_timer", "pclk_pmu_root", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 12, GFLAGS),
+	MUX(CLK_PMU_HP_TIMER, "clk_pmu_hp_timer", clk_pmu_hp_timer_parents_p, CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKSEL_CON(0), 4, 2, MFLAGS),
+	GATE(PCLK_PWM0, "pclk_pwm0", "pclk_pmu_root", 0,
+			RK3506_PMU_CLKGATE_CON(0), 15, GFLAGS),
+	COMPOSITE_NOMUX(CLK_PWM0, "clk_pwm0", "clk_gpll_div_100m", 0,
+			RK3506_PMU_CLKSEL_CON(0), 6, 4, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 0, GFLAGS),
+	GATE(CLK_OSC_PWM0, "clk_osc_pwm0", "xin24m", 0,
+			RK3506_PMU_CLKGATE_CON(1), 1, GFLAGS),
+	GATE(CLK_RC_PWM0, "clk_rc_pwm0", "clk_rc", 0,
+			RK3506_PMU_CLKGATE_CON(1), 2, GFLAGS),
+	COMPOSITE_NOMUX(CLK_MAC_OUT, "clk_mac_out", "gpll", 0,
+			RK3506_PMU_CLKSEL_CON(0), 10, 6, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 3, GFLAGS),
+	COMPOSITE(CLK_REF_OUT0, "clk_ref_out0", clk_ref_out_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(1), 6, 2, MFLAGS, 0, 6, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 4, GFLAGS),
+	COMPOSITE(CLK_REF_OUT1, "clk_ref_out1", clk_ref_out_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(1), 14, 2, MFLAGS, 8, 6, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 5, GFLAGS),
+	MUX(CLK_32K_FRAC_MUX, "clk_32k_frac_mux", clk_32k_frac_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(3), 0, 2, MFLAGS),
+	COMPOSITE_FRAC(CLK_32K_FRAC, "clk_32k_frac", "clk_32k_frac_mux", 0,
+			RK3506_PMU_CLKSEL_CON(2), 0,
+			RK3506_PMU_CLKGATE_CON(1), 6, GFLAGS),
+	COMPOSITE_NOMUX(CLK_32K_RC, "clk_32k_rc", "clk_rc", CLK_IS_CRITICAL,
+			RK3506_PMU_CLKSEL_CON(3), 2, 5, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 7, GFLAGS),
+	COMPOSITE_NODIV(CLK_32K, "clk_32k", clk_32k_parents_p, CLK_IS_CRITICAL,
+			RK3506_PMU_CLKSEL_CON(3), 7, 2, MFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 8, GFLAGS),
+	COMPOSITE_NODIV(CLK_32K_PMU, "clk_32k_pmu", clk_32k_parents_p, CLK_IS_CRITICAL,
+			RK3506_PMU_CLKSEL_CON(3), 9, 2, MFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 9, GFLAGS),
+	GATE(CLK_PMU_32K, "clk_pmu_32k", "clk_32k_pmu", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 3, GFLAGS),
+	GATE(CLK_PMU_HP_TIMER_32K, "clk_pmu_hp_timer_32k", "clk_32k_pmu", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 14, GFLAGS),
+	GATE(PCLK_TOUCH_KEY, "pclk_touch_key", "pclk_pmu_root", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(1), 12, GFLAGS),
+	GATE(CLK_TOUCH_KEY, "clk_touch_key", "xin24m", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(1), 13, GFLAGS),
+	COMPOSITE(CLK_REF_PHY_PLL, "clk_ref_phy_pll", gpll_v0pll_v1pll_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(4), 13, 2, MFLAGS, 6, 7, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 14, GFLAGS),
+	MUX(CLK_REF_PHY_PMU_MUX, "clk_ref_phy_pmu_mux", clk_ref_phy_pmu_mux_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(4), 15, 1, MFLAGS),
+	GATE(CLK_WIFI_OUT, "clk_wifi_out", "xin24m", 0,
+			RK3506_PMU_CLKGATE_CON(2), 0, GFLAGS),
+	MUX(CLK_V0PLL_REF, "clk_v0pll_ref", clk_vpll_ref_parents_p, CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKSEL_CON(6), 0, 1, MFLAGS),
+	MUX(CLK_V1PLL_REF, "clk_v1pll_ref", clk_vpll_ref_parents_p, CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKSEL_CON(6), 1, 1, MFLAGS),
+
+	/* secure ns */
+	GATE(CLK_CORE_CRYPTO_NS, "clk_core_crypto_ns", "clk_core_crypto", 0,
+			RK3506_CLKGATE_CON(5), 12, GFLAGS),
+	GATE(CLK_PKA_CRYPTO_NS, "clk_pka_crypto_ns", "clk_pka_crypto", 0,
+			RK3506_CLKGATE_CON(5), 13, GFLAGS),
+
+	/* io */
+	GATE(CLK_SPI2, "clk_spi2", "clk_spi2_io", 0,
+			RK3506_CLKGATE_CON(20), 0, GFLAGS),
+};
+
+static void __init rk3506_clk_init(struct device_node *np)
+{
+	struct rockchip_clk_provider *ctx;
+	unsigned long clk_nr_clks;
+	void __iomem *reg_base;
+
+	clk_nr_clks = rockchip_clk_find_max_clk_id(rk3506_clk_branches,
+						   ARRAY_SIZE(rk3506_clk_branches)) + 1;
+
+	reg_base = of_iomap(np, 0);
+	if (!reg_base) {
+		pr_err("%s: could not map cru region\n", __func__);
+		return;
+	}
+
+	ctx = rockchip_clk_init(np, reg_base, clk_nr_clks);
+	if (IS_ERR(ctx)) {
+		pr_err("%s: rockchip clk init failed\n", __func__);
+		iounmap(reg_base);
+		return;
+	}
+
+	rockchip_clk_register_plls(ctx, rk3506_pll_clks,
+				   ARRAY_SIZE(rk3506_pll_clks),
+				   0);
+
+	rockchip_clk_register_armclk_multi_pll(ctx, &rk3506_armclk,
+					       rk3506_cpuclk_rates,
+					       ARRAY_SIZE(rk3506_cpuclk_rates));
+
+	rockchip_clk_register_branches(ctx, rk3506_clk_branches,
+				       ARRAY_SIZE(rk3506_clk_branches));
+
+	rk3506_rst_init(np, reg_base);
+
+	rockchip_register_restart_notifier(ctx, RK3506_GLB_SRST_FST, NULL);
+
+	rockchip_clk_of_add_provider(np, ctx);
+
+	/* pvtpll src init */
+	writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RK3506_CLKSEL_CON(15));
+}
+
+CLK_OF_DECLARE(rk3506_cru, "rockchip,rk3506-cru", rk3506_clk_init);
+
+struct clk_rk3506_inits {
+	void (*inits)(struct device_node *np);
+};
+
+static const struct clk_rk3506_inits clk_rk3506_cru_init = {
+	.inits = rk3506_clk_init,
+};
+
+static const struct of_device_id clk_rk3506_match_table[] = {
+	{
+		.compatible = "rockchip,rk3506-cru",
+		.data = &clk_rk3506_cru_init,
+	},
+	{ }
+};
+
+static int clk_rk3506_probe(struct platform_device *pdev)
+{
+	const struct clk_rk3506_inits *init_data;
+	struct device *dev = &pdev->dev;
+
+	init_data = device_get_match_data(dev);
+	if (!init_data)
+		return -EINVAL;
+
+	if (init_data->inits)
+		init_data->inits(dev->of_node);
+
+	return 0;
+}
+
+static struct platform_driver clk_rk3506_driver = {
+	.probe		= clk_rk3506_probe,
+	.driver		= {
+		.name	= "clk-rk3506",
+		.of_match_table = clk_rk3506_match_table,
+		.suppress_bind_attrs = true,
+	},
+};
+builtin_platform_driver_probe(clk_rk3506_driver, clk_rk3506_probe);
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index 87f09320b942..b2fff1d13a4a 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -275,6 +275,18 @@ struct clk;
 #define RK3399_PMU_CLKGATE_CON(x)	((x) * 0x4 + 0x100)
 #define RK3399_PMU_SOFTRST_CON(x)	((x) * 0x4 + 0x110)
 
+#define RK3506_PMU_CRU_BASE		0x10000
+#define RK3506_PLL_CON(x)		((x) * 0x4 + RK3506_PMU_CRU_BASE)
+#define RK3506_CLKSEL_CON(x)		((x) * 0x4 + 0x300)
+#define RK3506_CLKGATE_CON(x)		((x) * 0x4 + 0x800)
+#define RK3506_SOFTRST_CON(x)		((x) * 0x4 + 0xa00)
+#define RK3506_PMU_CLKSEL_CON(x)	((x) * 0x4 + 0x300 + RK3506_PMU_CRU_BASE)
+#define RK3506_PMU_CLKGATE_CON(x)	((x) * 0x4 + 0x800 + RK3506_PMU_CRU_BASE)
+#define RK3506_MODE_CON			0x280
+#define RK3506_GLB_CNT_TH		0xc00
+#define RK3506_GLB_SRST_FST		0xc08
+#define RK3506_GLB_SRST_SND		0xc0c
+
 #define RK3528_PMU_CRU_BASE		0x10000
 #define RK3528_PCIE_CRU_BASE		0x20000
 #define RK3528_DDRPHY_CRU_BASE		0x28000
@@ -1329,6 +1341,7 @@ static inline void rockchip_register_softrst(struct device_node *np,
 }
 
 void rv1126b_rst_init(struct device_node *np, void __iomem *reg_base);
+void rk3506_rst_init(struct device_node *np, void __iomem *reg_base);
 void rk3528_rst_init(struct device_node *np, void __iomem *reg_base);
 void rk3562_rst_init(struct device_node *np, void __iomem *reg_base);
 void rk3576_rst_init(struct device_node *np, void __iomem *reg_base);
diff --git a/drivers/clk/rockchip/rst-rk3506.c b/drivers/clk/rockchip/rst-rk3506.c
new file mode 100644
index 000000000000..c3abde60f3c6
--- /dev/null
+++ b/drivers/clk/rockchip/rst-rk3506.c
@@ -0,0 +1,226 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2025 Rockchip Electronics Co., Ltd.
+ * Author: Finley Xiao <finley.xiao at rock-chips.com>
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <dt-bindings/reset/rockchip,rk3506-cru.h>
+#include "clk.h"
+
+/* 0xFF9A0000 + 0x0A00 */
+#define RK3506_CRU_RESET_OFFSET(id, reg, bit) [id] = (0 + reg * 16 + bit)
+
+/* mapping table for reset ID to register offset */
+static const int rk3506_register_offset[] = {
+	/* CRU-->SOFTRST_CON00 */
+	RK3506_CRU_RESET_OFFSET(SRST_NCOREPORESET0_AC, 0, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_NCOREPORESET1_AC, 0, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_NCOREPORESET2_AC, 0, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_NCORESET0_AC, 0, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_NCORESET1_AC, 0, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_NCORESET2_AC, 0, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_NL2RESET_AC, 0, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_A_CORE_BIU_AC, 0, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_H_M0_AC, 0, 10),
+
+	/* CRU-->SOFTRST_CON02 */
+	RK3506_CRU_RESET_OFFSET(SRST_NDBGRESET, 2, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_P_CORE_BIU, 2, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_PMU, 2, 15),
+
+	/* CRU-->SOFTRST_CON03 */
+	RK3506_CRU_RESET_OFFSET(SRST_P_DBG, 3, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_POT_DBG, 3, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_P_CORE_GRF, 3, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_CORE_EMA_DETECT, 3, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_REF_PVTPLL_CORE, 3, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_P_GPIO1, 3, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_DB_GPIO1, 3, 9),
+
+	/* CRU-->SOFTRST_CON04 */
+	RK3506_CRU_RESET_OFFSET(SRST_A_CORE_PERI_BIU, 4, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_A_DSMC, 4, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_P_DSMC, 4, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_FLEXBUS, 4, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_A_FLEXBUS, 4, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_H_FLEXBUS, 4, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_A_DSMC_SLV, 4, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_H_DSMC_SLV, 4, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_DSMC_SLV, 4, 13),
+
+	/* CRU-->SOFTRST_CON05 */
+	RK3506_CRU_RESET_OFFSET(SRST_A_BUS_BIU, 5, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_H_BUS_BIU, 5, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_P_BUS_BIU, 5, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_A_SYSRAM, 5, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_H_SYSRAM, 5, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_A_DMAC0, 5, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_A_DMAC1, 5, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_H_M0, 5, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_M0_JTAG, 5, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_H_CRYPTO, 5, 15),
+
+	/* CRU-->SOFTRST_CON06 */
+	RK3506_CRU_RESET_OFFSET(SRST_H_RNG, 6, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_P_BUS_GRF, 6, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_P_TIMER0, 6, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH0, 6, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH1, 6, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH2, 6, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH3, 6, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH4, 6, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH5, 6, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_P_WDT0, 6, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_T_WDT0, 6, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_P_WDT1, 6, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_T_WDT1, 6, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_P_MAILBOX, 6, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_P_INTMUX, 6, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_P_SPINLOCK, 6, 15),
+
+	/* CRU-->SOFTRST_CON07 */
+	RK3506_CRU_RESET_OFFSET(SRST_P_DDRC, 7, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_H_DDRPHY, 7, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_P_DDRMON, 7, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_DDRMON_OSC, 7, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_P_DDR_LPC, 7, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_H_USBOTG0, 7, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_USBOTG0_ADP, 7, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_H_USBOTG1, 7, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_USBOTG1_ADP, 7, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_P_USBPHY, 7, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_USBPHY_POR, 7, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_USBPHY_OTG0, 7, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_USBPHY_OTG1, 7, 14),
+
+	/* CRU-->SOFTRST_CON08 */
+	RK3506_CRU_RESET_OFFSET(SRST_A_DMA2DDR, 8, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_P_DMA2DDR, 8, 1),
+
+	/* CRU-->SOFTRST_CON09 */
+	RK3506_CRU_RESET_OFFSET(SRST_USBOTG0_UTMI, 9, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_USBOTG1_UTMI, 9, 1),
+
+	/* CRU-->SOFTRST_CON10 */
+	RK3506_CRU_RESET_OFFSET(SRST_A_DDRC_0, 10, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_A_DDRC_1, 10, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_A_DDR_BIU, 10, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_DDRC, 10, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_DDRMON, 10, 4),
+
+	/* CRU-->SOFTRST_CON11 */
+	RK3506_CRU_RESET_OFFSET(SRST_H_LSPERI_BIU, 11, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_P_UART0, 11, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_P_UART1, 11, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_P_UART2, 11, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_P_UART3, 11, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_P_UART4, 11, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_UART0, 11, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_UART1, 11, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_UART2, 11, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_UART3, 11, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_UART4, 11, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_P_I2C0, 11, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_I2C0, 11, 15),
+
+	/* CRU-->SOFTRST_CON12 */
+	RK3506_CRU_RESET_OFFSET(SRST_P_I2C1, 12, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_I2C1, 12, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_P_I2C2, 12, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_I2C2, 12, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_P_PWM1, 12, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_PWM1, 12, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_P_SPI0, 12, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_SPI0, 12, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_P_SPI1, 12, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_SPI1, 12, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_P_GPIO2, 12, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_DB_GPIO2, 12, 15),
+
+	/* CRU-->SOFTRST_CON13 */
+	RK3506_CRU_RESET_OFFSET(SRST_P_GPIO3, 13, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_DB_GPIO3, 13, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_P_GPIO4, 13, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_DB_GPIO4, 13, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_H_CAN0, 13, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_CAN0, 13, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_H_CAN1, 13, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_CAN1, 13, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_H_PDM, 13, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_M_PDM, 13, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_PDM, 13, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_SPDIFTX, 13, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_H_SPDIFTX, 13, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_H_SPDIFRX, 13, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_SPDIFRX, 13, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_M_SAI0, 13, 15),
+
+	/* CRU-->SOFTRST_CON14 */
+	RK3506_CRU_RESET_OFFSET(SRST_H_SAI0, 14, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_M_SAI1, 14, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_H_SAI1, 14, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_H_ASRC0, 14, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_ASRC0, 14, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_H_ASRC1, 14, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_ASRC1, 14, 8),
+
+	/* CRU-->SOFTRST_CON17 */
+	RK3506_CRU_RESET_OFFSET(SRST_H_HSPERI_BIU, 17, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_H_SDMMC, 17, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_H_FSPI, 17, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_S_FSPI, 17, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_P_SPI2, 17, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_A_MAC0, 17, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_A_MAC1, 17, 12),
+
+	/* CRU-->SOFTRST_CON18 */
+	RK3506_CRU_RESET_OFFSET(SRST_M_SAI2, 18, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_H_SAI2, 18, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_H_SAI3, 18, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_M_SAI3, 18, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_H_SAI4, 18, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_M_SAI4, 18, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_H_DSM, 18, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_M_DSM, 18, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_P_AUDIO_ADC, 18, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_M_AUDIO_ADC, 18, 15),
+
+	/* CRU-->SOFTRST_CON19 */
+	RK3506_CRU_RESET_OFFSET(SRST_P_SARADC, 19, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_SARADC, 19, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_SARADC_PHY, 19, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_P_OTPC_NS, 19, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_SBPI_OTPC_NS, 19, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_USER_OTPC_NS, 19, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_P_UART5, 19, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_UART5, 19, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_P_GPIO234_IOC, 19, 8),
+
+	/* CRU-->SOFTRST_CON21 */
+	RK3506_CRU_RESET_OFFSET(SRST_A_VIO_BIU, 21, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_H_VIO_BIU, 21, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_H_RGA, 21, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_A_RGA, 21, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_CORE_RGA, 21, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_A_VOP, 21, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_H_VOP, 21, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_VOP, 21, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_P_DPHY, 21, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_P_DSI_HOST, 21, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_P_TSADC, 21, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_TSADC, 21, 15),
+
+	/* CRU-->SOFTRST_CON22 */
+	RK3506_CRU_RESET_OFFSET(SRST_P_GPIO1_IOC, 22, 1),
+};
+
+void rk3506_rst_init(struct device_node *np, void __iomem *reg_base)
+{
+	rockchip_register_softrst_lut(np,
+				      rk3506_register_offset,
+				      ARRAY_SIZE(rk3506_register_offset),
+				      reg_base + RK3506_SOFTRST_CON(0),
+				      ROCKCHIP_SOFTRST_HIWORD_MASK);
+}
-- 
2.34.1



From shawn.lin at rock-chips.com  Mon Nov 10 19:17:23 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Tue, 11 Nov 2025 11:17:23 +0800
Subject: [RESEND] Re: [PATCH] PCI: dw-rockchip: Skip waiting for link up
In-Reply-To: <B721C8A516FDB604+a04b38d3-64ec-423f-9e4c-040c8d2aec76@radxa.com>
References: <55EB0E5F655F3AFC+136b89fd-98d4-42af-a99d-a0bb05cc93f3@radxa.com>
 <aRCI5kG16_1erMME@ryzen>
 <F8B2B6FA2884D69A+b7da13f2-0ffb-4308-b1ba-0549bc461be8@radxa.com>
 <780a4209-f89f-43a9-9364-331d3b77e61e@rock-chips.com>
 <4487DA40249CC821+19232169-a096-4737-bc6a-5cec9592d65f@radxa.com>
 <363d6b4d-c999-43d4-866e-880ef7d0dec3@rock-chips.com>
 <0C31787C387488ED+fd39bfe6-0844-4a87-bf48-675dd6d6a2df@radxa.com>
 <dc932773-af5b-4af7-a0d0-8cc72dfbd3c7@rock-chips.com>
 <aRHb4S40a7ZUDop1@ryzen>
 <2n3wamm3txxc6xbmvf3nnrvaqpgsck3w4a6omxnhex3mqeujib@2tb4svn5d3z6>
 <aRJEDEEJr9Ic-RKN@fedora>
 <B721C8A516FDB604+a04b38d3-64ec-423f-9e4c-040c8d2aec76@radxa.com>
Message-ID: <05bd0efe-9a84-40e9-af07-51c0b0d865bf@rock-chips.com>

? 2025/11/11 ??? 10:09, FUKAUMI Naoki ??:
> On 11/11/25 04:59, Niklas Cassel wrote:

...

> 
> Leaving the commit message aside, I'm currently testing with a revert of 
> the two patches.
> 
> Vanilla v6.18-rc5, CONFIG_PCI_DYNAMIC_OF_NODES=y, revert ec9fd499b9c6, 
> revert 0e0b45ab5d77.
> 
> It works stably on the ROCK 5A. The link speed is 2Gb/s.
> 
> The ROCK 5C is unstable. It initially worked with a link speed of 4Gb/s, 
> but eventually started showing kernel oops. The dts files for the 5A and 
> 5C are compatible and interchangeable, but even using the 5A's dts on 
> the 5C, the operation remains unstable.

The link speed on ROCK 5A is 2Gb/s also means it's downgraded now. Did
ROCK 5A work under the link speed of 4Gb/s before?

In case it's signal integrity relevant, you could enable PCIE_DW_DEBUGFS
and refer to Documentation/ABI/testing/debugfs-dwc-pcie to collect
RASDES info from there.

> 
> I plan to thoroughly investigate the ROCK 5C's behavior on v6.13, but 
> for now, I believe reverting the two patches is the correct action.
> 
> Best regards,
> 
> -- 
> FUKAUMI Naoki
> Radxa Computer (Shenzhen) Co., Ltd.
> 
>> Kind regards,
>> Niklas
>>
> 
> 
> 



From geraldogabriel at gmail.com  Mon Nov 10 21:06:53 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Tue, 11 Nov 2025 02:06:53 -0300
Subject: [PATCH] arm64: dts: rockchip: align bindings to PCIe spec
In-Reply-To: <d9e257bd-806c-48b4-bb22-f1342e9fc15a@rock-chips.com>
References: <4b5ffcccfef2a61838aa563521672a171acb27b2.1762321976.git.geraldogabriel@gmail.com>
 <ba120577-42da-424d-8102-9d085c1494c8@rock-chips.com>
 <aQsIXcQzeYop6a0B@geday>
 <67b605b0-7046-448a-bc9b-d3ac56333809@rock-chips.com>
 <aQ1c7ZDycxiOIy8Y@geday>
 <d9e257bd-806c-48b4-bb22-f1342e9fc15a@rock-chips.com>
Message-ID: <aRLEbfsmXnGwyigS@geday>

On Fri, Nov 07, 2025 at 11:01:04AM +0800, Shawn Lin wrote:
> + Ye Zhang
> 
> ? 2025/11/07 ??? 10:43, Geraldo Nascimento ??:
> > On Wed, Nov 05, 2025 at 04:56:36PM +0800, Shawn Lin wrote:
> >> ? 2025/11/05 ??? 16:18, Geraldo Nascimento ??:
> >>> Hi Shawn, glad to hear from you.
> >>>
> >>> Perhaps the following change is better? It resolves the issue
> >>> without the added complication of open drain. After you questioned
> >>> if open drain is actually part of the spec, I remembered that
> >>> GPIO_OPEN_DRAIN is actually (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_DRAIN)
> >>> so I decided to test with just GPIO_SINGLE_ENDED and it works.
> > 
> > Shawn,
> > 
> > I quote from the PCIe Mini Card Electromechanical Specification Rev 1.2
> > 
> > "3.4.1. Logic Signal Requirements
> > 
> > The 3.3V card logic levels for single-ended digital signals (WAKE#,
> > CLKREQ#, PERST#, and W_DISABLE#) are given in Table 3-7. [...]"
> > 
> > So while you are correct that PERST# is most definitely not Open Drain,
> > there's evidence on the spec that defines this signal as Single-Ended.
> > 
> 
> This's true. But I couldn't find any user in dts using either
> GPIO_SINGLE_ENDED or GPIO_OPEN_DRAIN for PCIe PERST#. I'm curious
> how these two flags affect actual behavior of chips. Ye, could you
> please help check it?
>

While I haven't heard from Ye Zhang still your comment instigated
me to dig deeper, thank you Shawn Lin. What I discovered I believe
is a bug in the Rockchip driver for the GPIO subsystem. Look:

diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
index 47174eb3ba76..5387c78ea11c 100644
--- a/drivers/gpio/gpio-rockchip.c
+++ b/drivers/gpio/gpio-rockchip.c
@@ -272,9 +272,10 @@ static int rockchip_gpio_direction_input(struct gpio_chip *gc,
 static int rockchip_gpio_direction_output(struct gpio_chip *gc,
 					  unsigned int offset, int value)
 {
-	rockchip_gpio_set(gc, offset, value);
 
-	return rockchip_gpio_set_direction(gc, offset, false);
+	rockchip_gpio_set_direction(gc, offset, false);
+
+	return rockchip_gpio_set(gc, offset, value);
 }
 
 /*

It seems to me the current logic is inverted, i.e. GPIO Port A Data
Register can't be successfully written if direction output is not set
yet.

I have to double-check with printk() but from what I see here it may
be very possible that first call to gpiod_get_index() will not set
proper value and only subsequent calls made to gpiod set_value()
will begin to set value.

For what it is worth, with the diff the workaround to set as open
source/emitter with pulldown or set open drain with pullup no longer
works, i.e. PCIe initial link training fails.

The workaround to drop TPVPERL still works, i.e. PCIe initial link
training proceeds, system operational.

Thanks,
Geraldo Nascimento

> > Thanks,
> > Geraldo Nascimento
> > 
> 


From naoki at radxa.com  Mon Nov 10 21:09:23 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Tue, 11 Nov 2025 05:09:23 +0000
Subject: [PATCH 4/4] arm64: dts: rockchip: Make eeprom read-only for Radxa ROCK 3C/5A/5C
In-Reply-To: <20251111050924.54880-1-naoki@radxa.com>
References: <20251111050924.54880-1-naoki@radxa.com>
Message-ID: <20251111050924.54880-5-naoki@radxa.com>

Make the BL24C16 EEPROM chips found on Radxa ROCK 3C, 5A and 5C SBCs
read-only, because they contain factory-programmed data that isn't
supposed to be modified by the end users.

Fixes: ee219017ddb50 ("arm64: dts: rockchip: Add Radxa ROCK 3C")
Fixes: 89c880808cff8 ("arm64: dts: rockchip: add I2C EEPROM to rock-5a")
Fixes: 3ddf5cdb77e6e ("arm64: dts: rockchip: add Radxa ROCK 5C")
Link: https://dl.radxa.com/rock3/docs/hw/3c/v1400/radxa_rock_3c_v1400_schematic.pdf p.13
Link: https://dl.radxa.com/rock5/5a/docs/hw/radxa_rock5a_V1.1_sch.pdf p.19
Link: https://dl.radxa.com/rock5/5c/docs/hw/v1100/radxa_rock_5c_schematic_v1100.pdf p.18
Link: https://github.com/radxa/u-boot/blob/next-dev-v2024.10/drivers/misc/radxa-i2c-eeprom.c
Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
 arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts  | 1 +
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 1 +
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts | 1 +
 3 files changed, 3 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
index 80ac40555e023..fa28b32f69108 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
@@ -466,6 +466,7 @@ eeprom: eeprom at 50 {
 		compatible = "belling,bl24c16a", "atmel,24c16";
 		reg = <0x50>;
 		pagesize = <16>;
+		read-only;
 		vcc-supply = <&vcca1v8_pmu>;
 	};
 };
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
index 041a0fff22ccb..d844a842d4cce 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
@@ -233,6 +233,7 @@ eeprom: eeprom at 50 {
 		compatible = "belling,bl24c16a", "atmel,24c16";
 		reg = <0x50>;
 		pagesize = <16>;
+		read-only;
 		vcc-supply = <&vcc_3v3_pmu>;
 	};
 };
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
index dd7317bab6135..665eecce063a8 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
@@ -325,6 +325,7 @@ eeprom at 50 {
 		compatible = "belling,bl24c16a", "atmel,24c16";
 		reg = <0x50>;
 		pagesize = <16>;
+		read-only;
 		vcc-supply = <&vcc_3v3_pmu>;
 	};
 };
-- 
2.43.0



From naoki at radxa.com  Mon Nov 10 21:09:21 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Tue, 11 Nov 2025 05:09:21 +0000
Subject: [PATCH 2/4] arm64: dts: rockchip: Add eeprom vcc-supply for Radxa ROCK 5A
In-Reply-To: <20251111050924.54880-1-naoki@radxa.com>
References: <20251111050924.54880-1-naoki@radxa.com>
Message-ID: <20251111050924.54880-3-naoki@radxa.com>

The VCC supply for the BL24C16 EEPROM chip found on Radxa ROCK 5A is
vcc_3v3_pmu, which is routed to vcc_3v3_s3 via a zero-ohm resistor.
Describe this supply.

Fixes: 89c880808cff8 ("arm64: dts: rockchip: add I2C EEPROM to rock-5a")
Link: https://dl.radxa.com/rock5/5a/docs/hw/radxa_rock5a_V1.1_sch.pdf p.19
Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
index 428c6f0232a34..041a0fff22ccb 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
@@ -233,6 +233,7 @@ eeprom: eeprom at 50 {
 		compatible = "belling,bl24c16a", "atmel,24c16";
 		reg = <0x50>;
 		pagesize = <16>;
+		vcc-supply = <&vcc_3v3_pmu>;
 	};
 };
 
@@ -600,7 +601,7 @@ regulator-state-mem {
 				};
 			};
 
-			vcc_3v3_s3: dcdc-reg8 {
+			vcc_3v3_pmu: vcc_3v3_s3: dcdc-reg8 {
 				regulator-name = "vcc_3v3_s3";
 				regulator-always-on;
 				regulator-boot-on;
-- 
2.43.0



From naoki at radxa.com  Mon Nov 10 21:09:19 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Tue, 11 Nov 2025 05:09:19 +0000
Subject: [PATCH 0/4] arm64: dts: rockchip: Fix eeprom description for Radxa ROCK 3C/5A/5C
Message-ID: <20251111050924.54880-1-naoki@radxa.com>

This patch series fixes incorrect or missing entries related to the
eeprom on the Radxa ROCK 3C, 5A, and 5C.

FUKAUMI Naoki (4):
  arm64: dts: rockchip: Move eeprom correct bus for Radxa ROCK 5A
  arm64: dts: rockchip: Add eeprom vcc-supply for Radxa ROCK 5A
  arm64: dts: rockchip: Add eeprom vcc-supply for Radxa ROCK 3C
  arm64: dts: rockchip: Make eeprom read-only for Radxa ROCK 3C/5A/5C

 arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts  |  2 ++
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 16 +++++++++-------
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts |  1 +
 3 files changed, 12 insertions(+), 7 deletions(-)

-- 
2.43.0



From naoki at radxa.com  Mon Nov 10 21:09:22 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Tue, 11 Nov 2025 05:09:22 +0000
Subject: [PATCH 3/4] arm64: dts: rockchip: Add eeprom vcc-supply for Radxa ROCK 3C
In-Reply-To: <20251111050924.54880-1-naoki@radxa.com>
References: <20251111050924.54880-1-naoki@radxa.com>
Message-ID: <20251111050924.54880-4-naoki@radxa.com>

The VCC supply for the BL24C16 EEPROM chip found on Radxa ROCK 3C is
vcca1v8_pmu.
Describe this supply.

Fixes: ee219017ddb50 ("arm64: dts: rockchip: Add Radxa ROCK 3C")
Link: https://dl.radxa.com/rock3/docs/hw/3c/v1400/radxa_rock_3c_v1400_schematic.pdf p.13
Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
 arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
index 6224d72813e59..80ac40555e023 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
@@ -466,6 +466,7 @@ eeprom: eeprom at 50 {
 		compatible = "belling,bl24c16a", "atmel,24c16";
 		reg = <0x50>;
 		pagesize = <16>;
+		vcc-supply = <&vcca1v8_pmu>;
 	};
 };
 
-- 
2.43.0



From naoki at radxa.com  Mon Nov 10 21:09:20 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Tue, 11 Nov 2025 05:09:20 +0000
Subject: [PATCH 1/4] arm64: dts: rockchip: Move eeprom correct bus for Radxa ROCK 5A
In-Reply-To: <20251111050924.54880-1-naoki@radxa.com>
References: <20251111050924.54880-1-naoki@radxa.com>
Message-ID: <20251111050924.54880-2-naoki@radxa.com>

BL24C16 EEPROM chip found on Radxa ROCK 5A is connected on i2c0 bus.
Move eeprom node from i2c2 to i2c0.

Fixes: 89c880808cff8 ("arm64: dts: rockchip: add I2C EEPROM to rock-5a")
Link: https://dl.radxa.com/rock5/5a/docs/hw/radxa_rock5a_V1.1_sch.pdf p.19
Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
index 19a08f7794e67..428c6f0232a34 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
@@ -228,6 +228,12 @@ regulator-state-mem {
 			regulator-off-in-suspend;
 		};
 	};
+
+	eeprom: eeprom at 50 {
+		compatible = "belling,bl24c16a", "atmel,24c16";
+		reg = <0x50>;
+		pagesize = <16>;
+	};
 };
 
 &i2c2 {
@@ -249,12 +255,6 @@ regulator-state-mem {
 			regulator-off-in-suspend;
 		};
 	};
-
-	eeprom: eeprom at 50 {
-		compatible = "belling,bl24c16a", "atmel,24c16";
-		reg = <0x50>;
-		pagesize = <16>;
-	};
 };
 
 &i2c3 {
-- 
2.43.0



From naoki at radxa.com  Mon Nov 10 21:14:14 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Tue, 11 Nov 2025 14:14:14 +0900
Subject: [PATCH v7 08/14] arm64: dts: rockchip: Make eeprom read-only for
 Radxa ROCK 5C
In-Reply-To: <20251109141859.206835-9-naoki@radxa.com>
References: <20251109141859.206835-1-naoki@radxa.com>
 <20251109141859.206835-9-naoki@radxa.com>
Message-ID: <763EE1918D15A524+92d33d40-8c8a-4ddf-81e9-2f57bcce821e@radxa.com>

Hi,

I'll drop this on v8. This will be handled in
  https://lore.kernel.org/linux-rockchip/20251111050924.54880-1-naoki at radxa.com/

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

On 11/9/25 23:18, FUKAUMI Naoki wrote:
> Make EEPROM read-only as it may contain factory-programmed
> board-specific data.
> 
> Fixes: 3ddf5cdb77e6 ("arm64: dts: rockchip: add Radxa ROCK 5C")
> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> ---
> Changes in v7:
> - New
> ---
>   arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts | 1 +
>   1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
> index e3f286df93b05..4f5376d0d109c 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
> @@ -325,6 +325,7 @@ eeprom at 50 {
>   		compatible = "belling,bl24c16a", "atmel,24c16";
>   		reg = <0x50>;
>   		pagesize = <16>;
> +		read-only;
>   		vcc-supply = <&vcc_3v3_pmu>;
>   	};
>   };



From dsimic at manjaro.org  Mon Nov 10 21:29:14 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Tue, 11 Nov 2025 06:29:14 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH 1/4] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= Move eeprom correct bus for Radxa ROCK 5A
In-Reply-To: <20251111050924.54880-2-naoki@radxa.com>
References: <20251111050924.54880-1-naoki@radxa.com> <20251111050924.54880-2-naoki@radxa.com>
Message-ID: <c0f072b9-ca40-b707-6b2c-e4683ca8aba2@manjaro.org>

Hello Naoki,

Thanks for this patch.  Please, see a couple of remarks below.

On Tuesday, November 11, 2025 06:09 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> BL24C16 EEPROM chip found on Radxa ROCK 5A is connected on i2c0 bus.
> Move eeprom node from i2c2 to i2c0.

I'd suggest that the patch subject is reworded a bit like this:

  arm64: dts: rockchip: Move the EEPROM to correct I2C bus on Radxa ROCK 5A

Also, the patch description would benefit from becoming reworded
like this:

  The BL24C16 EEPROM chip found on Radxa ROCK 5A is connected
  to the i2c0 bus, [1] so move the eeprom node from the i2c2 bus
  to the i2c0 bus.

  [1] https://dl.radxa.com/rock5/5a/docs/hw/radxa_rock5a_V1.1_sch.pdf, pp. 19

> Fixes: 89c880808cff8 ("arm64: dts: rockchip: add I2C EEPROM to rock-5a")
> Link: https://dl.radxa.com/rock5/5a/docs/hw/radxa_rock5a_V1.1_sch.pdf p.19

The suggestion above also shows how it would be better to use
explicitly placed references, instead of just placing them into
the Links lines, because that places the refernces closer to
the backed contents.  This isn't critical in this case, because
there isn't much contents, but it's a good practice nonetheless.

> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> ---
>  arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
> index 19a08f7794e67..428c6f0232a34 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
> @@ -228,6 +228,12 @@ regulator-state-mem {
>  			regulator-off-in-suspend;
>  		};
>  	};
> +
> +	eeprom: eeprom at 50 {
> +		compatible = "belling,bl24c16a", "atmel,24c16";
> +		reg = <0x50>;
> +		pagesize = <16>;
> +	};
>  };
>  
>  &i2c2 {
> @@ -249,12 +255,6 @@ regulator-state-mem {
>  			regulator-off-in-suspend;
>  		};
>  	};
> -
> -	eeprom: eeprom at 50 {
> -		compatible = "belling,bl24c16a", "atmel,24c16";
> -		reg = <0x50>;
> -		pagesize = <16>;
> -	};
>  };
>  
>  &i2c3 {



From dsimic at manjaro.org  Mon Nov 10 21:34:54 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Tue, 11 Nov 2025 06:34:54 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH 2/4] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= Add eeprom vcc-supply for Radxa ROCK 5A
In-Reply-To: <20251111050924.54880-3-naoki@radxa.com>
References: <20251111050924.54880-1-naoki@radxa.com> <20251111050924.54880-3-naoki@radxa.com>
Message-ID: <4d54b6ff-ab3e-4e0e-5ae7-200caf9528b8@manjaro.org>

Hello Naoki,

Thanks for this patch.  Please, see one remark below.

On Tuesday, November 11, 2025 06:09 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> The VCC supply for the BL24C16 EEPROM chip found on Radxa ROCK 5A is
> vcc_3v3_pmu, which is routed to vcc_3v3_s3 via a zero-ohm resistor.
> Describe this supply.
> 
> Fixes: 89c880808cff8 ("arm64: dts: rockchip: add I2C EEPROM to rock-5a")
> Link: https://dl.radxa.com/rock5/5a/docs/hw/radxa_rock5a_V1.1_sch.pdf p.19

The same suggestion about using explicitly placed references, from
the patch 1/4 in this series, applies here as well.

> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> ---
>  arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
> index 428c6f0232a34..041a0fff22ccb 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
> @@ -233,6 +233,7 @@ eeprom: eeprom at 50 {
>  		compatible = "belling,bl24c16a", "atmel,24c16";
>  		reg = <0x50>;
>  		pagesize = <16>;
> +		vcc-supply = <&vcc_3v3_pmu>;
>  	};
>  };
>  
> @@ -600,7 +601,7 @@ regulator-state-mem {
>  				};
>  			};
>  
> -			vcc_3v3_s3: dcdc-reg8 {
> +			vcc_3v3_pmu: vcc_3v3_s3: dcdc-reg8 {
>  				regulator-name = "vcc_3v3_s3";
>  				regulator-always-on;
>  				regulator-boot-on;



From dsimic at manjaro.org  Mon Nov 10 21:37:12 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Tue, 11 Nov 2025 06:37:12 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH 3/4] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= Add eeprom vcc-supply for Radxa ROCK 3C
In-Reply-To: <20251111050924.54880-4-naoki@radxa.com>
References: <20251111050924.54880-1-naoki@radxa.com> <20251111050924.54880-4-naoki@radxa.com>
Message-ID: <46ca3fd6-4513-0a0a-41b6-8fffae9b3242@manjaro.org>

Hello Naoki,

Thanks for this patch.  Please, see a couple of remarks below.

On Tuesday, November 11, 2025 06:09 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> The VCC supply for the BL24C16 EEPROM chip found on Radxa ROCK 3C is
> vcca1v8_pmu.

There's no need for a line break here.

> Describe this supply.
> 
> Fixes: ee219017ddb50 ("arm64: dts: rockchip: Add Radxa ROCK 3C")
> Link: https://dl.radxa.com/rock3/docs/hw/3c/v1400/radxa_rock_3c_v1400_schematic.pdf p.13

The same suggestion about using explicitly placed references, from
the patch 1/4 in this series, applies here as well.

> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> ---
>  arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
> index 6224d72813e59..80ac40555e023 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
> @@ -466,6 +466,7 @@ eeprom: eeprom at 50 {
>  		compatible = "belling,bl24c16a", "atmel,24c16";
>  		reg = <0x50>;
>  		pagesize = <16>;
> +		vcc-supply = <&vcca1v8_pmu>;
>  	};
>  };



From dsimic at manjaro.org  Mon Nov 10 21:38:32 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Tue, 11 Nov 2025 06:38:32 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH 4/4] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= Make eeprom read-only for Radxa ROCK 3C/5A/5C
In-Reply-To: <20251111050924.54880-5-naoki@radxa.com>
References: <20251111050924.54880-1-naoki@radxa.com> <20251111050924.54880-5-naoki@radxa.com>
Message-ID: <4babaf00-19f5-1d0d-6359-7f98897ef18e@manjaro.org>

Hello Naoki,

Thanks for this patch.  Please, see one remark below.

On Tuesday, November 11, 2025 06:09 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> Make the BL24C16 EEPROM chips found on Radxa ROCK 3C, 5A and 5C SBCs
> read-only, because they contain factory-programmed data that isn't
> supposed to be modified by the end users.
> 
> Fixes: ee219017ddb50 ("arm64: dts: rockchip: Add Radxa ROCK 3C")
> Fixes: 89c880808cff8 ("arm64: dts: rockchip: add I2C EEPROM to rock-5a")
> Fixes: 3ddf5cdb77e6e ("arm64: dts: rockchip: add Radxa ROCK 5C")
> Link: https://dl.radxa.com/rock3/docs/hw/3c/v1400/radxa_rock_3c_v1400_schematic.pdf p.13
> Link: https://dl.radxa.com/rock5/5a/docs/hw/radxa_rock5a_V1.1_sch.pdf p.19
> Link: https://dl.radxa.com/rock5/5c/docs/hw/v1100/radxa_rock_5c_schematic_v1100.pdf p.18
> Link: https://github.com/radxa/u-boot/blob/next-dev-v2024.10/drivers/misc/radxa-i2c-eeprom.c

The same suggestion about using explicitly placed references, from
the patch 1/4 in this series, applies here as well.

> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> ---
>  arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts  | 1 +
>  arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 1 +
>  arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts | 1 +
>  3 files changed, 3 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
> index 80ac40555e023..fa28b32f69108 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
> @@ -466,6 +466,7 @@ eeprom: eeprom at 50 {
>  		compatible = "belling,bl24c16a", "atmel,24c16";
>  		reg = <0x50>;
>  		pagesize = <16>;
> +		read-only;
>  		vcc-supply = <&vcca1v8_pmu>;
>  	};
>  };
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
> index 041a0fff22ccb..d844a842d4cce 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
> @@ -233,6 +233,7 @@ eeprom: eeprom at 50 {
>  		compatible = "belling,bl24c16a", "atmel,24c16";
>  		reg = <0x50>;
>  		pagesize = <16>;
> +		read-only;
>  		vcc-supply = <&vcc_3v3_pmu>;
>  	};
>  };
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
> index dd7317bab6135..665eecce063a8 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
> @@ -325,6 +325,7 @@ eeprom at 50 {
>  		compatible = "belling,bl24c16a", "atmel,24c16";
>  		reg = <0x50>;
>  		pagesize = <16>;
> +		read-only;
>  		vcc-supply = <&vcc_3v3_pmu>;
>  	};
>  };



From naoki at radxa.com  Mon Nov 10 21:41:12 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Tue, 11 Nov 2025 05:41:12 +0000
Subject: [PATCH v2] arm64: dts: rockchip: Turn all LEDs on at boot for Radxa boards
Message-ID: <20251111054112.55505-1-naoki@radxa.com>

Radxa's boards turn all LEDs on at boot(loader), but some boards don't
have `default-state` property in Linux kernel tree but have it in
U-Boot tree instead[1].

This patch adds `default-state = "on"` for (almost) all LEDs (with a
few exceptions which should be "off" such as RGB LEDs on E25 and LAN/
WAN LEDs on E20C/E52C).

Also, remove following redundant properties:
 linux,default-trigger = "default-on"; // use default-state = "on"
 default-state = "off"; // default is "off"

[1]
 https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3328-rock-pi-e-base-u-boot.dtsi#L10-12
 https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3399-rock-4c-plus-u-boot.dtsi#L11-17
 https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3399-rock-pi-4-u-boot.dtsi#L11-13
 https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3566-radxa-cm3-io-u-boot.dtsi#L10-12
 https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3566-rock-3c-u-boot.dtsi#L14-16
 https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3568-radxa-e25-u-boot.dtsi#L7-24
 https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3568-rock-3a-u-boot.dtsi#L11-13
 https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3588-rock-5b-u-boot.dtsi#L11-13
 https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3588s-rock-5a-u-boot.dtsi#L10-12

Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
Changes in v2:
- Add more URLs for reference
- Reword commit message
---
 arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts    | 1 -
 arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts    | 1 +
 arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts | 3 ++-
 arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi   | 1 +
 arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts   | 2 --
 arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts      | 1 -
 arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts | 1 +
 arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts      | 1 +
 arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi  | 1 +
 arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts      | 1 +
 arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts      | 3 ++-
 arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts   | 2 --
 arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts   | 3 ++-
 arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi     | 1 +
 arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts      | 1 +
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts     | 3 ++-
 16 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
index 7a32972bc2496..c1e3098b9a7bc 100644
--- a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
@@ -35,7 +35,6 @@ green-led {
 			function = LED_FUNCTION_POWER;
 			gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
 			label = "rockpis:green:power";
-			linux,default-trigger = "default-on";
 		};
 
 		blue-led {
diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
index a4bdd87d0729f..d3d6f34b66fb0 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
@@ -59,6 +59,7 @@ leds {
 
 		led-0 {
 			color = <LED_COLOR_ID_BLUE>;
+			default-state = "on";
 			gpios = <&gpio3 RK_PA5 GPIO_ACTIVE_LOW>;
 			linux,default-trigger = "heartbeat";
 		};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts
index 962b8b231c960..a83ffbef22a7b 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts
@@ -39,14 +39,15 @@ leds {
 		led-0 {
 			function = LED_FUNCTION_POWER;
 			color = <LED_COLOR_ID_GREEN>;
+			default-state = "on";
 			gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_LOW>;
-			linux,default-trigger = "default-on";
 		};
 
 		/* USER_LED2 */
 		led-1 {
 			function = LED_FUNCTION_STATUS;
 			color = <LED_COLOR_ID_BLUE>;
+			default-state = "on";
 			gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "heartbeat";
 		};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
index 046dbe3290178..ef434c23fe85c 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
@@ -35,6 +35,7 @@ leds {
 		led-0 {
 			function = LED_FUNCTION_STATUS;
 			color = <LED_COLOR_ID_BLUE>;
+			default-state = "on";
 			gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "heartbeat";
 		};
diff --git a/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts b/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts
index b324527561558..79d316a1d8495 100644
--- a/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts
@@ -62,7 +62,6 @@ leds {
 
 		led-lan {
 			color = <LED_COLOR_ID_GREEN>;
-			default-state = "off";
 			function = LED_FUNCTION_LAN;
 			gpios = <&gpio4 RK_PB5 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "netdev";
@@ -78,7 +77,6 @@ led-sys {
 
 		led-wan {
 			color = <LED_COLOR_ID_GREEN>;
-			default-state = "off";
 			function = LED_FUNCTION_WAN;
 			gpios = <&gpio4 RK_PC0 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "netdev";
diff --git a/arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts b/arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts
index c03ae1dd34560..0b696d49b71fa 100644
--- a/arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts
@@ -45,7 +45,6 @@ led-1 {
 		default-state = "on";
 		function = LED_FUNCTION_STATUS;
 		gpios = <&gpio3 RK_PC1 GPIO_ACTIVE_LOW>;
-		linux,default-trigger = "default-on";
 	};
 };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts b/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
index b5b253f04cdf5..9e7212b70e3f1 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
@@ -46,6 +46,7 @@ leds {
 		led-1 {
 			gpios = <&gpio4 RK_PA4 GPIO_ACTIVE_LOW>;
 			color = <LED_COLOR_ID_GREEN>;
+			default-state = "on";
 			function = LED_FUNCTION_ACTIVITY;
 			linux,default-trigger = "heartbeat";
 			pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
index 6224d72813e59..3ec108bcf89a1 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
@@ -47,6 +47,7 @@ led-0 {
 			gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
 			function = LED_FUNCTION_HEARTBEAT;
 			color = <LED_COLOR_ID_BLUE>;
+			default-state = "on";
 			linux,default-trigger = "heartbeat";
 			pinctrl-names = "default";
 			pinctrl-0 = <&user_led2>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi b/arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi
index 729e38b9f620e..140582f8e1034 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi
@@ -23,6 +23,7 @@ led_user: led-0 {
 			gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
 			function = LED_FUNCTION_HEARTBEAT;
 			color = <LED_COLOR_ID_GREEN>;
+			default-state = "on";
 			linux,default-trigger = "heartbeat";
 			pinctrl-names = "default";
 			pinctrl-0 = <&led_user_en>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
index 44cfdfeed6681..e6c18df0fa582 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
@@ -47,6 +47,7 @@ led_user: led-0 {
 			gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
 			function = LED_FUNCTION_HEARTBEAT;
 			color = <LED_COLOR_ID_BLUE>;
+			default-state = "on";
 			linux,default-trigger = "heartbeat";
 			pinctrl-names = "default";
 			pinctrl-0 = <&led_user_en>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts b/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts
index 9bc33422ced50..99d3a8be8f18c 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts
@@ -52,13 +52,14 @@ leds: leds {
 
 		power-led {
 			color = <LED_COLOR_ID_GREEN>;
+			default-state = "on";
 			function = LED_FUNCTION_STATUS;
 			gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>;
-			linux,default-trigger = "default-on";
 		};
 
 		user-led {
 			color = <LED_COLOR_ID_BLUE>;
+			default-state = "on";
 			function = LED_FUNCTION_HEARTBEAT;
 			gpios = <&gpio0 RK_PC4 GPIO_ACTIVE_LOW>;
 			linux,default-trigger = "heartbeat";
diff --git a/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts b/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts
index 854c118418eb8..f737769d4a007 100644
--- a/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts
@@ -71,7 +71,6 @@ leds-1 {
 
 		led-1 {
 			color = <LED_COLOR_ID_GREEN>;
-			default-state = "off";
 			function = LED_FUNCTION_LAN;
 			linux,default-trigger = "netdev";
 			pwms = <&pwm14 0 1000000 PWM_POLARITY_INVERTED>;
@@ -80,7 +79,6 @@ led-1 {
 
 		led-2 {
 			color = <LED_COLOR_ID_GREEN>;
-			default-state = "off";
 			function = LED_FUNCTION_WAN;
 			linux,default-trigger = "netdev";
 			pwms = <&pwm11 0 1000000 PWM_POLARITY_INVERTED>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
index bc8140883de47..86477346c3f5a 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
@@ -88,11 +88,12 @@ gpio-leds {
 		pinctrl-0 = <&led_pins>;
 
 		power-led1 {
+			default-state = "on";
 			gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
-			linux,default-trigger = "default-on";
 		};
 
 		hdd-led2 {
+			default-state = "on";
 			gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "disk-activity";
 		};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi
index e5c474e4d02a6..8c4a4270f9f93 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi
@@ -30,6 +30,7 @@ leds {
 		led_rgb_b {
 			function = LED_FUNCTION_STATUS;
 			color = <LED_COLOR_ID_BLUE>;
+			default-state = "on";
 			gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "heartbeat";
 		};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts
index 0dd90c744380b..87e9d4b86dad4 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts
@@ -33,6 +33,7 @@ leds {
 		led_rgb_b {
 			function = LED_FUNCTION_STATUS;
 			color = <LED_COLOR_ID_BLUE>;
+			default-state = "on";
 			gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "heartbeat";
 		};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
index 19a08f7794e67..46c81e796b100 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
@@ -54,6 +54,7 @@ leds {
 
 		io-led {
 			color = <LED_COLOR_ID_BLUE>;
+			default-state = "on";
 			function = LED_FUNCTION_STATUS;
 			gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "heartbeat";
@@ -61,9 +62,9 @@ io-led {
 
 		power-led {
 			color = <LED_COLOR_ID_GREEN>;
+			default-state = "on";
 			function = LED_FUNCTION_POWER;
 			gpios = <&gpio3 RK_PC4 GPIO_ACTIVE_HIGH>;
-			linux,default-trigger = "default-on";
 		};
 	};
 
-- 
2.43.0



From dsimic at manjaro.org  Mon Nov 10 21:46:55 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Tue, 11 Nov 2025 06:46:55 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH 0/4] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= Fix eeprom description for Radxa ROCK 3C/5A/5C
In-Reply-To: <20251111050924.54880-1-naoki@radxa.com>
References: <20251111050924.54880-1-naoki@radxa.com>
Message-ID: <6355d076-9263-ad0d-6460-c51f03b0a45e@manjaro.org>

Hello Naoki,

On Tuesday, November 11, 2025 06:09 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> This patch series fixes incorrect or missing entries related to the
> eeprom on the Radxa ROCK 3C, 5A, and 5C.

In general, there's no need for the standard prefixes in the
subjects of cover letters.  Thus, in this case the subject
could be reworded like this:

  Fix and improve EEPROM chip descriptions for Radxa ROCK 3C, 5A and 5C

> FUKAUMI Naoki (4):
>   arm64: dts: rockchip: Move eeprom correct bus for Radxa ROCK 5A
>   arm64: dts: rockchip: Add eeprom vcc-supply for Radxa ROCK 5A
>   arm64: dts: rockchip: Add eeprom vcc-supply for Radxa ROCK 3C
>   arm64: dts: rockchip: Make eeprom read-only for Radxa ROCK 3C/5A/5C
> 
>  arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts  |  2 ++
>  arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 16 +++++++++-------
>  arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts |  1 +
>  3 files changed, 12 insertions(+), 7 deletions(-)
> 
> -- 
> 2.43.0
>



From dsimic at manjaro.org  Mon Nov 10 22:04:33 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Tue, 11 Nov 2025 07:04:33 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v2] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= Turn all LEDs on at boot for Radxa boards
In-Reply-To: <20251111054112.55505-1-naoki@radxa.com>
References: <20251111054112.55505-1-naoki@radxa.com>
Message-ID: <959ed84f-f1bc-4606-4272-dcd7d853e86a@manjaro.org>

Hello Naoki,

Thanks for the v2.  Please, see a couple of remarks below.

On Tuesday, November 11, 2025 06:41 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> Radxa's boards turn all LEDs on at boot(loader), but some boards don't

s/Radxa's/Radxa/ -- because those are boards made by Radxa, not some
boards belonging to Radxa;  if it were specifically about the board
designs, the possessive form would be fine, for example

> have `default-state` property in Linux kernel tree but have it in
> U-Boot tree instead[1].
> 
> This patch adds `default-state = "on"` for (almost) all LEDs (with a
> few exceptions which should be "off" such as RGB LEDs on E25 and LAN/
> WAN LEDs on E20C/E52C).
> 
> Also, remove following redundant properties:
>  linux,default-trigger = "default-on"; // use default-state = "on"
>  default-state = "off"; // default is "off"
> 
> [1]
>  https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3328-rock-pi-e-base-u-boot.dtsi#L10-12
>  https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3399-rock-4c-plus-u-boot.dtsi#L11-17
>  https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3399-rock-pi-4-u-boot.dtsi#L11-13
>  https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3566-radxa-cm3-io-u-boot.dtsi#L10-12
>  https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3566-rock-3c-u-boot.dtsi#L14-16
>  https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3568-radxa-e25-u-boot.dtsi#L7-24
>  https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3568-rock-3a-u-boot.dtsi#L11-13
>  https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3588-rock-5b-u-boot.dtsi#L11-13
>  https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3588s-rock-5a-u-boot.dtsi#L10-12

Hmm, this particularly complex reference presents us with a somewhat
interesting literary challenge. :)  There should be only one URL per
reference, so one way to resolve this would be to reword the opening
paragraph like this:

  Radxa boards are intended to turn all their LEDs on at boot time,
  as part of the intended visual feedback to the end users, but some
  boards don't have the associated "default-state" LED properties
  defined in the Linux kernel, yet they have them defined in U-Boot.
  This includes ROCK Pi E, [1] ROCK 4C+, [2] ROCK Pi 4, [3] CM3, [4]
  ROCK 3C, [5] E25, [6] ROCK 3A, [7] ROCK 5B, [8] and ROCK 5A. [9]

  [1] https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3328-rock-pi-e-base-u-boot.dtsi#L10-12
  [2] https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3399-rock-4c-plus-u-boot.dtsi#L11-17
  [3] https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3399-rock-pi-4-u-boot.dtsi#L11-13
  [4] https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3566-radxa-cm3-io-u-boot.dtsi#L10-12
  [5] https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3566-rock-3c-u-boot.dtsi#L14-16
  [6] https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3568-radxa-e25-u-boot.dtsi#L7-24
  [7] https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3568-rock-3a-u-boot.dtsi#L11-13
  [8] https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3588-rock-5b-u-boot.dtsi#L11-13
  [9] https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3588s-rock-5a-u-boot.dtsi#L10-12

Of course, it would also make sense to order the list of boards and
the associated references alphabetically, which would make the list
more readable and is left as an exercise. :)

> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> ---
> Changes in v2:
> - Add more URLs for reference
> - Reword commit message
> ---
>  arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts    | 1 -
>  arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts    | 1 +
>  arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts | 3 ++-
>  arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi   | 1 +
>  arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts   | 2 --
>  arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts      | 1 -
>  arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts | 1 +
>  arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts      | 1 +
>  arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi  | 1 +
>  arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts      | 1 +
>  arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts      | 3 ++-
>  arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts   | 2 --
>  arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts   | 3 ++-
>  arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi     | 1 +
>  arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts      | 1 +
>  arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts     | 3 ++-
>  16 files changed, 16 insertions(+), 10 deletions(-)



From shawn.lin at rock-chips.com  Mon Nov 10 23:04:33 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Tue, 11 Nov 2025 15:04:33 +0800
Subject: [PATCH] arm64: dts: rockchip: Remove sdmmc max-frequency on RK3588S EVB1 board
Message-ID: <1762844673-123776-1-git-send-email-shawn.lin@rock-chips.com>

sdmmc on RK3588S EVB1 could work fine under 200Mhz, no need to limit it
to 150Mhz.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
---

 arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts
index 0df3e80f2..f820505 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts
@@ -465,7 +465,6 @@
 	cap-sd-highspeed;
 	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
 	disable-wp;
-	max-frequency = <150000000>;
 	no-mmc;
 	no-sdio;
 	sd-uhs-sdr104;
-- 
2.7.4



From naoki at radxa.com  Mon Nov 10 23:17:27 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Tue, 11 Nov 2025 07:17:27 +0000
Subject: [PATCH v2 0/3] Fixes and improvements to sdmmc descriptions for Radxa ROCK 5 ITX/5B/5B+/5T/5A/5C
Message-ID: <20251111071730.126238-1-naoki@radxa.com>

This patch series fixes microSD card detection for ROCK 5 ITX/5C and
improves sdmmc properties for ROCK 5 ITX/5B/5B+/5T/5A/5C.

FUKAUMI Naoki (3):
  arm64: dts: rockchip: Fix microSD card detect for Radxa ROCK 5 ITX/5C
  arm64: dts: rockchip: Add sdmmc pinctrl for Radxa ROCK 5
    ITX/5B/5B+/5T/5C
  arm64: dts: rockchip: Remove sdmmc max-frequency for Radxa ROCK 5
    ITX/5B/5B+/5T

 arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts     | 10 ++++++++--
 .../arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi |  9 ++++++++-
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts       |  8 ++++++++
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts       |  9 +++++++++
 4 files changed, 33 insertions(+), 3 deletions(-)

-- 
2.43.0



From naoki at radxa.com  Mon Nov 10 23:17:28 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Tue, 11 Nov 2025 07:17:28 +0000
Subject: [PATCH v2 1/3] arm64: dts: rockchip: Fix microSD card detect for Radxa ROCK 5 ITX/5C
In-Reply-To: <20251111071730.126238-1-naoki@radxa.com>
References: <20251111071730.126238-1-naoki@radxa.com>
Message-ID: <20251111071730.126238-2-naoki@radxa.com>

Due to the discussion about cd-gpios and sdmmmc_det pin functionality
[1], it would be better to use cd-gpios for now.

[1] https://lore.kernel.org/linux-rockchip/20240912152538.1.I858c2a0bf83606c8b59ba1ab6944978a398d2ac5 at changeid/

Fixes: 31390eb8ffbf2 ("arm64: dts: rockchip: add ROCK 5 ITX board")
Fixes: 3ddf5cdb77e6 ("arm64: dts: rockchip: add Radxa ROCK 5C")
Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
Changes in v2:
- Split a patch into two; this patch adds only `cd-gpios`
- Add fix for ROCK 5C
---
 arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts | 1 +
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts   | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
index bc8140883de47..6597c251d93c4 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
@@ -795,6 +795,7 @@ &sdmmc {
 	bus-width = <4>;
 	cap-mmc-highspeed;
 	cap-sd-highspeed;
+	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
 	disable-wp;
 	max-frequency = <200000000>;
 	no-sdio;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
index dd7317bab6135..9ba4f19f98582 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
@@ -533,6 +533,7 @@ &sdmmc {
 	bus-width = <4>;
 	cap-mmc-highspeed;
 	cap-sd-highspeed;
+	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
 	disable-wp;
 	no-sdio;
 	no-mmc;
-- 
2.43.0



From naoki at radxa.com  Mon Nov 10 23:17:29 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Tue, 11 Nov 2025 07:17:29 +0000
Subject: [PATCH v2 2/3] arm64: dts: rockchip: Add sdmmc pinctrl for Radxa ROCK 5 ITX/5B/5B+/5T/5C
In-Reply-To: <20251111071730.126238-1-naoki@radxa.com>
References: <20251111071730.126238-1-naoki@radxa.com>
Message-ID: <20251111071730.126238-3-naoki@radxa.com>

Since GPIO0_A4 is used for cd-gpios in sdmmc, use newly introduced
sdmmc_det_pin instead of default sdmmc_det for pinctrl-0 to set up pin
mux function as GPIO.

Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
Changes in v2:
- Split a patch into two; this patch adds properties for pinctrl
- Add fix for ROCK 5B/5B+/5T/5A/5C
---
 arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts      | 8 +++++++-
 arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi | 8 ++++++++
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts        | 8 ++++++++
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts        | 8 ++++++++
 4 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
index 6597c251d93c4..4c218ae6677ec 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
@@ -670,6 +670,12 @@ led_pins: led-pins {
 		};
 	};
 
+	mmc {
+		sdmmc_det_pin: sdmmc-det-pin {
+			rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
 	pcie {
 		pcie20x1_2_perstn: pcie20x1-2-perstn {
 			rockchip,pins = <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
@@ -801,7 +807,7 @@ &sdmmc {
 	no-sdio;
 	no-mmc;
 	pinctrl-names = "default";
-	pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd &sdmmc_det>;
+	pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd &sdmmc_det_pin>;
 	sd-uhs-sdr104;
 	vmmc-supply = <&vcc_3v3_s3>;
 	vqmmc-supply = <&vccio_sd_s0>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi
index 7aac77dfc5f16..a35c9469a2574 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi
@@ -509,6 +509,12 @@ hym8563_int: hym8563-int {
 		};
 	};
 
+	mmc {
+		sdmmc_det_pin: sdmmc-det-pin {
+			rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
 	pcie2 {
 		pcie2_0_rst: pcie2-0-rst {
 			rockchip,pins = <4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
@@ -598,6 +604,8 @@ &sdmmc {
 	cap-sd-highspeed;
 	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
 	disable-wp;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd &sdmmc_det_pin>;
 	sd-uhs-sdr104;
 	vmmc-supply = <&vcc_3v3_s3>;
 	vqmmc-supply = <&vccio_sd_s0>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
index 19a08f7794e67..fa0dbb6b8ab7e 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
@@ -377,6 +377,12 @@ io_led: io-led {
 		};
 	};
 
+	mmc {
+		sdmmc_det_pin: sdmmc-det-pin {
+			rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
 	pcie {
 		pow_en: pow-en {
 			rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
@@ -436,6 +442,8 @@ &sdmmc {
 	max-frequency = <150000000>;
 	no-sdio;
 	no-mmc;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd &sdmmc_det_pin>;
 	sd-uhs-sdr104;
 	vmmc-supply = <&vcc_3v3_s0>;
 	vqmmc-supply = <&vccio_sd_s0>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
index 9ba4f19f98582..b837c4e08cec0 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
@@ -473,6 +473,12 @@ gmac1_rstn: gmac1-rstn {
 		};
 	};
 
+	mmc {
+		sdmmc_det_pin: sdmmc-det-pin {
+			rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
 	pcie {
 		pcie20x1_2_perstn_m0: pcie20x1-2-perstn-m0 {
 			rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
@@ -537,6 +543,8 @@ &sdmmc {
 	disable-wp;
 	no-sdio;
 	no-mmc;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd &sdmmc_det_pin>;
 	sd-uhs-sdr104;
 	vmmc-supply = <&vcc_3v3_s3>;
 	vqmmc-supply = <&vccio_sd_s0>;
-- 
2.43.0



From naoki at radxa.com  Mon Nov 10 23:17:30 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Tue, 11 Nov 2025 07:17:30 +0000
Subject: [PATCH v2 3/3] arm64: dts: rockchip: Remove sdmmc max-frequency for Radxa ROCK 5 ITX/5B/5B+/5T
In-Reply-To: <20251111071730.126238-1-naoki@radxa.com>
References: <20251111071730.126238-1-naoki@radxa.com>
Message-ID: <20251111071730.126238-4-naoki@radxa.com>

Default max-frequency for sdmmc is "200000000"[1]. Remove redundant
definition.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi?h=v6.17#n2013

Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
Changes in v2:
- New
---
 arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts      | 1 -
 arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi | 1 -
 2 files changed, 2 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
index 4c218ae6677ec..e9585cc84080e 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
@@ -803,7 +803,6 @@ &sdmmc {
 	cap-sd-highspeed;
 	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
 	disable-wp;
-	max-frequency = <200000000>;
 	no-sdio;
 	no-mmc;
 	pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi
index a35c9469a2574..b3e76ad2d8694 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi
@@ -596,7 +596,6 @@ &sdhci {
 };
 
 &sdmmc {
-	max-frequency = <200000000>;
 	no-sdio;
 	no-mmc;
 	bus-width = <4>;
-- 
2.43.0



From zhangqing at rock-chips.com  Tue Nov 11 00:05:11 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Tue, 11 Nov 2025 16:05:11 +0800
Subject: [RESEND PATCH v8 1/4] dt-bindings: can: rockchip_canfd: add rk3576 CAN controller
Message-ID: <20251111080511.2923069-1-zhangqing@rock-chips.com>

Add documentation for the rockchip rk3576 CAN controller.

Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
---
 .../net/can/rockchip,rk3568v2-canfd.yaml      | 52 +++++++++++++++++--
 1 file changed, 48 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml b/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml
index a077c0330013..30782218728e 100644
--- a/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml
+++ b/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml
@@ -10,13 +10,12 @@ title:
 maintainers:
   - Marc Kleine-Budde <mkl at pengutronix.de>
 
-allOf:
-  - $ref: can-controller.yaml#
-
 properties:
   compatible:
     oneOf:
-      - const: rockchip,rk3568v2-canfd
+      - enum:
+          - rockchip,rk3568v2-canfd
+          - rockchip,rk3576-can
       - items:
           - const: rockchip,rk3568v3-canfd
           - const: rockchip,rk3568v2-canfd
@@ -43,6 +42,33 @@ properties:
       - const: core
       - const: apb
 
+  dmas:
+    maxItems: 1
+
+  dma-names:
+    items:
+      - const: rx
+
+allOf:
+  - $ref: can-controller.yaml#
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: rockchip,rk3576-can
+    then:
+      properties:
+        dmas:
+          minItems: 1
+          maxItems: 1
+        dma-names:
+          minItems: 1
+          maxItems: 1
+    else:
+      properties:
+        dmas: false
+        dma-names: false
+
 required:
   - compatible
   - reg
@@ -72,3 +98,21 @@ examples:
             reset-names = "core", "apb";
         };
     };
+
+  - |
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        can at 2ac00000 {
+            compatible = "rockchip,rk3576-can";
+            reg = <0x0 0x2ac00000 0x0 0x1000>;
+            interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+            clocks = <&cru CLK_CAN0>, <&cru PCLK_CAN0>;
+            clock-names = "baud", "pclk";
+            resets = <&cru SRST_CAN0>, <&cru SRST_P_CAN0>;
+            reset-names = "core", "apb";
+            dmas = <&dmac0 20>;
+            dma-names = "rx";
+        };
+    };
-- 
2.34.1



From cristian.ciocaltea at collabora.com  Tue Nov 11 00:30:39 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 11 Nov 2025 10:30:39 +0200
Subject: [PATCH v4 00/11] Add HDMI 2.1 FRL support to
 phy-rockchip-samsung-hdptx
In-Reply-To: <20250902-phy-hdptx-frl-v4-0-7d69176373ce@collabora.com>
References: <20250902-phy-hdptx-frl-v4-0-7d69176373ce@collabora.com>
Message-ID: <2fb8b8cc-c393-4b2b-a501-667e7a8c4dd4@collabora.com>

Hi,

On 9/2/25 11:44 PM, Cristian Ciocaltea wrote:
> The Samsung HDMI/eDP Transmitter Combo PHY is capable of handling four
> HDMI 2.1 Fixed Rate Link (FRL) lanes, while each lane can operate at
> 3Gbps, 6Gbps, 8Gbps, 10Gbps or 12Gbps.
> 
> This patchset extends the HDMI PHY configuration API to manage the FRL
> mode and provides all the required HDMI driver changes to enable FRL in
> addition to the already supported TMDS mode.

Just a kind reminder if this fell through the cracks.

Thanks,
Cristian


From michael.riesch at collabora.com  Tue Nov 11 00:37:29 2025
From: michael.riesch at collabora.com (Michael Riesch)
Date: Tue, 11 Nov 2025 09:37:29 +0100
Subject: [PATCH v14 00/18] media: rockchip: add a driver for the rockchip
 camera interface
In-Reply-To: <20251111000627.GA30837@pendragon.ideasonboard.com>
References: <20240220-rk3568-vicap-v14-0-b38b6da0fc80@collabora.com>
 <aQ4tJg8r_j4NyKhv@kekkonen.localdomain>
 <074cd08e-0412-49f9-8dd9-b1f96eb11717@collabora.com>
 <20251107185441.GG5558@pendragon.ideasonboard.com>
 <13c43edb-9592-4779-a39a-7856bb0f964d@collabora.com>
 <aRGlvQRVoQs0WjyA@kekkonen.localdomain>
 <b89746e1-4574-4b65-af69-c533576ed185@collabora.com>
 <20251111000627.GA30837@pendragon.ideasonboard.com>
Message-ID: <7266245d-46b8-4355-a966-654e816ec93c@collabora.com>

Hi Laurent,

On 11/11/25 01:06, Laurent Pinchart wrote:
> On Mon, Nov 10, 2025 at 11:29:57AM +0100, Michael Riesch wrote:
>> On 11/10/25 09:43, Sakari Ailus wrote:
>>> On Fri, Nov 07, 2025 at 09:51:37PM +0100, Michael Riesch wrote:
>>>> On 11/7/25 19:54, Laurent Pinchart wrote:
>>>>> On Fri, Nov 07, 2025 at 07:41:59PM +0100, Michael Riesch wrote:
>>>>>> On 11/7/25 18:32, Sakari Ailus wrote:
>>>>>>> On Fri, Oct 24, 2025 at 02:51:29PM +0200, Michael Riesch via B4 Relay wrote:
>>>>>>>> Habidere,
>>>>>>>>
>>>>>>>> This series introduces support for the Rockchip Camera Interface (CIF),
>>>>>>>> which is featured in many Rockchip SoCs in different variations.
>>>>>>>> For example, the PX30 Video Input Processor (VIP) is able to receive
>>>>>>>> video data via the Digital Video Port (DVP, a parallel data interface)
>>>>>>>> and transfer it into system memory using a double-buffering mechanism
>>>>>>>> called ping-pong mode.
>>>>>>>> The RK3568 Video Capture (VICAP) unit, on the other hand, features a
>>>>>>>> DVP and a MIPI CSI-2 receiver that can receive video data independently
>>>>>>>> (both using the ping-pong scheme).
>>>>>>>> The different variants may have additional features, such as scaling
>>>>>>>> and/or cropping.
>>>>>>>> Finally, the RK3588 VICAP unit constitutes an essential piece of the
>>>>>>>> camera interface with one DVP, six MIPI CSI-2 receivers, scale/crop
>>>>>>>> units, and a data path multiplexer (to scaler units, to ISP, ...).
>>>>>>>
>>>>>>> I understand both RK3568 and RK3588 include an ISP. Do you have insight on
>>>>>>> how would this work, should the support for the ISP be added later on?
>>>>>>
>>>>>> Short answer: Yes and yes.
>>>>>>
>>>>>> Long answer:
>>>>>>
>>>>>> The patch series at hand adds support for the PX30 VIP and the RK3568
>>>>>> VICAP. I cannot really say something about the PX30, but on the RK3568
>>>>>> VICAP and ISP are orthogonal (the ISP features its own MIPI CSI-2
>>>>>> receiver, different from that introduced in this series). Thus, ISP
>>>>>> support can be introduced anytime (whenever someone is motivated ;-)).
>>>>>
>>>>> Won't they both be connected to the same sensor though, and probably the
>>>>> same D-PHY in the SoC ? They don't seem entirely separate to me.
>>>>
>>>> The MIPI CSI-2 DPHY is shared, indeed. Thus, they *maybe technically
>>>> could be* connected to the same sensor, but I don't know whether that
>>>> works and fail to see why anyone would to such a thing (if it is about
>>>> raw capture, the MIPI CSI-2 receiver in the ISP can do that on its own).
>>>>
>>>> The DPHY can be operated in split mode, with two lanes for VICAP and two
>>>> lanes for ISP. This is not implemented yet, but can be done at a later
>>>> stage on PHY level (not media related). In this case, ISP and VICAP can
>>>> receive data from different subdevices via CSI-2.
>>>
>>> The two would be part of the same media graph in that case and as there are
>>> two CSI-2 receivers and a single PHY, the PHY would probably need to have a
>>> sub-device as well, to allow link configuration to be used to select where
>>> the PHY is connected.
>>>
>>> I don't think we have such a setup elsewhere, and supporting this would
>>> require changes in the MC framework.
>>
>> What follows is a response that also addresses issues raised during our
>> off-list discussion.
>>
>> First of all, I agree with you that the RK3568 HW is "a bit special" (to
>> say the least) in that regard. Let's have an outlook to newer SoCs, such
>> as the RK3588: Here, the MIPI CSI-2 DPHYs (there are two of them) with
>> their split mode are present as well, but the assignment is fixed. For
>> example, the RK3588 VICAP has six MIPI CSI-2 receiver units and six MIPI
>> CSI-2 capture units. Units 1 and 2 handle a different MIPI PHY, units 3
>> and 5 handle the DPHYs (without split mode), units 4 and/or 6 are active
>> whenever DPHY 1 and/or 2 is in split mode.
>>
>> I would model this by adding support for more than one (logical) PHYs
>> (phy-cells = <1>;) and assigning the logical PHYs to the MIPI CSI-2
>> receivers. There is not really a possibility to route anything at this
>> point (routing is done in a MUX unit that takes the different MIPI CSI-2
>> receivers as inputs).
>>
>> Now back to the peculiar RK3568 situation: By default the split mode of
>> the DPHY is off and both VICAP and ISP are able to receive the same data
>> (from up to four lanes) with their MIPI CSI-2 receivers (not sure
>> whether both can be active at the same time, though).
> 
> A common use case for capturing data from the same sensor through both
> ISP and VICAP would be routing image data to the ISP and embedded data
> to VICAP. Assuming the hardware is able to do this, there will be users
> interested in this feature.

VICAP and ISP would capture different CSI-2 links. AFAIK the embedded
data is usually transmitted on the same CSI-2 link but on a different
virtual channel. The MIPI CSI receiver in the ISP is capable of
capturing (up to three, I think) virtual channels and passing e.g. one
VC to the ISP and capturing another VC to memory.

>> There are two bits
>> in the GRF that define the lanes that ISP and VICAP receive in split
>> mode (lane 0/1 or lane 2/3). Not sure whether these bits are supposed to
>> be changed during runtime.
>>
>> I would suggest modelling this on PHY level in DT, e.g., by passing
>> reasonable properties to the dphy node, such as
>>     rockchip,dphy-split-mode;
> 
> Split mode should indeed be conveyed through DT, as it's a property of
> the hardware.

Ack!

> 
>>     rockchip,dphy-split-invert;
>> where the former activates the split mode and assigns lanes 0/1 to the
>> ISP and lanes 2/3 to the VICAP, and the latter inverts this assignment
>> (lanes 2/3 to the ISP and lanes 0/1 to the VICAP). This would facilitate
>> the reasonable use cases with reasonable effort.
> 
> This I'm less convinced about. The routing should be dynamic.

Ack.

> How do you envision the connections to the CSI-2 sources to be modelled
> in DT ? We need ports and endpoints, and data-lanes properties. Where
> would those reside on the RK3568 side ?

Goto ASCII sketch below for that...

>> Otherwise, to keep it perfectly general and most flexible and
>> everything, we would have to introduce another subdevice indeed, which
>> would be active on the RK3568 exclusively. Therefore, I don't see that
>> the PHY driver introduces this subdevice, but a specialized (syscon?)
>> MUX driver that deals with the RK3568 GRF bits. Something like this
>>
>>                            |----------------------|     |-------------|
>>  Sensor A --- /2 lanes --- | lane 0/1      to ISP | --- | ISP MIPI RX |
>>                            |                      |     |-------------|
>>                            |                      |
>>                            |                      |     |-------------|
>>  Sensor B --- /2 lanes --- | lane 2/3    to VICAP | --- |VICAP MIPI RX|
>>                            |----------------------|     |-------------|
>>
>> But IMHO this will be too much effort for corner use case that I doubt
>> anyone will actually use.
>>
>> What do you think:
>>  - Let's keep the PHYs out of V4L2/MC, ok?
>>  - Let's model the reasonable use cases with device tree properties in
>>    the dphy DT node, ok?
> 
> I think the routing should be dynamic.

In this case, my suggestion would be the following:

 - An additional MUX subdevice on the RK3568 only, see sketch above
 - One or two input ports (depending on split mode being activated)
 - Two output ports (to ISP MIPI RX, to VICAP MIPI RX)
 - Routing possible 1:N (both input ports can be connected to one or two
   output ports)
 - The subdevice will have ports, endpoints, data-lanes properties on
   both sides.

The nice thing about it is that the current state can be extended once
split mode is implemented, IOW patches 01/18 - 17/18 can be readily applied.

Patch 18/18 must not be applied at this time, as this would be the first
actual usage of the MIPI CSI-2 pipeline. I guess we need to implement
and insert the new subdevice first for the sake of uAPI compatibility.

So pretty-please-with-sugar-on-top can we merge 01-17 so that I don't
have to drag these patches along anymore?

Best regards,
Michael

> 
>>> How does the media graph look like for the device at the moment?
>>
>> Please take a look at the media graph in the documentation patch (PATCH
>> v14 01/18). This is without the ISP, but gives an overview of what the
>> RK3568 VICAP is capable of.
>>
>> Best regards,
>> Michael
>>
>>>> BTW the ISP is able to process the data captured by VICAP, but
>>>> apparently this includes a RAM round trip (VICAP captures to memory, ISP
>>>> operates in mem2mem mode).
>>>>
>>>>> A block diagram that shows connections between the CSI-2 pins, D-PHY,
>>>>> CSI-2 receivers, VICAP and ISP could help.
>>>>>
>>>>>> Once this patch series is merged, I'll push out changes that introduce
>>>>>> support for the RK3588 VICAP. We can discuss the integration of any
>>>>>> RK3588 ISP in this scope then -- and there may be some things to discuss
>>>>>> as there the VICAP and the ISP(s) are directly connected by means of a
>>>>>> MUX unit in the VICAP.
>>>>>>
>>>>>> Alright?
> 



From krzk at kernel.org  Tue Nov 11 01:26:13 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 11 Nov 2025 10:26:13 +0100
Subject: [RESEND PATCH v8 1/4] dt-bindings: can: rockchip_canfd: add
 rk3576 CAN controller
In-Reply-To: <20251111080511.2923069-1-zhangqing@rock-chips.com>
References: <20251111080511.2923069-1-zhangqing@rock-chips.com>
Message-ID: <7d663aee-d77f-4553-a173-af9c2d75da50@kernel.org>

On 11/11/2025 09:05, Elaine Zhang wrote:
> Add documentation for the rockchip rk3576 CAN controller.
> 
> Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
> ---
>  .../net/can/rockchip,rk3568v2-canfd.yaml      | 52 +++++++++++++++++--
>  1 file changed, 48 insertions(+), 4 deletions(-)

Your threading is completely broken. I don't see any other patches here.

That's v8, resend and still not correct :(

> 
> diff --git a/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml b/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml
> index a077c0330013..30782218728e 100644
> --- a/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml
> +++ b/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml
> @@ -10,13 +10,12 @@ title:
>  maintainers:
>    - Marc Kleine-Budde <mkl at pengutronix.de>
>  
> -allOf:
> -  - $ref: can-controller.yaml#
> -
>  properties:
>    compatible:
>      oneOf:
> -      - const: rockchip,rk3568v2-canfd
> +      - enum:
> +          - rockchip,rk3568v2-canfd
> +          - rockchip,rk3576-can
>        - items:
>            - const: rockchip,rk3568v3-canfd
>            - const: rockchip,rk3568v2-canfd
> @@ -43,6 +42,33 @@ properties:
>        - const: core
>        - const: apb
>  
> +  dmas:
> +    maxItems: 1
> +
> +  dma-names:
> +    items:
> +      - const: rx
> +
> +allOf:
> +  - $ref: can-controller.yaml#
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: rockchip,rk3576-can
> +    then:
> +      properties:
> +        dmas:
> +          minItems: 1
> +          maxItems: 1
> +        dma-names:
> +          minItems: 1
> +          maxItems: 1

Drop both, no need to duplicate what is in top level.


> +    else:
> +      properties:
> +        dmas: false
> +        dma-names: false
> +
>  required:
>    - compatible
>    - reg
> @@ -72,3 +98,21 @@ examples:
>              reset-names = "core", "apb";
>          };
>      };
> +
> +  - |
> +    soc {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +
> +        can at 2ac00000 {

Difference in one property usually does not justify new example.


Best regards,
Krzysztof


From michael.riesch at collabora.com  Tue Nov 11 02:42:04 2025
From: michael.riesch at collabora.com (Michael Riesch)
Date: Tue, 11 Nov 2025 11:42:04 +0100
Subject: [PATCH v14 00/18] media: rockchip: add a driver for the rockchip
 camera interface
In-Reply-To: <7266245d-46b8-4355-a966-654e816ec93c@collabora.com>
References: <20240220-rk3568-vicap-v14-0-b38b6da0fc80@collabora.com>
 <aQ4tJg8r_j4NyKhv@kekkonen.localdomain>
 <074cd08e-0412-49f9-8dd9-b1f96eb11717@collabora.com>
 <20251107185441.GG5558@pendragon.ideasonboard.com>
 <13c43edb-9592-4779-a39a-7856bb0f964d@collabora.com>
 <aRGlvQRVoQs0WjyA@kekkonen.localdomain>
 <b89746e1-4574-4b65-af69-c533576ed185@collabora.com>
 <20251111000627.GA30837@pendragon.ideasonboard.com>
 <7266245d-46b8-4355-a966-654e816ec93c@collabora.com>
Message-ID: <ea541696-40db-409e-955f-983723d42b79@collabora.com>

Hi Laurent,

On 11/11/25 09:37, Michael Riesch wrote:
> Hi Laurent,
> 
> On 11/11/25 01:06, Laurent Pinchart wrote:
>> On Mon, Nov 10, 2025 at 11:29:57AM +0100, Michael Riesch wrote:
>>> On 11/10/25 09:43, Sakari Ailus wrote:
>>>> On Fri, Nov 07, 2025 at 09:51:37PM +0100, Michael Riesch wrote:
>>>>> On 11/7/25 19:54, Laurent Pinchart wrote:
>>>>>> On Fri, Nov 07, 2025 at 07:41:59PM +0100, Michael Riesch wrote:
>>>>>>> On 11/7/25 18:32, Sakari Ailus wrote:
>>>>>>>> On Fri, Oct 24, 2025 at 02:51:29PM +0200, Michael Riesch via B4 Relay wrote:
>>>>>>>>> Habidere,
>>>>>>>>>
>>>>>>>>> This series introduces support for the Rockchip Camera Interface (CIF),
>>>>>>>>> which is featured in many Rockchip SoCs in different variations.
>>>>>>>>> For example, the PX30 Video Input Processor (VIP) is able to receive
>>>>>>>>> video data via the Digital Video Port (DVP, a parallel data interface)
>>>>>>>>> and transfer it into system memory using a double-buffering mechanism
>>>>>>>>> called ping-pong mode.
>>>>>>>>> The RK3568 Video Capture (VICAP) unit, on the other hand, features a
>>>>>>>>> DVP and a MIPI CSI-2 receiver that can receive video data independently
>>>>>>>>> (both using the ping-pong scheme).
>>>>>>>>> The different variants may have additional features, such as scaling
>>>>>>>>> and/or cropping.
>>>>>>>>> Finally, the RK3588 VICAP unit constitutes an essential piece of the
>>>>>>>>> camera interface with one DVP, six MIPI CSI-2 receivers, scale/crop
>>>>>>>>> units, and a data path multiplexer (to scaler units, to ISP, ...).
>>>>>>>>
>>>>>>>> I understand both RK3568 and RK3588 include an ISP. Do you have insight on
>>>>>>>> how would this work, should the support for the ISP be added later on?
>>>>>>>
>>>>>>> Short answer: Yes and yes.
>>>>>>>
>>>>>>> Long answer:
>>>>>>>
>>>>>>> The patch series at hand adds support for the PX30 VIP and the RK3568
>>>>>>> VICAP. I cannot really say something about the PX30, but on the RK3568
>>>>>>> VICAP and ISP are orthogonal (the ISP features its own MIPI CSI-2
>>>>>>> receiver, different from that introduced in this series). Thus, ISP
>>>>>>> support can be introduced anytime (whenever someone is motivated ;-)).
>>>>>>
>>>>>> Won't they both be connected to the same sensor though, and probably the
>>>>>> same D-PHY in the SoC ? They don't seem entirely separate to me.
>>>>>
>>>>> The MIPI CSI-2 DPHY is shared, indeed. Thus, they *maybe technically
>>>>> could be* connected to the same sensor, but I don't know whether that
>>>>> works and fail to see why anyone would to such a thing (if it is about
>>>>> raw capture, the MIPI CSI-2 receiver in the ISP can do that on its own).
>>>>>
>>>>> The DPHY can be operated in split mode, with two lanes for VICAP and two
>>>>> lanes for ISP. This is not implemented yet, but can be done at a later
>>>>> stage on PHY level (not media related). In this case, ISP and VICAP can
>>>>> receive data from different subdevices via CSI-2.
>>>>
>>>> The two would be part of the same media graph in that case and as there are
>>>> two CSI-2 receivers and a single PHY, the PHY would probably need to have a
>>>> sub-device as well, to allow link configuration to be used to select where
>>>> the PHY is connected.
>>>>
>>>> I don't think we have such a setup elsewhere, and supporting this would
>>>> require changes in the MC framework.
>>>
>>> What follows is a response that also addresses issues raised during our
>>> off-list discussion.
>>>
>>> First of all, I agree with you that the RK3568 HW is "a bit special" (to
>>> say the least) in that regard. Let's have an outlook to newer SoCs, such
>>> as the RK3588: Here, the MIPI CSI-2 DPHYs (there are two of them) with
>>> their split mode are present as well, but the assignment is fixed. For
>>> example, the RK3588 VICAP has six MIPI CSI-2 receiver units and six MIPI
>>> CSI-2 capture units. Units 1 and 2 handle a different MIPI PHY, units 3
>>> and 5 handle the DPHYs (without split mode), units 4 and/or 6 are active
>>> whenever DPHY 1 and/or 2 is in split mode.
>>>
>>> I would model this by adding support for more than one (logical) PHYs
>>> (phy-cells = <1>;) and assigning the logical PHYs to the MIPI CSI-2
>>> receivers. There is not really a possibility to route anything at this
>>> point (routing is done in a MUX unit that takes the different MIPI CSI-2
>>> receivers as inputs).
>>>
>>> Now back to the peculiar RK3568 situation: By default the split mode of
>>> the DPHY is off and both VICAP and ISP are able to receive the same data
>>> (from up to four lanes) with their MIPI CSI-2 receivers (not sure
>>> whether both can be active at the same time, though).
>>
>> A common use case for capturing data from the same sensor through both
>> ISP and VICAP would be routing image data to the ISP and embedded data
>> to VICAP. Assuming the hardware is able to do this, there will be users
>> interested in this feature.
> 
> VICAP and ISP would capture different CSI-2 links. AFAIK the embedded
> data is usually transmitted on the same CSI-2 link but on a different
> virtual channel. The MIPI CSI receiver in the ISP is capable of
> capturing (up to three, I think) virtual channels and passing e.g. one
> VC to the ISP and capturing another VC to memory.
> 
>>> There are two bits
>>> in the GRF that define the lanes that ISP and VICAP receive in split
>>> mode (lane 0/1 or lane 2/3). Not sure whether these bits are supposed to
>>> be changed during runtime.
>>>
>>> I would suggest modelling this on PHY level in DT, e.g., by passing
>>> reasonable properties to the dphy node, such as
>>>     rockchip,dphy-split-mode;
>>
>> Split mode should indeed be conveyed through DT, as it's a property of
>> the hardware.
> 
> Ack!
> 
>>
>>>     rockchip,dphy-split-invert;
>>> where the former activates the split mode and assigns lanes 0/1 to the
>>> ISP and lanes 2/3 to the VICAP, and the latter inverts this assignment
>>> (lanes 2/3 to the ISP and lanes 0/1 to the VICAP). This would facilitate
>>> the reasonable use cases with reasonable effort.
>>
>> This I'm less convinced about. The routing should be dynamic.
> 
> Ack.
> 
>> How do you envision the connections to the CSI-2 sources to be modelled
>> in DT ? We need ports and endpoints, and data-lanes properties. Where
>> would those reside on the RK3568 side ?
> 
> Goto ASCII sketch below for that...
> 
>>> Otherwise, to keep it perfectly general and most flexible and
>>> everything, we would have to introduce another subdevice indeed, which
>>> would be active on the RK3568 exclusively. Therefore, I don't see that
>>> the PHY driver introduces this subdevice, but a specialized (syscon?)
>>> MUX driver that deals with the RK3568 GRF bits. Something like this
>>>
>>>                            |----------------------|     |-------------|
>>>  Sensor A --- /2 lanes --- | lane 0/1      to ISP | --- | ISP MIPI RX |
>>>                            |                      |     |-------------|
>>>                            |                      |
>>>                            |                      |     |-------------|
>>>  Sensor B --- /2 lanes --- | lane 2/3    to VICAP | --- |VICAP MIPI RX|
>>>                            |----------------------|     |-------------|
>>>
>>> But IMHO this will be too much effort for corner use case that I doubt
>>> anyone will actually use.
>>>
>>> What do you think:
>>>  - Let's keep the PHYs out of V4L2/MC, ok?
>>>  - Let's model the reasonable use cases with device tree properties in
>>>    the dphy DT node, ok?
>>
>> I think the routing should be dynamic.
> 
> In this case, my suggestion would be the following:
> 
>  - An additional MUX subdevice on the RK3568 only, see sketch above
>  - One or two input ports (depending on split mode being activated)
>  - Two output ports (to ISP MIPI RX, to VICAP MIPI RX)
>  - Routing possible 1:N (both input ports can be connected to one or two
>    output ports)
>  - The subdevice will have ports, endpoints, data-lanes properties on
>    both sides.
> 
> The nice thing about it is that the current state can be extended once
> split mode is implemented, IOW patches 01/18 - 17/18 can be readily applied.
> 
> Patch 18/18 must not be applied at this time, as this would be the first
> actual usage of the MIPI CSI-2 pipeline. I guess we need to implement
> and insert the new subdevice first for the sake of uAPI compatibility.
> 
> So pretty-please-with-sugar-on-top can we merge 01-17 so that I don't
> have to drag these patches along anymore?

In an off-list chat with Sakari we found that it would make sense to
leave patches 01 and 12 away as well, in order to avoid uAPI
compatibility issues for good. The MIPI CSI-2 receiver bindings and
driver can be merged, as the only difference in the new setup will be
that on the RK3568 the receiver is connected to the new MUX subdevice,
rather than to a sensor (as will be the case on e.g. the RK3588).

Can we agree on the following plan:
 1) You shall merge patches 02/18 - 11/18 + 13/18 - 17/18.
 2) I shall add the MUX subdev and send a revised version of patches 01,
    12, 18 along with it.
 3) We shall have a solid basis to implement split mode in the DPHY
    driver, RK3568 ISP support (if anyone has time for that), and RK3588
    VICAP support.

OK for everyone? @Laurent: can we get an Ack from you?

Best regards,
Michael

> 
> Best regards,
> Michael
> 
>>
>>>> How does the media graph look like for the device at the moment?
>>>
>>> Please take a look at the media graph in the documentation patch (PATCH
>>> v14 01/18). This is without the ISP, but gives an overview of what the
>>> RK3568 VICAP is capable of.
>>>
>>> Best regards,
>>> Michael
>>>
>>>>> BTW the ISP is able to process the data captured by VICAP, but
>>>>> apparently this includes a RAM round trip (VICAP captures to memory, ISP
>>>>> operates in mem2mem mode).
>>>>>
>>>>>> A block diagram that shows connections between the CSI-2 pins, D-PHY,
>>>>>> CSI-2 receivers, VICAP and ISP could help.
>>>>>>
>>>>>>> Once this patch series is merged, I'll push out changes that introduce
>>>>>>> support for the RK3588 VICAP. We can discuss the integration of any
>>>>>>> RK3588 ISP in this scope then -- and there may be some things to discuss
>>>>>>> as there the VICAP and the ISP(s) are directly connected by means of a
>>>>>>> MUX unit in the VICAP.
>>>>>>>
>>>>>>> Alright?
>>
> 



From cassel at kernel.org  Tue Nov 11 02:51:00 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Tue, 11 Nov 2025 11:51:00 +0100
Subject: [PATCH 0/6] PCI: dwc: Revert Link Up IRQ support
Message-ID: <20251111105100.869997-8-cassel@kernel.org>

Revert all patches related to pcie-designware Root Complex Link Up IRQ
support.

While this fake hotplugging was a nice idea, it has shown that this feature
does not handle PCIe switches correctly:
pci_bus 0004:43: busn_res: can not insert [bus 43-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci_bus 0004:43: busn_res: [bus 43-41] end is updated to 43
pci_bus 0004:43: busn_res: can not insert [bus 43] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci 0004:42:00.0: devices behind bridge are unusable because [bus 43] cannot be assigned for them
pci_bus 0004:44: busn_res: can not insert [bus 44-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci_bus 0004:44: busn_res: [bus 44-41] end is updated to 44
pci_bus 0004:44: busn_res: can not insert [bus 44] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci 0004:42:02.0: devices behind bridge are unusable because [bus 44] cannot be assigned for them
pci_bus 0004:45: busn_res: can not insert [bus 45-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci_bus 0004:45: busn_res: [bus 45-41] end is updated to 45
pci_bus 0004:45: busn_res: can not insert [bus 45] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci 0004:42:06.0: devices behind bridge are unusable because [bus 45] cannot be assigned for them
pci_bus 0004:46: busn_res: can not insert [bus 46-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci_bus 0004:46: busn_res: [bus 46-41] end is updated to 46
pci_bus 0004:46: busn_res: can not insert [bus 46] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci 0004:42:0e.0: devices behind bridge are unusable because [bus 46] cannot be assigned for them
pci_bus 0004:42: busn_res: [bus 42-41] end is updated to 46
pci_bus 0004:42: busn_res: can not insert [bus 42-46] under [bus 41] (conflicts with (null) [bus 41])
pci 0004:41:00.0: devices behind bridge are unusable because [bus 42-46] cannot be assigned for them
pcieport 0004:40:00.0: bridge has subordinate 41 but max busn 46

During the initial scan, PCI core doesn't see the switch and since the Root
Port is not hot plug capable, the secondary bus number gets assigned as the
subordinate bus number. This means, the PCI core assumes that only one bus
will appear behind the Root Port since the Root Port is not hot plug
capable.

This works perfectly fine for PCIe endpoints connected to the Root Port,
since they don't extend the bus. However, if a PCIe switch is connected,
then there is a problem when the downstream busses starts showing up and
the PCI core doesn't extend the subordinate bus number after initial scan
during boot.

The long term plan is to migrate this driver to the pwrctrl framework,
once it adds proper support for powering up and enumerating PCIe switches.

Niklas Cassel (6):
  Revert "PCI: dw-rockchip: Don't wait for link since we can detect Link
    Up"
  Revert "PCI: dw-rockchip: Enumerate endpoints based on dll_link_up
    IRQ"
  Revert "PCI: qcom: Don't wait for link if we can detect Link Up"
  Revert "PCI: qcom: Enable MSI interrupts together with Link up if
    'Global IRQ' is supported"
  Revert "PCI: qcom: Enumerate endpoints based on Link up event in
    'global_irq' interrupt"
  Revert "PCI: dwc: Don't wait for link up if driver can detect Link Up
    event"

 .../pci/controller/dwc/pcie-designware-host.c | 10 +--
 drivers/pci/controller/dwc/pcie-designware.h  |  1 -
 drivers/pci/controller/dwc/pcie-dw-rockchip.c | 60 +-----------------
 drivers/pci/controller/dwc/pcie-qcom.c        | 63 +------------------
 4 files changed, 6 insertions(+), 128 deletions(-)

-- 
2.51.1



From cassel at kernel.org  Tue Nov 11 02:51:01 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Tue, 11 Nov 2025 11:51:01 +0100
Subject: [PATCH 1/6] Revert "PCI: dw-rockchip: Don't wait for link since we can detect Link Up"
In-Reply-To: <20251111105100.869997-8-cassel@kernel.org>
References: <20251111105100.869997-8-cassel@kernel.org>
Message-ID: <20251111105100.869997-9-cassel@kernel.org>

This reverts commit ec9fd499b9c60a187ac8d6414c3c343c77d32e42.

While this fake hotplugging was a nice idea, it has shown that this feature
does not handle PCIe switches correctly:
pci_bus 0004:43: busn_res: can not insert [bus 43-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci_bus 0004:43: busn_res: [bus 43-41] end is updated to 43
pci_bus 0004:43: busn_res: can not insert [bus 43] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci 0004:42:00.0: devices behind bridge are unusable because [bus 43] cannot be assigned for them
pci_bus 0004:44: busn_res: can not insert [bus 44-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci_bus 0004:44: busn_res: [bus 44-41] end is updated to 44
pci_bus 0004:44: busn_res: can not insert [bus 44] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci 0004:42:02.0: devices behind bridge are unusable because [bus 44] cannot be assigned for them
pci_bus 0004:45: busn_res: can not insert [bus 45-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci_bus 0004:45: busn_res: [bus 45-41] end is updated to 45
pci_bus 0004:45: busn_res: can not insert [bus 45] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci 0004:42:06.0: devices behind bridge are unusable because [bus 45] cannot be assigned for them
pci_bus 0004:46: busn_res: can not insert [bus 46-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci_bus 0004:46: busn_res: [bus 46-41] end is updated to 46
pci_bus 0004:46: busn_res: can not insert [bus 46] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci 0004:42:0e.0: devices behind bridge are unusable because [bus 46] cannot be assigned for them
pci_bus 0004:42: busn_res: [bus 42-41] end is updated to 46
pci_bus 0004:42: busn_res: can not insert [bus 42-46] under [bus 41] (conflicts with (null) [bus 41])
pci 0004:41:00.0: devices behind bridge are unusable because [bus 42-46] cannot be assigned for them
pcieport 0004:40:00.0: bridge has subordinate 41 but max busn 46

During the initial scan, PCI core doesn't see the switch and since the Root
Port is not hot plug capable, the secondary bus number gets assigned as the
subordinate bus number. This means, the PCI core assumes that only one bus
will appear behind the Root Port since the Root Port is not hot plug
capable.

This works perfectly fine for PCIe endpoints connected to the Root Port,
since they don't extend the bus. However, if a PCIe switch is connected,
then there is a problem when the downstream busses starts showing up and
the PCI core doesn't extend the subordinate bus number after initial scan
during boot.

The long term plan is to migrate this driver to the pwrctrl framework,
once it adds proper support for powering up and enumerating PCIe switches.

Cc: stable at vger.kernel.org
Suggested-by: Manivannan Sadhasivam <mani at kernel.org>
Signed-off-by: Niklas Cassel <cassel at kernel.org>
---
 drivers/pci/controller/dwc/pcie-dw-rockchip.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
index 3e2752c7dd09..07378ececd88 100644
--- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
+++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
@@ -541,7 +541,6 @@ static int rockchip_pcie_configure_rc(struct platform_device *pdev,
 
 	pp = &rockchip->pci.pp;
 	pp->ops = &rockchip_pcie_host_ops;
-	pp->use_linkup_irq = true;
 
 	ret = dw_pcie_host_init(pp);
 	if (ret) {
-- 
2.51.1



From cassel at kernel.org  Tue Nov 11 02:51:02 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Tue, 11 Nov 2025 11:51:02 +0100
Subject: [PATCH 2/6] Revert "PCI: dw-rockchip: Enumerate endpoints based on dll_link_up IRQ"
In-Reply-To: <20251111105100.869997-8-cassel@kernel.org>
References: <20251111105100.869997-8-cassel@kernel.org>
Message-ID: <20251111105100.869997-10-cassel@kernel.org>

This reverts commit 0e0b45ab5d770a748487ba0ae8f77d1fb0f0de3e.

While this fake hotplugging was a nice idea, it has shown that this feature
does not handle PCIe switches correctly:
pci_bus 0004:43: busn_res: can not insert [bus 43-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci_bus 0004:43: busn_res: [bus 43-41] end is updated to 43
pci_bus 0004:43: busn_res: can not insert [bus 43] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci 0004:42:00.0: devices behind bridge are unusable because [bus 43] cannot be assigned for them
pci_bus 0004:44: busn_res: can not insert [bus 44-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci_bus 0004:44: busn_res: [bus 44-41] end is updated to 44
pci_bus 0004:44: busn_res: can not insert [bus 44] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci 0004:42:02.0: devices behind bridge are unusable because [bus 44] cannot be assigned for them
pci_bus 0004:45: busn_res: can not insert [bus 45-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci_bus 0004:45: busn_res: [bus 45-41] end is updated to 45
pci_bus 0004:45: busn_res: can not insert [bus 45] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci 0004:42:06.0: devices behind bridge are unusable because [bus 45] cannot be assigned for them
pci_bus 0004:46: busn_res: can not insert [bus 46-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci_bus 0004:46: busn_res: [bus 46-41] end is updated to 46
pci_bus 0004:46: busn_res: can not insert [bus 46] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci 0004:42:0e.0: devices behind bridge are unusable because [bus 46] cannot be assigned for them
pci_bus 0004:42: busn_res: [bus 42-41] end is updated to 46
pci_bus 0004:42: busn_res: can not insert [bus 42-46] under [bus 41] (conflicts with (null) [bus 41])
pci 0004:41:00.0: devices behind bridge are unusable because [bus 42-46] cannot be assigned for them
pcieport 0004:40:00.0: bridge has subordinate 41 but max busn 46

During the initial scan, PCI core doesn't see the switch and since the Root
Port is not hot plug capable, the secondary bus number gets assigned as the
subordinate bus number. This means, the PCI core assumes that only one bus
will appear behind the Root Port since the Root Port is not hot plug
capable.

This works perfectly fine for PCIe endpoints connected to the Root Port,
since they don't extend the bus. However, if a PCIe switch is connected,
then there is a problem when the downstream busses starts showing up and
the PCI core doesn't extend the subordinate bus number after initial scan
during boot.

The long term plan is to migrate this driver to the pwrctrl framework,
once it adds proper support for powering up and enumerating PCIe switches.

Cc: stable at vger.kernel.org
Suggested-by: Manivannan Sadhasivam <mani at kernel.org>
Signed-off-by: Niklas Cassel <cassel at kernel.org>
---
 drivers/pci/controller/dwc/pcie-dw-rockchip.c | 59 +------------------
 1 file changed, 3 insertions(+), 56 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
index 07378ececd88..7eceec8c9c83 100644
--- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
+++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
@@ -448,34 +448,6 @@ static const struct dw_pcie_ops dw_pcie_ops = {
 	.stop_link = rockchip_pcie_stop_link,
 };
 
-static irqreturn_t rockchip_pcie_rc_sys_irq_thread(int irq, void *arg)
-{
-	struct rockchip_pcie *rockchip = arg;
-	struct dw_pcie *pci = &rockchip->pci;
-	struct dw_pcie_rp *pp = &pci->pp;
-	struct device *dev = pci->dev;
-	u32 reg;
-
-	reg = rockchip_pcie_readl_apb(rockchip, PCIE_CLIENT_INTR_STATUS_MISC);
-	rockchip_pcie_writel_apb(rockchip, reg, PCIE_CLIENT_INTR_STATUS_MISC);
-
-	dev_dbg(dev, "PCIE_CLIENT_INTR_STATUS_MISC: %#x\n", reg);
-	dev_dbg(dev, "LTSSM_STATUS: %#x\n", rockchip_pcie_get_ltssm(rockchip));
-
-	if (reg & PCIE_RDLH_LINK_UP_CHGED) {
-		if (rockchip_pcie_link_up(pci)) {
-			msleep(PCIE_RESET_CONFIG_WAIT_MS);
-			dev_dbg(dev, "Received Link up event. Starting enumeration!\n");
-			/* Rescan the bus to enumerate endpoint devices */
-			pci_lock_rescan_remove();
-			pci_rescan_bus(pp->bridge->bus);
-			pci_unlock_rescan_remove();
-		}
-	}
-
-	return IRQ_HANDLED;
-}
-
 static irqreturn_t rockchip_pcie_ep_sys_irq_thread(int irq, void *arg)
 {
 	struct rockchip_pcie *rockchip = arg;
@@ -508,29 +480,14 @@ static irqreturn_t rockchip_pcie_ep_sys_irq_thread(int irq, void *arg)
 	return IRQ_HANDLED;
 }
 
-static int rockchip_pcie_configure_rc(struct platform_device *pdev,
-				      struct rockchip_pcie *rockchip)
+static int rockchip_pcie_configure_rc(struct rockchip_pcie *rockchip)
 {
-	struct device *dev = &pdev->dev;
 	struct dw_pcie_rp *pp;
-	int irq, ret;
 	u32 val;
 
 	if (!IS_ENABLED(CONFIG_PCIE_ROCKCHIP_DW_HOST))
 		return -ENODEV;
 
-	irq = platform_get_irq_byname(pdev, "sys");
-	if (irq < 0)
-		return irq;
-
-	ret = devm_request_threaded_irq(dev, irq, NULL,
-					rockchip_pcie_rc_sys_irq_thread,
-					IRQF_ONESHOT, "pcie-sys-rc", rockchip);
-	if (ret) {
-		dev_err(dev, "failed to request PCIe sys IRQ\n");
-		return ret;
-	}
-
 	/* LTSSM enable control mode */
 	val = FIELD_PREP_WM16(PCIE_LTSSM_ENABLE_ENHANCE, 1);
 	rockchip_pcie_writel_apb(rockchip, val, PCIE_CLIENT_HOT_RESET_CTRL);
@@ -542,17 +499,7 @@ static int rockchip_pcie_configure_rc(struct platform_device *pdev,
 	pp = &rockchip->pci.pp;
 	pp->ops = &rockchip_pcie_host_ops;
 
-	ret = dw_pcie_host_init(pp);
-	if (ret) {
-		dev_err(dev, "failed to initialize host\n");
-		return ret;
-	}
-
-	/* unmask DLL up/down indicator */
-	val = FIELD_PREP_WM16(PCIE_RDLH_LINK_UP_CHGED, 0);
-	rockchip_pcie_writel_apb(rockchip, val, PCIE_CLIENT_INTR_MASK_MISC);
-
-	return ret;
+	return dw_pcie_host_init(pp);
 }
 
 static int rockchip_pcie_configure_ep(struct platform_device *pdev,
@@ -678,7 +625,7 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
 
 	switch (data->mode) {
 	case DW_PCIE_RC_TYPE:
-		ret = rockchip_pcie_configure_rc(pdev, rockchip);
+		ret = rockchip_pcie_configure_rc(rockchip);
 		if (ret)
 			goto deinit_clk;
 		break;
-- 
2.51.1



From kernel at airkyi.com  Tue Nov 11 02:50:30 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Tue, 11 Nov 2025 18:50:30 +0800
Subject: [PATCH v9 00/10] Add Type-C DP support for RK3399 EVB IND board
Message-ID: <20251111105040.94-1-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

This series focuses on adding Type-C DP support for USBDP PHY and DP
driver. The USBDP PHY and DP will perceive the changes in cable status
based on the USB PD and Type-C state machines provided by TCPM. Before
this, the USBDP PHY and DP controller of RK3399 sensed cable state
changes through extcon, and devices such as the RK3399 Gru-Chromebook
rely on them. This series should not break them.

====
1. DisplayPort HPD status notify

Before v7, I implemented a variety of DP HPD status notify. However,
they all had various problems and it was difficult to become a generic
solution.

Under the guidance of Heikki and Dmitry, a decoupled notification
method between the TypeC and DRM subsystems was introduced in v7.
First, a notification is sent when TypeC registers a new altmode.
Then, a generic DP AUX HPD bridge is implemented on the DRM side.

That makes it redundant for each Type-C controller driver to implement
a similar DP AUX HPD bridge in embedded scenarios.

====
2. Altmode switching and orientation switching for USBDP PHY

For USB Type-C interfaces, an external Type-C controller chip assists
by detecting cable attachment, determining plug orientation, and
reporting USB PD message. The USB/DP combo PHY supports software
configurable pin mapping and DisplayPort lane assignment. Based on
these message, the combo PHY can perform both altmode switching and
orientation switching via software.

The RK3399 EVB IND board has a Type-C interface DisplayPort. It use
fusb302 chip as Type-C controller. The connection diagram is shown below:

fusb302 chip +---> USB2.0 PHY ----> DWC3 USB controller
             |
             +---> USB/DP PHY0 +--> CDN-DP controller
                               |
                               +--> DWC3 USB controller

====
3. Multiple bridge model for RK3399 CDN-DP

The RK3399 has two USB/DP combo PHY and one CDN-DP controller. And
the CDN-DP can be switched to output to one of the PHYs.

USB/DP PHY0 ---+
               | <----> CDN-DP controller
USB/DP PHY1 ---+

In previous versions, if both PHY ports were connected to DP,
the CDN-DP driver would select the first PHY port for output.

On Dmitry's suggestion, we introduced a multi-bridge model to support
flexible selection of the output PHY port. For each PHY port, a
separate encoder and bridge are registered.

The change is based on the DRM AUX HPD bridge, rather than the
extcon approach. This requires the DT to correctly describe the
connections between the first bridge in bridge chain and DP
controller. And Once the first bridge is obtained, we can get the
last bridge corresponding to the USB-C connector, and then set the
DRM connector's fwnode to the corresponding one to enable HPD
notification.

====
Patch1 add notifier functions for Type-C core.
Patch2 export all Type-C device types for identification.
Patch3 add generic USB Type-C DP HPD bridge.
Patch4 add new Type-C mode switch for RK3399 USBDP phy binding.
Patch5 add typec_mux and typec_switch for RK3399 USBDP PHY.
Patch6 add DRM AUX bridge support for RK3399 USBDP PHY.
Patch7 drops CDN-DP's extcon dependency when Type-C is present.
Patch8 add multiple bridges to support PHY port selection.
Patch9 add missing dp_out port for RK3399 CDN-DP.
Patch10 add Type-C DP support for RK3399 EVB IND board.

Changes in v9:
- Link to V8: https://lore.kernel.org/all/20251029071435.88-1-kernel at airkyi.com/
- Remove the exposed DRM_AUX_HPD_BRIDGE option, and select
DRM_AUX_HPD_TYPEC_BRIDGE when it is available.
- Add usb role switch for Type-C.
- Remove USB2 PHY in Type-C connection.
- ...

Changes in v8:
- Link to V7: https://lore.kernel.org/all/20251023033009.90-1-kernel at airkyi.com/
- Export all typec device types for identification.
- Merge generic DP HPD bridge into one module.
- Fix coding style.

Changes in v7:
- Link to V6: https://lore.kernel.org/all/20251016022741.91-1-kernel at airkyi.com/
- Add notifier functions for Type-C core.
- Add generic USB Type-C DP HPD bridge.

Changes in v6:
- Link to V5: https://lore.kernel.org/all/20251011033233.97-1-kernel at airkyi.com/
- Fix depend in Kconfig.
- Check DP svid in tcphy_typec_mux_set().
- Remove mode setting in tcphy_orien_sw_set().
- Rename some variable names.
- Attach the DP bridge to the next bridge.

Changes in v5:
- Link to V4: https://lore.kernel.org/all/20250922012039.323-1-kernel at airkyi.com/
- Remove the calls related to `drm_aux_hpd_bridge_notify()`.
- Place the helper functions in the same compilation unit.
- Add more comments about parent device.
- Add DRM AUX bridge support for RK3399 USBDP PHY
- By parsing the HPD bridge chain, set the connector's of_node to the
of_node corresponding to the USB-C connector.
- Return EDID cache when other port is already enabled.

Changes in v4:
- Link to V3: https://lore.kernel.org/all/20250729090032.97-1-kernel at airkyi.com/
- Add default HPD device for DisplayPort altmode.
- Introduce multiple bridges for CDN-DP.
- ...

Changes in v3:
- Link to V2: https://lore.kernel.org/all/20250718062619.99-1-kernel at airkyi.com/
- Add more descriptions to clarify the role of the PHY in switching.
- Fix wrong vdo value.
- Fix port node in usb-c-connector.

Changes in v2:
- Link to V1: https://lore.kernel.org/all/20250715112456.101-1-kernel at airkyi.com/
- Reuse dp-port/usb3-port in rk3399-typec-phy binding.
- Fix compile error when CONFIG_TYPEC is not enabled.
- Notify DP HPD state by USB/DP PHY.
- Ignore duplicate HPD events.
- Add endpoint to link DP PHY and DP controller.
- Fix devicetree coding style.

Chaoyi Chen (10):
  usb: typec: Add notifier functions
  usb: typec: Export all typec device types
  drm/bridge: Implement generic USB Type-C DP HPD bridge
  dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode-switch
  phy: rockchip: phy-rockchip-typec: Add typec_mux/typec_switch support
  phy: rockchip: phy-rockchip-typec: Add DRM AUX bridge
  drm/rockchip: cdn-dp: Support handle lane info without extcon
  drm/rockchip: cdn-dp: Add multiple bridges to support PHY port
    selection
  arm64: dts: rockchip: Add missing dp_out port for RK3399 CDN-DP
  arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort

 .../phy/rockchip,rk3399-typec-phy.yaml        |   6 +
 arch/arm64/boot/dts/rockchip/rk3399-base.dtsi |  10 +-
 .../boot/dts/rockchip/rk3399-evb-ind.dts      | 147 ++++++
 drivers/gpu/drm/bridge/Kconfig                |  10 +
 drivers/gpu/drm/bridge/Makefile               |   1 +
 .../gpu/drm/bridge/aux-hpd-typec-dp-bridge.c  |  50 +++
 drivers/gpu/drm/rockchip/Kconfig              |   1 +
 drivers/gpu/drm/rockchip/cdn-dp-core.c        | 354 ++++++++++++---
 drivers/gpu/drm/rockchip/cdn-dp-core.h        |  24 +-
 drivers/phy/rockchip/Kconfig                  |   3 +
 drivers/phy/rockchip/phy-rockchip-typec.c     | 420 +++++++++++++++++-
 drivers/usb/typec/Makefile                    |   2 +-
 drivers/usb/typec/bus.h                       |   2 +
 drivers/usb/typec/class.c                     |   6 +
 drivers/usb/typec/class.h                     |  10 -
 drivers/usb/typec/notify.c                    |  23 +
 include/linux/usb/typec.h                     |  10 +
 include/linux/usb/typec_altmode.h             |   9 +
 18 files changed, 995 insertions(+), 93 deletions(-)
 create mode 100644 drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
 create mode 100644 drivers/usb/typec/notify.c

-- 
2.51.1



From kernel at airkyi.com  Tue Nov 11 02:50:31 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Tue, 11 Nov 2025 18:50:31 +0800
Subject: [PATCH v9 01/10] usb: typec: Add notifier functions
In-Reply-To: <20251111105040.94-1-kernel@airkyi.com>
References: <20251111105040.94-1-kernel@airkyi.com>
Message-ID: <20251111105040.94-2-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

Some other part of kernel may want to know the event of typec bus.

This patch add common notifier function to notify these event.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---

Changes in v9:
- Remove redundant header files.

Changes in v8:
- Fix coding style.

 drivers/usb/typec/Makefile        |  2 +-
 drivers/usb/typec/bus.h           |  2 ++
 drivers/usb/typec/class.c         |  2 ++
 drivers/usb/typec/notify.c        | 23 +++++++++++++++++++++++
 include/linux/usb/typec_altmode.h |  9 +++++++++
 5 files changed, 37 insertions(+), 1 deletion(-)
 create mode 100644 drivers/usb/typec/notify.c

diff --git a/drivers/usb/typec/Makefile b/drivers/usb/typec/Makefile
index 7a368fea61bc..20d09c5314d7 100644
--- a/drivers/usb/typec/Makefile
+++ b/drivers/usb/typec/Makefile
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_TYPEC)		+= typec.o
-typec-y				:= class.o mux.o bus.o pd.o retimer.o
+typec-y				:= class.o mux.o notify.o bus.o pd.o retimer.o
 typec-$(CONFIG_ACPI)		+= port-mapper.o
 obj-$(CONFIG_TYPEC)		+= altmodes/
 obj-$(CONFIG_TYPEC_TCPM)	+= tcpm/
diff --git a/drivers/usb/typec/bus.h b/drivers/usb/typec/bus.h
index 643b8c81786d..820b59b6d434 100644
--- a/drivers/usb/typec/bus.h
+++ b/drivers/usb/typec/bus.h
@@ -26,6 +26,8 @@ struct altmode {
 	struct altmode			*plug[2];
 };
 
+void typec_notify_event(unsigned long event, void *data);
+
 #define to_altmode(d) container_of(d, struct altmode, adev)
 
 extern const struct bus_type typec_bus;
diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
index 9b2647cb199b..9d2aa3dd3f56 100644
--- a/drivers/usb/typec/class.c
+++ b/drivers/usb/typec/class.c
@@ -600,6 +600,8 @@ typec_register_altmode(struct device *parent,
 		return ERR_PTR(ret);
 	}
 
+	typec_notify_event(TYPEC_ALTMODE_REGISTERED, &alt->adev);
+
 	return &alt->adev;
 }
 
diff --git a/drivers/usb/typec/notify.c b/drivers/usb/typec/notify.c
new file mode 100644
index 000000000000..9e50b54da359
--- /dev/null
+++ b/drivers/usb/typec/notify.c
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/notifier.h>
+
+#include "bus.h"
+
+static BLOCKING_NOTIFIER_HEAD(typec_notifier_list);
+
+int typec_altmode_register_notify(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_register(&typec_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(typec_altmode_register_notify);
+
+int typec_altmode_unregister_notify(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_unregister(&typec_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(typec_altmode_unregister_notify);
+
+void typec_notify_event(unsigned long event, void *data)
+{
+	blocking_notifier_call_chain(&typec_notifier_list, event, data);
+}
diff --git a/include/linux/usb/typec_altmode.h b/include/linux/usb/typec_altmode.h
index f7db3bd4c90e..59e20702504b 100644
--- a/include/linux/usb/typec_altmode.h
+++ b/include/linux/usb/typec_altmode.h
@@ -10,6 +10,7 @@
 #define MODE_DISCOVERY_MAX	6
 
 struct typec_altmode_ops;
+struct notifier_block;
 
 /**
  * struct typec_altmode - USB Type-C alternate mode device
@@ -77,6 +78,14 @@ int typec_altmode_notify(struct typec_altmode *altmode, unsigned long conf,
 const struct typec_altmode *
 typec_altmode_get_partner(struct typec_altmode *altmode);
 
+enum usb_typec_event {
+	TYPEC_ALTMODE_REGISTERED,
+	TYPEC_ALTMODE_UNREGISTERED,
+};
+
+int typec_altmode_register_notify(struct notifier_block *nb);
+int typec_altmode_unregister_notify(struct notifier_block *nb);
+
 /**
  * struct typec_cable_ops - Cable alternate mode operations vector
  * @enter: Operations to be executed with Enter Mode Command
-- 
2.51.1



From kernel at airkyi.com  Tue Nov 11 02:50:32 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Tue, 11 Nov 2025 18:50:32 +0800
Subject: [PATCH v9 02/10] usb: typec: Export all typec device types
In-Reply-To: <20251111105040.94-1-kernel@airkyi.com>
References: <20251111105040.94-1-kernel@airkyi.com>
Message-ID: <20251111105040.94-3-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

Export all typec device types for identification.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
Reviewed-by: Heikki Krogerus <heikki.krogerus at linux.intel.com>
---

(no changes since v9)

 drivers/usb/typec/class.c |  4 ++++
 drivers/usb/typec/class.h | 10 ----------
 include/linux/usb/typec.h | 10 ++++++++++
 3 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
index 9d2aa3dd3f56..449f921acd9c 100644
--- a/drivers/usb/typec/class.c
+++ b/drivers/usb/typec/class.c
@@ -792,6 +792,7 @@ const struct device_type typec_partner_dev_type = {
 	.groups = typec_partner_groups,
 	.release = typec_partner_release,
 };
+EXPORT_SYMBOL_GPL(typec_partner_dev_type);
 
 static void typec_partner_link_device(struct typec_partner *partner, struct device *dev)
 {
@@ -1146,6 +1147,7 @@ const struct device_type typec_plug_dev_type = {
 	.groups = typec_plug_groups,
 	.release = typec_plug_release,
 };
+EXPORT_SYMBOL_GPL(typec_plug_dev_type);
 
 /**
  * typec_plug_set_num_altmodes - Set the number of available plug altmodes
@@ -1294,6 +1296,7 @@ const struct device_type typec_cable_dev_type = {
 	.groups = typec_cable_groups,
 	.release = typec_cable_release,
 };
+EXPORT_SYMBOL_GPL(typec_cable_dev_type);
 
 /**
  * typec_cable_get - Get a reference to the USB Type-C cable
@@ -2033,6 +2036,7 @@ const struct device_type typec_port_dev_type = {
 	.uevent = typec_uevent,
 	.release = typec_release,
 };
+EXPORT_SYMBOL_GPL(typec_port_dev_type);
 
 /* --------------------------------------- */
 /* Driver callbacks to report role updates */
diff --git a/drivers/usb/typec/class.h b/drivers/usb/typec/class.h
index db2fe96c48ff..f04f6987bed8 100644
--- a/drivers/usb/typec/class.h
+++ b/drivers/usb/typec/class.h
@@ -87,16 +87,6 @@ struct typec_port {
 #define to_typec_cable(_dev_) container_of(_dev_, struct typec_cable, dev)
 #define to_typec_partner(_dev_) container_of(_dev_, struct typec_partner, dev)
 
-extern const struct device_type typec_partner_dev_type;
-extern const struct device_type typec_cable_dev_type;
-extern const struct device_type typec_plug_dev_type;
-extern const struct device_type typec_port_dev_type;
-
-#define is_typec_partner(dev) ((dev)->type == &typec_partner_dev_type)
-#define is_typec_cable(dev) ((dev)->type == &typec_cable_dev_type)
-#define is_typec_plug(dev) ((dev)->type == &typec_plug_dev_type)
-#define is_typec_port(dev) ((dev)->type == &typec_port_dev_type)
-
 extern const struct class typec_mux_class;
 extern const struct class retimer_class;
 extern const struct class typec_class;
diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h
index 309251572e2e..02fed8293415 100644
--- a/include/linux/usb/typec.h
+++ b/include/linux/usb/typec.h
@@ -56,6 +56,16 @@ enum typec_role {
 	TYPEC_SOURCE,
 };
 
+extern const struct device_type typec_partner_dev_type;
+extern const struct device_type typec_cable_dev_type;
+extern const struct device_type typec_plug_dev_type;
+extern const struct device_type typec_port_dev_type;
+
+#define is_typec_partner(dev) ((dev)->type == &typec_partner_dev_type)
+#define is_typec_cable(dev) ((dev)->type == &typec_cable_dev_type)
+#define is_typec_plug(dev) ((dev)->type == &typec_plug_dev_type)
+#define is_typec_port(dev) ((dev)->type == &typec_port_dev_type)
+
 static inline int is_sink(enum typec_role role)
 {
 	return role == TYPEC_SINK;
-- 
2.51.1



From kernel at airkyi.com  Tue Nov 11 02:50:33 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Tue, 11 Nov 2025 18:50:33 +0800
Subject: [PATCH v9 03/10] drm/bridge: Implement generic USB Type-C DP HPD bridge
In-Reply-To: <20251111105040.94-1-kernel@airkyi.com>
References: <20251111105040.94-1-kernel@airkyi.com>
Message-ID: <20251111105040.94-4-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

The HPD function of Type-C DP is implemented through
drm_connector_oob_hotplug_event(). For embedded DP, it is required
that the DRM connector fwnode corresponds to the Type-C port fwnode.

To describe the relationship between the DP controller and the Type-C
port device, we usually using drm_bridge to build a bridge chain.

Now several USB-C controller drivers have already implemented the DP
HPD bridge function provided by aux-hpd-bridge.c, it will build a DP
HPD bridge on USB-C connector port device.

But this requires the USB-C controller driver to manually register the
HPD bridge. If the driver does not implement this feature, the bridge
will not be create.

So this patch implements a generic DP HPD bridge based on
aux-hpd-bridge.c. It will monitor Type-C bus events, and when a
Type-C port device containing the DP svid is registered, it will
create an HPD bridge for it without the need for the USB-C controller
driver to implement it.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---

Changes in v9:
- Remove the exposed DRM_AUX_HPD_BRIDGE option, and select
DRM_AUX_HPD_TYPEC_BRIDGE when it is available.
- Add more commit comment about problem background.

Changes in v8:
- Merge generic DP HPD bridge into one module.

 drivers/gpu/drm/bridge/Kconfig                | 10 ++++
 drivers/gpu/drm/bridge/Makefile               |  1 +
 .../gpu/drm/bridge/aux-hpd-typec-dp-bridge.c  | 50 +++++++++++++++++++
 3 files changed, 61 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index a250afd8d662..559487aa09a9 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -30,6 +30,16 @@ config DRM_AUX_HPD_BRIDGE
 	  Simple bridge that terminates the bridge chain and provides HPD
 	  support.
 
+if DRM_AUX_HPD_BRIDGE
+config DRM_AUX_HPD_TYPEC_BRIDGE
+	tristate
+	depends on TYPEC || !TYPEC
+	default TYPEC
+	help
+	  Simple bridge that terminates the bridge chain and provides HPD
+	  support. It build bridge on each USB-C connector device node.
+endif
+
 menu "Display Interface Bridges"
 	depends on DRM && DRM_BRIDGE
 
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index c7dc03182e59..a3a0393d2e72 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_DRM_AUX_BRIDGE) += aux-bridge.o
 obj-$(CONFIG_DRM_AUX_HPD_BRIDGE) += aux-hpd-bridge.o
+obj-$(CONFIG_DRM_AUX_HPD_TYPEC_BRIDGE) += aux-hpd-typec-dp-bridge.o
 obj-$(CONFIG_DRM_CHIPONE_ICN6211) += chipone-icn6211.o
 obj-$(CONFIG_DRM_CHRONTEL_CH7033) += chrontel-ch7033.o
 obj-$(CONFIG_DRM_CROS_EC_ANX7688) += cros-ec-anx7688.o
diff --git a/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c b/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
new file mode 100644
index 000000000000..9cb6a0cb0f0a
--- /dev/null
+++ b/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0+
+#include <linux/of.h>
+#include <linux/usb/typec_altmode.h>
+#include <linux/usb/typec_dp.h>
+
+#include <drm/bridge/aux-bridge.h>
+
+static int drm_typec_bus_event(struct notifier_block *nb,
+			       unsigned long action, void *data)
+{
+	struct typec_altmode *alt = (struct typec_altmode *)data;
+
+	if (action != TYPEC_ALTMODE_REGISTERED)
+		goto done;
+
+	if (is_typec_partner(&alt->dev) || alt->svid != USB_TYPEC_DP_SID)
+		goto done;
+
+	/*
+	 * alt->dev.parent->parent : USB-C controller device
+	 * alt->dev.parent         : USB-C connector device
+	 */
+	drm_dp_hpd_bridge_register(alt->dev.parent->parent,
+				   to_of_node(alt->dev.parent->fwnode));
+
+done:
+	return NOTIFY_OK;
+}
+
+static struct notifier_block drm_typec_event_nb = {
+	.notifier_call = drm_typec_bus_event,
+};
+
+static void drm_aux_hpd_typec_dp_bridge_module_exit(void)
+{
+	typec_altmode_unregister_notify(&drm_typec_event_nb);
+}
+
+static int __init drm_aux_hpd_typec_dp_bridge_module_init(void)
+{
+	typec_altmode_register_notify(&drm_typec_event_nb);
+
+	return 0;
+}
+
+module_init(drm_aux_hpd_typec_dp_bridge_module_init);
+module_exit(drm_aux_hpd_typec_dp_bridge_module_exit);
+
+MODULE_DESCRIPTION("DRM TYPEC DP HPD BRIDGE");
+MODULE_LICENSE("GPL");
-- 
2.51.1



From kernel at airkyi.com  Tue Nov 11 02:50:35 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Tue, 11 Nov 2025 18:50:35 +0800
Subject: [PATCH v9 05/10] phy: rockchip: phy-rockchip-typec: Add typec_mux/typec_switch support
In-Reply-To: <20251111105040.94-1-kernel@airkyi.com>
References: <20251111105040.94-1-kernel@airkyi.com>
Message-ID: <20251111105040.94-6-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

This patch add support for Type-C Port Controller Manager. Each PHY
will register typec_mux and typec_switch when external Type-C
controller is present. Type-C events are handled by TCPM without
extcon.

The extcon device should still be supported.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---

(no changes since v7)

Changes in v6:
- Fix depend in Kconfig.
- Check DP svid in tcphy_typec_mux_set().
- Remove mode setting in tcphy_orien_sw_set().

(no changes since v5)

Changes in v4:
- Remove notify DP HPD state by USB/DP PHY.

(no changes since v3)

Changes in v2:
- Fix compile error when CONFIG_TYPEC is not enabled.
- Notify DP HPD state by USB/DP PHY.

 drivers/phy/rockchip/Kconfig              |   1 +
 drivers/phy/rockchip/phy-rockchip-typec.c | 368 +++++++++++++++++++++-
 2 files changed, 353 insertions(+), 16 deletions(-)

diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
index 14698571b607..db4adc7c53da 100644
--- a/drivers/phy/rockchip/Kconfig
+++ b/drivers/phy/rockchip/Kconfig
@@ -119,6 +119,7 @@ config PHY_ROCKCHIP_SNPS_PCIE3
 config PHY_ROCKCHIP_TYPEC
 	tristate "Rockchip TYPEC PHY Driver"
 	depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST)
+	depends on TYPEC || TYPEC=n
 	select EXTCON
 	select GENERIC_PHY
 	select RESET_CONTROLLER
diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c
index d9701b6106d5..1f5b4142cbe4 100644
--- a/drivers/phy/rockchip/phy-rockchip-typec.c
+++ b/drivers/phy/rockchip/phy-rockchip-typec.c
@@ -54,6 +54,8 @@
 
 #include <linux/mfd/syscon.h>
 #include <linux/phy/phy.h>
+#include <linux/usb/typec_dp.h>
+#include <linux/usb/typec_mux.h>
 
 #define CMN_SSM_BANDGAP			(0x21 << 2)
 #define CMN_SSM_BIAS			(0x22 << 2)
@@ -286,12 +288,23 @@
 #define RX_DIAG_SC2C_DELAY		(0x81e1 << 2)
 
 #define PMA_LANE_CFG			(0xc000 << 2)
+#define PMA_LANE3_DP_LANE_SEL(x)	(((x) & 0x3) << 14)
+#define PMA_LANE3_INTERFACE_SEL(x)	(((x) & 0x1) << 12)
+#define PMA_LANE2_DP_LANE_SEL(x)	(((x) & 0x3) << 10)
+#define PMA_LANE2_INTERFACE_SEL(x)	(((x) & 0x1) << 8)
+#define PMA_LANE1_DP_LANE_SEL(x)	(((x) & 0x3) << 6)
+#define PMA_LANE1_INTERFACE_SEL(x)	(((x) & 0x1) << 4)
+#define PMA_LANE0_DP_LANE_SEL(x)	(((x) & 0x3) << 2)
+#define PMA_LANE0_INTERFACE_SEL(x)	(((x) & 0x1) << 0)
 #define PIPE_CMN_CTRL1			(0xc001 << 2)
 #define PIPE_CMN_CTRL2			(0xc002 << 2)
 #define PIPE_COM_LOCK_CFG1		(0xc003 << 2)
 #define PIPE_COM_LOCK_CFG2		(0xc004 << 2)
 #define PIPE_RCV_DET_INH		(0xc005 << 2)
 #define DP_MODE_CTL			(0xc008 << 2)
+#define PHY_DP_POWER_STATE_ACK_MASK	GENMASK(7, 4)
+#define PHY_DP_POWER_STATE_ACK_SHIFT	4
+#define PHY_DP_POWER_STATE_MASK		GENMASK(3, 0)
 #define DP_CLK_CTL			(0xc009 << 2)
 #define STS				(0xc00F << 2)
 #define PHY_ISO_CMN_CTRL		(0xc010 << 2)
@@ -327,8 +340,15 @@
 
 #define DP_MODE_A0			BIT(4)
 #define DP_MODE_A2			BIT(6)
-#define DP_MODE_ENTER_A0		0xc101
-#define DP_MODE_ENTER_A2		0xc104
+
+#define DP_MODE_MASK			0xf
+#define DP_MODE_ENTER_A0		BIT(0)
+#define DP_MODE_ENTER_A2		BIT(2)
+#define DP_MODE_ENTER_A3		BIT(3)
+#define DP_MODE_A0_ACK			BIT(4)
+#define DP_MODE_A2_ACK			BIT(6)
+#define DP_MODE_A3_ACK			BIT(7)
+#define DP_LINK_RESET_DEASSERTED	BIT(8)
 
 #define PHY_MODE_SET_TIMEOUT		100000
 
@@ -340,6 +360,31 @@
 #define MODE_DFP_USB			BIT(1)
 #define MODE_DFP_DP			BIT(2)
 
+enum phy_dp_lane_num {
+	PHY_DP_LANE_0 = 0,
+	PHY_DP_LANE_1,
+	PHY_DP_LANE_2,
+	PHY_DP_LANE_3,
+};
+
+enum phy_pma_if {
+	PMA_IF_PIPE_PCS = 0,
+	PMA_IF_PHY_DP,
+};
+
+enum phy_typec_role {
+	TYPEC_PHY_USB = 0,
+	TYPEC_PHY_DP,
+	TYPEC_PHY_MAX,
+};
+
+enum phy_dp_power_state {
+	PHY_DP_POWER_STATE_A0 = 0,
+	PHY_DP_POWER_STATE_A1,
+	PHY_DP_POWER_STATE_A2,
+	PHY_DP_POWER_STATE_A3,
+};
+
 struct usb3phy_reg {
 	u32 offset;
 	u32 enable_bit;
@@ -372,18 +417,22 @@ struct rockchip_typec_phy {
 	struct device *dev;
 	void __iomem *base;
 	struct extcon_dev *extcon;
+	struct typec_mux_dev *mux;
+	struct typec_switch_dev *sw;
 	struct regmap *grf_regs;
 	struct clk *clk_core;
 	struct clk *clk_ref;
 	struct reset_control *uphy_rst;
 	struct reset_control *pipe_rst;
 	struct reset_control *tcphy_rst;
+	struct phy *phys[TYPEC_PHY_MAX];
 	const struct rockchip_usb3phy_port_cfg *port_cfgs;
 	/* mutex to protect access to individual PHYs */
 	struct mutex lock;
 
 	bool flip;
 	u8 mode;
+	u8 new_mode;
 };
 
 struct phy_reg {
@@ -454,6 +503,99 @@ static const struct rockchip_usb3phy_port_cfg rk3399_usb3phy_port_cfgs[] = {
 	{ /* sentinel */ }
 };
 
+static int tcphy_cfg_usb3_to_usb2_only(struct rockchip_typec_phy *tcphy,
+				       bool value);
+
+static int tcphy_dp_set_power_state(struct rockchip_typec_phy *tcphy,
+				    enum phy_dp_power_state state)
+{
+	u32 ack, reg, sts = BIT(state);
+	int ret;
+
+	/*
+	 * Power state changes must not be requested until after the cmn_ready
+	 * signal has gone active.
+	 */
+	reg = readl(tcphy->base + PMA_CMN_CTRL1);
+	if (!(reg & CMN_READY)) {
+		dev_err(tcphy->dev, "cmn_ready in the inactive state\n");
+		return -EINVAL;
+	}
+
+	reg = readl(tcphy->base + DP_MODE_CTL);
+	reg &= ~PHY_DP_POWER_STATE_MASK;
+	reg |= sts;
+	writel(reg, tcphy->base + DP_MODE_CTL);
+
+	ret = readl_poll_timeout(tcphy->base + DP_MODE_CTL,
+				 ack, (((ack & PHY_DP_POWER_STATE_ACK_MASK) >>
+				 PHY_DP_POWER_STATE_ACK_SHIFT) == sts), 10,
+				 PHY_MODE_SET_TIMEOUT);
+	if (ret < 0) {
+		dev_err(tcphy->dev, "failed to enter power state %d\n", state);
+		return ret;
+	}
+
+	return 0;
+}
+
+/*
+ * For the TypeC PHY, the 4 lanes are mapping to the USB TypeC receptacle pins
+ * as follows:
+ *   -------------------------------------------------------------------
+ *	PHY Lanes/Module Pins			TypeC Receptacle Pins
+ *   -------------------------------------------------------------------
+ *	Lane0 (tx_p/m_ln_0)			TX1+/TX1- (pins A2/A3)
+ *	Lane1 (tx_rx_p/m_ln_1)			RX1+/RX1- (pins B11/B10)
+ *	Lane2 (tx_rx_p/m_ln_2)			RX2+/RX2- (pins A11/A10)
+ *	Lane3 (tx_p/m_ln_3)			TX2+/TX2- (pins B2/B3)
+ *   -------------------------------------------------------------------
+ *
+ * USB and DP lanes mapping to TypeC PHY lanes for each of pin assignment
+ * options (normal connector orientation) described in the VESA DisplayPort
+ * Alt Mode on USB TypeC Standard as follows:
+ *
+ * ----------------------------------------------------------------------
+ *	PHY Lanes	A	B	C	D	E	F
+ * ----------------------------------------------------------------------
+ *	  0	       ML1     SSTX    ML2     SSTX    ML2     SSTX
+ *	  1	       ML3     SSRX    ML3     SSRX    ML3     SSRX
+ *	  2	       ML2     ML1     ML0     ML0     ML0     ML0
+ *	  3	       ML0     ML0     ML1     ML1     ML1     ML1
+ * ----------------------------------------------------------------------
+ */
+static void tcphy_set_lane_mapping(struct rockchip_typec_phy *tcphy, u8 mode)
+{
+	/*
+	 * The PMA_LANE_CFG register is used to select whether a PMA lane
+	 * is mapped for USB or PHY DP. The PMA_LANE_CFG register is
+	 * configured based on a normal connector orientation. Logic in the
+	 * PHY automatically handles the flipped connector case based on the
+	 * setting of orientation of TypeC PHY.
+	 */
+	if (mode == MODE_DFP_DP) {
+		/* This maps to VESA DP Alt Mode pin assignments C and E. */
+		writel(PMA_LANE3_DP_LANE_SEL(PHY_DP_LANE_1) |
+		       PMA_LANE3_INTERFACE_SEL(PMA_IF_PHY_DP) |
+		       PMA_LANE2_DP_LANE_SEL(PHY_DP_LANE_0) |
+		       PMA_LANE2_INTERFACE_SEL(PMA_IF_PHY_DP) |
+		       PMA_LANE1_DP_LANE_SEL(PHY_DP_LANE_3) |
+		       PMA_LANE1_INTERFACE_SEL(PMA_IF_PHY_DP) |
+		       PMA_LANE0_DP_LANE_SEL(PHY_DP_LANE_2) |
+		       PMA_LANE0_INTERFACE_SEL(PMA_IF_PHY_DP),
+		       tcphy->base + PMA_LANE_CFG);
+	} else {
+		/* This maps to VESA DP Alt Mode pin assignments D and F. */
+		writel(PMA_LANE3_DP_LANE_SEL(PHY_DP_LANE_1) |
+		       PMA_LANE3_INTERFACE_SEL(PMA_IF_PHY_DP) |
+		       PMA_LANE2_DP_LANE_SEL(PHY_DP_LANE_0) |
+		       PMA_LANE2_INTERFACE_SEL(PMA_IF_PHY_DP) |
+		       PMA_LANE1_INTERFACE_SEL(PMA_IF_PIPE_PCS) |
+		       PMA_LANE0_INTERFACE_SEL(PMA_IF_PIPE_PCS),
+		       tcphy->base + PMA_LANE_CFG);
+	}
+}
+
 static void tcphy_cfg_24m(struct rockchip_typec_phy *tcphy)
 {
 	u32 i, rdata;
@@ -743,8 +885,10 @@ static int tcphy_phy_init(struct rockchip_typec_phy *tcphy, u8 mode)
 	tcphy_dp_aux_set_flip(tcphy);
 
 	tcphy_cfg_24m(tcphy);
+	tcphy_set_lane_mapping(tcphy, mode);
 
 	if (mode == MODE_DFP_DP) {
+		tcphy_cfg_usb3_to_usb2_only(tcphy, true);
 		tcphy_cfg_dp_pll(tcphy);
 		for (i = 0; i < 4; i++)
 			tcphy_dp_cfg_lane(tcphy, i);
@@ -768,7 +912,10 @@ static int tcphy_phy_init(struct rockchip_typec_phy *tcphy, u8 mode)
 		writel(PIN_ASSIGN_D_F, tcphy->base + PMA_LANE_CFG);
 	}
 
-	writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL);
+	val = readl(tcphy->base + DP_MODE_CTL);
+	val &= ~DP_MODE_MASK;
+	val |= DP_MODE_ENTER_A2 | DP_LINK_RESET_DEASSERTED;
+	writel(val, tcphy->base + DP_MODE_CTL);
 
 	reset_control_deassert(tcphy->uphy_rst);
 
@@ -811,8 +958,9 @@ static int tcphy_get_mode(struct rockchip_typec_phy *tcphy)
 	u8 mode;
 	int ret, ufp, dp;
 
+	/* If extcon not exist, try to use tcpm mode */
 	if (!edev)
-		return MODE_DFP_USB;
+		return tcphy->new_mode;
 
 	ufp = extcon_get_state(edev, EXTCON_USB);
 	dp = extcon_get_state(edev, EXTCON_DISP_DP);
@@ -850,6 +998,71 @@ static int tcphy_get_mode(struct rockchip_typec_phy *tcphy)
 	return mode;
 }
 
+#if IS_ENABLED(CONFIG_TYPEC)
+static int tcphy_orien_sw_set(struct typec_switch_dev *sw,
+			      enum typec_orientation orien)
+{
+	struct rockchip_typec_phy *tcphy = typec_switch_get_drvdata(sw);
+
+	mutex_lock(&tcphy->lock);
+
+	if (orien == TYPEC_ORIENTATION_NONE) {
+		tcphy->new_mode = MODE_DISCONNECT;
+		goto unlock_ret;
+	}
+
+	tcphy->flip = (orien == TYPEC_ORIENTATION_REVERSE) ? true : false;
+
+unlock_ret:
+	mutex_unlock(&tcphy->lock);
+	return 0;
+}
+
+static void udphy_orien_switch_unregister(void *data)
+{
+	struct rockchip_typec_phy *tcphy = data;
+
+	typec_switch_unregister(tcphy->sw);
+}
+
+static int tcphy_setup_orien_switch(struct rockchip_typec_phy *tcphy)
+{
+	struct typec_switch_desc sw_desc = { };
+	struct device_node *np;
+	int ret = 0;
+
+	np = of_get_child_by_name(tcphy->dev->of_node, "usb3-port");
+	if (!np)
+		return 0;
+
+	if (!of_property_read_bool(np, "orientation-switch"))
+		goto put_np;
+
+	sw_desc.drvdata = tcphy;
+	sw_desc.fwnode = device_get_named_child_node(tcphy->dev, "usb3-port");
+	sw_desc.set = tcphy_orien_sw_set;
+
+	tcphy->sw = typec_switch_register(tcphy->dev, &sw_desc);
+	if (IS_ERR(tcphy->sw)) {
+		dev_err(tcphy->dev, "Error register typec orientation switch: %ld\n",
+			PTR_ERR(tcphy->sw));
+		ret = PTR_ERR(tcphy->sw);
+		goto put_np;
+	}
+
+	ret = devm_add_action_or_reset(tcphy->dev, udphy_orien_switch_unregister, tcphy);
+
+put_np:
+	of_node_put(np);
+	return ret;
+}
+#else
+static int tcphy_setup_orien_switch(struct rockchip_typec_phy *tcphy)
+{
+	return 0;
+}
+#endif
+
 static int tcphy_cfg_usb3_to_usb2_only(struct rockchip_typec_phy *tcphy,
 				       bool value)
 {
@@ -989,14 +1202,9 @@ static int rockchip_dp_phy_power_on(struct phy *phy)
 
 	tcphy_dp_aux_calibration(tcphy);
 
-	writel(DP_MODE_ENTER_A0, tcphy->base + DP_MODE_CTL);
-
-	ret = readx_poll_timeout(readl, tcphy->base + DP_MODE_CTL,
-				 val, val & DP_MODE_A0, 1000,
-				 PHY_MODE_SET_TIMEOUT);
-	if (ret < 0) {
-		writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL);
-		dev_err(tcphy->dev, "failed to wait TCPHY enter A0\n");
+	ret = tcphy_dp_set_power_state(tcphy, PHY_DP_POWER_STATE_A0);
+	if (ret) {
+		dev_err(tcphy->dev, "failed to enter A0 power state\n");
 		goto power_on_finish;
 	}
 
@@ -1013,6 +1221,7 @@ static int rockchip_dp_phy_power_on(struct phy *phy)
 static int rockchip_dp_phy_power_off(struct phy *phy)
 {
 	struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy);
+	int ret;
 
 	mutex_lock(&tcphy->lock);
 
@@ -1021,7 +1230,11 @@ static int rockchip_dp_phy_power_off(struct phy *phy)
 
 	tcphy->mode &= ~MODE_DFP_DP;
 
-	writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL);
+	ret = tcphy_dp_set_power_state(tcphy, PHY_DP_POWER_STATE_A2);
+	if (ret) {
+		dev_err(tcphy->dev, "failed to enter A2 power state\n");
+		goto unlock;
+	}
 
 	if (tcphy->mode == MODE_DISCONNECT)
 		tcphy_phy_deinit(tcphy);
@@ -1037,6 +1250,93 @@ static const struct phy_ops rockchip_dp_phy_ops = {
 	.owner		= THIS_MODULE,
 };
 
+#if IS_ENABLED(CONFIG_TYPEC)
+static int tcphy_typec_mux_set(struct typec_mux_dev *mux, struct typec_mux_state *state)
+{
+	struct rockchip_typec_phy *tcphy = typec_mux_get_drvdata(mux);
+	struct typec_displayport_data *data;
+	int hpd = 0;
+
+	mutex_lock(&tcphy->lock);
+
+	switch (state->mode) {
+	case TYPEC_STATE_SAFE:
+		fallthrough;
+	case TYPEC_STATE_USB:
+		tcphy->new_mode = MODE_DFP_USB;
+		phy_set_bus_width(tcphy->phys[TYPEC_PHY_DP], 0);
+		break;
+	case TYPEC_DP_STATE_C:
+	case TYPEC_DP_STATE_E:
+		if (state->alt->svid != USB_TYPEC_DP_SID)
+			break;
+		tcphy->new_mode = MODE_DFP_DP;
+		data = state->data;
+		hpd = !!(data->status & DP_STATUS_HPD_STATE);
+		phy_set_bus_width(tcphy->phys[TYPEC_PHY_DP], hpd ? 4 : 0);
+		break;
+	case TYPEC_DP_STATE_D:
+		if (state->alt->svid != USB_TYPEC_DP_SID)
+			break;
+		tcphy->new_mode = MODE_DFP_DP | MODE_DFP_USB;
+		data = state->data;
+		hpd = !!(data->status & DP_STATUS_HPD_STATE);
+		phy_set_bus_width(tcphy->phys[TYPEC_PHY_DP], hpd ? 2 : 0);
+		break;
+	default:
+		break;
+	}
+
+	mutex_unlock(&tcphy->lock);
+
+	return 0;
+}
+
+static void tcphy_typec_mux_unregister(void *data)
+{
+	struct rockchip_typec_phy *tcphy = data;
+
+	typec_mux_unregister(tcphy->mux);
+}
+
+static int tcphy_setup_typec_mux(struct rockchip_typec_phy *tcphy)
+{
+	struct typec_mux_desc mux_desc = {};
+	struct device_node *np;
+	int ret = 0;
+
+	np = of_get_child_by_name(tcphy->dev->of_node, "dp-port");
+	if (!np)
+		return 0;
+
+	if (!of_property_read_bool(np, "mode-switch"))
+		goto put_np;
+
+	mux_desc.drvdata = tcphy;
+	mux_desc.fwnode = device_get_named_child_node(tcphy->dev, "dp-port");
+	mux_desc.set = tcphy_typec_mux_set;
+
+	tcphy->mux = typec_mux_register(tcphy->dev, &mux_desc);
+	if (IS_ERR(tcphy->mux)) {
+		dev_err(tcphy->dev, "Error register typec mux: %ld\n",
+			PTR_ERR(tcphy->mux));
+		ret = PTR_ERR(tcphy->mux);
+		goto put_np;
+	}
+
+	ret = devm_add_action_or_reset(tcphy->dev, tcphy_typec_mux_unregister, tcphy);
+
+put_np:
+	of_node_put(np);
+	return ret;
+}
+#else
+static int tcphy_setup_typec_mux(struct rockchip_typec_phy *tcphy)
+{
+	return 0;
+}
+#endif
+
 static int tcphy_parse_dt(struct rockchip_typec_phy *tcphy,
 			  struct device *dev)
 {
@@ -1095,6 +1395,25 @@ static void typec_phy_pre_init(struct rockchip_typec_phy *tcphy)
 	tcphy->mode = MODE_DISCONNECT;
 }
 
+static int typec_dp_lane_get(struct rockchip_typec_phy *tcphy)
+{
+	int dp_lanes;
+
+	switch (tcphy->new_mode) {
+	case MODE_DFP_DP:
+		dp_lanes = 4;
+		break;
+	case MODE_DFP_DP | MODE_DFP_USB:
+		dp_lanes = 2;
+		break;
+	default:
+		dp_lanes = 0;
+		break;
+	}
+
+	return dp_lanes;
+}
+
 static int rockchip_typec_phy_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -1142,6 +1461,7 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev)
 		return ret;
 
 	tcphy->dev = dev;
+	tcphy->new_mode = MODE_DFP_USB;
 	platform_set_drvdata(pdev, tcphy);
 	mutex_init(&tcphy->lock);
 
@@ -1151,6 +1471,7 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev)
 	if (IS_ERR(tcphy->extcon)) {
 		if (PTR_ERR(tcphy->extcon) == -ENODEV) {
 			tcphy->extcon = NULL;
+			dev_info(dev, "extcon not exist, try to use typec mux\n");
 		} else {
 			if (PTR_ERR(tcphy->extcon) != -EPROBE_DEFER)
 				dev_err(dev, "Invalid or missing extcon\n");
@@ -1158,19 +1479,34 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev)
 		}
 	}
 
+	ret = tcphy_setup_orien_switch(tcphy);
+	if (ret)
+		return ret;
+
+	ret = tcphy_setup_typec_mux(tcphy);
+	if (ret)
+		return ret;
+
 	pm_runtime_enable(dev);
 
 	for_each_available_child_of_node(np, child_np) {
 		struct phy *phy;
 
-		if (of_node_name_eq(child_np, "dp-port"))
+		if (of_node_name_eq(child_np, "dp-port")) {
 			phy = devm_phy_create(dev, child_np,
 					      &rockchip_dp_phy_ops);
-		else if (of_node_name_eq(child_np, "usb3-port"))
+			if (!IS_ERR(phy)) {
+				tcphy->phys[TYPEC_PHY_DP] = phy;
+				phy_set_bus_width(phy, typec_dp_lane_get(tcphy));
+			}
+		} else if (of_node_name_eq(child_np, "usb3-port")) {
 			phy = devm_phy_create(dev, child_np,
 					      &rockchip_usb3_phy_ops);
-		else
+			if (!IS_ERR(phy))
+				tcphy->phys[TYPEC_PHY_USB] = phy;
+		} else {
 			continue;
+		}
 
 		if (IS_ERR(phy)) {
 			dev_err(dev, "failed to create phy: %pOFn\n",
-- 
2.51.1



From kernel at airkyi.com  Tue Nov 11 02:50:34 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Tue, 11 Nov 2025 18:50:34 +0800
Subject: [PATCH v9 04/10] dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode-switch
In-Reply-To: <20251111105040.94-1-kernel@airkyi.com>
References: <20251111105040.94-1-kernel@airkyi.com>
Message-ID: <20251111105040.94-5-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

The RK3399 SoC integrates two USB/DP combo PHYs, each of which
supports software-configurable pin mapping and DisplayPort lane
assignment. These capabilities enable the PHY itself to handle both
mode switching and orientation switching, based on the Type-C plug
orientation and USB PD negotiation results.

While an external Type-C controller is still required to detect cable
attachment and report USB PD events, the actual mode and orientation
switching is performed internally by the PHY through software
configuration. This allows the PHY to act as a Type-C multiplexer for
both data role and DP altmode configuration.

To reflect this hardware design, this patch introduces a new
"mode-switch" property for the dp-port node in the device tree bindings.
This property indicates that the connected PHY is capable of handling
Type-C mode switching itself.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---

(no changes since v5)

Changes in v4:
- Remove "|" in description.

Changes in v3:
- Add more descriptions to clarify the role of the PHY in switching.

Changes in v2:
- Reuse dp-port/usb3-port in rk3399-typec-phy binding.

 .../devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml  | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml
index 91c011f68cd0..83ebcde096ea 100644
--- a/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml
@@ -51,6 +51,12 @@ properties:
       '#phy-cells':
         const: 0
 
+      mode-switch:
+        description:
+          Indicates the PHY can handle altmode switching. In this case,
+          requires an external USB Type-C controller to report USB PD message.
+        type: boolean
+
       port:
         $ref: /schemas/graph.yaml#/properties/port
         description: Connection to USB Type-C connector
-- 
2.51.1



From kernel at airkyi.com  Tue Nov 11 02:50:37 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Tue, 11 Nov 2025 18:50:37 +0800
Subject: [PATCH v9 07/10] drm/rockchip: cdn-dp: Support handle lane info without extcon
In-Reply-To: <20251111105040.94-1-kernel@airkyi.com>
References: <20251111105040.94-1-kernel@airkyi.com>
Message-ID: <20251111105040.94-8-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

This patch add support for get PHY lane info without help of extcon.

There is no extcon needed if the Type-C controller is present. In this
case, the lane info can be get from PHY instead of extcon.

The extcon device should still be supported if Type-C controller is
not present.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---

(no changes since v5)

Changes in v4:
- Remove cdn_dp_hpd_notify().

(no changes since v3)

Changes in v2:
- Ignore duplicate HPD events.

 drivers/gpu/drm/rockchip/cdn-dp-core.c | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index b7e3f5dcf8d5..1e27301584a4 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -156,6 +156,9 @@ static int cdn_dp_get_port_lanes(struct cdn_dp_port *port)
 	int dptx;
 	u8 lanes;
 
+	if (!edev)
+		return phy_get_bus_width(port->phy);
+
 	dptx = extcon_get_state(edev, EXTCON_DISP_DP);
 	if (dptx > 0) {
 		extcon_get_property(edev, EXTCON_DISP_DP,
@@ -219,7 +222,7 @@ static bool cdn_dp_check_sink_connection(struct cdn_dp_device *dp)
 	 * some docks need more time to power up.
 	 */
 	while (time_before(jiffies, timeout)) {
-		if (!extcon_get_state(port->extcon, EXTCON_DISP_DP))
+		if (port->extcon && !extcon_get_state(port->extcon, EXTCON_DISP_DP))
 			return false;
 
 		if (!cdn_dp_get_sink_count(dp, &sink_count))
@@ -385,11 +388,14 @@ static int cdn_dp_enable_phy(struct cdn_dp_device *dp, struct cdn_dp_port *port)
 		goto err_power_on;
 	}
 
-	ret = extcon_get_property(port->extcon, EXTCON_DISP_DP,
-				  EXTCON_PROP_USB_TYPEC_POLARITY, &property);
-	if (ret) {
-		DRM_DEV_ERROR(dp->dev, "get property failed\n");
-		goto err_power_on;
+	property.intval = 0;
+	if (port->extcon) {
+		ret = extcon_get_property(port->extcon, EXTCON_DISP_DP,
+					  EXTCON_PROP_USB_TYPEC_POLARITY, &property);
+		if (ret) {
+			DRM_DEV_ERROR(dp->dev, "get property failed\n");
+			goto err_power_on;
+		}
 	}
 
 	port->lanes = cdn_dp_get_port_lanes(port);
@@ -1028,6 +1034,9 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
 	for (i = 0; i < dp->ports; i++) {
 		port = dp->port[i];
 
+		if (!port->extcon)
+			continue;
+
 		port->event_nb.notifier_call = cdn_dp_pd_event;
 		ret = devm_extcon_register_notifier(dp->dev, port->extcon,
 						    EXTCON_DISP_DP,
@@ -1120,14 +1129,14 @@ static int cdn_dp_probe(struct platform_device *pdev)
 		    PTR_ERR(phy) == -EPROBE_DEFER)
 			return -EPROBE_DEFER;
 
-		if (IS_ERR(extcon) || IS_ERR(phy))
+		if (IS_ERR(phy) || PTR_ERR(extcon) != -ENODEV)
 			continue;
 
 		port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
 		if (!port)
 			return -ENOMEM;
 
-		port->extcon = extcon;
+		port->extcon = IS_ERR(extcon) ? NULL : extcon;
 		port->phy = phy;
 		port->dp = dp;
 		port->id = i;
-- 
2.51.1



From kernel at airkyi.com  Tue Nov 11 02:50:36 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Tue, 11 Nov 2025 18:50:36 +0800
Subject: [PATCH v9 06/10] phy: rockchip: phy-rockchip-typec: Add DRM AUX bridge
In-Reply-To: <20251111105040.94-1-kernel@airkyi.com>
References: <20251111105040.94-1-kernel@airkyi.com>
Message-ID: <20251111105040.94-7-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

Using the DRM_AUX_BRIDGE helper to create the transparent DRM bridge
device.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---

(no changes since v7)

Changes in v6:
- Fix depend in Kconfig. 

 drivers/phy/rockchip/Kconfig              |  2 +
 drivers/phy/rockchip/phy-rockchip-typec.c | 52 +++++++++++++++++++++++
 2 files changed, 54 insertions(+)

diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
index db4adc7c53da..bcb5476222fc 100644
--- a/drivers/phy/rockchip/Kconfig
+++ b/drivers/phy/rockchip/Kconfig
@@ -120,6 +120,8 @@ config PHY_ROCKCHIP_TYPEC
 	tristate "Rockchip TYPEC PHY Driver"
 	depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST)
 	depends on TYPEC || TYPEC=n
+	depends on DRM || DRM=n
+	select DRM_AUX_BRIDGE if DRM_BRIDGE
 	select EXTCON
 	select GENERIC_PHY
 	select RESET_CONTROLLER
diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c
index 1f5b4142cbe4..748a6eb8ad95 100644
--- a/drivers/phy/rockchip/phy-rockchip-typec.c
+++ b/drivers/phy/rockchip/phy-rockchip-typec.c
@@ -36,6 +36,7 @@
  * orientation, false is normal orientation.
  */
 
+#include <linux/auxiliary_bus.h>
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/delay.h>
@@ -56,6 +57,7 @@
 #include <linux/phy/phy.h>
 #include <linux/usb/typec_dp.h>
 #include <linux/usb/typec_mux.h>
+#include <drm/bridge/aux-bridge.h>
 
 #define CMN_SSM_BANDGAP			(0x21 << 2)
 #define CMN_SSM_BIAS			(0x22 << 2)
@@ -415,6 +417,7 @@ struct rockchip_usb3phy_port_cfg {
 
 struct rockchip_typec_phy {
 	struct device *dev;
+	struct auxiliary_device dp_port_dev;
 	void __iomem *base;
 	struct extcon_dev *extcon;
 	struct typec_mux_dev *mux;
@@ -1299,6 +1302,51 @@ static void tcphy_typec_mux_unregister(void *data)
 	typec_mux_unregister(tcphy->mux);
 }
 
+static void tcphy_dp_port_dev_release(struct device *dev)
+{
+	struct auxiliary_device *adev = to_auxiliary_dev(dev);
+
+	of_node_put(adev->dev.of_node);
+}
+
+static void tcphy_dp_port_unregister_adev(void *_adev)
+{
+	struct auxiliary_device *adev = _adev;
+
+	auxiliary_device_delete(adev);
+	auxiliary_device_uninit(adev);
+}
+
+static int tcphy_aux_bridge_register(struct rockchip_typec_phy *tcphy, struct device_node *np)
+{
+	struct auxiliary_device *adev = &tcphy->dp_port_dev;
+	int ret;
+
+	adev->name = "dp_port";
+	adev->dev.parent = tcphy->dev;
+	adev->dev.of_node = of_node_get(np);
+	adev->dev.release = tcphy_dp_port_dev_release;
+
+	ret = auxiliary_device_init(adev);
+
+	if (ret) {
+		of_node_put(adev->dev.of_node);
+		return ret;
+	}
+
+	ret = auxiliary_device_add(adev);
+	if (ret) {
+		auxiliary_device_uninit(adev);
+		return ret;
+	}
+
+	devm_add_action_or_reset(tcphy->dev, tcphy_dp_port_unregister_adev, adev);
+
+	ret = drm_aux_bridge_register(&adev->dev);
+
+	return 0;
+}
+
 static int tcphy_setup_typec_mux(struct rockchip_typec_phy *tcphy)
 {
 	struct typec_mux_desc mux_desc = {};
@@ -1312,6 +1360,10 @@ static int tcphy_setup_typec_mux(struct rockchip_typec_phy *tcphy)
 	if (!of_property_read_bool(np, "mode-switch"))
 		goto put_np;
 
+	ret = tcphy_aux_bridge_register(tcphy, np);
+	if (ret)
+		goto put_np;
+
 	mux_desc.drvdata = tcphy;
 	mux_desc.fwnode = device_get_named_child_node(tcphy->dev, "dp-port");
 	mux_desc.set = tcphy_typec_mux_set;
-- 
2.51.1



From kernel at airkyi.com  Tue Nov 11 02:50:38 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Tue, 11 Nov 2025 18:50:38 +0800
Subject: [PATCH v9 08/10] drm/rockchip: cdn-dp: Add multiple bridges to support PHY port selection
In-Reply-To: <20251111105040.94-1-kernel@airkyi.com>
References: <20251111105040.94-1-kernel@airkyi.com>
Message-ID: <20251111105040.94-9-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

The RK3399 has two USB/DP combo PHY and one CDN-DP controller. And
the CDN-DP can be switched to output to one of the PHYs. If both ports
are plugged into DP, DP will select the first port for output.

This patch adds support for multiple bridges, enabling users to flexibly
select the output port. For each PHY port, a separate encoder and bridge
are registered.

The change is based on the DRM AUX HPD bridge, rather than the
extcon approach. This requires the DT to correctly describe the
connections between the first bridge in bridge chain and DP
controller. For example, the bridge chain may be like this:

PHY aux birdge -> fsa4480 analog audio switch bridge ->
onnn,nb7vpq904m USB reminder bridge -> USB-C controller AUX HPD bridge

In this case, the connection relationships among the PHY aux bridge
and the DP contorller need to be described in DT.

In addition, the cdn_dp_parse_next_bridge_dt() will parses it and
determines whether to register one or two bridges.

Since there is only one DP controller, only one of the PHY ports can
output at a time. The key is how to switch between different PHYs,
which is handled by cdn_dp_switch_port() and cdn_dp_enable().

There are two cases:

1. Neither bridge is enabled. In this case, both bridges can
independently read the EDID, and the PHY port may switch before
reading the EDID.

2. One bridge is already enabled. In this case, other bridges are not
allowed to read the EDID. So we will try to return the cached EDID.

Since the scenario of two ports plug in at the same time is rare,
I don't have a board which support two TypeC connector to test this.
Therefore, I tested forced switching on a single PHY port, as well as
output using a fake PHY port alongside a real PHY port.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---

Changes in v9:
- Select DRM_AUX_HPD_BRIDGE when using DP driver.

(no changes since v7)

Changes in v6:
- Rename some variable names.
- Attach the DP bridge to the next bridge.

Changes in v5:
- By parsing the HPD bridge chain, set the connector's of_node to the
of_node corresponding to the USB-C connector.
- Return EDID cache when other port is already enabled.

 drivers/gpu/drm/rockchip/Kconfig       |   1 +
 drivers/gpu/drm/rockchip/cdn-dp-core.c | 329 ++++++++++++++++++++-----
 drivers/gpu/drm/rockchip/cdn-dp-core.h |  24 +-
 3 files changed, 297 insertions(+), 57 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index b7b025814e72..10d9f29a3d44 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -56,6 +56,7 @@ config ROCKCHIP_CDN_DP
 	select DRM_DISPLAY_HELPER
 	select DRM_BRIDGE_CONNECTOR
 	select DRM_DISPLAY_DP_HELPER
+	select DRM_AUX_HPD_BRIDGE
 	help
 	  This selects support for Rockchip SoC specific extensions
 	  for the cdn DP driver. If you want to enable Dp on
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 1e27301584a4..5c0e5209d3b8 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -27,16 +27,17 @@
 #include "cdn-dp-core.h"
 #include "cdn-dp-reg.h"
 
-static inline struct cdn_dp_device *bridge_to_dp(struct drm_bridge *bridge)
+static int cdn_dp_switch_port(struct cdn_dp_device *dp, struct cdn_dp_port *prev_port,
+			      struct cdn_dp_port *port);
+
+static inline struct cdn_dp_bridge *bridge_to_dp_bridge(struct drm_bridge *bridge)
 {
-	return container_of(bridge, struct cdn_dp_device, bridge);
+	return container_of(bridge, struct cdn_dp_bridge, bridge);
 }
 
-static inline struct cdn_dp_device *encoder_to_dp(struct drm_encoder *encoder)
+static inline struct cdn_dp_device *bridge_to_dp(struct drm_bridge *bridge)
 {
-	struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
-
-	return container_of(rkencoder, struct cdn_dp_device, encoder);
+	return bridge_to_dp_bridge(bridge)->parent;
 }
 
 #define GRF_SOC_CON9		0x6224
@@ -191,14 +192,27 @@ static int cdn_dp_get_sink_count(struct cdn_dp_device *dp, u8 *sink_count)
 static struct cdn_dp_port *cdn_dp_connected_port(struct cdn_dp_device *dp)
 {
 	struct cdn_dp_port *port;
-	int i, lanes;
+	int i, lanes[MAX_PHY];
 
 	for (i = 0; i < dp->ports; i++) {
 		port = dp->port[i];
-		lanes = cdn_dp_get_port_lanes(port);
-		if (lanes)
+		lanes[i] = cdn_dp_get_port_lanes(port);
+		if (!dp->next_bridge_valid)
 			return port;
 	}
+
+	if (dp->next_bridge_valid) {
+		/* If more than one port is available, pick the last active port */
+		if (dp->active_port > 0 && lanes[dp->active_port])
+			return dp->port[dp->active_port];
+
+		/* If the last active port is not available, pick an available port in order */
+		for (i = 0; i < dp->bridge_count; i++) {
+			if (lanes[i])
+				return dp->port[i];
+		}
+	}
+
 	return NULL;
 }
 
@@ -253,12 +267,45 @@ static const struct drm_edid *
 cdn_dp_bridge_edid_read(struct drm_bridge *bridge, struct drm_connector *connector)
 {
 	struct cdn_dp_device *dp = bridge_to_dp(bridge);
-	const struct drm_edid *drm_edid;
+	struct cdn_dp_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
+	struct cdn_dp_port *port = dp->port[dp_bridge->id];
+	struct cdn_dp_port *prev_port;
+	const struct drm_edid *drm_edid = NULL;
+	int i, ret;
 
 	mutex_lock(&dp->lock);
+
+	/* More than one port is available */
+	if (dp->bridge_count > 1 && !port->phy_enabled) {
+		for (i = 0; i < dp->bridge_count; i++) {
+			/* Another port already enable */
+			if (dp->bridge_list[i] != dp_bridge && dp->bridge_list[i]->enabled)
+				goto get_cache;
+			/* Find already enabled port */
+			if (dp->port[i]->phy_enabled)
+				prev_port = dp->port[i];
+		}
+
+		/* Switch to current port */
+		if (prev_port) {
+			ret = cdn_dp_switch_port(dp, prev_port, port);
+			if (ret)
+				goto get_cache;
+		}
+	}
+
 	drm_edid = drm_edid_read_custom(connector, cdn_dp_get_edid_block, dp);
+	/* replace edid cache */
+	if (dp->edid_cache[dp_bridge->id])
+		drm_edid_free(dp->edid_cache[dp_bridge->id]);
+	dp->edid_cache[dp_bridge->id] = drm_edid_dup(drm_edid);
+
 	mutex_unlock(&dp->lock);
+	return drm_edid;
 
+get_cache:
+	drm_edid = drm_edid_dup(dp->edid_cache[dp_bridge->id]);
+	mutex_unlock(&dp->lock);
 	return drm_edid;
 }
 
@@ -267,12 +314,13 @@ cdn_dp_bridge_mode_valid(struct drm_bridge *bridge,
 			 const struct drm_display_info *display_info,
 			 const struct drm_display_mode *mode)
 {
+	struct cdn_dp_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
 	struct cdn_dp_device *dp = bridge_to_dp(bridge);
 	u32 requested, actual, rate, sink_max, source_max = 0;
 	u8 lanes, bpc;
 
 	/* If DP is disconnected, every mode is invalid */
-	if (!dp->connected)
+	if (!dp_bridge->connected || !dp->connected)
 		return MODE_BAD;
 
 	switch (display_info->bpc) {
@@ -550,6 +598,54 @@ static bool cdn_dp_check_link_status(struct cdn_dp_device *dp)
 	return drm_dp_channel_eq_ok(link_status, min(port->lanes, sink_lanes));
 }
 
+static int cdn_dp_switch_port(struct cdn_dp_device *dp, struct cdn_dp_port *prev_port,
+			      struct cdn_dp_port *port)
+{
+	int ret;
+
+	if (dp->active)
+		return 0;
+
+	ret = cdn_dp_disable_phy(dp, prev_port);
+	if (ret)
+		goto out;
+	ret = cdn_dp_enable_phy(dp, port);
+	if (ret)
+		goto out;
+
+	ret = cdn_dp_get_sink_capability(dp);
+	if (ret) {
+		cdn_dp_disable_phy(dp, port);
+		goto out;
+	}
+
+	dp->active = true;
+	dp->lanes = port->lanes;
+
+	if (!cdn_dp_check_link_status(dp)) {
+		dev_info(dp->dev, "Connected with sink; re-train link\n");
+
+		ret = cdn_dp_train_link(dp);
+		if (ret) {
+			dev_err(dp->dev, "Training link failed: %d\n", ret);
+			goto out;
+		}
+
+		ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE);
+		if (ret) {
+			dev_err(dp->dev, "Failed to idle video %d\n", ret);
+			goto out;
+		}
+
+		ret = cdn_dp_config_video(dp);
+		if (ret)
+			dev_err(dp->dev, "Failed to configure video: %d\n", ret);
+	}
+
+out:
+	return ret;
+}
+
 static void cdn_dp_display_info_update(struct cdn_dp_device *dp,
 				       struct drm_display_info *display_info)
 {
@@ -571,6 +667,7 @@ static void cdn_dp_display_info_update(struct cdn_dp_device *dp,
 static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_atomic_state *state)
 {
 	struct cdn_dp_device *dp = bridge_to_dp(bridge);
+	struct cdn_dp_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
 	struct drm_connector *connector;
 	int ret, val;
 
@@ -580,7 +677,7 @@ static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_at
 
 	cdn_dp_display_info_update(dp, &connector->display_info);
 
-	ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, &dp->encoder.encoder);
+	ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, &dp_bridge->encoder.encoder);
 	if (ret < 0) {
 		DRM_DEV_ERROR(dp->dev, "Could not get vop id, %d", ret);
 		return;
@@ -599,6 +696,9 @@ static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_at
 
 	mutex_lock(&dp->lock);
 
+	if (dp->next_bridge_valid)
+		dp->active_port = dp_bridge->id;
+
 	ret = cdn_dp_enable(dp);
 	if (ret) {
 		DRM_DEV_ERROR(dp->dev, "Failed to enable bridge %d\n",
@@ -631,6 +731,7 @@ static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_at
 		goto out;
 	}
 
+	dp_bridge->enabled = true;
 out:
 	mutex_unlock(&dp->lock);
 }
@@ -638,9 +739,11 @@ static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_at
 static void cdn_dp_bridge_atomic_disable(struct drm_bridge *bridge, struct drm_atomic_state *state)
 {
 	struct cdn_dp_device *dp = bridge_to_dp(bridge);
+	struct cdn_dp_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
 	int ret;
 
 	mutex_lock(&dp->lock);
+	dp_bridge->enabled = false;
 
 	if (dp->active) {
 		ret = cdn_dp_disable(dp);
@@ -827,6 +930,16 @@ static int cdn_dp_audio_mute_stream(struct drm_bridge *bridge,
 	return ret;
 }
 
+static void cdn_dp_bridge_hpd_notify(struct drm_bridge *bridge,
+			   enum drm_connector_status status)
+{
+	struct cdn_dp_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
+	struct cdn_dp_device *dp = bridge_to_dp(bridge);
+
+	dp->bridge_list[dp_bridge->id]->connected = status == connector_status_connected;
+	schedule_work(&dp->event_work);
+}
+
 static const struct drm_bridge_funcs cdn_dp_bridge_funcs = {
 	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
 	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
@@ -837,6 +950,7 @@ static const struct drm_bridge_funcs cdn_dp_bridge_funcs = {
 	.atomic_disable = cdn_dp_bridge_atomic_disable,
 	.mode_valid = cdn_dp_bridge_mode_valid,
 	.mode_set = cdn_dp_bridge_mode_set,
+	.hpd_notify = cdn_dp_bridge_hpd_notify,
 
 	.dp_audio_prepare = cdn_dp_audio_prepare,
 	.dp_audio_mute_stream = cdn_dp_audio_mute_stream,
@@ -885,7 +999,8 @@ static void cdn_dp_pd_event_work(struct work_struct *work)
 {
 	struct cdn_dp_device *dp = container_of(work, struct cdn_dp_device,
 						event_work);
-	int ret;
+	bool connected;
+	int i, ret;
 
 	mutex_lock(&dp->lock);
 
@@ -944,9 +1059,12 @@ static void cdn_dp_pd_event_work(struct work_struct *work)
 
 out:
 	mutex_unlock(&dp->lock);
-	drm_bridge_hpd_notify(&dp->bridge,
-			      dp->connected ? connector_status_connected
-					    : connector_status_disconnected);
+	for (i = 0; i < dp->bridge_count; i++) {
+		connected = dp->connected && dp->bridge_list[i]->connected;
+		drm_bridge_hpd_notify(&dp->bridge_list[i]->bridge,
+				      connected ? connector_status_connected
+						: connector_status_disconnected);
+	}
 }
 
 static int cdn_dp_pd_event(struct notifier_block *nb,
@@ -966,28 +1084,16 @@ static int cdn_dp_pd_event(struct notifier_block *nb,
 	return NOTIFY_DONE;
 }
 
-static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
+static int cdn_bridge_add(struct device *dev,
+			  struct drm_bridge *bridge,
+			  struct drm_bridge *next_bridge,
+			  struct drm_encoder *encoder)
 {
 	struct cdn_dp_device *dp = dev_get_drvdata(dev);
-	struct drm_encoder *encoder;
+	struct drm_device *drm_dev = dp->drm_dev;
+	struct drm_bridge *last_bridge = NULL;
 	struct drm_connector *connector;
-	struct cdn_dp_port *port;
-	struct drm_device *drm_dev = data;
-	int ret, i;
-
-	ret = cdn_dp_parse_dt(dp);
-	if (ret < 0)
-		return ret;
-
-	dp->drm_dev = drm_dev;
-	dp->connected = false;
-	dp->active = false;
-	dp->active_port = -1;
-	dp->fw_loaded = false;
-
-	INIT_WORK(&dp->event_work, cdn_dp_pd_event_work);
-
-	encoder = &dp->encoder.encoder;
+	int ret;
 
 	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
 							     dev->of_node);
@@ -1002,26 +1108,38 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
 
 	drm_encoder_helper_add(encoder, &cdn_dp_encoder_helper_funcs);
 
-	dp->bridge.ops =
-			DRM_BRIDGE_OP_DETECT |
-			DRM_BRIDGE_OP_EDID |
-			DRM_BRIDGE_OP_HPD |
-			DRM_BRIDGE_OP_DP_AUDIO;
-	dp->bridge.of_node = dp->dev->of_node;
-	dp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
-	dp->bridge.hdmi_audio_dev = dp->dev;
-	dp->bridge.hdmi_audio_max_i2s_playback_channels = 8;
-	dp->bridge.hdmi_audio_spdif_playback = 1;
-	dp->bridge.hdmi_audio_dai_port = -1;
-
-	ret = devm_drm_bridge_add(dev, &dp->bridge);
+
+	bridge->ops =
+		DRM_BRIDGE_OP_DETECT |
+		DRM_BRIDGE_OP_EDID |
+		DRM_BRIDGE_OP_HPD |
+		DRM_BRIDGE_OP_DP_AUDIO;
+	bridge->of_node = dp->dev->of_node;
+	bridge->type = DRM_MODE_CONNECTOR_DisplayPort;
+	bridge->hdmi_audio_dev = dp->dev;
+	bridge->hdmi_audio_max_i2s_playback_channels = 8;
+	bridge->hdmi_audio_spdif_playback = 1;
+	bridge->hdmi_audio_dai_port = -1;
+
+	ret = devm_drm_bridge_add(dev, bridge);
 	if (ret)
 		return ret;
 
-	ret = drm_bridge_attach(encoder, &dp->bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+	ret = drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
 	if (ret)
 		return ret;
 
+	if (next_bridge) {
+		ret = drm_bridge_attach(encoder, next_bridge, bridge,
+					DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+		if (ret)
+			return ret;
+
+		last_bridge = next_bridge;
+		while (drm_bridge_get_next_bridge(last_bridge))
+			last_bridge = drm_bridge_get_next_bridge(last_bridge);
+	}
+
 	connector = drm_bridge_connector_init(drm_dev, encoder);
 	if (IS_ERR(connector)) {
 		ret = PTR_ERR(connector);
@@ -1029,8 +1147,102 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
 		return ret;
 	}
 
+	if (last_bridge)
+		connector->fwnode = fwnode_handle_get(of_fwnode_handle(last_bridge->of_node));
+
 	drm_connector_attach_encoder(connector, encoder);
 
+	return 0;
+}
+
+static int cdn_dp_parse_next_bridge_dt(struct cdn_dp_device *dp)
+{
+	struct device_node *np = dp->dev->of_node;
+	struct device_node *port __free(device_node) = of_graph_get_port_by_id(np, 1);
+	struct drm_bridge *bridge;
+	int count = 0;
+	int ret = 0;
+	int i;
+
+	/* If device use extcon, do not use hpd bridge */
+	for (i = 0; i < dp->ports; i++) {
+		if (dp->port[i]->extcon) {
+			dp->bridge_count = 1;
+			return 0;
+		}
+	}
+
+
+	/* One endpoint may correspond to one next bridge. */
+	for_each_of_graph_port_endpoint(port, dp_ep) {
+		struct device_node *next_bridge_node __free(device_node) =
+			of_graph_get_remote_port_parent(dp_ep);
+
+		bridge = of_drm_find_bridge(next_bridge_node);
+		if (!bridge) {
+			ret = -EPROBE_DEFER;
+			goto out;
+		}
+
+		dp->next_bridge_valid = true;
+		dp->next_bridge_list[count].bridge = bridge;
+		dp->next_bridge_list[count].parent = dp;
+		dp->next_bridge_list[count].id = count;
+		count++;
+	}
+
+out:
+	dp->bridge_count = count ? count : 1;
+	return ret;
+}
+
+static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
+{
+	struct cdn_dp_device *dp = dev_get_drvdata(dev);
+	struct drm_bridge *bridge, *next_bridge;
+	struct drm_encoder *encoder;
+	struct cdn_dp_port *port;
+	struct drm_device *drm_dev = data;
+	struct cdn_dp_bridge *dp_bridge;
+	int ret, i;
+
+	ret = cdn_dp_parse_dt(dp);
+	if (ret < 0)
+		return ret;
+
+	ret = cdn_dp_parse_next_bridge_dt(dp);
+	if (ret)
+		return ret;
+
+	dp->drm_dev = drm_dev;
+	dp->connected = false;
+	dp->active = false;
+	dp->active_port = -1;
+	dp->fw_loaded = false;
+
+	for (i = 0; i < dp->bridge_count; i++) {
+		dp_bridge = devm_drm_bridge_alloc(dev, struct cdn_dp_bridge, bridge,
+						    &cdn_dp_bridge_funcs);
+		if (IS_ERR(dp_bridge))
+			return PTR_ERR(dp_bridge);
+		dp_bridge->id = i;
+		dp_bridge->parent = dp;
+		if (!dp->next_bridge_valid)
+			dp_bridge->connected = true;
+		dp->bridge_list[i] = dp_bridge;
+	}
+
+	for (i = 0; i < dp->bridge_count; i++) {
+		encoder = &dp->bridge_list[i]->encoder.encoder;
+		bridge = &dp->bridge_list[i]->bridge;
+		next_bridge = dp->next_bridge_list[i].bridge;
+		ret = cdn_bridge_add(dev, bridge, next_bridge, encoder);
+		if (ret)
+			return ret;
+	}
+
+	INIT_WORK(&dp->event_work, cdn_dp_pd_event_work);
+
 	for (i = 0; i < dp->ports; i++) {
 		port = dp->port[i];
 
@@ -1058,10 +1270,17 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
 static void cdn_dp_unbind(struct device *dev, struct device *master, void *data)
 {
 	struct cdn_dp_device *dp = dev_get_drvdata(dev);
-	struct drm_encoder *encoder = &dp->encoder.encoder;
+	struct drm_encoder *encoder;
+	int i;
 
 	cancel_work_sync(&dp->event_work);
-	encoder->funcs->destroy(encoder);
+	for (i = 0; i < dp->bridge_count; i++) {
+		encoder = &dp->bridge_list[i]->encoder.encoder;
+		encoder->funcs->destroy(encoder);
+	}
+
+	for (i = 0; i < MAX_PHY; i++)
+		drm_edid_free(dp->edid_cache[i]);
 
 	pm_runtime_disable(dev);
 	if (dp->fw_loaded)
@@ -1112,10 +1331,10 @@ static int cdn_dp_probe(struct platform_device *pdev)
 	int ret;
 	int i;
 
-	dp = devm_drm_bridge_alloc(dev, struct cdn_dp_device, bridge,
-				   &cdn_dp_bridge_funcs);
-	if (IS_ERR(dp))
-		return PTR_ERR(dp);
+	dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
+	if (!dp)
+		return -ENOMEM;
+
 	dp->dev = dev;
 
 	match = of_match_node(cdn_dp_dt_ids, pdev->dev.of_node);
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.h b/drivers/gpu/drm/rockchip/cdn-dp-core.h
index e9c30b9fd543..ce1707a5c746 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.h
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h
@@ -38,6 +38,8 @@ enum vic_pxl_encoding_format {
 	Y_ONLY = 0x10,
 };
 
+struct cdn_dp_device;
+
 struct video_info {
 	bool h_sync_polarity;
 	bool v_sync_polarity;
@@ -63,16 +65,34 @@ struct cdn_dp_port {
 	u8 id;
 };
 
+struct cdn_dp_bridge {
+	struct cdn_dp_device *parent;
+	struct drm_bridge bridge;
+	struct rockchip_encoder encoder;
+	bool connected;
+	bool enabled;
+	int id;
+};
+
+struct cdn_dp_next_bridge {
+	struct cdn_dp_device *parent;
+	struct drm_bridge *bridge;
+	int id;
+};
+
 struct cdn_dp_device {
 	struct device *dev;
 	struct drm_device *drm_dev;
-	struct drm_bridge bridge;
-	struct rockchip_encoder encoder;
+	int bridge_count;
+	struct cdn_dp_bridge *bridge_list[MAX_PHY];
+	struct cdn_dp_next_bridge next_bridge_list[MAX_PHY];
+	const struct drm_edid *edid_cache[MAX_PHY];
 	struct drm_display_mode mode;
 	struct platform_device *audio_pdev;
 	struct work_struct event_work;
 
 	struct mutex lock;
+	bool next_bridge_valid;
 	bool connected;
 	bool active;
 	bool suspended;
-- 
2.51.1



From kernel at airkyi.com  Tue Nov 11 02:50:39 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Tue, 11 Nov 2025 18:50:39 +0800
Subject: [PATCH v9 09/10] arm64: dts: rockchip: Add missing dp_out port for RK3399 CDN-DP
In-Reply-To: <20251111105040.94-1-kernel@airkyi.com>
References: <20251111105040.94-1-kernel@airkyi.com>
Message-ID: <20251111105040.94-10-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

Let's make the ports nodes of cdn_dp in the same style as the other
display interface, and match the style of ports's yaml.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---

(no changes since v5)

Changes in v4:
- Remove unnecessary #address/#size-cells

(no changes since v1)

 arch/arm64/boot/dts/rockchip/rk3399-base.dtsi | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi
index 4dcceb9136b7..93b42820998f 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi
@@ -618,7 +618,11 @@ cdn_dp: dp at fec00000 {
 		status = "disabled";
 
 		ports {
-			dp_in: port {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			dp_in: port at 0 {
+				reg = <0>;
 				#address-cells = <1>;
 				#size-cells = <0>;
 
@@ -632,6 +636,10 @@ dp_in_vopl: endpoint at 1 {
 					remote-endpoint = <&vopl_out_dp>;
 				};
 			};
+
+			dp_out: port at 1 {
+				reg = <1>;
+			};
 		};
 	};
 
-- 
2.51.1



From kernel at airkyi.com  Tue Nov 11 02:50:40 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Tue, 11 Nov 2025 18:50:40 +0800
Subject: [PATCH v9 10/10] arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort
In-Reply-To: <20251111105040.94-1-kernel@airkyi.com>
References: <20251111105040.94-1-kernel@airkyi.com>
Message-ID: <20251111105040.94-11-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

The RK3399 EVB IND board has a Type-C interface DisplayPort.
It use fusb302 chip as Type-C controller.

fusb302 chip ---> USB/DP PHY0 <----> CDN-DP controller

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---

Changes in v9:
- Add usb role switch for Type-C.
- Remove USB2 PHY in Type-C connection.

(no changes since v4)

Changes in v3:
- Fix wrong vdo value.
- Fix port node in usb-c-connector.

Changes in v2:
- Add endpoint to link DP PHY and DP controller.
- Fix devicetree coding style.

 .../boot/dts/rockchip/rk3399-evb-ind.dts      | 147 ++++++++++++++++++
 1 file changed, 147 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts
index 70aee1ab904c..be1e90f7a453 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts
@@ -4,6 +4,7 @@
  */
 
 /dts-v1/;
+#include <dt-bindings/usb/pd.h>
 #include "rk3399.dtsi"
 
 / {
@@ -19,6 +20,21 @@ chosen {
 		stdout-path = "serial2:1500000n8";
 	};
 
+	sound: sound {
+		compatible = "rockchip,rk3399-gru-sound";
+		rockchip,cpu = <&i2s0 &spdif>;
+	};
+
+	vbus_typec: regulator-vbus-typec {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc5v0_typec0_en>;
+		regulator-name = "vbus_typec";
+		vin-supply = <&vcc5v0_sys>;
+	};
+
 	vcc5v0_sys: regulator-vcc5v0-sys {
 		compatible = "regulator-fixed";
 		enable-active-high;
@@ -31,6 +47,11 @@ vcc5v0_sys: regulator-vcc5v0-sys {
 	};
 };
 
+&cdn_dp {
+	phys = <&tcphy0_dp>;
+	status = "okay";
+};
+
 &cpu_b0 {
 	cpu-supply = <&vdd_cpu_b>;
 };
@@ -55,6 +76,12 @@ &cpu_l3 {
 	cpu-supply = <&vdd_cpu_l>;
 };
 
+&dp_out {
+	dp_controller_output: endpoint {
+		remote-endpoint = <&dp_phy_in>;
+	};
+};
+
 &emmc_phy {
 	status = "okay";
 };
@@ -341,6 +368,71 @@ regulator-state-mem {
 	};
 };
 
+&i2c4 {
+	i2c-scl-rising-time-ns = <475>;
+	i2c-scl-falling-time-ns = <26>;
+	status = "okay";
+
+	usbc0: typec-portc at 22 {
+		compatible = "fcs,fusb302";
+		reg = <0x22>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <RK_PA2 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&usbc0_int>;
+		vbus-supply = <&vbus_typec>;
+
+		usb_con: connector {
+			compatible = "usb-c-connector";
+			label = "USB-C";
+			data-role = "dual";
+			power-role = "dual";
+			try-power-role = "sink";
+			op-sink-microwatt = <1000000>;
+			sink-pdos =
+				<PDO_FIXED(5000, 2500, PDO_FIXED_USB_COMM)>;
+			source-pdos =
+				<PDO_FIXED(5000, 1500, PDO_FIXED_USB_COMM)>;
+
+			altmodes {
+				displayport {
+					svid = /bits/ 16 <0xff01>;
+					vdo = <0x00001c46>;
+				};
+			};
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					reg = <0>;
+
+					usbc0_orien_sw: endpoint {
+						remote-endpoint = <&tcphy0_orientation_switch>;
+					};
+				};
+
+				port at 1 {
+					reg = <1>;
+
+					usbc0_role_sw: endpoint {
+						remote-endpoint = <&dwc3_0_role_switch>;
+					};
+				};
+
+				port at 2 {
+					reg = <2>;
+
+					dp_altmode_mux: endpoint {
+						remote-endpoint = <&tcphy0_typec_dp>;
+					};
+				};
+			};
+		};
+	};
+};
+
 &i2s2 {
 	status = "okay";
 };
@@ -354,6 +446,16 @@ &io_domains {
 };
 
 &pinctrl {
+	usb-typec {
+		usbc0_int: usbc0-int {
+			rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+
+		vcc5v0_typec0_en: vcc5v0-typec0-en {
+			rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
 	pmic {
 		pmic_int_l: pmic-int-l {
 			rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>;
@@ -400,10 +502,48 @@ &sdmmc {
 	status = "okay";
 };
 
+&sound {
+	rockchip,codec = <&cdn_dp>;
+	status = "okay";
+};
+
+&spdif {
+	status = "okay";
+};
+
 &tcphy0 {
 	status = "okay";
 };
 
+&tcphy0_dp {
+	mode-switch;
+
+	port {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		tcphy0_typec_dp: endpoint at 0 {
+			reg = <0>;
+			remote-endpoint = <&dp_altmode_mux>;
+		};
+
+		dp_phy_in: endpoint at 1 {
+			reg = <1>;
+			remote-endpoint = <&dp_controller_output>;
+		};
+	};
+};
+
+&tcphy0_usb3 {
+	orientation-switch;
+
+	port {
+		tcphy0_orientation_switch: endpoint {
+			remote-endpoint = <&usbc0_orien_sw>;
+		};
+	};
+};
+
 &tcphy1 {
 	status = "okay";
 };
@@ -461,7 +601,14 @@ &usb_host1_ohci {
 };
 
 &usbdrd_dwc3_0 {
+	usb-role-switch;
 	status = "okay";
+
+	port {
+		dwc3_0_role_switch: endpoint {
+			remote-endpoint = <&usbc0_role_sw>;
+		};
+	};
 };
 
 &usbdrd3_0 {
-- 
2.51.1



From krzk at kernel.org  Tue Nov 11 03:09:05 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 11 Nov 2025 12:09:05 +0100
Subject: [PATCH v9 04/10] dt-bindings: phy: rockchip: rk3399-typec-phy:
 Support mode-switch
In-Reply-To: <20251111105040.94-5-kernel@airkyi.com>
References: <20251111105040.94-1-kernel@airkyi.com>
 <20251111105040.94-5-kernel@airkyi.com>
Message-ID: <868f09fd-8fe8-4c01-952f-6317604c43a3@kernel.org>

On 11/11/2025 11:50, Chaoyi Chen wrote:
> While an external Type-C controller is still required to detect cable
> attachment and report USB PD events, the actual mode and orientation
> switching is performed internally by the PHY through software
> configuration. This allows the PHY to act as a Type-C multiplexer for
> both data role and DP altmode configuration.
> 
> To reflect this hardware design, this patch introduces a new
> "mode-switch" property for the dp-port node in the device tree bindings.
> This property indicates that the connected PHY is capable of handling
> Type-C mode switching itself.
> 
> Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> 
> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

There are never blank lines between tags.

Best regards,
Krzysztof


From naoki at radxa.com  Tue Nov 11 03:43:05 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Tue, 11 Nov 2025 20:43:05 +0900
Subject: [PATCH v7 04/14] arm64: dts: rockchip: Fix microSD card detect
 for Radxa ROCK 5C
In-Reply-To: <20251109141859.206835-5-naoki@radxa.com>
References: <20251109141859.206835-1-naoki@radxa.com>
 <20251109141859.206835-5-naoki@radxa.com>
Message-ID: <FC06F2D88D1A6D6B+2515ff82-cd34-4f1d-8078-feb669912e41@radxa.com>

Hi,

I'll drop this on v8. This will be handled in
  https://lore.kernel.org/linux-rockchip/20251111071730.126238-1-naoki at radxa.com/

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

On 11/9/25 23:18, FUKAUMI Naoki wrote:
> Due to the discussion about cd-gpios and sdmmmc_det pin
> functionality[1], it would be better to use cd-gpios for now.
> 
> [1] https://lore.kernel.org/linux-rockchip/20240912152538.1.I858c2a0bf83606c8b59ba1ab6944978a398d2ac5 at changeid/T/#u
> 
> Fixes: 3ddf5cdb77e6 ("arm64: dts: rockchip: add Radxa ROCK 5C")
> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> ---
> Changes in v7:
> - Add pinctrl-*
> - Reword commit message
> Changes in v6:
> - Reword commit message
> Changes in v5:
> - Reword commit message
> Changes in v4:
> - None
> Changes in v3:
> - None
> Changes in v2:
> - None
> ---
>   arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts | 3 +++
>   1 file changed, 3 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
> index 9a9430b2494b7..1257aaac8f350 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
> @@ -510,9 +510,12 @@ &sdmmc {
>   	bus-width = <4>;
>   	cap-mmc-highspeed;
>   	cap-sd-highspeed;
> +	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
>   	disable-wp;
>   	no-sdio;
>   	no-mmc;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd>;
>   	sd-uhs-sdr104;
>   	vmmc-supply = <&vcc_3v3_s3>;
>   	vqmmc-supply = <&vccio_sd_s0>;




From naoki at radxa.com  Tue Nov 11 03:52:54 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Tue, 11 Nov 2025 20:52:54 +0900
Subject: [PATCH v6 0/3] Add Radxa CM5 and IO Board
In-Reply-To: <CAMWSM7gezjVSoF+-7ivboTeB=5gQAE-QVrbAbKu3M=obmb3Axg@mail.gmail.com>
References: <20251105051335.17652-1-naoki@radxa.com>
 <199E172C8E20ED38+71169242-5525-4d60-9e37-a03ad172d639@radxa.com>
 <CAMWSM7gezjVSoF+-7ivboTeB=5gQAE-QVrbAbKu3M=obmb3Axg@mail.gmail.com>
Message-ID: <617FDAB231C501DC+3f9809df-87df-4a02-bd5f-ebc6299b3aa7@radxa.com>

Hi all,

On 11/6/25 02:48, Joseph Kogut wrote:
> Hello all,
> 
> On Wed, Nov 5, 2025 at 4:15?AM FUKAUMI Naoki <naoki at radxa.com> wrote:
>>
>> I'd like to clarify the situation regarding the v6 patch series I submitted.
>>
>> The original device tree work for the Radxa CM5 and IO Board was
>> authored by Joseph Kogut. I took over the responsibility of getting it
>> upstreamed with his agreement.
> 
> I'll confirm this. I've been in communication with Naoki. They made a
> large number of revisions to my original patch series, which I think
> have technical merit. I suggested they submit the patches themselves,
> and gave them explicit permission to add my Signed-off-by and CC me.
> 
> I assume this was the correct way for them to continue the work I
> started, but if not, please let us know the best way to proceed.

Can anyone help us?

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> Best,
> Joseph
> 




From cassel at kernel.org  Tue Nov 11 04:39:06 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Tue, 11 Nov 2025 13:39:06 +0100
Subject: [PATCH 0/6] PCI: dwc: Revert Link Up IRQ support
In-Reply-To: <aRMZS3EUYx189Xup@wunner.de>
References: <20251111105100.869997-8-cassel@kernel.org>
 <aRMZS3EUYx189Xup@wunner.de>
Message-ID: <aRMuascJFSuE6NBd@ryzen>

Hello Lukas,

On Tue, Nov 11, 2025 at 12:08:59PM +0100, Lukas Wunner wrote:
> On Tue, Nov 11, 2025 at 11:51:00AM +0100, Niklas Cassel wrote:
> > Revert all patches related to pcie-designware Root Complex Link Up IRQ
> > support.
> > 
> > While this fake hotplugging was a nice idea, it has shown that this feature
> > does not handle PCIe switches correctly:
> [...]
> > During the initial scan, PCI core doesn't see the switch and since the Root
> > Port is not hot plug capable, the secondary bus number gets assigned as the
> > subordinate bus number. This means, the PCI core assumes that only one bus
> > will appear behind the Root Port since the Root Port is not hot plug
> > capable.
> > 
> > This works perfectly fine for PCIe endpoints connected to the Root Port,
> > since they don't extend the bus. However, if a PCIe switch is connected,
> > then there is a problem when the downstream busses starts showing up and
> > the PCI core doesn't extend the subordinate bus number after initial scan
> > during boot.
> 
> In principle it is possible to set the is_hotplug_bridge flag on the
> bridge to force allocation of more buses.  We've already got a quirk
> to set the flag on a Conventional PCI bridge whose hotplug capability
> cannot be discovered otherwise (see quirk_hotplug_bridge() in
> drivers/pci/quirks.c).

While pdev->is_hotplug_bridge was also mentioned by Mani, he seems to
prefer a revert + eventual migration to pwrctrl framework:
https://lore.kernel.org/linux-pci/4f4wsgf56eublizg63fz6xmdjixesalb2q3rxetphd55jpqqju at zfyzsxfgiyim/
https://lore.kernel.org/linux-pci/2n3wamm3txxc6xbmvf3nnrvaqpgsck3w4a6omxnhex3mqeujib at 2tb4svn5d3z6/


Kind regards,
Niklas


From diederik at cknow-tech.com  Tue Nov 11 05:07:25 2025
From: diederik at cknow-tech.com (Diederik de Haas)
Date: Tue, 11 Nov 2025 14:07:25 +0100
Subject: [PATCH v2] arm64: dts: rockchip: Turn all LEDs on at boot for
 Radxa boards
In-Reply-To: <20251111054112.55505-1-naoki@radxa.com>
References: <20251111054112.55505-1-naoki@radxa.com>
Message-ID: <DE5W0143QGG2.3C7SW89IJKZ4P@cknow-tech.com>

On Tue Nov 11, 2025 at 6:41 AM CET, FUKAUMI Naoki wrote:
> Radxa's boards turn all LEDs on at boot(loader), but some boards don't
> have `default-state` property in Linux kernel tree but have it in
> U-Boot tree instead[1].
>
> This patch adds `default-state = "on"` for (almost) all LEDs (with a
> few exceptions which should be "off" such as RGB LEDs on E25 and LAN/
> WAN LEDs on E20C/E52C).

I'm missing the *why* these changes would be an improvement.

Personally, for both 'heartbeat' and 'netdev' triggers, I want them to
be off by default and once it gets a 'heartbeat' or a 'netdev' trigger,
THEN I want the LED to be on/blinking.

> Also, remove following redundant properties:
>  linux,default-trigger = "default-on"; // use default-state = "on"
>  default-state = "off"; // default is "off"
>
> [1]
>  https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3328-rock-pi-e-base-u-boot.dtsi#L10-12
>  https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3399-rock-4c-plus-u-boot.dtsi#L11-17
>  https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3399-rock-pi-4-u-boot.dtsi#L11-13
>  https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3566-radxa-cm3-io-u-boot.dtsi#L10-12
>  https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3566-rock-3c-u-boot.dtsi#L14-16
>  https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3568-radxa-e25-u-boot.dtsi#L7-24
>  https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3568-rock-3a-u-boot.dtsi#L11-13
>  https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3588-rock-5b-u-boot.dtsi#L11-13

That the *bootloader* turns them on, is fine by me as it signals the
board has received power and the bootloader has started.
I don't think that that automatically means that Linux must do the same.

Not a Radxa board, but the PineTab2's keyboard LEDs are turned on. I
find that useful wrt the bootloader, but (actually) annoying that it is
on by default with Linux. When I want/need backlight on the keyboard,
I'll turn it on myself. Now I need to turn it off in 90% of cases.

My 0.02

>  https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3588s-rock-5a-u-boot.dtsi#L10-12
>
> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> ---
> Changes in v2:
> - Add more URLs for reference
> - Reword commit message
> ---
>  arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts    | 1 -
>  arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts    | 1 +
>  arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts | 3 ++-
>  arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi   | 1 +
>  arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts   | 2 --
>  arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts      | 1 -
>  arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts | 1 +
>  arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts      | 1 +
>  arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi  | 1 +
>  arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts      | 1 +
>  arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts      | 3 ++-
>  arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts   | 2 --
>  arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts   | 3 ++-
>  arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi     | 1 +
>  arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts      | 1 +
>  arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts     | 3 ++-
>  16 files changed, 16 insertions(+), 10 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
> index 7a32972bc2496..c1e3098b9a7bc 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
> @@ -35,7 +35,6 @@ green-led {
>  			function = LED_FUNCTION_POWER;
>  			gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
>  			label = "rockpis:green:power";
> -			linux,default-trigger = "default-on";
>  		};
>  
>  		blue-led {
> diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
> index a4bdd87d0729f..d3d6f34b66fb0 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
> @@ -59,6 +59,7 @@ leds {
>  
>  		led-0 {
>  			color = <LED_COLOR_ID_BLUE>;
> +			default-state = "on";
>  			gpios = <&gpio3 RK_PA5 GPIO_ACTIVE_LOW>;
>  			linux,default-trigger = "heartbeat";
>  		};
> diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts
> index 962b8b231c960..a83ffbef22a7b 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts
> @@ -39,14 +39,15 @@ leds {
>  		led-0 {
>  			function = LED_FUNCTION_POWER;
>  			color = <LED_COLOR_ID_GREEN>;
> +			default-state = "on";
>  			gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_LOW>;
> -			linux,default-trigger = "default-on";
>  		};
>  
>  		/* USER_LED2 */
>  		led-1 {
>  			function = LED_FUNCTION_STATUS;
>  			color = <LED_COLOR_ID_BLUE>;
> +			default-state = "on";
>  			gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
>  			linux,default-trigger = "heartbeat";
>  		};
> diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
> index 046dbe3290178..ef434c23fe85c 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
> @@ -35,6 +35,7 @@ leds {
>  		led-0 {
>  			function = LED_FUNCTION_STATUS;
>  			color = <LED_COLOR_ID_BLUE>;
> +			default-state = "on";
>  			gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
>  			linux,default-trigger = "heartbeat";
>  		};
> diff --git a/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts b/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts
> index b324527561558..79d316a1d8495 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts
> @@ -62,7 +62,6 @@ leds {
>  
>  		led-lan {
>  			color = <LED_COLOR_ID_GREEN>;
> -			default-state = "off";
>  			function = LED_FUNCTION_LAN;
>  			gpios = <&gpio4 RK_PB5 GPIO_ACTIVE_HIGH>;
>  			linux,default-trigger = "netdev";
> @@ -78,7 +77,6 @@ led-sys {
>  
>  		led-wan {
>  			color = <LED_COLOR_ID_GREEN>;
> -			default-state = "off";
>  			function = LED_FUNCTION_WAN;
>  			gpios = <&gpio4 RK_PC0 GPIO_ACTIVE_HIGH>;
>  			linux,default-trigger = "netdev";
> diff --git a/arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts b/arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts
> index c03ae1dd34560..0b696d49b71fa 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts
> @@ -45,7 +45,6 @@ led-1 {
>  		default-state = "on";
>  		function = LED_FUNCTION_STATUS;
>  		gpios = <&gpio3 RK_PC1 GPIO_ACTIVE_LOW>;
> -		linux,default-trigger = "default-on";
>  	};
>  };
>  
> diff --git a/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts b/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
> index b5b253f04cdf5..9e7212b70e3f1 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
> @@ -46,6 +46,7 @@ leds {
>  		led-1 {
>  			gpios = <&gpio4 RK_PA4 GPIO_ACTIVE_LOW>;
>  			color = <LED_COLOR_ID_GREEN>;
> +			default-state = "on";
>  			function = LED_FUNCTION_ACTIVITY;
>  			linux,default-trigger = "heartbeat";
>  			pinctrl-names = "default";
> diff --git a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
> index 6224d72813e59..3ec108bcf89a1 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
> @@ -47,6 +47,7 @@ led-0 {
>  			gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
>  			function = LED_FUNCTION_HEARTBEAT;
>  			color = <LED_COLOR_ID_BLUE>;
> +			default-state = "on";
>  			linux,default-trigger = "heartbeat";
>  			pinctrl-names = "default";
>  			pinctrl-0 = <&user_led2>;
> diff --git a/arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi b/arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi
> index 729e38b9f620e..140582f8e1034 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi
> @@ -23,6 +23,7 @@ led_user: led-0 {
>  			gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
>  			function = LED_FUNCTION_HEARTBEAT;
>  			color = <LED_COLOR_ID_GREEN>;
> +			default-state = "on";
>  			linux,default-trigger = "heartbeat";
>  			pinctrl-names = "default";
>  			pinctrl-0 = <&led_user_en>;
> diff --git a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
> index 44cfdfeed6681..e6c18df0fa582 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
> @@ -47,6 +47,7 @@ led_user: led-0 {
>  			gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
>  			function = LED_FUNCTION_HEARTBEAT;
>  			color = <LED_COLOR_ID_BLUE>;
> +			default-state = "on";
>  			linux,default-trigger = "heartbeat";
>  			pinctrl-names = "default";
>  			pinctrl-0 = <&led_user_en>;
> diff --git a/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts b/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts
> index 9bc33422ced50..99d3a8be8f18c 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts
> @@ -52,13 +52,14 @@ leds: leds {
>  
>  		power-led {
>  			color = <LED_COLOR_ID_GREEN>;
> +			default-state = "on";
>  			function = LED_FUNCTION_STATUS;
>  			gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>;
> -			linux,default-trigger = "default-on";
>  		};
>  
>  		user-led {
>  			color = <LED_COLOR_ID_BLUE>;
> +			default-state = "on";
>  			function = LED_FUNCTION_HEARTBEAT;
>  			gpios = <&gpio0 RK_PC4 GPIO_ACTIVE_LOW>;
>  			linux,default-trigger = "heartbeat";
> diff --git a/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts b/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts
> index 854c118418eb8..f737769d4a007 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts
> @@ -71,7 +71,6 @@ leds-1 {
>  
>  		led-1 {
>  			color = <LED_COLOR_ID_GREEN>;
> -			default-state = "off";
>  			function = LED_FUNCTION_LAN;
>  			linux,default-trigger = "netdev";
>  			pwms = <&pwm14 0 1000000 PWM_POLARITY_INVERTED>;
> @@ -80,7 +79,6 @@ led-1 {
>  
>  		led-2 {
>  			color = <LED_COLOR_ID_GREEN>;
> -			default-state = "off";
>  			function = LED_FUNCTION_WAN;
>  			linux,default-trigger = "netdev";
>  			pwms = <&pwm11 0 1000000 PWM_POLARITY_INVERTED>;
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
> index bc8140883de47..86477346c3f5a 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
> @@ -88,11 +88,12 @@ gpio-leds {
>  		pinctrl-0 = <&led_pins>;
>  
>  		power-led1 {
> +			default-state = "on";
>  			gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
> -			linux,default-trigger = "default-on";
>  		};
>  
>  		hdd-led2 {
> +			default-state = "on";
>  			gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>;
>  			linux,default-trigger = "disk-activity";
>  		};
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi
> index e5c474e4d02a6..8c4a4270f9f93 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi
> @@ -30,6 +30,7 @@ leds {
>  		led_rgb_b {
>  			function = LED_FUNCTION_STATUS;
>  			color = <LED_COLOR_ID_BLUE>;
> +			default-state = "on";
>  			gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
>  			linux,default-trigger = "heartbeat";
>  		};
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts
> index 0dd90c744380b..87e9d4b86dad4 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts
> @@ -33,6 +33,7 @@ leds {
>  		led_rgb_b {
>  			function = LED_FUNCTION_STATUS;
>  			color = <LED_COLOR_ID_BLUE>;
> +			default-state = "on";
>  			gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
>  			linux,default-trigger = "heartbeat";
>  		};
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
> index 19a08f7794e67..46c81e796b100 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
> @@ -54,6 +54,7 @@ leds {
>  
>  		io-led {
>  			color = <LED_COLOR_ID_BLUE>;
> +			default-state = "on";
>  			function = LED_FUNCTION_STATUS;
>  			gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
>  			linux,default-trigger = "heartbeat";
> @@ -61,9 +62,9 @@ io-led {
>  
>  		power-led {
>  			color = <LED_COLOR_ID_GREEN>;
> +			default-state = "on";
>  			function = LED_FUNCTION_POWER;
>  			gpios = <&gpio3 RK_PC4 GPIO_ACTIVE_HIGH>;
> -			linux,default-trigger = "default-on";
>  		};
>  	};
>  



From cassel at kernel.org  Tue Nov 11 05:08:36 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Tue, 11 Nov 2025 14:08:36 +0100
Subject: [PATCH v3] PCI: dw-rockchip: Prevent advertising L1 Substates
 support
In-Reply-To: <176101411705.9573.17573145190800888773.b4-ty@kernel.org>
References: <20251017163252.598812-2-cassel@kernel.org>
 <176101411705.9573.17573145190800888773.b4-ty@kernel.org>
Message-ID: <aRM1VOodnSpaob3P@ryzen>

Hello Mani,

On Tue, Oct 21, 2025 at 08:05:17AM +0530, Manivannan Sadhasivam wrote:
> 
> On Fri, 17 Oct 2025 18:32:53 +0200, Niklas Cassel wrote:
> > The L1 substates support requires additional steps to work, namely:
> > -Proper handling of the CLKREQ# sideband signal. (It is mostly handled by
> >  hardware, but software still needs to set the clkreq fields in the
> >  PCIE_CLIENT_POWER_CON register to match the hardware implementation.)
> > -Program the frequency of the aux clock into the
> >  DSP_PCIE_PL_AUX_CLK_FREQ_OFF register. (During L1 substates the core_clk
> >  is turned off and the aux_clk is used instead.)
> > 
> > [...]
> 
> Applied, thanks!
> 
> [1/1] PCI: dw-rockchip: Prevent advertising L1 Substates support
>       commit: 40331c63e7901a2cc75ce6b5d24d50601efb833d

Last update in this thread was "Applied, thanks!"

and the patch was applied to pci/controller/dw-rockchip

since then it seems to have been demoted to pci/controller/dw-rockchip-pend

I'm simply curious, what is the plan for this patch?

I know that Shawn was working on a series that adds support for L1ss for
this driver, but it seems to have stagnated, so it seems far from certain
that it will be ready in time to make it for the v6.19 merge window.

Right now, pci/next branch seems to merge pci/controller/dw-rockchip rather
than pci/controller/dw-rockchip-pend.

If the L1ss does not make it in time, then this patch will not have had any
time in linux-next, which might not make Linus happy.


Kind regards,
Niklas


From shawn.lin at rock-chips.com  Tue Nov 11 05:28:08 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Tue, 11 Nov 2025 21:28:08 +0800
Subject: [PATCH v3] PCI: dw-rockchip: Prevent advertising L1 Substates
 support
In-Reply-To: <aRM1VOodnSpaob3P@ryzen>
References: <20251017163252.598812-2-cassel@kernel.org>
 <176101411705.9573.17573145190800888773.b4-ty@kernel.org>
 <aRM1VOodnSpaob3P@ryzen>
Message-ID: <6a2bef88-1fe8-4477-a179-e97e1e0b7178@rock-chips.com>


? 2025/11/11 ??? 21:08, Niklas Cassel ??:
> Hello Mani,
> 
> On Tue, Oct 21, 2025 at 08:05:17AM +0530, Manivannan Sadhasivam wrote:
>>
>> On Fri, 17 Oct 2025 18:32:53 +0200, Niklas Cassel wrote:
>>> The L1 substates support requires additional steps to work, namely:
>>> -Proper handling of the CLKREQ# sideband signal. (It is mostly handled by
>>>   hardware, but software still needs to set the clkreq fields in the
>>>   PCIE_CLIENT_POWER_CON register to match the hardware implementation.)
>>> -Program the frequency of the aux clock into the
>>>   DSP_PCIE_PL_AUX_CLK_FREQ_OFF register. (During L1 substates the core_clk
>>>   is turned off and the aux_clk is used instead.)
>>>
>>> [...]
>>
>> Applied, thanks!
>>
>> [1/1] PCI: dw-rockchip: Prevent advertising L1 Substates support
>>        commit: 40331c63e7901a2cc75ce6b5d24d50601efb833d
> 
> Last update in this thread was "Applied, thanks!"
> 
> and the patch was applied to pci/controller/dw-rockchip
> 
> since then it seems to have been demoted to pci/controller/dw-rockchip-pend
> 
> I'm simply curious, what is the plan for this patch?
> 
> I know that Shawn was working on a series that adds support for L1ss for
> this driver, but it seems to have stagnated, so it seems far from certain

Yes, that's because Bjorn prefers to disable it in dwc core intially and
sent a patch which we discussed but didn't come to a conclusion. So I 
still be waiting..:?

> that it will be ready in time to make it for the v6.19 merge window.
> 
> Right now, pci/next branch seems to merge pci/controller/dw-rockchip rather
> than pci/controller/dw-rockchip-pend.
> 
> If the L1ss does not make it in time, then this patch will not have had any
> time in linux-next, which might not make Linus happy.
> 
> 
> Kind regards,
> Niklas
> 



From shawn.lin at rock-chips.com  Tue Nov 11 05:33:56 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Tue, 11 Nov 2025 21:33:56 +0800
Subject: [PATCH 0/6] PCI: dwc: Revert Link Up IRQ support
In-Reply-To: <20251111105100.869997-8-cassel@kernel.org>
References: <20251111105100.869997-8-cassel@kernel.org>
Message-ID: <6b847014-ea46-4e16-8eab-c1a57e7a236e@rock-chips.com>


? 2025/11/11 ??? 18:51, Niklas Cassel ??:
> Revert all patches related to pcie-designware Root Complex Link Up IRQ
> support.
> 
> While this fake hotplugging was a nice idea, it has shown that this feature
> does not handle PCIe switches correctly:
> pci_bus 0004:43: busn_res: can not insert [bus 43-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:43: busn_res: [bus 43-41] end is updated to 43
> pci_bus 0004:43: busn_res: can not insert [bus 43] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:00.0: devices behind bridge are unusable because [bus 43] cannot be assigned for them
> pci_bus 0004:44: busn_res: can not insert [bus 44-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:44: busn_res: [bus 44-41] end is updated to 44
> pci_bus 0004:44: busn_res: can not insert [bus 44] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:02.0: devices behind bridge are unusable because [bus 44] cannot be assigned for them
> pci_bus 0004:45: busn_res: can not insert [bus 45-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:45: busn_res: [bus 45-41] end is updated to 45
> pci_bus 0004:45: busn_res: can not insert [bus 45] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:06.0: devices behind bridge are unusable because [bus 45] cannot be assigned for them
> pci_bus 0004:46: busn_res: can not insert [bus 46-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:46: busn_res: [bus 46-41] end is updated to 46
> pci_bus 0004:46: busn_res: can not insert [bus 46] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:0e.0: devices behind bridge are unusable because [bus 46] cannot be assigned for them
> pci_bus 0004:42: busn_res: [bus 42-41] end is updated to 46
> pci_bus 0004:42: busn_res: can not insert [bus 42-46] under [bus 41] (conflicts with (null) [bus 41])
> pci 0004:41:00.0: devices behind bridge are unusable because [bus 42-46] cannot be assigned for them
> pcieport 0004:40:00.0: bridge has subordinate 41 but max busn 46
> 
> During the initial scan, PCI core doesn't see the switch and since the Root
> Port is not hot plug capable, the secondary bus number gets assigned as the
> subordinate bus number. This means, the PCI core assumes that only one bus
> will appear behind the Root Port since the Root Port is not hot plug
> capable.
> 
> This works perfectly fine for PCIe endpoints connected to the Root Port,
> since they don't extend the bus. However, if a PCIe switch is connected,
> then there is a problem when the downstream busses starts showing up and
> the PCI core doesn't extend the subordinate bus number after initial scan
> during boot.
> 
> The long term plan is to migrate this driver to the pwrctrl framework,
> once it adds proper support for powering up and enumerating PCIe switches.

For pcie-dw-rockchip

Acked-by: Shawn Lin <shawn.lin at rock-chips.com>
Tested-by: Shawn Lin <shawn.lin at rock-chips.com>

> 
> Niklas Cassel (6):
>    Revert "PCI: dw-rockchip: Don't wait for link since we can detect Link
>      Up"
>    Revert "PCI: dw-rockchip: Enumerate endpoints based on dll_link_up
>      IRQ"
>    Revert "PCI: qcom: Don't wait for link if we can detect Link Up"
>    Revert "PCI: qcom: Enable MSI interrupts together with Link up if
>      'Global IRQ' is supported"
>    Revert "PCI: qcom: Enumerate endpoints based on Link up event in
>      'global_irq' interrupt"
>    Revert "PCI: dwc: Don't wait for link up if driver can detect Link Up
>      event"
> 
>   .../pci/controller/dwc/pcie-designware-host.c | 10 +--
>   drivers/pci/controller/dwc/pcie-designware.h  |  1 -
>   drivers/pci/controller/dwc/pcie-dw-rockchip.c | 60 +-----------------
>   drivers/pci/controller/dwc/pcie-qcom.c        | 63 +------------------
>   4 files changed, 6 insertions(+), 128 deletions(-)
> 



From cassel at kernel.org  Tue Nov 11 06:00:01 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Tue, 11 Nov 2025 15:00:01 +0100
Subject: [RESEND] Re: [PATCH] PCI: dw-rockchip: Skip waiting for link up
In-Reply-To: <05bd0efe-9a84-40e9-af07-51c0b0d865bf@rock-chips.com>
References: <780a4209-f89f-43a9-9364-331d3b77e61e@rock-chips.com>
 <4487DA40249CC821+19232169-a096-4737-bc6a-5cec9592d65f@radxa.com>
 <363d6b4d-c999-43d4-866e-880ef7d0dec3@rock-chips.com>
 <0C31787C387488ED+fd39bfe6-0844-4a87-bf48-675dd6d6a2df@radxa.com>
 <dc932773-af5b-4af7-a0d0-8cc72dfbd3c7@rock-chips.com>
 <aRHb4S40a7ZUDop1@ryzen>
 <2n3wamm3txxc6xbmvf3nnrvaqpgsck3w4a6omxnhex3mqeujib@2tb4svn5d3z6>
 <aRJEDEEJr9Ic-RKN@fedora>
 <B721C8A516FDB604+a04b38d3-64ec-423f-9e4c-040c8d2aec76@radxa.com>
 <05bd0efe-9a84-40e9-af07-51c0b0d865bf@rock-chips.com>
Message-ID: <aRNBYX8MbR7PtssY@ryzen>

On Tue, Nov 11, 2025 at 11:17:23AM +0800, Shawn Lin wrote:
> > 
> > It works stably on the ROCK 5A. The link speed is 2Gb/s.
> > 
> > The ROCK 5C is unstable. It initially worked with a link speed of 4Gb/s,
> > but eventually started showing kernel oops. The dts files for the 5A and
> > 5C are compatible and interchangeable, but even using the 5A's dts on
> > the 5C, the operation remains unstable.
> 
> The link speed on ROCK 5A is 2Gb/s also means it's downgraded now. Did
> ROCK 5A work under the link speed of 4Gb/s before?
> 
> In case it's signal integrity relevant, you could enable PCIE_DW_DEBUGFS
> and refer to Documentation/ABI/testing/debugfs-dwc-pcie to collect
> RASDES info from there.

Just a quick note:
I've noticed that you cannot blindly look at the link speed in dmesg.

E.g. on my ROCK 5B boards, I can occasionally see something like:
[    1.417181] pci 0000:01:00.0: 4.000 Gb/s available PCIe bandwidth, limited by 5.0 GT/s PCIe x1 link

However, if I check the actual link speed with lspci after boot:

# lspci -vvv  -s 0000:01:00.0 | grep LnkSta:
                LnkSta: Speed 8GT/s, Width x4

I can see that the link is actually using the correct speed + number of lanes.


Kind regards,
Niklas


From mani at kernel.org  Tue Nov 11 06:00:38 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Tue, 11 Nov 2025 19:30:38 +0530
Subject: [PATCH 0/6] PCI: dwc: Revert Link Up IRQ support
In-Reply-To: <aRMZS3EUYx189Xup@wunner.de>
References: <20251111105100.869997-8-cassel@kernel.org>
 <aRMZS3EUYx189Xup@wunner.de>
Message-ID: <admktutwz6542najyyo5vlrci5euqlxnwueaqxixxy7pruqoe5@6qbbejnn5gpb>

On Tue, Nov 11, 2025 at 12:08:59PM +0100, Lukas Wunner wrote:
> On Tue, Nov 11, 2025 at 11:51:00AM +0100, Niklas Cassel wrote:
> > Revert all patches related to pcie-designware Root Complex Link Up IRQ
> > support.
> > 
> > While this fake hotplugging was a nice idea, it has shown that this feature
> > does not handle PCIe switches correctly:
> [...]
> > During the initial scan, PCI core doesn't see the switch and since the Root
> > Port is not hot plug capable, the secondary bus number gets assigned as the
> > subordinate bus number. This means, the PCI core assumes that only one bus
> > will appear behind the Root Port since the Root Port is not hot plug
> > capable.
> > 
> > This works perfectly fine for PCIe endpoints connected to the Root Port,
> > since they don't extend the bus. However, if a PCIe switch is connected,
> > then there is a problem when the downstream busses starts showing up and
> > the PCI core doesn't extend the subordinate bus number after initial scan
> > during boot.
> 
> In principle it is possible to set the is_hotplug_bridge flag on the
> bridge to force allocation of more buses.  We've already got a quirk
> to set the flag on a Conventional PCI bridge whose hotplug capability
> cannot be discovered otherwise (see quirk_hotplug_bridge() in
> drivers/pci/quirks.c).

But here, the bridges are not hotplug capable at all. They do not support the
PCI Hot-Plug Specification. So setting the flag would be incorrect.

- Mani

-- 
????????? ????????


From dsimic at manjaro.org  Tue Nov 11 06:33:49 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Tue, 11 Nov 2025 15:33:49 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v6 0/3] Add Radxa CM5 and IO Board
In-Reply-To: <617FDAB231C501DC+3f9809df-87df-4a02-bd5f-ebc6299b3aa7@radxa.com>
References: <20251105051335.17652-1-naoki@radxa.com>
 <199E172C8E20ED38+71169242-5525-4d60-9e37-a03ad172d639@radxa.com>
 <CAMWSM7gezjVSoF+-7ivboTeB=5gQAE-QVrbAbKu3M=obmb3Axg@mail.gmail.com> <617FDAB231C501DC+3f9809df-87df-4a02-bd5f-ebc6299b3aa7@radxa.com>
Message-ID: <a10340af-1d0a-bb0b-4835-7b2c9e67d664@manjaro.org>

Hello all,

On Tuesday, November 11, 2025 12:52 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> On 11/6/25 02:48, Joseph Kogut wrote:
> > On Wed, Nov 5, 2025 at 4:15?AM FUKAUMI Naoki <naoki at radxa.com> wrote:
> >> I'd like to clarify the situation regarding the v6 patch series I submitted.
> >>
> >> The original device tree work for the Radxa CM5 and IO Board was
> >> authored by Joseph Kogut. I took over the responsibility of getting it
> >> upstreamed with his agreement.
> > 
> > I'll confirm this. I've been in communication with Naoki. They made a
> > large number of revisions to my original patch series, which I think
> > have technical merit. I suggested they submit the patches themselves,
> > and gave them explicit permission to add my Signed-off-by and CC me.
> > 
> > I assume this was the correct way for them to continue the work I
> > started, but if not, please let us know the best way to proceed.
> 
> Can anyone help us?

I'm not exactly sure how to resolve the current situation, but for
Signed-off-by tags to be present, in this case you'd need to have
Co-developed-by tags as well, because the final patch versions,
which would be submitted by Naoki, would differ significantly from
the versions that Joseph actively worked on, if I understood
everything correctly.  Though, for Joseph's Signed-off-by tags to
be included there, he would also need to participate actively in
the development of the final patch versions.

Another option, technically a bit simpler, would be to include just
Originally-by tags for Joseph, which would indicate that Joseph gave
up on the development of the patches and handed them over to Naoki
for future development and submission to the mailing lists. Though,
that would require Joseph to publicly state exactly that.



From dsimic at manjaro.org  Tue Nov 11 06:46:04 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Tue, 11 Nov 2025 15:46:04 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v2] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= Turn all LEDs on at boot for Radxa boards
In-Reply-To: <DE5W0143QGG2.3C7SW89IJKZ4P@cknow-tech.com>
References: <20251111054112.55505-1-naoki@radxa.com> <DE5W0143QGG2.3C7SW89IJKZ4P@cknow-tech.com>
Message-ID: <516e919a-42af-8707-4e75-a808df8971fd@manjaro.org>

Hello Diederik,

On Tuesday, November 11, 2025 14:07 CET, "Diederik de Haas" <diederik at cknow-tech.com> wrote:
> On Tue Nov 11, 2025 at 6:41 AM CET, FUKAUMI Naoki wrote:
> > Radxa's boards turn all LEDs on at boot(loader), but some boards don't
> > have `default-state` property in Linux kernel tree but have it in
> > U-Boot tree instead[1].
> >
> > This patch adds `default-state = "on"` for (almost) all LEDs (with a
> > few exceptions which should be "off" such as RGB LEDs on E25 and LAN/
> > WAN LEDs on E20C/E52C).
> 
> I'm missing the *why* these changes would be an improvement.
> 
> Personally, for both 'heartbeat' and 'netdev' triggers, I want them to
> be off by default and once it gets a 'heartbeat' or a 'netdev' trigger,
> THEN I want the LED to be on/blinking.

That's a good question for Naoki.  My own preference would also
be to have the device's power LED turned on by U-Boot as quickly
as possible after supplying power to the board or turning it on
by pressing the power button.  I'm actually not a big fan of
having all the LEDs shining for a couple of seconds or so, which
may actually look like some error condition to me.

Having all that in mind, I may suggest that just the U-Boot's
behavior is changed to turn the power LEDs on only.



From luca.ceresoli at bootlin.com  Tue Nov 11 07:14:11 2025
From: luca.ceresoli at bootlin.com (Luca Ceresoli)
Date: Tue, 11 Nov 2025 16:14:11 +0100
Subject: [PATCH v9 08/10] drm/rockchip: cdn-dp: Add multiple bridges to
 support PHY port selection
In-Reply-To: <20251111105040.94-9-kernel@airkyi.com>
References: <20251111105040.94-1-kernel@airkyi.com>
 <20251111105040.94-9-kernel@airkyi.com>
Message-ID: <DE5YP3AVGOG3.OHP68Z0F6KBU@bootlin.com>

Hello Chaoyi,

On Tue Nov 11, 2025 at 11:50 AM CET, Chaoyi Chen wrote:
> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
>
> The RK3399 has two USB/DP combo PHY and one CDN-DP controller. And
> the CDN-DP can be switched to output to one of the PHYs. If both ports
> are plugged into DP, DP will select the first port for output.
>
> This patch adds support for multiple bridges, enabling users to flexibly
> select the output port. For each PHY port, a separate encoder and bridge
> are registered.
>
> The change is based on the DRM AUX HPD bridge, rather than the
> extcon approach. This requires the DT to correctly describe the
> connections between the first bridge in bridge chain and DP
> controller. For example, the bridge chain may be like this:
>
> PHY aux birdge -> fsa4480 analog audio switch bridge ->
> onnn,nb7vpq904m USB reminder bridge -> USB-C controller AUX HPD bridge
>
> In this case, the connection relationships among the PHY aux bridge
> and the DP contorller need to be described in DT.
>
> In addition, the cdn_dp_parse_next_bridge_dt() will parses it and
> determines whether to register one or two bridges.
>
> Since there is only one DP controller, only one of the PHY ports can
> output at a time. The key is how to switch between different PHYs,
> which is handled by cdn_dp_switch_port() and cdn_dp_enable().
>
> There are two cases:
>
> 1. Neither bridge is enabled. In this case, both bridges can
> independently read the EDID, and the PHY port may switch before
> reading the EDID.
>
> 2. One bridge is already enabled. In this case, other bridges are not
> allowed to read the EDID. So we will try to return the cached EDID.
>
> Since the scenario of two ports plug in at the same time is rare,
> I don't have a board which support two TypeC connector to test this.
> Therefore, I tested forced switching on a single PHY port, as well as
> output using a fake PHY port alongside a real PHY port.
>
> Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>

[...]

> @@ -966,28 +1084,16 @@ static int cdn_dp_pd_event(struct notifier_block *nb,
>  	return NOTIFY_DONE;
>  }
>
> -static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
> +static int cdn_bridge_add(struct device *dev,
> +			  struct drm_bridge *bridge,
> +			  struct drm_bridge *next_bridge,
> +			  struct drm_encoder *encoder)
>  {
>  	struct cdn_dp_device *dp = dev_get_drvdata(dev);
> -	struct drm_encoder *encoder;
> +	struct drm_device *drm_dev = dp->drm_dev;
> +	struct drm_bridge *last_bridge = NULL;
>  	struct drm_connector *connector;
> -	struct cdn_dp_port *port;
> -	struct drm_device *drm_dev = data;
> -	int ret, i;

[...]

> +	if (next_bridge) {
> +		ret = drm_bridge_attach(encoder, next_bridge, bridge,
> +					DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> +		if (ret)
> +			return ret;
> +
> +		last_bridge = next_bridge;
> +		while (drm_bridge_get_next_bridge(last_bridge))
> +			last_bridge = drm_bridge_get_next_bridge(last_bridge);

DRM bridges are now refcounted, and you are not calling drm_bridge_get()
and drm_bridge_put() here. But here you can use
drm_bridge_chain_get_last_bridge() which will simplify your job.

Don't forget to call drm_bridge_put() on the returned bridge when the
bridge is not referenced anymore. This should be as easy as adding a
cleanup action on the variable declaration above:

-	struct drm_bridge *last_bridge = NULL;
+	struct drm_bridge *last_bridge __free(drm_bridge_put) = NULL;

> @@ -1029,8 +1147,102 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
>  		return ret;
>  	}
>
> +	if (last_bridge)
> +		connector->fwnode = fwnode_handle_get(of_fwnode_handle(last_bridge->of_node));
> +
>  	drm_connector_attach_encoder(connector, encoder);
>
> +	return 0;
> +}
> +
> +static int cdn_dp_parse_next_bridge_dt(struct cdn_dp_device *dp)
> +{
> +	struct device_node *np = dp->dev->of_node;
> +	struct device_node *port __free(device_node) = of_graph_get_port_by_id(np, 1);
> +	struct drm_bridge *bridge;
> +	int count = 0;
> +	int ret = 0;
> +	int i;
> +
> +	/* If device use extcon, do not use hpd bridge */
> +	for (i = 0; i < dp->ports; i++) {
> +		if (dp->port[i]->extcon) {
> +			dp->bridge_count = 1;
> +			return 0;
> +		}
> +	}
> +
> +
> +	/* One endpoint may correspond to one next bridge. */
> +	for_each_of_graph_port_endpoint(port, dp_ep) {
> +		struct device_node *next_bridge_node __free(device_node) =
> +			of_graph_get_remote_port_parent(dp_ep);
> +
> +		bridge = of_drm_find_bridge(next_bridge_node);
> +		if (!bridge) {
> +			ret = -EPROBE_DEFER;
> +			goto out;
> +		}
> +
> +		dp->next_bridge_valid = true;
> +		dp->next_bridge_list[count].bridge = bridge;

You are storing a reference to a drm_bridge, so have to increment the
refcount:

		dp->next_bridge_list[count].bridge = drm_bridge_get(bridge);
		                                     ^^^^^^^^^^^^^^

FYI there is a plan to replace of_drm_find_bridge() with a function that
increases the bridge refcount before returning the bridge, but it's not
there yet. When that will happen, the explicit drm_bridge_get() won't be
needed anymore and this code can be updated accordingly.

Also you have to call drm_bridge_put() to release that reference when the
pointer goes away. I guess that should happen in cdn_dp_unbind().

> +static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
> +{

In this function you do:
...(see below)...

> +	struct cdn_dp_device *dp = dev_get_drvdata(dev);
> +	struct drm_bridge *bridge, *next_bridge;
> +	struct drm_encoder *encoder;
> +	struct cdn_dp_port *port;
> +	struct drm_device *drm_dev = data;
> +	struct cdn_dp_bridge *dp_bridge;
> +	int ret, i;
> +
> +	ret = cdn_dp_parse_dt(dp);
> +	if (ret < 0)
.> +		return ret;
> +
> +	ret = cdn_dp_parse_next_bridge_dt(dp);

1. compute the next bridges and store them in dp->next_bridge_list[]
...

> +	if (ret)
> +		return ret;
> +
> +	dp->drm_dev = drm_dev;
> +	dp->connected = false;
> +	dp->active = false;
> +	dp->active_port = -1;
> +	dp->fw_loaded = false;
> +
> +	for (i = 0; i < dp->bridge_count; i++) {
> +		dp_bridge = devm_drm_bridge_alloc(dev, struct cdn_dp_bridge, bridge,
> +						    &cdn_dp_bridge_funcs);
> +		if (IS_ERR(dp_bridge))
> +			return PTR_ERR(dp_bridge);
> +		dp_bridge->id = i;
> +		dp_bridge->parent = dp;
> +		if (!dp->next_bridge_valid)
> +			dp_bridge->connected = true;
> +		dp->bridge_list[i] = dp_bridge;
> +	}
> +
> +	for (i = 0; i < dp->bridge_count; i++) {
> +		encoder = &dp->bridge_list[i]->encoder.encoder;
> +		bridge = &dp->bridge_list[i]->bridge;
> +		next_bridge = dp->next_bridge_list[i].bridge;
> +		ret = cdn_bridge_add(dev, bridge, next_bridge, encoder);

...
2. pass the dp->next_bridge_list[i].bridge to cdn_bridge_add
3. not use  dp->next_bridge_list[i] elsewhere

So you may want to change this function to parse into a local array, with
function scope. If you do this, the drm_bridge_get/put() I mentioned above
should still exist, but would be localized to this function, thus even
easier to handle.

Even better, you can parse the DT one bridge at a time inside the for loop,
so you don't need to store any next_bridge pointer array. This will need a
bit of rework of cdn_dp_parse_next_bridge_dt() though, and I haven't
checked in detail so it might be not worth.

[...]

> +struct cdn_dp_bridge {
> +	struct cdn_dp_device *parent;
> +	struct drm_bridge bridge;
> +	struct rockchip_encoder encoder;
> +	bool connected;
> +	bool enabled;
> +	int id;
> +};
> +
> +struct cdn_dp_next_bridge {
> +	struct cdn_dp_device *parent;
> +	struct drm_bridge *bridge;
> +	int id;

The @parent and @id fields are unused if I'm not mistaken.

If it is the case then you can... (see below)

>  struct cdn_dp_device {
>  	struct device *dev;
>  	struct drm_device *drm_dev;
> -	struct drm_bridge bridge;
> -	struct rockchip_encoder encoder;
> +	int bridge_count;
> +	struct cdn_dp_bridge *bridge_list[MAX_PHY];
> +	struct cdn_dp_next_bridge next_bridge_list[MAX_PHY];

...replace this line with:
	struct drm_bridge *next_bridge[MAX_PHY];

Unless of course you just don't store the next_bridge at all, as I
suggested above, and which looks way easier and more efficient.

Best regards,
Luca

--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From naoki at radxa.com  Tue Nov 11 07:32:57 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Wed, 12 Nov 2025 00:32:57 +0900
Subject: [PATCH v2] arm64: dts: rockchip: Turn all LEDs on at boot for
 Radxa boards
In-Reply-To: <516e919a-42af-8707-4e75-a808df8971fd@manjaro.org>
References: <20251111054112.55505-1-naoki@radxa.com>
 <DE5W0143QGG2.3C7SW89IJKZ4P@cknow-tech.com>
 <516e919a-42af-8707-4e75-a808df8971fd@manjaro.org>
Message-ID: <B0C8C5A69B9F465E+ba0ad139-d3d9-4492-ac9a-cc58f8f35074@radxa.com>

Hi Diederik, Dragan,

On 11/11/25 23:46, Dragan Simic wrote:
> Hello Diederik,
> 
> On Tuesday, November 11, 2025 14:07 CET, "Diederik de Haas" <diederik at cknow-tech.com> wrote:
>> On Tue Nov 11, 2025 at 6:41 AM CET, FUKAUMI Naoki wrote:
>>> Radxa's boards turn all LEDs on at boot(loader), but some boards don't
>>> have `default-state` property in Linux kernel tree but have it in
>>> U-Boot tree instead[1].
>>>
>>> This patch adds `default-state = "on"` for (almost) all LEDs (with a
>>> few exceptions which should be "off" such as RGB LEDs on E25 and LAN/
>>> WAN LEDs on E20C/E52C).
>>
>> I'm missing the *why* these changes would be an improvement.
>>
>> Personally, for both 'heartbeat' and 'netdev' triggers, I want them to
>> be off by default and once it gets a 'heartbeat' or a 'netdev' trigger,
>> THEN I want the LED to be on/blinking.
> 
> That's a good question for Naoki.  My own preference would also
> be to have the device's power LED turned on by U-Boot as quickly
> as possible after supplying power to the board or turning it on
> by pressing the power button.  I'm actually not a big fan of
> having all the LEDs shining for a couple of seconds or so, which
> may actually look like some error condition to me.
> 
> Having all that in mind, I may suggest that just the U-Boot's
> behavior is changed to turn the power LEDs on only.

I can't quite explain it, but...

- 1st (Power) LED

The 1st (power) LED turns on automatically/immediately without software 
intervention. (On some boards, this LED cannot be controlled by software 
at all.)

In DTS, this should be described using `default-state = "on"`. The use 
of the Linux-specific property `linux,default-trigger = "default-on"` is 
unsuitable for non-Linux environments.

- 2nd (Heartbeat) LED

The 2nd (heartbeat) LED can be controlled by software. It should be lit 
up as quickly as possible to indicate that the very first software 
(e.g., the bootloader) is running.

On Linux, usually this is used as `linux,default-trigger = "heartbeat"`. 
It indicates that kernel is running (regardless of the `default-state` 
setting), and its behavior can be modified in user space.

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.


From dsimic at manjaro.org  Tue Nov 11 08:14:59 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Tue, 11 Nov 2025 17:14:59 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v2] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= Turn all LEDs on at boot for Radxa boards
In-Reply-To: <B0C8C5A69B9F465E+ba0ad139-d3d9-4492-ac9a-cc58f8f35074@radxa.com>
References: <20251111054112.55505-1-naoki@radxa.com>
 <DE5W0143QGG2.3C7SW89IJKZ4P@cknow-tech.com>
 <516e919a-42af-8707-4e75-a808df8971fd@manjaro.org> <B0C8C5A69B9F465E+ba0ad139-d3d9-4492-ac9a-cc58f8f35074@radxa.com>
Message-ID: <41275775-9e6e-9202-4c79-6140a56e41d5@manjaro.org>

Hello all,

(+ Quentin)

On Tuesday, November 11, 2025 16:32 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> On 11/11/25 23:46, Dragan Simic wrote:
> > On Tuesday, November 11, 2025 14:07 CET, "Diederik de Haas" <diederik at cknow-tech.com> wrote:
> >> On Tue Nov 11, 2025 at 6:41 AM CET, FUKAUMI Naoki wrote:
> >>> Radxa's boards turn all LEDs on at boot(loader), but some boards don't
> >>> have `default-state` property in Linux kernel tree but have it in
> >>> U-Boot tree instead[1].
> >>>
> >>> This patch adds `default-state = "on"` for (almost) all LEDs (with a
> >>> few exceptions which should be "off" such as RGB LEDs on E25 and LAN/
> >>> WAN LEDs on E20C/E52C).
> >>
> >> I'm missing the *why* these changes would be an improvement.
> >>
> >> Personally, for both 'heartbeat' and 'netdev' triggers, I want them to
> >> be off by default and once it gets a 'heartbeat' or a 'netdev' trigger,
> >> THEN I want the LED to be on/blinking.
> > 
> > That's a good question for Naoki.  My own preference would also
> > be to have the device's power LED turned on by U-Boot as quickly
> > as possible after supplying power to the board or turning it on
> > by pressing the power button.  I'm actually not a big fan of
> > having all the LEDs shining for a couple of seconds or so, which
> > may actually look like some error condition to me.
> > 
> > Having all that in mind, I may suggest that just the U-Boot's
> > behavior is changed to turn the power LEDs on only.
> 
> I can't quite explain it, but...
> 
> - 1st (Power) LED
> 
> The 1st (power) LED turns on automatically/immediately without software 
> intervention. (On some boards, this LED cannot be controlled by software 
> at all.)
> 
> In DTS, this should be described using `default-state = "on"`. The use 
> of the Linux-specific property `linux,default-trigger = "default-on"` is 
> unsuitable for non-Linux environments.
> 
> - 2nd (Heartbeat) LED
> 
> The 2nd (heartbeat) LED can be controlled by software. It should be lit 
> up as quickly as possible to indicate that the very first software 
> (e.g., the bootloader) is running.
> 
> On Linux, usually this is used as `linux,default-trigger = "heartbeat"`. 
> It indicates that kernel is running (regardless of the `default-state` 
> setting), and its behavior can be modified in user space.

As discussed already in the #linux-rockchip IRC channel, [1] perhaps
the best option would be to have the power LEDs turned on as quickly
upon powering on the board as possible, and to have U-Boot pulsate
the heartbeat LEDs using the LED_BOOT feature.  In such a scenario,
no other LEDs would be turned on early, and the LED-related DT parts
specific to U-Boot would be migrated to the kernel DTs.

[1] https://libera.catirclogs.org/linux-rockchip/2025-11-11#38997824;



From ulf.hansson at linaro.org  Tue Nov 11 08:55:26 2025
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 11 Nov 2025 17:55:26 +0100
Subject: [PATCH] mmc: dw_mmc-rockchip: Add memory clock auto-gating support
In-Reply-To: <1762242094-55346-1-git-send-email-shawn.lin@rock-chips.com>
References: <1762242094-55346-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <CAPDyKFpLp--cn4T3ifL8zB=GqptHZtnRH+V8Z370LNsj7n3wNA@mail.gmail.com>

On Tue, 4 Nov 2025 at 08:41, Shawn Lin <shawn.lin at rock-chips.com> wrote:
>
> Per design recommendations, the memory clock can be gated when there
> is no in-flight transfer, which helps save power. This feature is
> introduced alongside internal phase support, and this patch enables it.

Just to make sure, does this work if the controller is used for SDIO
and has SDIO irqs enabled?

Or perhaps that is taken care of in dw_mci_prepare_sdio_irq()?

>
> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>

Kind regards
Uffe

> ---
>
>  drivers/mmc/host/dw_mmc-rockchip.c | 6 ++++++
>  1 file changed, 6 insertions(+)
>
> diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c
> index 6813549..62c68cd 100644
> --- a/drivers/mmc/host/dw_mmc-rockchip.c
> +++ b/drivers/mmc/host/dw_mmc-rockchip.c
> @@ -19,6 +19,8 @@
>  #define RK3288_CLKGEN_DIV              2
>  #define SDMMC_TIMING_CON0              0x130
>  #define SDMMC_TIMING_CON1              0x134
> +#define SDMMC_MISC_CON                 0x138
> +#define MEM_CLK_AUTOGATE_ENABLE                BIT(5)
>  #define ROCKCHIP_MMC_DELAY_SEL         BIT(10)
>  #define ROCKCHIP_MMC_DEGREE_MASK       0x3
>  #define ROCKCHIP_MMC_DEGREE_OFFSET     1
> @@ -470,6 +472,7 @@ static int dw_mci_rk3576_parse_dt(struct dw_mci *host)
>
>  static int dw_mci_rockchip_init(struct dw_mci *host)
>  {
> +       struct dw_mci_rockchip_priv_data *priv = host->priv;
>         int ret, i;
>
>         /* It is slot 8 on Rockchip SoCs */
> @@ -494,6 +497,9 @@ static int dw_mci_rockchip_init(struct dw_mci *host)
>                         dev_warn(host->dev, "no valid minimum freq: %d\n", ret);
>         }
>
> +       if (priv->internal_phase)
> +               mci_writel(host, MISC_CON, MEM_CLK_AUTOGATE_ENABLE);
> +
>         return 0;
>  }
>
> --
> 2.7.4
>


From michael.opdenacker at rootcommit.com  Tue Nov 11 09:20:22 2025
From: michael.opdenacker at rootcommit.com (michael.opdenacker at rootcommit.com)
Date: Tue, 11 Nov 2025 17:20:22 +0000 (UTC)
Subject: [PATCH 1/2] dt-bindings: arm: rockchip: Asus Tinkerboard 3 and 3S
In-Reply-To: <20251111172003.2324525-1-michael.opdenacker@rootcommit.com>
References: <20251111172003.2324525-1-michael.opdenacker@rootcommit.com>
Message-ID: <20251111172003.2324525-2-michael.opdenacker@rootcommit.com>

From: Michael Opdenacker <michael.opdenacker at rootcommit.com>

Document the compatible strings for Asus Tinkerboard 3 [1] and 3S [2],
which are SBCs based on the Rockchip 3566 SoC.

The "3S" version ("S" for "storage") just adds a 16 GB eMMC
and a "mask ROM" DIP switch to the "3" version.

Link: https://tinker-board.asus.com/series/tinker-board-3.html [1]
Link: https://tinker-board.asus.com/series/tinker-board-3s.html [2]
Signed-off-by: Michael Opdenacker <michael.opdenacker at rootcommit.com>
---
 Documentation/devicetree/bindings/arm/rockchip.yaml | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
index 6aceaa8acbb2..451597a6cffb 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.yaml
+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
@@ -86,6 +86,17 @@ properties:
           - const: asus,rk3288-tinker-s
           - const: rockchip,rk3288
 
+      - description: Asus Tinker board 3
+        items:
+          - const: asus,rk3566-tinker-3
+          - const: rockchip,rk3566
+
+      - description: Asus Tinker board 3S
+        items:
+          - const: asus,rk3566-tinker-3s
+          - const: asus,rk3566-tinker-3
+          - const: rockchip,rk3566
+
       - description: Beelink A1
         items:
           - const: azw,beelink-a1


From michael.opdenacker at rootcommit.com  Tue Nov 11 09:20:23 2025
From: michael.opdenacker at rootcommit.com (michael.opdenacker at rootcommit.com)
Date: Tue, 11 Nov 2025 17:20:23 +0000 (UTC)
Subject: [PATCH 2/2] arm64: dts: rockchip: add Tinkerboard 3 and 3S device tree
In-Reply-To: <20251111172003.2324525-1-michael.opdenacker@rootcommit.com>
References: <20251111172003.2324525-1-michael.opdenacker@rootcommit.com>
Message-ID: <20251111172003.2324525-3-michael.opdenacker@rootcommit.com>

From: Michael Opdenacker <michael.opdenacker at rootcommit.com>

Add initial device tree support for Asus Tinkerboard 3 [1] and 3S [2],
which are SBCs based on the Rockchip 3566 SoC.

The "3S" version ("S" for "storage") just adds a 16 GB eMMC
and a "mask ROM" DIP switch (to mask the eMMC and enter "Mask ROM"
mode for recovery) to the "3" version.

This adds support for:
- Debug UART (/dev/ttyS2)
- SD card (/dev/mmcblk1)
- eMMC (/dev/mmcblk0, only on Tinkerboard 3S)
- I2C:
  - i2c0 (internal bus with a PMIC and regulators)
  - i2c2 (internal bus with an at24 eeprom and an RTC device)
- USB 2.0 ports
- 2 GPIO LEDS

Link: https://tinker-board.asus.com/series/tinker-board-3.html [1]
Link: https://tinker-board.asus.com/series/tinker-board-3s.html [2]
Signed-off-by: Michael Opdenacker <michael.opdenacker at rootcommit.com>
---
 arch/arm64/boot/dts/rockchip/Makefile         |   2 +
 .../boot/dts/rockchip/rk3566-tinker-3.dts     |  14 +
 .../boot/dts/rockchip/rk3566-tinker-3.dtsi    | 264 ++++++++++++++++++
 .../boot/dts/rockchip/rk3566-tinker-3s.dts    |  30 ++
 4 files changed, 310 insertions(+)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-tinker-3.dts
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-tinker-3.dtsi
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-tinker-3s.dts

diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index ad684e3831bc..381831cab20c 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -130,6 +130,8 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-lubancat-1.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-nanopi-r3s.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-bigtreetech-cb2-manta.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-bigtreetech-pi2.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-tinker-3.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-tinker-3s.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-bpi-r2-pro.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-v10.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-fastrhino-r66s.dtb
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-tinker-3.dts b/arch/arm64/boot/dts/rockchip/rk3566-tinker-3.dts
new file mode 100644
index 000000000000..938af35b9004
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-tinker-3.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2025 Michael Opdenacker <michael.opdenacker at rootcommit.com>
+ */
+
+/dts-v1/;
+
+#include "rk3566-tinker-3.dtsi"
+
+/ {
+	model = "Rockchip RK3566 Asus Tinker Board 3";
+	compatible = "asus,rk3566-tinker-3", "rockchip,rk3566";
+};
+
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-tinker-3.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-tinker-3.dtsi
new file mode 100644
index 000000000000..45269d33b0cb
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-tinker-3.dtsi
@@ -0,0 +1,264 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2025 Michael Opdenacker <michael.opdenacker at rootcommit.com>
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
+#include "rk3566.dtsi"
+
+/ {
+	aliases {
+		serial2 = &uart2;
+		mmc1 = &sdmmc0;
+		i2c0 = &i2c0;
+		i2c2 = &i2c2;
+	};
+
+	chosen {
+		stdout-path = "serial2:1500000n8";
+	};
+
+	vcc3v3_sys: regulator-3v3-vcc-sys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+
+	vcc5v0_sys: regulator-5v0-vcc-sys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+	};
+
+	vcc5v0_usb_host: regulator-5v0-vcc-usb-host {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&usb_host_pwren_h>;
+		regulator-name = "vcc5v0_usb_host";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+
+	gpio_leds: gpio-leds {
+		compatible = "gpio-leds";
+
+		act-led {
+			gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger="mmc1";
+};
+
+		rsv-led {
+			gpios = <&gpio0 RK_PD6 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger="none";
+		};
+	};
+};
+
+&uart2 {
+	status = "okay";
+};
+
+&i2c0 {
+	status = "okay";
+
+	rk809: pmic at 20 {
+		compatible = "rockchip,rk809";
+		reg = <0x20>;
+		assigned-clocks = <&cru I2S1_MCLKOUT_TX>;
+		assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>;
+		#clock-cells = <1>;
+		clocks = <&cru I2S1_MCLKOUT_TX>;
+		clock-names = "mclk";
+		clock-output-names = "rk809-clkout1", "rk809-clkout2";
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_int_l>, <&i2s1m0_mclk>;
+		#sound-dai-cells = <0>;
+		system-power-controller;
+		wakeup-source;
+
+		vcc1-supply = <&vcc3v3_sys>;
+		vcc2-supply = <&vcc3v3_sys>;
+		vcc3-supply = <&vcc3v3_sys>;
+		vcc4-supply = <&vcc3v3_sys>;
+		vcc5-supply = <&vcc3v3_sys>;
+		vcc6-supply = <&vcc3v3_sys>;
+		vcc7-supply = <&vcc3v3_sys>;
+		vcc8-supply = <&vcc3v3_sys>;
+		vcc9-supply = <&vcc3v3_sys>;
+
+		regulators {
+			vcc_1v8: DCDC_REG5 {
+				regulator-name = "vcc_1v8";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc3v3_sd: SWITCH_REG2 {
+				regulator-name = "vcc3v3_sd";
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vccio_sd: LDO_REG5 {
+				regulator-name = "vccio_sd";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_3v3: SWITCH_REG1 {
+				regulator-name = "vcc_3v3";
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+		};
+	};
+
+	vdd_cpu: regulator at 40 {
+		compatible = "silergy,syr827";
+		reg = <0x40>;
+		fcs,suspend-voltage-selector = <1>;
+		regulator-name = "vdd_cpu";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <830000>;
+		regulator-max-microvolt = <1200000>;
+		regulator-ramp-delay = <2300>;
+		vin-supply = <&vcc3v3_sys>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+};
+
+&i2c2 {
+	status = "okay";
+
+	m24c08 at 50 {
+		compatible = "atmel,24c08";
+		reg = <0x50>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&tb3_eeprom>;
+		status = "okay";
+	};
+
+	rtc_isl1208: rtc at 6f {
+		compatible = "isil,isl1208";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_externalrtc_reg>;
+		interrupt-names = "irq";
+		interrupts-extended = <&gpio0 RK_PD3 IRQ_TYPE_EDGE_FALLING>;
+		reg = <0x6f>;
+		status = "okay";
+	};
+};
+
+&sdmmc0 {
+	bus-width = <4>;
+	cap-sd-highspeed;
+	disable-wp;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
+	vmmc-supply = <&vcc3v3_sd>;
+	vqmmc-supply = <&vccio_sd>;
+	status = "okay";
+};
+
+&usb_host0_ehci {
+	status = "okay";
+};
+
+&usb_host0_ohci {
+	status = "okay";
+};
+
+&usb_host1_ehci {
+	status = "okay";
+};
+
+&usb_host1_ohci {
+	status = "okay";
+};
+
+&usb2phy0 {
+	status = "okay";
+};
+
+&usb2phy0_host {
+	phy-supply = <&vcc5v0_usb_host>;
+	status = "okay";
+};
+
+&usb2phy1 {
+	status = "okay";
+};
+
+&usb2phy1_host {
+	phy-supply = <&vcc5v0_usb_host>;
+	status = "okay";
+};
+
+&pinctrl {
+	pmic {
+		pmic_int_l: pmic-int-l {
+			rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	usb {
+		usb_host_pwren_h: usb-host-pwren-h {
+			rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		usb_otg_pwren_h: usb-otg-pwren-h {
+			rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	rtc {
+		pinctrl_externalrtc_reg: externalrtcreggrp {
+			rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	eeprom {
+		tb3_eeprom: tb3-eeprom {
+			rockchip,pins = <3 RK_PC1 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-tinker-3s.dts b/arch/arm64/boot/dts/rockchip/rk3566-tinker-3s.dts
new file mode 100644
index 000000000000..ba7efd702050
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-tinker-3s.dts
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2025 Michael Opdenacker <michael.opdenacker at rootcommit.com>
+ */
+
+/dts-v1/;
+
+#include "rk3566-tinker-3.dtsi"
+
+/ {
+	model = "Rockchip RK3566 Asus Tinker Board 3S";
+	compatible = "asus,rk3566-tinker-3s", "asus,rk3566-tinker-3", "rockchip,rk3566";
+
+	aliases {
+		mmc0 = &sdhci;
+	};
+};
+
+&sdhci {
+	bus-width = <8>;
+	cap-mmc-highspeed;
+	max-frequency = <200000000>;
+	mmc-hs200-1_8v;
+	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
+	vmmc-supply = <&vcc_3v3>;
+	vqmmc-supply = <&vcc_1v8>;
+	status = "okay";
+};


From ulf.hansson at linaro.org  Tue Nov 11 09:36:13 2025
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 11 Nov 2025 18:36:13 +0100
Subject: [PATCH v2 1/2] mmc: sdhci-of-dwcmshc: Add command queue support
 for rockchip SOCs
In-Reply-To: <20251031-rockchip-emmc-cqe-support-v2-1-958171f5edad@collabora.com>
References: <20251031-rockchip-emmc-cqe-support-v2-0-958171f5edad@collabora.com>
 <20251031-rockchip-emmc-cqe-support-v2-1-958171f5edad@collabora.com>
Message-ID: <CAPDyKFrSKDE4BNLGge0qk2A3m+MfNjfRsqc0VJ-NMekBRFPNSw@mail.gmail.com>

On Fri, 31 Oct 2025 at 16:58, Sebastian Reichel
<sebastian.reichel at collabora.com> wrote:
>
> This adds CQE support for the Rockchip RK3588 and RK3576 platform. To
> be functional, the eMMC device-tree node must have a 'supports-cqe;'
> flag property.
>
> As the RK3576 device-tree has been upstreamed with the 'supports-cqe;'
> property set by default, the kernel already tried to use CQE, which
> results in system hang during suspend. This fixes the issue.
>
> Co-developed-by: Yifeng Zhao <yifeng.zhao at rock-chips.com>
> Signed-off-by: Yifeng Zhao <yifeng.zhao at rock-chips.com>
> Signed-off-by: Sebastian Reichel <sebastian.reichel at collabora.com>

Applied for next, thanks!

Kind regards
Uffe


> ---
>  drivers/mmc/host/sdhci-of-dwcmshc.c | 93 +++++++++++++++++++++++++++++++++++--
>  1 file changed, 90 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c
> index eebd45389956..47509435254b 100644
> --- a/drivers/mmc/host/sdhci-of-dwcmshc.c
> +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c
> @@ -24,6 +24,7 @@
>
>  #include "sdhci-pltfm.h"
>  #include "cqhci.h"
> +#include "sdhci-cqhci.h"
>
>  #define SDHCI_DWCMSHC_ARG2_STUFF       GENMASK(31, 16)
>
> @@ -82,6 +83,8 @@
>  #define DWCMSHC_EMMC_DLL_TXCLK         0x808
>  #define DWCMSHC_EMMC_DLL_STRBIN                0x80c
>  #define DECMSHC_EMMC_DLL_CMDOUT                0x810
> +#define DECMSHC_EMMC_MISC_CON          0x81C
> +#define MISC_INTCLK_EN                 BIT(1)
>  #define DWCMSHC_EMMC_DLL_STATUS0       0x840
>  #define DWCMSHC_EMMC_DLL_START         BIT(0)
>  #define DWCMSHC_EMMC_DLL_LOCKED                BIT(8)
> @@ -234,6 +237,7 @@ struct dwcmshc_priv {
>
>  struct dwcmshc_pltfm_data {
>         const struct sdhci_pltfm_data pdata;
> +       const struct cqhci_host_ops *cqhci_host_ops;
>         int (*init)(struct device *dev, struct sdhci_host *host, struct dwcmshc_priv *dwc_priv);
>         void (*postinit)(struct sdhci_host *host, struct dwcmshc_priv *dwc_priv);
>  };
> @@ -561,6 +565,68 @@ static void dwcmshc_cqhci_dumpregs(struct mmc_host *mmc)
>         sdhci_dumpregs(mmc_priv(mmc));
>  }
>
> +static void rk35xx_sdhci_cqe_pre_enable(struct mmc_host *mmc)
> +{
> +       struct sdhci_host *host = mmc_priv(mmc);
> +       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> +       struct dwcmshc_priv *dwc_priv = sdhci_pltfm_priv(pltfm_host);
> +       u32 reg;
> +
> +       reg = sdhci_readl(host, dwc_priv->vendor_specific_area2 + CQHCI_CFG);
> +       reg |= CQHCI_ENABLE;
> +       sdhci_writel(host, reg, dwc_priv->vendor_specific_area2 + CQHCI_CFG);
> +}
> +
> +static void rk35xx_sdhci_cqe_enable(struct mmc_host *mmc)
> +{
> +       struct sdhci_host *host = mmc_priv(mmc);
> +       u32 reg;
> +
> +       reg = sdhci_readl(host, SDHCI_PRESENT_STATE);
> +       while (reg & SDHCI_DATA_AVAILABLE) {
> +               sdhci_readl(host, SDHCI_BUFFER);
> +               reg = sdhci_readl(host, SDHCI_PRESENT_STATE);
> +       }
> +
> +       sdhci_writew(host, DWCMSHC_SDHCI_CQE_TRNS_MODE, SDHCI_TRANSFER_MODE);
> +
> +       sdhci_cqe_enable(mmc);
> +}
> +
> +static void rk35xx_sdhci_cqe_disable(struct mmc_host *mmc, bool recovery)
> +{
> +       struct sdhci_host *host = mmc_priv(mmc);
> +       unsigned long flags;
> +       u32 ctrl;
> +
> +       /*
> +        * During CQE command transfers, command complete bit gets latched.
> +        * So s/w should clear command complete interrupt status when CQE is
> +        * either halted or disabled. Otherwise unexpected SDCHI legacy
> +        * interrupt gets triggered when CQE is halted/disabled.
> +        */
> +       spin_lock_irqsave(&host->lock, flags);
> +       ctrl = sdhci_readl(host, SDHCI_INT_ENABLE);
> +       ctrl |= SDHCI_INT_RESPONSE;
> +       sdhci_writel(host,  ctrl, SDHCI_INT_ENABLE);
> +       sdhci_writel(host, SDHCI_INT_RESPONSE, SDHCI_INT_STATUS);
> +       spin_unlock_irqrestore(&host->lock, flags);
> +
> +       sdhci_cqe_disable(mmc, recovery);
> +}
> +
> +static void rk35xx_sdhci_cqe_post_disable(struct mmc_host *mmc)
> +{
> +       struct sdhci_host *host = mmc_priv(mmc);
> +       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> +       struct dwcmshc_priv *dwc_priv = sdhci_pltfm_priv(pltfm_host);
> +       u32 ctrl;
> +
> +       ctrl = sdhci_readl(host, dwc_priv->vendor_specific_area2 + CQHCI_CFG);
> +       ctrl &= ~CQHCI_ENABLE;
> +       sdhci_writel(host, ctrl, dwc_priv->vendor_specific_area2 + CQHCI_CFG);
> +}
> +
>  static void dwcmshc_rk3568_set_clock(struct sdhci_host *host, unsigned int clock)
>  {
>         struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> @@ -679,6 +745,10 @@ static void rk35xx_sdhci_reset(struct sdhci_host *host, u8 mask)
>         struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>         struct dwcmshc_priv *dwc_priv = sdhci_pltfm_priv(pltfm_host);
>         struct rk35xx_priv *priv = dwc_priv->priv;
> +       u32 extra = sdhci_readl(host, DECMSHC_EMMC_MISC_CON);
> +
> +       if ((host->mmc->caps2 & MMC_CAP2_CQE) && (mask & SDHCI_RESET_ALL))
> +               cqhci_deactivate(host->mmc);
>
>         if (mask & SDHCI_RESET_ALL && priv->reset) {
>                 reset_control_assert(priv->reset);
> @@ -687,6 +757,9 @@ static void rk35xx_sdhci_reset(struct sdhci_host *host, u8 mask)
>         }
>
>         sdhci_reset(host, mask);
> +
> +       /* Enable INTERNAL CLOCK */
> +       sdhci_writel(host, MISC_INTCLK_EN | extra, DECMSHC_EMMC_MISC_CON);
>  }
>
>  static int dwcmshc_rk35xx_init(struct device *dev, struct sdhci_host *host,
> @@ -1188,6 +1261,15 @@ static const struct dwcmshc_pltfm_data sdhci_dwcmshc_bf3_pdata = {
>  };
>  #endif
>
> +static const struct cqhci_host_ops rk35xx_cqhci_ops = {
> +       .pre_enable     = rk35xx_sdhci_cqe_pre_enable,
> +       .enable         = rk35xx_sdhci_cqe_enable,
> +       .disable        = rk35xx_sdhci_cqe_disable,
> +       .post_disable   = rk35xx_sdhci_cqe_post_disable,
> +       .dumpregs       = dwcmshc_cqhci_dumpregs,
> +       .set_tran_desc  = dwcmshc_set_tran_desc,
> +};
> +
>  static const struct dwcmshc_pltfm_data sdhci_dwcmshc_rk35xx_pdata = {
>         .pdata = {
>                 .ops = &sdhci_dwcmshc_rk35xx_ops,
> @@ -1196,6 +1278,7 @@ static const struct dwcmshc_pltfm_data sdhci_dwcmshc_rk35xx_pdata = {
>                 .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
>                            SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN,
>         },
> +       .cqhci_host_ops = &rk35xx_cqhci_ops,
>         .init = dwcmshc_rk35xx_init,
>         .postinit = dwcmshc_rk35xx_postinit,
>  };
> @@ -1245,7 +1328,8 @@ static const struct cqhci_host_ops dwcmshc_cqhci_ops = {
>         .set_tran_desc  = dwcmshc_set_tran_desc,
>  };
>
> -static void dwcmshc_cqhci_init(struct sdhci_host *host, struct platform_device *pdev)
> +static void dwcmshc_cqhci_init(struct sdhci_host *host, struct platform_device *pdev,
> +                              const struct dwcmshc_pltfm_data *pltfm_data)
>  {
>         struct cqhci_host *cq_host;
>         struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> @@ -1275,7 +1359,10 @@ static void dwcmshc_cqhci_init(struct sdhci_host *host, struct platform_device *
>         }
>
>         cq_host->mmio = host->ioaddr + priv->vendor_specific_area2;
> -       cq_host->ops = &dwcmshc_cqhci_ops;
> +       if (pltfm_data->cqhci_host_ops)
> +               cq_host->ops = pltfm_data->cqhci_host_ops;
> +       else
> +               cq_host->ops = &dwcmshc_cqhci_ops;
>
>         /* Enable using of 128-bit task descriptors */
>         dma64 = host->flags & SDHCI_USE_64_BIT_DMA;
> @@ -1443,7 +1530,7 @@ static int dwcmshc_probe(struct platform_device *pdev)
>                 priv->vendor_specific_area2 =
>                         sdhci_readw(host, DWCMSHC_P_VENDOR_AREA2);
>
> -               dwcmshc_cqhci_init(host, pdev);
> +               dwcmshc_cqhci_init(host, pdev, pltfm_data);
>         }
>
>         if (pltfm_data->postinit)
>
> --
> 2.51.0
>


From ulf.hansson at linaro.org  Tue Nov 11 09:36:17 2025
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 11 Nov 2025 18:36:17 +0100
Subject: [PATCH] mmc: dw_mmc-rockchip: Fix wrong internal phase calculate
In-Reply-To: <1762228283-5025-1-git-send-email-shawn.lin@rock-chips.com>
References: <1762228283-5025-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <CAPDyKFrdnzqeC=b5LBH+AsrDmbwXWTrZZpAHo58pB3=OdQf1cQ@mail.gmail.com>

On Tue, 4 Nov 2025 at 04:51, Shawn Lin <shawn.lin at rock-chips.com> wrote:
>
> ciu clock is 2 times of io clock, but the sample clk used is
> derived from io clock provided to the card. So we should use
> io clock to calculate the phase.
>
> Fixes: 59903441f5e4 ("mmc: dw_mmc-rockchip: Add internal phase support")
> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>

Applied for fixes and by adding a stable-tag, thanks!

Kind regards
Uffe


> ---
>
>  drivers/mmc/host/dw_mmc-rockchip.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c
> index 82dd906..6813549 100644
> --- a/drivers/mmc/host/dw_mmc-rockchip.c
> +++ b/drivers/mmc/host/dw_mmc-rockchip.c
> @@ -42,7 +42,7 @@ struct dw_mci_rockchip_priv_data {
>   */
>  static int rockchip_mmc_get_internal_phase(struct dw_mci *host, bool sample)
>  {
> -       unsigned long rate = clk_get_rate(host->ciu_clk);
> +       unsigned long rate = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
>         u32 raw_value;
>         u16 degrees;
>         u32 delay_num = 0;
> @@ -85,7 +85,7 @@ static int rockchip_mmc_get_phase(struct dw_mci *host, bool sample)
>
>  static int rockchip_mmc_set_internal_phase(struct dw_mci *host, bool sample, int degrees)
>  {
> -       unsigned long rate = clk_get_rate(host->ciu_clk);
> +       unsigned long rate = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV;
>         u8 nineties, remainder;
>         u8 delay_num;
>         u32 raw_value;
> --
> 2.7.4
>


From conor at kernel.org  Tue Nov 11 09:43:42 2025
From: conor at kernel.org (Conor Dooley)
Date: Tue, 11 Nov 2025 17:43:42 +0000
Subject: [PATCH v7 4/5] dt-bindings: clock: rockchip: Add RK3506 clock
 and reset unit
In-Reply-To: <20251111025738.869847-5-zhangqing@rock-chips.com>
References: <20251111025738.869847-1-zhangqing@rock-chips.com>
 <20251111025738.869847-5-zhangqing@rock-chips.com>
Message-ID: <20251111-pond-flashcard-b14f99011c0a@spud>

On Tue, Nov 11, 2025 at 10:57:37AM +0800, Elaine Zhang wrote:
> From: Finley Xiao <finley.xiao at rock-chips.com>
> 
> Add device tree bindings for clock and reset unit on RK3506 SoC.
> Add clock and reset IDs for RK3506 SoC.
> 
> Signed-off-by: Finley Xiao <finley.xiao at rock-chips.com>
> Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
> ---
>  .../bindings/clock/rockchip,rk3506-cru.yaml   |  51 ++++
>  .../dt-bindings/clock/rockchip,rk3506-cru.h   | 285 ++++++++++++++++++
>  .../dt-bindings/reset/rockchip,rk3506-cru.h   | 211 +++++++++++++
>  3 files changed, 547 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
>  create mode 100644 include/dt-bindings/clock/rockchip,rk3506-cru.h
>  create mode 100644 include/dt-bindings/reset/rockchip,rk3506-cru.h
> 
> diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml b/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
> new file mode 100644
> index 000000000000..34bb45f2f227
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
> @@ -0,0 +1,51 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/rockchip,rk3506-cru.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Rockchip RK3506 Clock and Reset Unit (CRU)
> +
> +maintainers:
> +  - Finley Xiao <finley.xiao at rock-chips.com>
> +  - Heiko Stuebner <heiko at sntech.de>
> +
> +description:
> +  The RK3506 CRU generates the clock and also implements reset for SoC
> +  peripherals.
> +
> +properties:
> +  compatible:
> +    const: rockchip,rk3506-cru
> +
> +  reg:
> +    maxItems: 1
> +
> +  "#clock-cells":
> +    const: 1
> +
> +  "#reset-cells":
> +    const: 1
> +
> +  clocks:
> +    maxItems: 1

https://lore.kernel.org/all/20251104-nutty-lunchroom-36a5879db0b9 at spud/

I still don't see my feedback about the input clock being required
addressed. I gave that review 2 versions ago.

> +  clock-names:
> +    const: xin24m

Also, why does this clock name have a frequency in it, when you have
stated that:
| Our default hardware input clock is 24M.
| Some Socs and hardware input clocks support 24M?24.576M?26M. For

Default doesn't mean "only", so having the name contain it is weird.
pw-bot: changes-requested


> +
> +required:
> +  - compatible
> +  - reg
> +  - "#clock-cells"
> +  - "#reset-cells"
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    clock-controller at ff9a0000 {
> +      compatible = "rockchip,rk3506-cru";
> +      reg = <0xff9a0000 0x20000>;
> +      #clock-cells = <1>;
> +      #reset-cells = <1>;
> +    };
> diff --git a/include/dt-bindings/clock/rockchip,rk3506-cru.h b/include/dt-bindings/clock/rockchip,rk3506-cru.h
> new file mode 100644
> index 000000000000..71d7dda23cc9
> --- /dev/null
> +++ b/include/dt-bindings/clock/rockchip,rk3506-cru.h
> @@ -0,0 +1,285 @@
> +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
> +/*
> + * Copyright (c) 2023-2025 Rockchip Electronics Co., Ltd.
> + * Author: Finley Xiao <finley.xiao at rock-chips.com>
> + */
> +
> +#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3506_H
> +#define _DT_BINDINGS_CLK_ROCKCHIP_RK3506_H
> +
> +/* cru plls */
> +#define PLL_GPLL			0
> +#define PLL_V0PLL			1
> +#define PLL_V1PLL			2
> +
> +/* cru-clocks indices */
> +#define ARMCLK				3
> +#define CLK_DDR				4
> +#define XIN24M_GATE			5
> +#define CLK_GPLL_GATE			6
> +#define CLK_V0PLL_GATE			7
> +#define CLK_V1PLL_GATE			8
> +#define CLK_GPLL_DIV			9
> +#define CLK_GPLL_DIV_100M		10
> +#define CLK_V0PLL_DIV			11
> +#define CLK_V1PLL_DIV			12
> +#define CLK_INT_VOICE_MATRIX0		13
> +#define CLK_INT_VOICE_MATRIX1		14
> +#define CLK_INT_VOICE_MATRIX2		15
> +#define CLK_FRAC_UART_MATRIX0_MUX	16
> +#define CLK_FRAC_UART_MATRIX1_MUX	17
> +#define CLK_FRAC_VOICE_MATRIX0_MUX	18
> +#define CLK_FRAC_VOICE_MATRIX1_MUX	19
> +#define CLK_FRAC_COMMON_MATRIX0_MUX	20
> +#define CLK_FRAC_COMMON_MATRIX1_MUX	21
> +#define CLK_FRAC_COMMON_MATRIX2_MUX	22
> +#define CLK_FRAC_UART_MATRIX0		23
> +#define CLK_FRAC_UART_MATRIX1		24
> +#define CLK_FRAC_VOICE_MATRIX0		25
> +#define CLK_FRAC_VOICE_MATRIX1		26
> +#define CLK_FRAC_COMMON_MATRIX0		27
> +#define CLK_FRAC_COMMON_MATRIX1		28
> +#define CLK_FRAC_COMMON_MATRIX2		29
> +#define CLK_REF_USBPHY_TOP		30
> +#define CLK_REF_DPHY_TOP		31
> +#define ACLK_CORE_ROOT			32
> +#define PCLK_CORE_ROOT			33
> +#define PCLK_DBG			34
> +#define PCLK_CORE_GRF			35
> +#define PCLK_CORE_CRU			36
> +#define CLK_CORE_EMA_DETECT		37
> +#define CLK_REF_PVTPLL_CORE		38
> +#define PCLK_GPIO1			39
> +#define DBCLK_GPIO1			40
> +#define ACLK_CORE_PERI_ROOT		41
> +#define HCLK_CORE_PERI_ROOT		42
> +#define PCLK_CORE_PERI_ROOT		43
> +#define CLK_DSMC			44
> +#define ACLK_DSMC			45
> +#define PCLK_DSMC			46
> +#define CLK_FLEXBUS_TX			47
> +#define CLK_FLEXBUS_RX			48
> +#define ACLK_FLEXBUS			49
> +#define HCLK_FLEXBUS			50
> +#define ACLK_DSMC_SLV			51
> +#define HCLK_DSMC_SLV			52
> +#define ACLK_BUS_ROOT			53
> +#define HCLK_BUS_ROOT			54
> +#define PCLK_BUS_ROOT			55
> +#define ACLK_SYSRAM			56
> +#define HCLK_SYSRAM			57
> +#define ACLK_DMAC0			58
> +#define ACLK_DMAC1			59
> +#define HCLK_M0				60
> +#define PCLK_BUS_GRF			61
> +#define PCLK_TIMER			62
> +#define CLK_TIMER0_CH0			63
> +#define CLK_TIMER0_CH1			64
> +#define CLK_TIMER0_CH2			65
> +#define CLK_TIMER0_CH3			66
> +#define CLK_TIMER0_CH4			67
> +#define CLK_TIMER0_CH5			68
> +#define PCLK_WDT0			69
> +#define TCLK_WDT0			70
> +#define PCLK_WDT1			71
> +#define TCLK_WDT1			72
> +#define PCLK_MAILBOX			73
> +#define PCLK_INTMUX			74
> +#define PCLK_SPINLOCK			75
> +#define PCLK_DDRC			76
> +#define HCLK_DDRPHY			77
> +#define PCLK_DDRMON			78
> +#define CLK_DDRMON_OSC			79
> +#define PCLK_STDBY			80
> +#define HCLK_USBOTG0			81
> +#define HCLK_USBOTG0_PMU		82
> +#define CLK_USBOTG0_ADP			83
> +#define HCLK_USBOTG1			84
> +#define HCLK_USBOTG1_PMU		85
> +#define CLK_USBOTG1_ADP			86
> +#define PCLK_USBPHY			87
> +#define ACLK_DMA2DDR			88
> +#define PCLK_DMA2DDR			89
> +#define STCLK_M0			90
> +#define CLK_DDRPHY			91
> +#define CLK_DDRC_SRC			92
> +#define ACLK_DDRC_0			93
> +#define ACLK_DDRC_1			94
> +#define CLK_DDRC			95
> +#define CLK_DDRMON			96
> +#define HCLK_LSPERI_ROOT		97
> +#define PCLK_LSPERI_ROOT		98
> +#define PCLK_UART0			99
> +#define PCLK_UART1			100
> +#define PCLK_UART2			101
> +#define PCLK_UART3			102
> +#define PCLK_UART4			103
> +#define SCLK_UART0			104
> +#define SCLK_UART1			105
> +#define SCLK_UART2			106
> +#define SCLK_UART3			107
> +#define SCLK_UART4			108
> +#define PCLK_I2C0			109
> +#define CLK_I2C0			110
> +#define PCLK_I2C1			111
> +#define CLK_I2C1			112
> +#define PCLK_I2C2			113
> +#define CLK_I2C2			114
> +#define PCLK_PWM1			115
> +#define CLK_PWM1			116
> +#define CLK_OSC_PWM1			117
> +#define CLK_RC_PWM1			118
> +#define CLK_FREQ_PWM1			119
> +#define CLK_COUNTER_PWM1		120
> +#define PCLK_SPI0			121
> +#define CLK_SPI0			122
> +#define PCLK_SPI1			123
> +#define CLK_SPI1			124
> +#define PCLK_GPIO2			125
> +#define DBCLK_GPIO2			126
> +#define PCLK_GPIO3			127
> +#define DBCLK_GPIO3			128
> +#define PCLK_GPIO4			129
> +#define DBCLK_GPIO4			130
> +#define HCLK_CAN0			131
> +#define CLK_CAN0			132
> +#define HCLK_CAN1			133
> +#define CLK_CAN1			134
> +#define HCLK_PDM			135
> +#define MCLK_PDM			136
> +#define CLKOUT_PDM			137
> +#define MCLK_SPDIFTX			138
> +#define HCLK_SPDIFTX			139
> +#define HCLK_SPDIFRX			140
> +#define MCLK_SPDIFRX			141
> +#define MCLK_SAI0			142
> +#define HCLK_SAI0			143
> +#define MCLK_OUT_SAI0			144
> +#define MCLK_SAI1			145
> +#define HCLK_SAI1			146
> +#define MCLK_OUT_SAI1			147
> +#define HCLK_ASRC0			148
> +#define CLK_ASRC0			149
> +#define HCLK_ASRC1			150
> +#define CLK_ASRC1			151
> +#define PCLK_CRU			152
> +#define PCLK_PMU_ROOT			153
> +#define MCLK_ASRC0			154
> +#define MCLK_ASRC1			155
> +#define MCLK_ASRC2			156
> +#define MCLK_ASRC3			157
> +#define LRCK_ASRC0_SRC			158
> +#define LRCK_ASRC0_DST			159
> +#define LRCK_ASRC1_SRC			160
> +#define LRCK_ASRC1_DST			161
> +#define ACLK_HSPERI_ROOT		162
> +#define HCLK_HSPERI_ROOT		163
> +#define PCLK_HSPERI_ROOT		164
> +#define CCLK_SRC_SDMMC			165
> +#define HCLK_SDMMC			166
> +#define HCLK_FSPI			167
> +#define SCLK_FSPI			168
> +#define PCLK_SPI2			169
> +#define ACLK_MAC0			170
> +#define ACLK_MAC1			171
> +#define PCLK_MAC0			172
> +#define PCLK_MAC1			173
> +#define CLK_MAC_ROOT			174
> +#define CLK_MAC0			175
> +#define CLK_MAC1			176
> +#define MCLK_SAI2			177
> +#define HCLK_SAI2			178
> +#define MCLK_OUT_SAI2			179
> +#define MCLK_SAI3_SRC			180
> +#define HCLK_SAI3			181
> +#define MCLK_SAI3			182
> +#define MCLK_OUT_SAI3			183
> +#define MCLK_SAI4_SRC			184
> +#define HCLK_SAI4			185
> +#define MCLK_SAI4			186
> +#define HCLK_DSM			187
> +#define MCLK_DSM			188
> +#define PCLK_AUDIO_ADC			189
> +#define MCLK_AUDIO_ADC			190
> +#define MCLK_AUDIO_ADC_DIV4		191
> +#define PCLK_SARADC			192
> +#define CLK_SARADC			193
> +#define PCLK_OTPC_NS			194
> +#define CLK_SBPI_OTPC_NS		195
> +#define CLK_USER_OTPC_NS		196
> +#define PCLK_UART5			197
> +#define SCLK_UART5			198
> +#define PCLK_GPIO234_IOC		199
> +#define CLK_MAC_PTP_ROOT		200
> +#define CLK_MAC0_PTP			201
> +#define CLK_MAC1_PTP			202
> +#define CLK_SPI2			203
> +#define ACLK_VIO_ROOT			204
> +#define HCLK_VIO_ROOT			205
> +#define PCLK_VIO_ROOT			206
> +#define HCLK_RGA			207
> +#define ACLK_RGA			208
> +#define CLK_CORE_RGA			209
> +#define ACLK_VOP			210
> +#define HCLK_VOP			211
> +#define DCLK_VOP			212
> +#define PCLK_DPHY			213
> +#define PCLK_DSI_HOST			214
> +#define PCLK_TSADC			215
> +#define CLK_TSADC			216
> +#define CLK_TSADC_TSEN			217
> +#define PCLK_GPIO1_IOC			218
> +#define PCLK_OTPC_S			219
> +#define CLK_SBPI_OTPC_S			220
> +#define CLK_USER_OTPC_S			221
> +#define PCLK_OTP_MASK			222
> +#define PCLK_KEYREADER			223
> +#define HCLK_BOOTROM			224
> +#define PCLK_DDR_SERVICE		225
> +#define HCLK_CRYPTO_S			226
> +#define HCLK_KEYLAD			227
> +#define CLK_CORE_CRYPTO			228
> +#define CLK_PKA_CRYPTO			229
> +#define CLK_CORE_CRYPTO_S		230
> +#define CLK_PKA_CRYPTO_S		231
> +#define ACLK_CRYPTO_S			232
> +#define HCLK_RNG_S			233
> +#define CLK_CORE_CRYPTO_NS		234
> +#define CLK_PKA_CRYPTO_NS		235
> +#define ACLK_CRYPTO_NS			236
> +#define HCLK_CRYPTO_NS			237
> +#define HCLK_RNG			238
> +#define CLK_PMU				239
> +#define PCLK_PMU			240
> +#define CLK_PMU_32K			241
> +#define PCLK_PMU_CRU			242
> +#define PCLK_PMU_GRF			243
> +#define PCLK_GPIO0_IOC			244
> +#define PCLK_GPIO0			245
> +#define DBCLK_GPIO0			246
> +#define PCLK_GPIO1_SHADOW		247
> +#define DBCLK_GPIO1_SHADOW		248
> +#define PCLK_PMU_HP_TIMER		249
> +#define CLK_PMU_HP_TIMER		250
> +#define CLK_PMU_HP_TIMER_32K		251
> +#define PCLK_PWM0			252
> +#define CLK_PWM0			253
> +#define CLK_OSC_PWM0			254
> +#define CLK_RC_PWM0			255
> +#define CLK_MAC_OUT			256
> +#define CLK_REF_OUT0			257
> +#define CLK_REF_OUT1			258
> +#define CLK_32K_FRAC			259
> +#define CLK_32K_RC			260
> +#define CLK_32K				261
> +#define CLK_32K_PMU			262
> +#define PCLK_TOUCH_KEY			263
> +#define CLK_TOUCH_KEY			264
> +#define CLK_REF_PHY_PLL			265
> +#define CLK_REF_PHY_PMU_MUX		266
> +#define CLK_WIFI_OUT			267
> +#define CLK_V0PLL_REF			268
> +#define CLK_V1PLL_REF			269
> +#define CLK_32K_FRAC_MUX		270
> +
> +#endif
> diff --git a/include/dt-bindings/reset/rockchip,rk3506-cru.h b/include/dt-bindings/reset/rockchip,rk3506-cru.h
> new file mode 100644
> index 000000000000..31c0d4aa410f
> --- /dev/null
> +++ b/include/dt-bindings/reset/rockchip,rk3506-cru.h
> @@ -0,0 +1,211 @@
> +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
> +/*
> + * Copyright (c) 2023-2025 Rockchip Electronics Co., Ltd.
> + * Author: Finley Xiao <finley.xiao at rock-chips.com>
> + */
> +
> +#ifndef _DT_BINDINGS_REST_ROCKCHIP_RK3506_H
> +#define _DT_BINDINGS_REST_ROCKCHIP_RK3506_H
> +
> +/* CRU-->SOFTRST_CON00 */
> +#define SRST_NCOREPORESET0_AC	0
> +#define SRST_NCOREPORESET1_AC	1
> +#define SRST_NCOREPORESET2_AC	2
> +#define SRST_NCORESET0_AC	3
> +#define SRST_NCORESET1_AC	4
> +#define SRST_NCORESET2_AC	5
> +#define SRST_NL2RESET_AC	6
> +#define SRST_A_CORE_BIU_AC	7
> +#define SRST_H_M0_AC		8
> +
> +/* CRU-->SOFTRST_CON02 */
> +#define SRST_NDBGRESET		9
> +#define SRST_P_CORE_BIU		10
> +#define SRST_PMU		11
> +
> +/* CRU-->SOFTRST_CON03 */
> +#define SRST_P_DBG		12
> +#define SRST_POT_DBG		13
> +#define SRST_P_CORE_GRF		14
> +#define SRST_CORE_EMA_DETECT	15
> +#define SRST_REF_PVTPLL_CORE	16
> +#define SRST_P_GPIO1		17
> +#define SRST_DB_GPIO1		18
> +
> +/* CRU-->SOFTRST_CON04 */
> +#define SRST_A_CORE_PERI_BIU	19
> +#define SRST_A_DSMC		20
> +#define SRST_P_DSMC		21
> +#define SRST_FLEXBUS		22
> +#define SRST_A_FLEXBUS		23
> +#define SRST_H_FLEXBUS		24
> +#define SRST_A_DSMC_SLV		25
> +#define SRST_H_DSMC_SLV		26
> +#define SRST_DSMC_SLV		27
> +
> +/* CRU-->SOFTRST_CON05 */
> +#define SRST_A_BUS_BIU		28
> +#define SRST_H_BUS_BIU		29
> +#define SRST_P_BUS_BIU		30
> +#define SRST_A_SYSRAM		31
> +#define SRST_H_SYSRAM		32
> +#define SRST_A_DMAC0		33
> +#define SRST_A_DMAC1		34
> +#define SRST_H_M0		35
> +#define SRST_M0_JTAG		36
> +#define SRST_H_CRYPTO		37
> +
> +/* CRU-->SOFTRST_CON06 */
> +#define SRST_H_RNG		38
> +#define SRST_P_BUS_GRF		39
> +#define SRST_P_TIMER0		40
> +#define SRST_TIMER0_CH0		41
> +#define SRST_TIMER0_CH1		42
> +#define SRST_TIMER0_CH2		43
> +#define SRST_TIMER0_CH3		44
> +#define SRST_TIMER0_CH4		45
> +#define SRST_TIMER0_CH5		46
> +#define SRST_P_WDT0		47
> +#define SRST_T_WDT0		48
> +#define SRST_P_WDT1		49
> +#define SRST_T_WDT1		50
> +#define SRST_P_MAILBOX		51
> +#define SRST_P_INTMUX		52
> +#define SRST_P_SPINLOCK		53
> +
> +/* CRU-->SOFTRST_CON07 */
> +#define SRST_P_DDRC		54
> +#define SRST_H_DDRPHY		55
> +#define SRST_P_DDRMON		56
> +#define SRST_DDRMON_OSC		57
> +#define SRST_P_DDR_LPC		58
> +#define SRST_H_USBOTG0		59
> +#define SRST_USBOTG0_ADP	60
> +#define SRST_H_USBOTG1		61
> +#define SRST_USBOTG1_ADP	62
> +#define SRST_P_USBPHY		63
> +#define SRST_USBPHY_POR		64
> +#define SRST_USBPHY_OTG0	65
> +#define SRST_USBPHY_OTG1	66
> +
> +/* CRU-->SOFTRST_CON08 */
> +#define SRST_A_DMA2DDR		67
> +#define SRST_P_DMA2DDR		68
> +
> +/* CRU-->SOFTRST_CON09 */
> +#define SRST_USBOTG0_UTMI	69
> +#define SRST_USBOTG1_UTMI	70
> +
> +/* CRU-->SOFTRST_CON10 */
> +#define SRST_A_DDRC_0		71
> +#define SRST_A_DDRC_1		72
> +#define SRST_A_DDR_BIU		73
> +#define SRST_DDRC		74
> +#define SRST_DDRMON		75
> +
> +/* CRU-->SOFTRST_CON11 */
> +#define SRST_H_LSPERI_BIU	76
> +#define SRST_P_UART0		77
> +#define SRST_P_UART1		78
> +#define SRST_P_UART2		79
> +#define SRST_P_UART3		80
> +#define SRST_P_UART4		81
> +#define SRST_UART0		82
> +#define SRST_UART1		83
> +#define SRST_UART2		84
> +#define SRST_UART3		85
> +#define SRST_UART4		86
> +#define SRST_P_I2C0		87
> +#define SRST_I2C0		88
> +
> +/* CRU-->SOFTRST_CON12 */
> +#define SRST_P_I2C1		89
> +#define SRST_I2C1		90
> +#define SRST_P_I2C2		91
> +#define SRST_I2C2		92
> +#define SRST_P_PWM1		93
> +#define SRST_PWM1		94
> +#define SRST_P_SPI0		95
> +#define SRST_SPI0		96
> +#define SRST_P_SPI1		97
> +#define SRST_SPI1		98
> +#define SRST_P_GPIO2		99
> +#define SRST_DB_GPIO2		100
> +
> +/* CRU-->SOFTRST_CON13 */
> +#define SRST_P_GPIO3		101
> +#define SRST_DB_GPIO3		102
> +#define SRST_P_GPIO4		103
> +#define SRST_DB_GPIO4		104
> +#define SRST_H_CAN0		105
> +#define SRST_CAN0		106
> +#define SRST_H_CAN1		107
> +#define SRST_CAN1		108
> +#define SRST_H_PDM		109
> +#define SRST_M_PDM		110
> +#define SRST_PDM		111
> +#define SRST_SPDIFTX		112
> +#define SRST_H_SPDIFTX		113
> +#define SRST_H_SPDIFRX		114
> +#define SRST_SPDIFRX		115
> +#define SRST_M_SAI0		116
> +
> +/* CRU-->SOFTRST_CON14 */
> +#define SRST_H_SAI0		117
> +#define SRST_M_SAI1		118
> +#define SRST_H_SAI1		119
> +#define SRST_H_ASRC0		120
> +#define SRST_ASRC0		121
> +#define SRST_H_ASRC1		122
> +#define SRST_ASRC1		123
> +
> +/* CRU-->SOFTRST_CON17 */
> +#define SRST_H_HSPERI_BIU	124
> +#define SRST_H_SDMMC		125
> +#define SRST_H_FSPI		126
> +#define SRST_S_FSPI		127
> +#define SRST_P_SPI2		128
> +#define SRST_A_MAC0		129
> +#define SRST_A_MAC1		130
> +
> +/* CRU-->SOFTRST_CON18 */
> +#define SRST_M_SAI2		131
> +#define SRST_H_SAI2		132
> +#define SRST_H_SAI3		133
> +#define SRST_M_SAI3		134
> +#define SRST_H_SAI4		135
> +#define SRST_M_SAI4		136
> +#define SRST_H_DSM		137
> +#define SRST_M_DSM		138
> +#define SRST_P_AUDIO_ADC	139
> +#define SRST_M_AUDIO_ADC	140
> +
> +/* CRU-->SOFTRST_CON19 */
> +#define SRST_P_SARADC		141
> +#define SRST_SARADC		142
> +#define SRST_SARADC_PHY		143
> +#define SRST_P_OTPC_NS		144
> +#define SRST_SBPI_OTPC_NS	145
> +#define SRST_USER_OTPC_NS	146
> +#define SRST_P_UART5		147
> +#define SRST_UART5		148
> +#define SRST_P_GPIO234_IOC	149
> +
> +/* CRU-->SOFTRST_CON21 */
> +#define SRST_A_VIO_BIU		150
> +#define SRST_H_VIO_BIU		151
> +#define SRST_H_RGA		152
> +#define SRST_A_RGA		153
> +#define SRST_CORE_RGA		154
> +#define SRST_A_VOP		155
> +#define SRST_H_VOP		156
> +#define SRST_VOP		157
> +#define SRST_P_DPHY		158
> +#define SRST_P_DSI_HOST		159
> +#define SRST_P_TSADC		160
> +#define SRST_TSADC		161
> +
> +/* CRU-->SOFTRST_CON22 */
> +#define SRST_P_GPIO1_IOC	162
> +
> +#endif
> -- 
> 2.34.1
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251111/bb02bee7/attachment-0001.sig>

From quentin.schulz at cherry.de  Tue Nov 11 10:32:55 2025
From: quentin.schulz at cherry.de (Quentin Schulz)
Date: Tue, 11 Nov 2025 19:32:55 +0100
Subject: [PATCH v2] arm64: dts: rockchip: Turn all LEDs on at boot for
 Radxa boards
In-Reply-To: <41275775-9e6e-9202-4c79-6140a56e41d5@manjaro.org>
References: <20251111054112.55505-1-naoki@radxa.com>
 <DE5W0143QGG2.3C7SW89IJKZ4P@cknow-tech.com>
 <516e919a-42af-8707-4e75-a808df8971fd@manjaro.org>
 <B0C8C5A69B9F465E+ba0ad139-d3d9-4492-ac9a-cc58f8f35074@radxa.com>
 <41275775-9e6e-9202-4c79-6140a56e41d5@manjaro.org>
Message-ID: <572f341f-a5fa-4f1c-ad60-a5fe3e046d6d@cherry.de>

Hi all,

On 11/11/25 5:14 PM, Dragan Simic wrote:
> Hello all,
> 
> (+ Quentin)
> 
> On Tuesday, November 11, 2025 16:32 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
>> On 11/11/25 23:46, Dragan Simic wrote:
>>> On Tuesday, November 11, 2025 14:07 CET, "Diederik de Haas" <diederik at cknow-tech.com> wrote:
>>>> On Tue Nov 11, 2025 at 6:41 AM CET, FUKAUMI Naoki wrote:
>>>>> Radxa's boards turn all LEDs on at boot(loader), but some boards don't
>>>>> have `default-state` property in Linux kernel tree but have it in
>>>>> U-Boot tree instead[1].
>>>>>
>>>>> This patch adds `default-state = "on"` for (almost) all LEDs (with a
>>>>> few exceptions which should be "off" such as RGB LEDs on E25 and LAN/
>>>>> WAN LEDs on E20C/E52C).
>>>>
>>>> I'm missing the *why* these changes would be an improvement.
>>>>
>>>> Personally, for both 'heartbeat' and 'netdev' triggers, I want them to
>>>> be off by default and once it gets a 'heartbeat' or a 'netdev' trigger,
>>>> THEN I want the LED to be on/blinking.
>>>
>>> That's a good question for Naoki.  My own preference would also
>>> be to have the device's power LED turned on by U-Boot as quickly
>>> as possible after supplying power to the board or turning it on
>>> by pressing the power button.  I'm actually not a big fan of
>>> having all the LEDs shining for a couple of seconds or so, which
>>> may actually look like some error condition to me.
>>>
>>> Having all that in mind, I may suggest that just the U-Boot's
>>> behavior is changed to turn the power LEDs on only.
>>
>> I can't quite explain it, but...
>>
>> - 1st (Power) LED
>>
>> The 1st (power) LED turns on automatically/immediately without software
>> intervention. (On some boards, this LED cannot be controlled by software
>> at all.)
>>
>> In DTS, this should be described using `default-state = "on"`. The use
>> of the Linux-specific property `linux,default-trigger = "default-on"` is
>> unsuitable for non-Linux environments.
>>
>> - 2nd (Heartbeat) LED
>>
>> The 2nd (heartbeat) LED can be controlled by software. It should be lit
>> up as quickly as possible to indicate that the very first software
>> (e.g., the bootloader) is running.
>>
>> On Linux, usually this is used as `linux,default-trigger = "heartbeat"`.
>> It indicates that kernel is running (regardless of the `default-state`
>> setting), and its behavior can be modified in user space.
> 
> As discussed already in the #linux-rockchip IRC channel, [1] perhaps
> the best option would be to have the power LEDs turned on as quickly
> upon powering on the board as possible, and to have U-Boot pulsate
> the heartbeat LEDs using the LED_BOOT feature.  In such a scenario,
> no other LEDs would be turned on early, and the LED-related DT parts
> specific to U-Boot would be migrated to the kernel DTs.
> 
> [1] https://libera.catirclogs.org/linux-rockchip/2025-11-11#38997824;
> 

The LED_BOOT feature (guarded by the Kconfig symbol of the same name) in 
U-Boot only applies if /options/u-boot/boot-led property is set.

If the driver for the LED (typically a GPIO LED controller I guess, so 
LED_GPIO symbol) is compiled in, then, as far as I could tell, the Boot 
LED will be turned on right before entering the main loop of U-Boot.

If LED_BLINK (if HW blinking is supported) or LED_SW_BLINK is enabled, 
the Boot LED will be blinking some time after relocation but still 
turned on soon after (if it reaches that part of the code). This means 
it'll be on before the kernel starts.

I'm not sure there's a way to hook something *after* we've entered 
U-Boot main-loop (read "call led_boot_blink() from some board file"), 
aside from calling `led <led-name> blink <period>` from U-Boot CLI.

I'm a bit bummed by this behavior, I would have preferred the ability to 
have the Boot LED blink until the kernel starts. I could then have a 
different period for U-Boot (50% duty cycle at 250ms period by default) 
and for the kernel. Of course, if it's SW blinking, once exiting U-Boot 
it won't blink anymore until the kernel takes over, but that's also a 
nice information to have. Anyway, I'm not sure this is actually possible 
with the LED_BOOT feature though one should be able to do this by 
specifying the label of an LED node to fetch from DT and then calling 
led_set_period(dev, period_ms); followed by led_set_state(dev, 
LEDST_BLINK); in a board file, but this is also not so nice as it then 
also requires some C board-specific code in U-Boot.

In U-Boot, only LEDs which have a "default-state" properties will be 
auto-configured, otherwise one needs to control them manually (e.g. via 
the `led` CLI command).

If one wants to detect via an LED the current boot stage (U-Boot 
reached, kernel started), then we need to NOT use LED_BOOT feature and 
have U-Boot set the "boot" LED the opposite state than the default HW 
state, i.e. if the LED is on without any running SW (power applied to 
the device, empty boot media), then U-Boot should set it to off. Then 
the kernel simply needs to start the heartbeat mode whenever ready. If 
the default HW state is off, then U-Boot should set it on. I haven't 
looked into the kernel side of things, but there could be a window 
during which default-state property is applied before the heartbeat is 
actually started.

The logic exposed in the previous paragraph should provide visual cues 
on the current boot stage.

Note that LEDs with linux,default-trigger = "pattern" (with 
default-state property) will be blinking once auto-configured in U-Boot 
as well according to my reading of the led-uclass.c.

Hope this helps.

Cheers,
Quentin


From s.shtylyov at omp.ru  Tue Nov 11 12:56:19 2025
From: s.shtylyov at omp.ru (Sergey Shtylyov)
Date: Tue, 11 Nov 2025 23:56:19 +0300
Subject: [PATCH RFT] drm/rockchip: vop: fix simple case of window scaling
Message-ID: <40da59f8-10e9-49b0-9f25-1474067625f6@omp.ru>

In scl_cal_scale2(), if the dst parameter equals to 1, then division by
0 will happen. Actually, the whole {src,dst} - 1 thing is caused by what
seems to be an error in the Rockchip manuals which say that the window's
width/height fields of the VOP_WIN<n>_{ACT,DSP}_INFO registers should be
used for the division verbatim -- and those are actually 1 less than the
window's real width/height; so scl_cal_scale2() returns expected result
(0x1000) only when src equals dst...

Found by Linux Verification Center (linuxtesting.org) with the Svace static
analysis tool.

Fixes: 1194fffbb102 ("drm/rockchip: vop: spilt scale regsters")
Signed-off-by: Sergey Shtylyov <s.shtylyov at omp.ru>

---
The patch is against the drm-misc-fixes branch of the DRM kernel.git repo
on gitlab.freedesktop.org.

Note that scl_cal_scale() does look buggy as well, but I can't figure out
(even having the RK3288 manual) how to properly fix that (it's only clear
that -1 should be removed; perhaps Mark Yao can help there...

 drivers/gpu/drm/rockchip/rockchip_drm_vop.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: kernel/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
===================================================================
--- kernel.orig/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ kernel/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -360,7 +360,7 @@ static inline uint16_t scl_cal_scale(int
 
 static inline uint16_t scl_cal_scale2(int src, int dst)
 {
-	return ((src - 1) << 12) / (dst - 1);
+	return (src << 12) / dst;
 }
 
 #define GET_SCL_FT_BILI_DN(src, dst)	scl_cal_scale(src, dst, 12)


From helgaas at kernel.org  Tue Nov 11 13:43:36 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 11 Nov 2025 15:43:36 -0600
Subject: [PATCH v3] PCI: dw-rockchip: Prevent advertising L1 Substates
 support
In-Reply-To: <aRM1VOodnSpaob3P@ryzen>
Message-ID: <20251111214336.GA2190667@bhelgaas>

On Tue, Nov 11, 2025 at 02:08:36PM +0100, Niklas Cassel wrote:
> On Tue, Oct 21, 2025 at 08:05:17AM +0530, Manivannan Sadhasivam wrote:
> > On Fri, 17 Oct 2025 18:32:53 +0200, Niklas Cassel wrote:
> > > The L1 substates support requires additional steps to work, namely:
> > > -Proper handling of the CLKREQ# sideband signal. (It is mostly handled by
> > >  hardware, but software still needs to set the clkreq fields in the
> > >  PCIE_CLIENT_POWER_CON register to match the hardware implementation.)
> > > -Program the frequency of the aux clock into the
> > >  DSP_PCIE_PL_AUX_CLK_FREQ_OFF register. (During L1 substates the core_clk
> > >  is turned off and the aux_clk is used instead.)
> > > 
> > > [...]
> > 
> > Applied, thanks!
> > 
> > [1/1] PCI: dw-rockchip: Prevent advertising L1 Substates support
> >       commit: 40331c63e7901a2cc75ce6b5d24d50601efb833d
> 
> Last update in this thread was "Applied, thanks!"
>
> and the patch was applied to pci/controller/dw-rockchip
> 
> since then it seems to have been demoted to
> pci/controller/dw-rockchip-pend

That was Oct 20, and we had some conversation about a more generic
approach after that, so I moved it to dw-rockchip-pend while we worked
that out.

I fleshed it out the generic approach and will post it soon.


From helgaas at kernel.org  Tue Nov 11 14:16:07 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 11 Nov 2025 16:16:07 -0600
Subject: [PATCH 0/4] PCI: dwc: Advertise L1 PM Substates only if driver requests it
Message-ID: <20251111221621.2208606-1-helgaas@kernel.org>

From: Bjorn Helgaas <bhelgaas at google.com>

This is a follow-up to Niklas's patch at
https://lore.kernel.org/r/20251017163252.598812-2-cassel at kernel.org.  That
patch clears the L1 PM Substate Supported bits for the dw-rockchip driver,
which doesn't yet do the device configuration to support the L1 Substates.

This series does the same thing, but in the DWC core so it applies to all
DWC-based drivers.  Drivers that do support L1 Substates (currently
tegra194 and qcom) indicate that by setting "dw_pcie.l1ss_support", and the
DWC core will leave the L1 PM Substate Supported bits alone.

This also includes Shawn's patches to add the dw-rockchip support for L1
Substates.

The problem this fixes is that users are currently able to enable L1
Substates, e.g., by

  - building with with CONFIG_PCIEASPM_POWER_SUPERSAVE=y
  - booting with "pcie_aspm.policy=powersupersave"
  - echo powersupersave > /sys/module/pcie_aspm/parameters/policy
  - echo 1 > /sys/bus/pci/devices/.../link/l1_1_aspm

but this breaks devices if the platform doesn't support CLKREQ# or lacks
Root Port configuration.  This series avoids that problem by preventing the
kernel from enabling L1.x in the first place.

Bjorn Helgaas (2):
  PCI: dwc: Advertise L1 PM Substates only if driver requests it
  PCI: tegra194: Remove unnecessary L1SS disable code

Shawn Lin (2):
  PCI: dw-rockchip: Configure L1sub support
  arm64: dts: rockchip: Add PCIe clkreq stuff for RK3588 EVB1

 .../boot/dts/rockchip/rk3588-evb1-v10.dts     |  7 +++-
 .../pci/controller/dwc/pcie-designware-ep.c   |  2 +
 .../pci/controller/dwc/pcie-designware-host.c |  2 +
 drivers/pci/controller/dwc/pcie-designware.c  | 24 ++++++++++++
 drivers/pci/controller/dwc/pcie-designware.h  |  2 +
 drivers/pci/controller/dwc/pcie-dw-rockchip.c | 38 +++++++++++++++++++
 drivers/pci/controller/dwc/pcie-qcom.c        |  2 +
 drivers/pci/controller/dwc/pcie-tegra194.c    | 35 ++---------------
 8 files changed, 78 insertions(+), 34 deletions(-)

-- 
2.43.0



From helgaas at kernel.org  Tue Nov 11 14:16:08 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 11 Nov 2025 16:16:08 -0600
Subject: [PATCH 1/4] PCI: dwc: Advertise L1 PM Substates only if driver requests it
In-Reply-To: <20251111221621.2208606-1-helgaas@kernel.org>
References: <20251111221621.2208606-1-helgaas@kernel.org>
Message-ID: <20251111221621.2208606-2-helgaas@kernel.org>

From: Bjorn Helgaas <bhelgaas at google.com>

L1 PM Substates require the CLKREF# signal and may also require
device-specific support.  If CLKREF# is not supported or driver support is
lacking, enabling L1.1 or L1.2 may cause errors when accessing devices,
e.g.,

  nvme nvme0: controller is down; will reset: CSTS=0xffffffff, PCI_STATUS=0x10

If the kernel is built with CONFIG_PCIEASPM_POWER_SUPERSAVE=y or users
enable L1.x via sysfs, users may trip over these errors even if L1
Substates haven't been enabled by firmware or the driver.

To prevent such errors, disable advertising the L1 PM Substates unless the
driver sets "dw_pcie.l1ss_support" to indicate that it knows CLKREF# is
present and any device-specific configuration has been done.

Set "dw_pcie.l1ss_support" in tegra194 (if DT includes the
"supports-clkreq' property) and qcom (for 2.7.0 controllers) so they can
continue to use L1 Substates.

Based on Niklas's patch:
https://patch.msgid.link/20251017163252.598812-2-cassel at kernel.org

Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
---
 .../pci/controller/dwc/pcie-designware-ep.c   |  2 ++
 .../pci/controller/dwc/pcie-designware-host.c |  2 ++
 drivers/pci/controller/dwc/pcie-designware.c  | 24 +++++++++++++++++++
 drivers/pci/controller/dwc/pcie-designware.h  |  2 ++
 drivers/pci/controller/dwc/pcie-qcom.c        |  2 ++
 drivers/pci/controller/dwc/pcie-tegra194.c    |  3 +++
 6 files changed, 35 insertions(+)

diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index 7f2112c2fb21..c94cff6eeb01 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -966,6 +966,8 @@ int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)
 	if (ep->ops->init)
 		ep->ops->init(ep);
 
+	dw_pcie_config_l1ss(pci);
+
 	ptm_cap_base = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_PTM);
 
 	/*
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index 20c9333bcb1c..f1d5b45a3214 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -1060,6 +1060,8 @@ int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
 		PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
 	dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
 
+	dw_pcie_config_l1ss(pci);
+
 	dw_pcie_config_presets(pp);
 	/*
 	 * If the platform provides its own child bus config accesses, it means
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
index c644216995f6..ede686623fad 100644
--- a/drivers/pci/controller/dwc/pcie-designware.c
+++ b/drivers/pci/controller/dwc/pcie-designware.c
@@ -1081,6 +1081,30 @@ void dw_pcie_edma_remove(struct dw_pcie *pci)
 	dw_edma_remove(&pci->edma);
 }
 
+void dw_pcie_config_l1ss(struct dw_pcie *pci)
+{
+	u16 l1ss;
+	u32 l1ss_cap;
+
+	if (!pci->l1ss_support)
+		return;
+
+	l1ss = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_L1SS);
+	if (!l1ss)
+		return;
+
+	/*
+	 * Unless the driver claims "l1ss_support", don't advertise L1 PM
+	 * Substates because they require CLKREF# and possibly other
+	 * device-specific configuration.
+	 */
+	l1ss_cap = dw_pcie_readl_dbi(pci, l1ss + PCI_L1SS_CAP);
+	l1ss_cap &= ~(PCI_L1SS_CAP_PCIPM_L1_1 | PCI_L1SS_CAP_ASPM_L1_1 |
+		      PCI_L1SS_CAP_PCIPM_L1_2 | PCI_L1SS_CAP_ASPM_L1_2 |
+		      PCI_L1SS_CAP_L1_PM_SS);
+	dw_pcie_writel_dbi(pci, l1ss + PCI_L1SS_CAP, l1ss_cap);
+}
+
 void dw_pcie_setup(struct dw_pcie *pci)
 {
 	u32 val;
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index e995f692a1ec..8d14b1fe2280 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -516,6 +516,7 @@ struct dw_pcie {
 	int			max_link_speed;
 	u8			n_fts[2];
 	struct dw_edma_chip	edma;
+	bool			l1ss_support;	/* L1 PM Substates support */
 	struct clk_bulk_data	app_clks[DW_PCIE_NUM_APP_CLKS];
 	struct clk_bulk_data	core_clks[DW_PCIE_NUM_CORE_CLKS];
 	struct reset_control_bulk_data	app_rsts[DW_PCIE_NUM_APP_RSTS];
@@ -573,6 +574,7 @@ int dw_pcie_prog_ep_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
 				int type, u64 parent_bus_addr,
 				u8 bar, size_t size);
 void dw_pcie_disable_atu(struct dw_pcie *pci, u32 dir, int index);
+void dw_pcie_config_l1ss(struct dw_pcie *pci);
 void dw_pcie_setup(struct dw_pcie *pci);
 void dw_pcie_iatu_detect(struct dw_pcie *pci);
 int dw_pcie_edma_detect(struct dw_pcie *pci);
diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index 805edbbfe7eb..61c2f4e2f74d 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -1067,6 +1067,8 @@ static int qcom_pcie_init_2_7_0(struct qcom_pcie *pcie)
 	val &= ~REQ_NOT_ENTR_L1;
 	writel(val, pcie->parf + PARF_PM_CTRL);
 
+	pci->l1ss_support = true;
+
 	val = readl(pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
 	val |= EN;
 	writel(val, pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
index 10e74458e667..3934757baa30 100644
--- a/drivers/pci/controller/dwc/pcie-tegra194.c
+++ b/drivers/pci/controller/dwc/pcie-tegra194.c
@@ -703,6 +703,9 @@ static void init_host_aspm(struct tegra_pcie_dw *pcie)
 	val |= (pcie->aspm_pwr_on_t << 19);
 	dw_pcie_writel_dbi(pci, pcie->cfg_link_cap_l1sub, val);
 
+	if (pcie->supports_clkreq)
+		pci->l1ss_support = true;
+
 	/* Program L0s and L1 entrance latencies */
 	val = dw_pcie_readl_dbi(pci, PCIE_PORT_AFR);
 	val &= ~PORT_AFR_L0S_ENTRANCE_LAT_MASK;
-- 
2.43.0



From helgaas at kernel.org  Tue Nov 11 14:16:09 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 11 Nov 2025 16:16:09 -0600
Subject: [PATCH 2/4] PCI: tegra194: Remove unnecessary L1SS disable code
In-Reply-To: <20251111221621.2208606-1-helgaas@kernel.org>
References: <20251111221621.2208606-1-helgaas@kernel.org>
Message-ID: <20251111221621.2208606-3-helgaas@kernel.org>

From: Bjorn Helgaas <bhelgaas at google.com>

The DWC core clears the L1 Substates Supported bits unless the driver sets
the "dw_pcie.l1ss_support" flag.

The tegra194 init_host_aspm() sets "dw_pcie.l1ss_support" if the platform
has the "supports-clkreq" DT property.  If "supports-clkreq" is absent,
"dw_pcie.l1ss_support" is not set, and the DWC core will clear the L1
Substates Supported bits.

The tegra194 code to clear the L1 Substates Supported bits is unnecessary,
so remove it.

Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
---
 drivers/pci/controller/dwc/pcie-tegra194.c | 32 ----------------------
 1 file changed, 32 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
index 3934757baa30..d5545bf37f81 100644
--- a/drivers/pci/controller/dwc/pcie-tegra194.c
+++ b/drivers/pci/controller/dwc/pcie-tegra194.c
@@ -608,24 +608,6 @@ static struct pci_ops tegra_pci_ops = {
 };
 
 #if defined(CONFIG_PCIEASPM)
-static void disable_aspm_l11(struct tegra_pcie_dw *pcie)
-{
-	u32 val;
-
-	val = dw_pcie_readl_dbi(&pcie->pci, pcie->cfg_link_cap_l1sub);
-	val &= ~PCI_L1SS_CAP_ASPM_L1_1;
-	dw_pcie_writel_dbi(&pcie->pci, pcie->cfg_link_cap_l1sub, val);
-}
-
-static void disable_aspm_l12(struct tegra_pcie_dw *pcie)
-{
-	u32 val;
-
-	val = dw_pcie_readl_dbi(&pcie->pci, pcie->cfg_link_cap_l1sub);
-	val &= ~PCI_L1SS_CAP_ASPM_L1_2;
-	dw_pcie_writel_dbi(&pcie->pci, pcie->cfg_link_cap_l1sub, val);
-}
-
 static inline u32 event_counter_prog(struct tegra_pcie_dw *pcie, u32 event)
 {
 	u32 val;
@@ -729,8 +711,6 @@ static void init_debugfs(struct tegra_pcie_dw *pcie)
 				    aspm_state_cnt);
 }
 #else
-static inline void disable_aspm_l12(struct tegra_pcie_dw *pcie) { return; }
-static inline void disable_aspm_l11(struct tegra_pcie_dw *pcie) { return; }
 static inline void init_host_aspm(struct tegra_pcie_dw *pcie) { return; }
 static inline void init_debugfs(struct tegra_pcie_dw *pcie) { return; }
 #endif
@@ -934,12 +914,6 @@ static int tegra_pcie_dw_host_init(struct dw_pcie_rp *pp)
 
 	init_host_aspm(pcie);
 
-	/* Disable ASPM-L1SS advertisement if there is no CLKREQ routing */
-	if (!pcie->supports_clkreq) {
-		disable_aspm_l11(pcie);
-		disable_aspm_l12(pcie);
-	}
-
 	if (!pcie->of_data->has_l1ss_exit_fix) {
 		val = dw_pcie_readl_dbi(pci, GEN3_RELATED_OFF);
 		val &= ~GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL;
@@ -1874,12 +1848,6 @@ static void pex_ep_event_pex_rst_deassert(struct tegra_pcie_dw *pcie)
 
 	init_host_aspm(pcie);
 
-	/* Disable ASPM-L1SS advertisement if there is no CLKREQ routing */
-	if (!pcie->supports_clkreq) {
-		disable_aspm_l11(pcie);
-		disable_aspm_l12(pcie);
-	}
-
 	if (!pcie->of_data->has_l1ss_exit_fix) {
 		val = dw_pcie_readl_dbi(pci, GEN3_RELATED_OFF);
 		val &= ~GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL;
-- 
2.43.0



From helgaas at kernel.org  Tue Nov 11 14:16:10 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 11 Nov 2025 16:16:10 -0600
Subject: [PATCH 3/4] PCI: dw-rockchip: Configure L1sub support
In-Reply-To: <20251111221621.2208606-1-helgaas@kernel.org>
References: <20251111221621.2208606-1-helgaas@kernel.org>
Message-ID: <20251111221621.2208606-4-helgaas@kernel.org>

From: Shawn Lin <shawn.lin at rock-chips.com>

L1 PM Substates for RC mode require support in the dw-rockchip driver
including proper handling of the CLKREQ# sideband signal. It is mostly
handled by hardware, but software still needs to set the clkreq fields
in the PCIE_CLIENT_POWER_CON register to match the hardware implementation.

For more details, see section '18.6.6.4 L1 Substate' in the RK3658 TRM 1.1
Part 2, or section '11.6.6.4 L1 Substate' in the RK3588 TRM 1.0 Part2.

Meanwhile, for the EP mode, we haven't prepared enough to actually support
L1 PM Substates yet. So disable it now until proper support is added later.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
[bhelgaas: set pci->l1ss_support so DWC core preserves L1SS Capability bits;
drop corresponding code here]
Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
Link: https://patch.msgid.link/1761187883-150120-1-git-send-email-shawn.lin at rock-chips.com
---
 drivers/pci/controller/dwc/pcie-dw-rockchip.c | 38 +++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
index 3e2752c7dd09..62a095752833 100644
--- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
+++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
@@ -62,6 +62,12 @@
 /* Interrupt Mask Register Related to Miscellaneous Operation */
 #define PCIE_CLIENT_INTR_MASK_MISC	0x24
 
+/* Power Management Control Register */
+#define PCIE_CLIENT_POWER_CON		0x2c
+#define  PCIE_CLKREQ_READY		FIELD_PREP_WM16(BIT(0), 1)
+#define  PCIE_CLKREQ_NOT_READY		FIELD_PREP_WM16(BIT(0), 0)
+#define  PCIE_CLKREQ_PULL_DOWN		FIELD_PREP_WM16(GENMASK(13, 12), 1)
+
 /* Hot Reset Control Register */
 #define PCIE_CLIENT_HOT_RESET_CTRL	0x180
 #define  PCIE_LTSSM_APP_DLY2_EN		BIT(1)
@@ -85,6 +91,7 @@ struct rockchip_pcie {
 	struct regulator *vpcie3v3;
 	struct irq_domain *irq_domain;
 	const struct rockchip_pcie_of_data *data;
+	bool supports_clkreq;
 };
 
 struct rockchip_pcie_of_data {
@@ -200,6 +207,32 @@ static bool rockchip_pcie_link_up(struct dw_pcie *pci)
 	return FIELD_GET(PCIE_LINKUP_MASK, val) == PCIE_LINKUP;
 }
 
+/*
+ * See e.g. section '11.6.6.4 L1 Substate' in the RK3588 TRM V1.0 for the steps
+ * needed to support L1 substates. Currently, just enable L1 substates for RC
+ * mode if CLKREQ# is properly connected and supports-clkreq is present in DT.
+ * For EP mode, there are more things should be done to actually save power in
+ * L1 substates, so disable L1 substates until there is proper support.
+ */
+static void rockchip_pcie_configure_l1sub(struct dw_pcie *pci)
+{
+	struct rockchip_pcie *rockchip = to_rockchip_pcie(pci);
+
+	/* Enable L1 substates if CLKREQ# is properly connected */
+	if (rockchip->supports_clkreq &&
+	    rockchip->data->mode == DW_PCIE_RC_TYPE ) {
+		rockchip_pcie_writel_apb(rockchip, PCIE_CLKREQ_READY,
+					 PCIE_CLIENT_POWER_CON);
+		pci->l1ss_support = true;
+		return;
+	}
+
+	/* Otherwise, pull down CLKREQ# */
+	rockchip_pcie_writel_apb(rockchip,
+				 PCIE_CLKREQ_PULL_DOWN | PCIE_CLKREQ_NOT_READY,
+				 PCIE_CLIENT_POWER_CON);
+}
+
 static void rockchip_pcie_enable_l0s(struct dw_pcie *pci)
 {
 	u32 cap, lnkcap;
@@ -264,6 +297,7 @@ static int rockchip_pcie_host_init(struct dw_pcie_rp *pp)
 	irq_set_chained_handler_and_data(irq, rockchip_pcie_intx_handler,
 					 rockchip);
 
+	rockchip_pcie_configure_l1sub(pci);
 	rockchip_pcie_enable_l0s(pci);
 
 	return 0;
@@ -301,6 +335,7 @@ static void rockchip_pcie_ep_init(struct dw_pcie_ep *ep)
 	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
 	enum pci_barno bar;
 
+	rockchip_pcie_configure_l1sub(pci);
 	rockchip_pcie_enable_l0s(pci);
 	rockchip_pcie_ep_hide_broken_ats_cap_rk3588(ep);
 
@@ -412,6 +447,9 @@ static int rockchip_pcie_resource_get(struct platform_device *pdev,
 		return dev_err_probe(&pdev->dev, PTR_ERR(rockchip->rst),
 				     "failed to get reset lines\n");
 
+	rockchip->supports_clkreq = of_property_read_bool(pdev->dev.of_node,
+							  "supports-clkreq");
+
 	return 0;
 }
 
-- 
2.43.0



From helgaas at kernel.org  Tue Nov 11 14:16:11 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 11 Nov 2025 16:16:11 -0600
Subject: [PATCH 4/4] arm64: dts: rockchip: Add PCIe clkreq stuff for RK3588 EVB1
In-Reply-To: <20251111221621.2208606-1-helgaas@kernel.org>
References: <20251111221621.2208606-1-helgaas@kernel.org>
Message-ID: <20251111221621.2208606-5-helgaas@kernel.org>

From: Shawn Lin <shawn.lin at rock-chips.com>

Add supports-clkreq and pinmux for PCIe ASPM L1 substates.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
Reviewed-by: Hans Zhang <hans.zhang at cixtech.com>
Acked-by: Manivannan Sadhasivam <mani at kernel.org>
Link: https://patch.msgid.link/1761187883-150120-2-git-send-email-shawn.lin at rock-chips.com
---
 arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
index ff1ba5ed56ef..c9d284cb738b 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
@@ -522,6 +522,7 @@ &pcie2x1l0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pcie2_0_rst>, <&pcie2_0_wake>, <&pcie2_0_clkreq>, <&wifi_host_wake_irq>;
 	reset-gpios = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>;
+	supports-clkreq;
 	vpcie3v3-supply = <&vcc3v3_wlan>;
 	status = "okay";
 
@@ -545,7 +546,8 @@ wifi: wifi at 0,0 {
 &pcie2x1l1 {
 	reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
 	pinctrl-names = "default";
-	pinctrl-0 = <&pcie2_1_rst>, <&rtl8111_isolate>;
+	pinctrl-0 = <&pcie2_1_rst>, <&rtl8111_isolate>, <&pcie30x1m1_1_clkreqn>;
+	supports-clkreq;
 	status = "okay";
 };
 
@@ -555,7 +557,8 @@ &pcie30phy {
 
 &pcie3x4 {
 	pinctrl-names = "default";
-	pinctrl-0 = <&pcie3_reset>;
+	pinctrl-0 = <&pcie3_reset>, <&pcie30x4m1_clkreqn>;
+	supports-clkreq;
 	reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
 	vpcie3v3-supply = <&vcc3v3_pcie30>;
 	status = "okay";
-- 
2.43.0



From Frank.li at nxp.com  Tue Nov 11 14:48:07 2025
From: Frank.li at nxp.com (Frank Li)
Date: Tue, 11 Nov 2025 17:48:07 -0500
Subject: [PATCH 1/4] PCI: dwc: Advertise L1 PM Substates only if driver
 requests it
In-Reply-To: <20251111221621.2208606-2-helgaas@kernel.org>
References: <20251111221621.2208606-1-helgaas@kernel.org>
 <20251111221621.2208606-2-helgaas@kernel.org>
Message-ID: <aRO9J9ybdseyExYK@lizhi-Precision-Tower-5810>

On Tue, Nov 11, 2025 at 04:16:08PM -0600, Bjorn Helgaas wrote:
> From: Bjorn Helgaas <bhelgaas at google.com>
>
> L1 PM Substates require the CLKREF# signal and may also require
> device-specific support.  If CLKREF# is not supported or driver support is
> lacking, enabling L1.1 or L1.2 may cause errors when accessing devices,
> e.g.,
>
>   nvme nvme0: controller is down; will reset: CSTS=0xffffffff, PCI_STATUS=0x10
>
> If the kernel is built with CONFIG_PCIEASPM_POWER_SUPERSAVE=y or users
> enable L1.x via sysfs, users may trip over these errors even if L1
> Substates haven't been enabled by firmware or the driver.
>
> To prevent such errors, disable advertising the L1 PM Substates unless the
> driver sets "dw_pcie.l1ss_support" to indicate that it knows CLKREF# is
> present and any device-specific configuration has been done.
>
> Set "dw_pcie.l1ss_support" in tegra194 (if DT includes the
> "supports-clkreq' property) and qcom (for 2.7.0 controllers) so they can
> continue to use L1 Substates.
>
> Based on Niklas's patch:
> https://patch.msgid.link/20251017163252.598812-2-cassel at kernel.org
>
> Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
> ---
>  .../pci/controller/dwc/pcie-designware-ep.c   |  2 ++
>  .../pci/controller/dwc/pcie-designware-host.c |  2 ++
>  drivers/pci/controller/dwc/pcie-designware.c  | 24 +++++++++++++++++++
>  drivers/pci/controller/dwc/pcie-designware.h  |  2 ++
>  drivers/pci/controller/dwc/pcie-qcom.c        |  2 ++
>  drivers/pci/controller/dwc/pcie-tegra194.c    |  3 +++
>  6 files changed, 35 insertions(+)
>
...
>
> +void dw_pcie_config_l1ss(struct dw_pcie *pci)
> +{
> +	u16 l1ss;
> +	u32 l1ss_cap;
> +
> +	if (!pci->l1ss_support)

I think when l1ss_support true, need return.
when l1ss_support false, need clean PCI_L1SS_CAP.

Do your logic reverise?

Frank

> +		return;
> +
> +	l1ss = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_L1SS);
> +	if (!l1ss)
> +		return;
> +
> +	/*
> +	 * Unless the driver claims "l1ss_support", don't advertise L1 PM
> +	 * Substates because they require CLKREF# and possibly other
> +	 * device-specific configuration.
> +	 */
> +	l1ss_cap = dw_pcie_readl_dbi(pci, l1ss + PCI_L1SS_CAP);
> +	l1ss_cap &= ~(PCI_L1SS_CAP_PCIPM_L1_1 | PCI_L1SS_CAP_ASPM_L1_1 |
> +		      PCI_L1SS_CAP_PCIPM_L1_2 | PCI_L1SS_CAP_ASPM_L1_2 |
> +		      PCI_L1SS_CAP_L1_PM_SS);
> +	dw_pcie_writel_dbi(pci, l1ss + PCI_L1SS_CAP, l1ss_cap);
> +}
> +
>  void dw_pcie_setup(struct dw_pcie *pci)
>  {
>  	u32 val;
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> index e995f692a1ec..8d14b1fe2280 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -516,6 +516,7 @@ struct dw_pcie {
>  	int			max_link_speed;
>  	u8			n_fts[2];
>  	struct dw_edma_chip	edma;
> +	bool			l1ss_support;	/* L1 PM Substates support */
>  	struct clk_bulk_data	app_clks[DW_PCIE_NUM_APP_CLKS];
>  	struct clk_bulk_data	core_clks[DW_PCIE_NUM_CORE_CLKS];
>  	struct reset_control_bulk_data	app_rsts[DW_PCIE_NUM_APP_RSTS];
> @@ -573,6 +574,7 @@ int dw_pcie_prog_ep_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
>  				int type, u64 parent_bus_addr,
>  				u8 bar, size_t size);
>  void dw_pcie_disable_atu(struct dw_pcie *pci, u32 dir, int index);
> +void dw_pcie_config_l1ss(struct dw_pcie *pci);
>  void dw_pcie_setup(struct dw_pcie *pci);
>  void dw_pcie_iatu_detect(struct dw_pcie *pci);
>  int dw_pcie_edma_detect(struct dw_pcie *pci);
> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
> index 805edbbfe7eb..61c2f4e2f74d 100644
> --- a/drivers/pci/controller/dwc/pcie-qcom.c
> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> @@ -1067,6 +1067,8 @@ static int qcom_pcie_init_2_7_0(struct qcom_pcie *pcie)
>  	val &= ~REQ_NOT_ENTR_L1;
>  	writel(val, pcie->parf + PARF_PM_CTRL);
>
> +	pci->l1ss_support = true;
> +
>  	val = readl(pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
>  	val |= EN;
>  	writel(val, pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
> diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
> index 10e74458e667..3934757baa30 100644
> --- a/drivers/pci/controller/dwc/pcie-tegra194.c
> +++ b/drivers/pci/controller/dwc/pcie-tegra194.c
> @@ -703,6 +703,9 @@ static void init_host_aspm(struct tegra_pcie_dw *pcie)
>  	val |= (pcie->aspm_pwr_on_t << 19);
>  	dw_pcie_writel_dbi(pci, pcie->cfg_link_cap_l1sub, val);
>
> +	if (pcie->supports_clkreq)
> +		pci->l1ss_support = true;
> +
>  	/* Program L0s and L1 entrance latencies */
>  	val = dw_pcie_readl_dbi(pci, PCIE_PORT_AFR);
>  	val &= ~PORT_AFR_L0S_ENTRANCE_LAT_MASK;
> --
> 2.43.0
>


From helgaas at kernel.org  Tue Nov 11 15:07:10 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 11 Nov 2025 17:07:10 -0600
Subject: [PATCH 1/4] PCI: dwc: Advertise L1 PM Substates only if driver
 requests it
In-Reply-To: <aRO9J9ybdseyExYK@lizhi-Precision-Tower-5810>
Message-ID: <20251111230710.GA2210983@bhelgaas>

On Tue, Nov 11, 2025 at 05:48:07PM -0500, Frank Li wrote:
> On Tue, Nov 11, 2025 at 04:16:08PM -0600, Bjorn Helgaas wrote:
> > From: Bjorn Helgaas <bhelgaas at google.com>
> >
> > L1 PM Substates require the CLKREF# signal and may also require
> > device-specific support.  If CLKREF# is not supported or driver support is
> > lacking, enabling L1.1 or L1.2 may cause errors when accessing devices,
> > e.g.,
> >
> >   nvme nvme0: controller is down; will reset: CSTS=0xffffffff, PCI_STATUS=0x10
> >
> > If the kernel is built with CONFIG_PCIEASPM_POWER_SUPERSAVE=y or users
> > enable L1.x via sysfs, users may trip over these errors even if L1
> > Substates haven't been enabled by firmware or the driver.
> >
> > To prevent such errors, disable advertising the L1 PM Substates unless the
> > driver sets "dw_pcie.l1ss_support" to indicate that it knows CLKREF# is
> > present and any device-specific configuration has been done.
> >
> > Set "dw_pcie.l1ss_support" in tegra194 (if DT includes the
> > "supports-clkreq' property) and qcom (for 2.7.0 controllers) so they can
> > continue to use L1 Substates.
> >
> > Based on Niklas's patch:
> > https://patch.msgid.link/20251017163252.598812-2-cassel at kernel.org
> >
> > Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
> > ---
> >  .../pci/controller/dwc/pcie-designware-ep.c   |  2 ++
> >  .../pci/controller/dwc/pcie-designware-host.c |  2 ++
> >  drivers/pci/controller/dwc/pcie-designware.c  | 24 +++++++++++++++++++
> >  drivers/pci/controller/dwc/pcie-designware.h  |  2 ++
> >  drivers/pci/controller/dwc/pcie-qcom.c        |  2 ++
> >  drivers/pci/controller/dwc/pcie-tegra194.c    |  3 +++
> >  6 files changed, 35 insertions(+)
> >
> ...
> >
> > +void dw_pcie_config_l1ss(struct dw_pcie *pci)
> > +{
> > +	u16 l1ss;
> > +	u32 l1ss_cap;
> > +
> > +	if (!pci->l1ss_support)
> 
> I think when l1ss_support true, need return.
> when l1ss_support false, need clean PCI_L1SS_CAP.
> 
> Do your logic reverise?

Yes!  Thank you, fixed locally.


From naoki at radxa.com  Tue Nov 11 15:26:50 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Wed, 12 Nov 2025 08:26:50 +0900
Subject: [PATCH v6 0/3] Add Radxa CM5 and IO Board
In-Reply-To: <a10340af-1d0a-bb0b-4835-7b2c9e67d664@manjaro.org>
References: <20251105051335.17652-1-naoki@radxa.com>
 <199E172C8E20ED38+71169242-5525-4d60-9e37-a03ad172d639@radxa.com>
 <CAMWSM7gezjVSoF+-7ivboTeB=5gQAE-QVrbAbKu3M=obmb3Axg@mail.gmail.com>
 <617FDAB231C501DC+3f9809df-87df-4a02-bd5f-ebc6299b3aa7@radxa.com>
 <a10340af-1d0a-bb0b-4835-7b2c9e67d664@manjaro.org>
Message-ID: <2892FE50237CD58E+0f15924c-a915-4446-954c-d81a782d23e9@radxa.com>

Hi Dragan, Joseph,

On 11/11/25 23:33, Dragan Simic wrote:
> Hello all,
> 
> On Tuesday, November 11, 2025 12:52 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
>> On 11/6/25 02:48, Joseph Kogut wrote:
>>> On Wed, Nov 5, 2025 at 4:15?AM FUKAUMI Naoki <naoki at radxa.com> wrote:
>>>> I'd like to clarify the situation regarding the v6 patch series I submitted.
>>>>
>>>> The original device tree work for the Radxa CM5 and IO Board was
>>>> authored by Joseph Kogut. I took over the responsibility of getting it
>>>> upstreamed with his agreement.
>>>
>>> I'll confirm this. I've been in communication with Naoki. They made a
>>> large number of revisions to my original patch series, which I think
>>> have technical merit. I suggested they submit the patches themselves,
>>> and gave them explicit permission to add my Signed-off-by and CC me.
>>>
>>> I assume this was the correct way for them to continue the work I
>>> started, but if not, please let us know the best way to proceed.
>>
>> Can anyone help us?
> 
> I'm not exactly sure how to resolve the current situation, but for
> Signed-off-by tags to be present, in this case you'd need to have
> Co-developed-by tags as well, because the final patch versions,
> which would be submitted by Naoki, would differ significantly from
> the versions that Joseph actively worked on, if I understood
> everything correctly.  Though, for Joseph's Signed-off-by tags to
> be included there, he would also need to participate actively in
> the development of the final patch versions.

https://www.kernel.org/doc/html/latest/process/submitting-patches.html#when-to-use-acked-by-cc-and-co-developed-by

If
----
From: Joseph Kogut <joseph.kogut at gmail.com>

<changelog>

Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
Co-developed-by: FUKAUMI Naoki <naoki at radxa.com>
Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
----
then I can submit my patch series?

Or,

> Another option, technically a bit simpler, would be to include just
> Originally-by tags for Joseph, which would indicate that Joseph gave
> up on the development of the patches and handed them over to Naoki
> for future development and submission to the mailing lists. Though,
> that would require Joseph to publicly state exactly that.

I cannot find any documentation about "Originally-by".
Is this correct?
----
<changelog>

Originally-by: Joseph Kogut <joseph.kogut at gmail.com>
Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
----

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.



From naoki at radxa.com  Tue Nov 11 15:42:15 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Wed, 12 Nov 2025 08:42:15 +0900
Subject: [PATCH v2] arm64: dts: rockchip: Turn all LEDs on at boot for
 Radxa boards
In-Reply-To: <572f341f-a5fa-4f1c-ad60-a5fe3e046d6d@cherry.de>
References: <20251111054112.55505-1-naoki@radxa.com>
 <DE5W0143QGG2.3C7SW89IJKZ4P@cknow-tech.com>
 <516e919a-42af-8707-4e75-a808df8971fd@manjaro.org>
 <B0C8C5A69B9F465E+ba0ad139-d3d9-4492-ac9a-cc58f8f35074@radxa.com>
 <41275775-9e6e-9202-4c79-6140a56e41d5@manjaro.org>
 <572f341f-a5fa-4f1c-ad60-a5fe3e046d6d@cherry.de>
Message-ID: <774C3AB9F17BAE47+14f8b8ba-ba78-410e-b44c-4d077585d05a@radxa.com>

Hi Quentin,

On 11/12/25 03:32, Quentin Schulz wrote:
> Hi all,
> 
> On 11/11/25 5:14 PM, Dragan Simic wrote:
>> Hello all,
>>
>> (+ Quentin)
>>
>> On Tuesday, November 11, 2025 16:32 CET, FUKAUMI Naoki 
>> <naoki at radxa.com> wrote:
>>> On 11/11/25 23:46, Dragan Simic wrote:
>>>> On Tuesday, November 11, 2025 14:07 CET, "Diederik de Haas" 
>>>> <diederik at cknow-tech.com> wrote:
>>>>> On Tue Nov 11, 2025 at 6:41 AM CET, FUKAUMI Naoki wrote:
>>>>>> Radxa's boards turn all LEDs on at boot(loader), but some boards 
>>>>>> don't
>>>>>> have `default-state` property in Linux kernel tree but have it in
>>>>>> U-Boot tree instead[1].
>>>>>>
>>>>>> This patch adds `default-state = "on"` for (almost) all LEDs (with a
>>>>>> few exceptions which should be "off" such as RGB LEDs on E25 and LAN/
>>>>>> WAN LEDs on E20C/E52C).
>>>>>
>>>>> I'm missing the *why* these changes would be an improvement.
>>>>>
>>>>> Personally, for both 'heartbeat' and 'netdev' triggers, I want them to
>>>>> be off by default and once it gets a 'heartbeat' or a 'netdev' 
>>>>> trigger,
>>>>> THEN I want the LED to be on/blinking.
>>>>
>>>> That's a good question for Naoki.? My own preference would also
>>>> be to have the device's power LED turned on by U-Boot as quickly
>>>> as possible after supplying power to the board or turning it on
>>>> by pressing the power button.? I'm actually not a big fan of
>>>> having all the LEDs shining for a couple of seconds or so, which
>>>> may actually look like some error condition to me.
>>>>
>>>> Having all that in mind, I may suggest that just the U-Boot's
>>>> behavior is changed to turn the power LEDs on only.
>>>
>>> I can't quite explain it, but...
>>>
>>> - 1st (Power) LED
>>>
>>> The 1st (power) LED turns on automatically/immediately without software
>>> intervention. (On some boards, this LED cannot be controlled by software
>>> at all.)
>>>
>>> In DTS, this should be described using `default-state = "on"`. The use
>>> of the Linux-specific property `linux,default-trigger = "default-on"` is
>>> unsuitable for non-Linux environments.
>>>
>>> - 2nd (Heartbeat) LED
>>>
>>> The 2nd (heartbeat) LED can be controlled by software. It should be lit
>>> up as quickly as possible to indicate that the very first software
>>> (e.g., the bootloader) is running.
>>>
>>> On Linux, usually this is used as `linux,default-trigger = "heartbeat"`.
>>> It indicates that kernel is running (regardless of the `default-state`
>>> setting), and its behavior can be modified in user space.
>>
>> As discussed already in the #linux-rockchip IRC channel, [1] perhaps
>> the best option would be to have the power LEDs turned on as quickly
>> upon powering on the board as possible, and to have U-Boot pulsate
>> the heartbeat LEDs using the LED_BOOT feature.? In such a scenario,
>> no other LEDs would be turned on early, and the LED-related DT parts
>> specific to U-Boot would be migrated to the kernel DTs.
>>
>> [1] https://libera.catirclogs.org/linux-rockchip/2025-11-11#38997824;
>>
> 
> The LED_BOOT feature (guarded by the Kconfig symbol of the same name) in 
> U-Boot only applies if /options/u-boot/boot-led property is set.

For the default state of the heartbeat LED, I'm thinking of using 
LED_BOOT (/options/u-boot/boot-led), but I'm concerned that this is 
U-Boot-specific.

> If the driver for the LED (typically a GPIO LED controller I guess, so 
> LED_GPIO symbol) is compiled in, then, as far as I could tell, the Boot 
> LED will be turned on right before entering the main loop of U-Boot.
> 
> If LED_BLINK (if HW blinking is supported) or LED_SW_BLINK is enabled, 
> the Boot LED will be blinking some time after relocation but still 
> turned on soon after (if it reaches that part of the code). This means 
> it'll be on before the kernel starts.
> 
> I'm not sure there's a way to hook something *after* we've entered U- 
> Boot main-loop (read "call led_boot_blink() from some board file"), 
> aside from calling `led <led-name> blink <period>` from U-Boot CLI.
> 
> I'm a bit bummed by this behavior, I would have preferred the ability to 
> have the Boot LED blink until the kernel starts. I could then have a 
> different period for U-Boot (50% duty cycle at 250ms period by default) 
> and for the kernel. Of course, if it's SW blinking, once exiting U-Boot 
> it won't blink anymore until the kernel takes over, but that's also a 
> nice information to have. Anyway, I'm not sure this is actually possible 
> with the LED_BOOT feature though one should be able to do this by 
> specifying the label of an LED node to fetch from DT and then calling 
> led_set_period(dev, period_ms); followed by led_set_state(dev, 
> LEDST_BLINK); in a board file, but this is also not so nice as it then 
> also requires some C board-specific code in U-Boot.
> 
> In U-Boot, only LEDs which have a "default-state" properties will be 
> auto-configured, otherwise one needs to control them manually (e.g. via 
> the `led` CLI command).

As you know, default "default-state" is "off".
  https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/leds/common.yaml?h=v6.17#n74

As far as I understand, there should not be any workarounds for specific 
implementations.
  https://lore.kernel.org/linux-rockchip/3389401.44csPzL39Z at phil/

So removing `default-state = "off"` is acceptable, right?

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> If one wants to detect via an LED the current boot stage (U-Boot 
> reached, kernel started), then we need to NOT use LED_BOOT feature and 
> have U-Boot set the "boot" LED the opposite state than the default HW 
> state, i.e. if the LED is on without any running SW (power applied to 
> the device, empty boot media), then U-Boot should set it to off. Then 
> the kernel simply needs to start the heartbeat mode whenever ready. If 
> the default HW state is off, then U-Boot should set it on. I haven't 
> looked into the kernel side of things, but there could be a window 
> during which default-state property is applied before the heartbeat is 
> actually started.
> 
> The logic exposed in the previous paragraph should provide visual cues 
> on the current boot stage.
> 
> Note that LEDs with linux,default-trigger = "pattern" (with default- 
> state property) will be blinking once auto-configured in U-Boot as well 
> according to my reading of the led-uclass.c.
> 
> Hope this helps.
> 
> Cheers,
> Quentin
> 



From shawn.lin at rock-chips.com  Tue Nov 11 16:45:03 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Wed, 12 Nov 2025 08:45:03 +0800
Subject: [PATCH] mmc: dw_mmc-rockchip: Add memory clock auto-gating
 support
In-Reply-To: <CAPDyKFpLp--cn4T3ifL8zB=GqptHZtnRH+V8Z370LNsj7n3wNA@mail.gmail.com>
References: <1762242094-55346-1-git-send-email-shawn.lin@rock-chips.com>
 <CAPDyKFpLp--cn4T3ifL8zB=GqptHZtnRH+V8Z370LNsj7n3wNA@mail.gmail.com>
Message-ID: <fcc9262c-5bd8-4f96-971c-c61ae8cbde69@rock-chips.com>

? 2025/11/12 ??? 0:55, Ulf Hansson ??:
> On Tue, 4 Nov 2025 at 08:41, Shawn Lin <shawn.lin at rock-chips.com> wrote:
>>
>> Per design recommendations, the memory clock can be gated when there
>> is no in-flight transfer, which helps save power. This feature is
>> introduced alongside internal phase support, and this patch enables it.
> 
> Just to make sure, does this work if the controller is used for SDIO
> and has SDIO irqs enabled?
> 
> Or perhaps that is taken care of in dw_mci_prepare_sdio_irq()?
> 

Yes, it works for SDIO case too.

>>
>> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
> 
> Kind regards
> Uffe
> 
>> ---
>>
>>   drivers/mmc/host/dw_mmc-rockchip.c | 6 ++++++
>>   1 file changed, 6 insertions(+)
>>
>> diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c
>> index 6813549..62c68cd 100644
>> --- a/drivers/mmc/host/dw_mmc-rockchip.c
>> +++ b/drivers/mmc/host/dw_mmc-rockchip.c
>> @@ -19,6 +19,8 @@
>>   #define RK3288_CLKGEN_DIV              2
>>   #define SDMMC_TIMING_CON0              0x130
>>   #define SDMMC_TIMING_CON1              0x134
>> +#define SDMMC_MISC_CON                 0x138
>> +#define MEM_CLK_AUTOGATE_ENABLE                BIT(5)
>>   #define ROCKCHIP_MMC_DELAY_SEL         BIT(10)
>>   #define ROCKCHIP_MMC_DEGREE_MASK       0x3
>>   #define ROCKCHIP_MMC_DEGREE_OFFSET     1
>> @@ -470,6 +472,7 @@ static int dw_mci_rk3576_parse_dt(struct dw_mci *host)
>>
>>   static int dw_mci_rockchip_init(struct dw_mci *host)
>>   {
>> +       struct dw_mci_rockchip_priv_data *priv = host->priv;
>>          int ret, i;
>>
>>          /* It is slot 8 on Rockchip SoCs */
>> @@ -494,6 +497,9 @@ static int dw_mci_rockchip_init(struct dw_mci *host)
>>                          dev_warn(host->dev, "no valid minimum freq: %d\n", ret);
>>          }
>>
>> +       if (priv->internal_phase)
>> +               mci_writel(host, MISC_CON, MEM_CLK_AUTOGATE_ENABLE);
>> +
>>          return 0;
>>   }
>>
>> --
>> 2.7.4
>>
> 



From dsimic at manjaro.org  Tue Nov 11 16:46:06 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Wed, 12 Nov 2025 01:46:06 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v6 0/3] Add Radxa CM5 and IO Board
In-Reply-To: <2892FE50237CD58E+0f15924c-a915-4446-954c-d81a782d23e9@radxa.com>
References: <20251105051335.17652-1-naoki@radxa.com>
 <199E172C8E20ED38+71169242-5525-4d60-9e37-a03ad172d639@radxa.com>
 <CAMWSM7gezjVSoF+-7ivboTeB=5gQAE-QVrbAbKu3M=obmb3Axg@mail.gmail.com>
 <617FDAB231C501DC+3f9809df-87df-4a02-bd5f-ebc6299b3aa7@radxa.com>
 <a10340af-1d0a-bb0b-4835-7b2c9e67d664@manjaro.org> <2892FE50237CD58E+0f15924c-a915-4446-954c-d81a782d23e9@radxa.com>
Message-ID: <19ce0a41-563c-6202-6b94-b2c644a0b827@manjaro.org>

Hello Naoki,

On Wednesday, November 12, 2025 00:26 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> On 11/11/25 23:33, Dragan Simic wrote:
> > On Tuesday, November 11, 2025 12:52 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> >> On 11/6/25 02:48, Joseph Kogut wrote:
> >>> On Wed, Nov 5, 2025 at 4:15?AM FUKAUMI Naoki <naoki at radxa.com> wrote:
> >>>> I'd like to clarify the situation regarding the v6 patch series I submitted.
> >>>>
> >>>> The original device tree work for the Radxa CM5 and IO Board was
> >>>> authored by Joseph Kogut. I took over the responsibility of getting it
> >>>> upstreamed with his agreement.
> >>>
> >>> I'll confirm this. I've been in communication with Naoki. They made a
> >>> large number of revisions to my original patch series, which I think
> >>> have technical merit. I suggested they submit the patches themselves,
> >>> and gave them explicit permission to add my Signed-off-by and CC me.
> >>>
> >>> I assume this was the correct way for them to continue the work I
> >>> started, but if not, please let us know the best way to proceed.
> >>
> >> Can anyone help us?
> > 
> > I'm not exactly sure how to resolve the current situation, but for
> > Signed-off-by tags to be present, in this case you'd need to have
> > Co-developed-by tags as well, because the final patch versions,
> > which would be submitted by Naoki, would differ significantly from
> > the versions that Joseph actively worked on, if I understood
> > everything correctly.  Though, for Joseph's Signed-off-by tags to
> > be included there, he would also need to participate actively in
> > the development of the final patch versions.
> 
> https://www.kernel.org/doc/html/latest/process/submitting-patches.html#when-to-use-acked-by-cc-and-co-developed-by
> 
> If
> ----
> From: Joseph Kogut <joseph.kogut at gmail.com>
> 
> <changelog>
> 
> Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
> Co-developed-by: FUKAUMI Naoki <naoki at radxa.com>
> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> ----
> then I can submit my patch series?

Actually, the Co-developed-by tags would be pointing to Joseph
in that case, but as I described it above, this approach basically
cannot be used, because Joseph's original work differs a lot from
what you'd actually submit to the mailing list(s).

> Or,
> 
> > Another option, technically a bit simpler, would be to include just
> > Originally-by tags for Joseph, which would indicate that Joseph gave
> > up on the development of the patches and handed them over to Naoki
> > for future development and submission to the mailing lists. Though,
> > that would require Joseph to publicly state exactly that.
> 
> I cannot find any documentation about "Originally-by".
> Is this correct?
> ----
> <changelog>
> 
> Originally-by: Joseph Kogut <joseph.kogut at gmail.com>
> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> ----

That approach is the only I see applicable in this case.  However,
let's hear opinions from other people as well.

By the way, what you called changelogs in the examples above is
usually called patch descriptions.  When they become merged, they
become called commit descriptions or, sometimes, commit messages.
Using the standard lingo usually helps. :)



From naoki at radxa.com  Tue Nov 11 17:01:20 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Wed, 12 Nov 2025 10:01:20 +0900
Subject: [PATCH v6 0/3] Add Radxa CM5 and IO Board
In-Reply-To: <19ce0a41-563c-6202-6b94-b2c644a0b827@manjaro.org>
References: <20251105051335.17652-1-naoki@radxa.com>
 <199E172C8E20ED38+71169242-5525-4d60-9e37-a03ad172d639@radxa.com>
 <CAMWSM7gezjVSoF+-7ivboTeB=5gQAE-QVrbAbKu3M=obmb3Axg@mail.gmail.com>
 <617FDAB231C501DC+3f9809df-87df-4a02-bd5f-ebc6299b3aa7@radxa.com>
 <a10340af-1d0a-bb0b-4835-7b2c9e67d664@manjaro.org>
 <2892FE50237CD58E+0f15924c-a915-4446-954c-d81a782d23e9@radxa.com>
 <19ce0a41-563c-6202-6b94-b2c644a0b827@manjaro.org>
Message-ID: <EB08CB02156A172D+abf42f17-09e1-40ea-9369-eca481d230a6@radxa.com>

Hi Dragan, Joseph, all

On 11/12/25 09:46, Dragan Simic wrote:
> Hello Naoki,
> 
> On Wednesday, November 12, 2025 00:26 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
>> On 11/11/25 23:33, Dragan Simic wrote:
>>> On Tuesday, November 11, 2025 12:52 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
>>>> On 11/6/25 02:48, Joseph Kogut wrote:
>>>>> On Wed, Nov 5, 2025 at 4:15?AM FUKAUMI Naoki <naoki at radxa.com> wrote:
>>>>>> I'd like to clarify the situation regarding the v6 patch series I submitted.
>>>>>>
>>>>>> The original device tree work for the Radxa CM5 and IO Board was
>>>>>> authored by Joseph Kogut. I took over the responsibility of getting it
>>>>>> upstreamed with his agreement.
>>>>>
>>>>> I'll confirm this. I've been in communication with Naoki. They made a
>>>>> large number of revisions to my original patch series, which I think
>>>>> have technical merit. I suggested they submit the patches themselves,
>>>>> and gave them explicit permission to add my Signed-off-by and CC me.
>>>>>
>>>>> I assume this was the correct way for them to continue the work I
>>>>> started, but if not, please let us know the best way to proceed.
>>>>
>>>> Can anyone help us?
>>>
>>> I'm not exactly sure how to resolve the current situation, but for
>>> Signed-off-by tags to be present, in this case you'd need to have
>>> Co-developed-by tags as well, because the final patch versions,
>>> which would be submitted by Naoki, would differ significantly from
>>> the versions that Joseph actively worked on, if I understood
>>> everything correctly.  Though, for Joseph's Signed-off-by tags to
>>> be included there, he would also need to participate actively in
>>> the development of the final patch versions.
>>
>> https://www.kernel.org/doc/html/latest/process/submitting-patches.html#when-to-use-acked-by-cc-and-co-developed-by
>>
>> If
>> ----
>> From: Joseph Kogut <joseph.kogut at gmail.com>
>>
>> <changelog>
>>
>> Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
>> Co-developed-by: FUKAUMI Naoki <naoki at radxa.com>
>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
>> ----
>> then I can submit my patch series?
> 
> Actually, the Co-developed-by tags would be pointing to Joseph
> in that case, but as I described it above, this approach basically
> cannot be used, because Joseph's original work differs a lot from
> what you'd actually submit to the mailing list(s).
> 
>> Or,
>>
>>> Another option, technically a bit simpler, would be to include just
>>> Originally-by tags for Joseph, which would indicate that Joseph gave
>>> up on the development of the patches and handed them over to Naoki
>>> for future development and submission to the mailing lists. Though,
>>> that would require Joseph to publicly state exactly that.
>>
>> I cannot find any documentation about "Originally-by".
>> Is this correct?
>> ----
>> <changelog>
>>
>> Originally-by: Joseph Kogut <joseph.kogut at gmail.com>
>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
>> ----
> 
> That approach is the only I see applicable in this case.  However,
> let's hear opinions from other people as well.

Thank you very much for your advice.

So I want to hear Joseph's public statement and the opinions of other 
people.

> By the way, what you called changelogs in the examples above is
> usually called patch descriptions.  When they become merged, they
> become called commit descriptions or, sometimes, commit messages.
> Using the standard lingo usually helps. :)

Ah, it comes from
  https://www.kernel.org/doc/html/latest/process/submitting-patches.html#when-to-use-acked-by-cc-and-co-developed-by

Should it be fixed? ;)

Best regards

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.



From shawn.lin at rock-chips.com  Tue Nov 11 17:03:38 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Wed, 12 Nov 2025 09:03:38 +0800
Subject: [PATCH 1/4] PCI: dwc: Advertise L1 PM Substates only if driver
 requests it
In-Reply-To: <20251111221621.2208606-2-helgaas@kernel.org>
References: <20251111221621.2208606-1-helgaas@kernel.org>
 <20251111221621.2208606-2-helgaas@kernel.org>
Message-ID: <79a8c3cc-2b60-4bce-b1ba-7ab5f033f924@rock-chips.com>

? 2025/11/12 ??? 6:16, Bjorn Helgaas ??:
> From: Bjorn Helgaas <bhelgaas at google.com>
> 
> L1 PM Substates require the CLKREF# signal and may also require
> device-specific support.  If CLKREF# is not supported or driver support is
> lacking, enabling L1.1 or L1.2 may cause errors when accessing devices,
> e.g.,
> 
>    nvme nvme0: controller is down; will reset: CSTS=0xffffffff, PCI_STATUS=0x10
> 
> If the kernel is built with CONFIG_PCIEASPM_POWER_SUPERSAVE=y or users
> enable L1.x via sysfs, users may trip over these errors even if L1
> Substates haven't been enabled by firmware or the driver.
> 
> To prevent such errors, disable advertising the L1 PM Substates unless the
> driver sets "dw_pcie.l1ss_support" to indicate that it knows CLKREF# is
> present and any device-specific configuration has been done.
> 
> Set "dw_pcie.l1ss_support" in tegra194 (if DT includes the
> "supports-clkreq' property) and qcom (for 2.7.0 controllers) so they can
> continue to use L1 Substates.
> 
> Based on Niklas's patch:
> https://patch.msgid.link/20251017163252.598812-2-cassel at kernel.org


Except the issue Fank pointed out, the commit msg says CLKREF# 3 times
which seems not a term from spec. Should it be CLKREQ# ?

Otherwise,
Reviewed-by: Shawn Lin <shawn.lin at rock-chips.com>

> 
> Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
> ---
>   .../pci/controller/dwc/pcie-designware-ep.c   |  2 ++
>   .../pci/controller/dwc/pcie-designware-host.c |  2 ++
>   drivers/pci/controller/dwc/pcie-designware.c  | 24 +++++++++++++++++++
>   drivers/pci/controller/dwc/pcie-designware.h  |  2 ++
>   drivers/pci/controller/dwc/pcie-qcom.c        |  2 ++
>   drivers/pci/controller/dwc/pcie-tegra194.c    |  3 +++
>   6 files changed, 35 insertions(+)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
> index 7f2112c2fb21..c94cff6eeb01 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> @@ -966,6 +966,8 @@ int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)
>   	if (ep->ops->init)
>   		ep->ops->init(ep);
>   
> +	dw_pcie_config_l1ss(pci);
> +
>   	ptm_cap_base = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_PTM);
>   
>   	/*
> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> index 20c9333bcb1c..f1d5b45a3214 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -1060,6 +1060,8 @@ int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
>   		PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
>   	dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
>   
> +	dw_pcie_config_l1ss(pci);
> +
>   	dw_pcie_config_presets(pp);
>   	/*
>   	 * If the platform provides its own child bus config accesses, it means
> diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
> index c644216995f6..ede686623fad 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.c
> +++ b/drivers/pci/controller/dwc/pcie-designware.c
> @@ -1081,6 +1081,30 @@ void dw_pcie_edma_remove(struct dw_pcie *pci)
>   	dw_edma_remove(&pci->edma);
>   }
>   
> +void dw_pcie_config_l1ss(struct dw_pcie *pci)
> +{
> +	u16 l1ss;
> +	u32 l1ss_cap;
> +
> +	if (!pci->l1ss_support)
> +		return;
> +
> +	l1ss = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_L1SS);
> +	if (!l1ss)
> +		return;
> +
> +	/*
> +	 * Unless the driver claims "l1ss_support", don't advertise L1 PM
> +	 * Substates because they require CLKREF# and possibly other
> +	 * device-specific configuration.
> +	 */
> +	l1ss_cap = dw_pcie_readl_dbi(pci, l1ss + PCI_L1SS_CAP);
> +	l1ss_cap &= ~(PCI_L1SS_CAP_PCIPM_L1_1 | PCI_L1SS_CAP_ASPM_L1_1 |
> +		      PCI_L1SS_CAP_PCIPM_L1_2 | PCI_L1SS_CAP_ASPM_L1_2 |
> +		      PCI_L1SS_CAP_L1_PM_SS);
> +	dw_pcie_writel_dbi(pci, l1ss + PCI_L1SS_CAP, l1ss_cap);
> +}
> +
>   void dw_pcie_setup(struct dw_pcie *pci)
>   {
>   	u32 val;
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> index e995f692a1ec..8d14b1fe2280 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -516,6 +516,7 @@ struct dw_pcie {
>   	int			max_link_speed;
>   	u8			n_fts[2];
>   	struct dw_edma_chip	edma;
> +	bool			l1ss_support;	/* L1 PM Substates support */
>   	struct clk_bulk_data	app_clks[DW_PCIE_NUM_APP_CLKS];
>   	struct clk_bulk_data	core_clks[DW_PCIE_NUM_CORE_CLKS];
>   	struct reset_control_bulk_data	app_rsts[DW_PCIE_NUM_APP_RSTS];
> @@ -573,6 +574,7 @@ int dw_pcie_prog_ep_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
>   				int type, u64 parent_bus_addr,
>   				u8 bar, size_t size);
>   void dw_pcie_disable_atu(struct dw_pcie *pci, u32 dir, int index);
> +void dw_pcie_config_l1ss(struct dw_pcie *pci);
>   void dw_pcie_setup(struct dw_pcie *pci);
>   void dw_pcie_iatu_detect(struct dw_pcie *pci);
>   int dw_pcie_edma_detect(struct dw_pcie *pci);
> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
> index 805edbbfe7eb..61c2f4e2f74d 100644
> --- a/drivers/pci/controller/dwc/pcie-qcom.c
> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> @@ -1067,6 +1067,8 @@ static int qcom_pcie_init_2_7_0(struct qcom_pcie *pcie)
>   	val &= ~REQ_NOT_ENTR_L1;
>   	writel(val, pcie->parf + PARF_PM_CTRL);
>   
> +	pci->l1ss_support = true;
> +
>   	val = readl(pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
>   	val |= EN;
>   	writel(val, pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
> diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
> index 10e74458e667..3934757baa30 100644
> --- a/drivers/pci/controller/dwc/pcie-tegra194.c
> +++ b/drivers/pci/controller/dwc/pcie-tegra194.c
> @@ -703,6 +703,9 @@ static void init_host_aspm(struct tegra_pcie_dw *pcie)
>   	val |= (pcie->aspm_pwr_on_t << 19);
>   	dw_pcie_writel_dbi(pci, pcie->cfg_link_cap_l1sub, val);
>   
> +	if (pcie->supports_clkreq)
> +		pci->l1ss_support = true;
> +
>   	/* Program L0s and L1 entrance latencies */
>   	val = dw_pcie_readl_dbi(pci, PCIE_PORT_AFR);
>   	val &= ~PORT_AFR_L0S_ENTRANCE_LAT_MASK;



From dsimic at manjaro.org  Tue Nov 11 17:14:26 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Wed, 12 Nov 2025 02:14:26 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v6 0/3] Add Radxa CM5 and IO Board
In-Reply-To: <EB08CB02156A172D+abf42f17-09e1-40ea-9369-eca481d230a6@radxa.com>
References: <20251105051335.17652-1-naoki@radxa.com>
 <199E172C8E20ED38+71169242-5525-4d60-9e37-a03ad172d639@radxa.com>
 <CAMWSM7gezjVSoF+-7ivboTeB=5gQAE-QVrbAbKu3M=obmb3Axg@mail.gmail.com>
 <617FDAB231C501DC+3f9809df-87df-4a02-bd5f-ebc6299b3aa7@radxa.com>
 <a10340af-1d0a-bb0b-4835-7b2c9e67d664@manjaro.org>
 <2892FE50237CD58E+0f15924c-a915-4446-954c-d81a782d23e9@radxa.com>
 <19ce0a41-563c-6202-6b94-b2c644a0b827@manjaro.org> <EB08CB02156A172D+abf42f17-09e1-40ea-9369-eca481d230a6@radxa.com>
Message-ID: <a2581eae-e8bd-c404-5d4a-a50fddfb5d6a@manjaro.org>

On Wednesday, November 12, 2025 02:01 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> On 11/12/25 09:46, Dragan Simic wrote:
> > By the way, what you called changelogs in the examples above is
> > usually called patch descriptions.  When they become merged, they
> > become called commit descriptions or, sometimes, commit messages.
> > Using the standard lingo usually helps. :)
> 
> Ah, it comes from
>   https://www.kernel.org/doc/html/latest/process/submitting-patches.html#when-to-use-acked-by-cc-and-co-developed-by
> 
> Should it be fixed? ;)

Ah, I see, thanks.  IMHO, the wording in that document should be
adjusted a bit, but I don't have the time and energy required to
actually do that. :)



From chaoyi.chen at rock-chips.com  Tue Nov 11 17:37:36 2025
From: chaoyi.chen at rock-chips.com (Chaoyi Chen)
Date: Wed, 12 Nov 2025 09:37:36 +0800
Subject: [PATCH v9 08/10] drm/rockchip: cdn-dp: Add multiple bridges to
 support PHY port selection
In-Reply-To: <DE5YP3AVGOG3.OHP68Z0F6KBU@bootlin.com>
References: <20251111105040.94-1-kernel@airkyi.com>
 <20251111105040.94-9-kernel@airkyi.com>
 <DE5YP3AVGOG3.OHP68Z0F6KBU@bootlin.com>
Message-ID: <b1a339e7-a011-4b4b-8988-2e3768753c85@rock-chips.com>

Hello Luca,

On 11/11/2025 11:14 PM, Luca Ceresoli wrote:
> Hello Chaoyi,
>
> On Tue Nov 11, 2025 at 11:50 AM CET, Chaoyi Chen wrote:
>> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
>>
>> The RK3399 has two USB/DP combo PHY and one CDN-DP controller. And
>> the CDN-DP can be switched to output to one of the PHYs. If both ports
>> are plugged into DP, DP will select the first port for output.
>>
>> This patch adds support for multiple bridges, enabling users to flexibly
>> select the output port. For each PHY port, a separate encoder and bridge
>> are registered.
>>
>> The change is based on the DRM AUX HPD bridge, rather than the
>> extcon approach. This requires the DT to correctly describe the
>> connections between the first bridge in bridge chain and DP
>> controller. For example, the bridge chain may be like this:
>>
>> PHY aux birdge -> fsa4480 analog audio switch bridge ->
>> onnn,nb7vpq904m USB reminder bridge -> USB-C controller AUX HPD bridge
>>
>> In this case, the connection relationships among the PHY aux bridge
>> and the DP contorller need to be described in DT.
>>
>> In addition, the cdn_dp_parse_next_bridge_dt() will parses it and
>> determines whether to register one or two bridges.
>>
>> Since there is only one DP controller, only one of the PHY ports can
>> output at a time. The key is how to switch between different PHYs,
>> which is handled by cdn_dp_switch_port() and cdn_dp_enable().
>>
>> There are two cases:
>>
>> 1. Neither bridge is enabled. In this case, both bridges can
>> independently read the EDID, and the PHY port may switch before
>> reading the EDID.
>>
>> 2. One bridge is already enabled. In this case, other bridges are not
>> allowed to read the EDID. So we will try to return the cached EDID.
>>
>> Since the scenario of two ports plug in at the same time is rare,
>> I don't have a board which support two TypeC connector to test this.
>> Therefore, I tested forced switching on a single PHY port, as well as
>> output using a fake PHY port alongside a real PHY port.
>>
>> Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> [...]
>
>> @@ -966,28 +1084,16 @@ static int cdn_dp_pd_event(struct notifier_block *nb,
>>   	return NOTIFY_DONE;
>>   }
>>
>> -static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
>> +static int cdn_bridge_add(struct device *dev,
>> +			  struct drm_bridge *bridge,
>> +			  struct drm_bridge *next_bridge,
>> +			  struct drm_encoder *encoder)
>>   {
>>   	struct cdn_dp_device *dp = dev_get_drvdata(dev);
>> -	struct drm_encoder *encoder;
>> +	struct drm_device *drm_dev = dp->drm_dev;
>> +	struct drm_bridge *last_bridge = NULL;
>>   	struct drm_connector *connector;
>> -	struct cdn_dp_port *port;
>> -	struct drm_device *drm_dev = data;
>> -	int ret, i;
> [...]
>
>> +	if (next_bridge) {
>> +		ret = drm_bridge_attach(encoder, next_bridge, bridge,
>> +					DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>> +		if (ret)
>> +			return ret;
>> +
>> +		last_bridge = next_bridge;
>> +		while (drm_bridge_get_next_bridge(last_bridge))
>> +			last_bridge = drm_bridge_get_next_bridge(last_bridge);
> DRM bridges are now refcounted, and you are not calling drm_bridge_get()
> and drm_bridge_put() here. But here you can use
> drm_bridge_chain_get_last_bridge() which will simplify your job.
>
> Don't forget to call drm_bridge_put() on the returned bridge when the
> bridge is not referenced anymore. This should be as easy as adding a
> cleanup action on the variable declaration above:
>
> -	struct drm_bridge *last_bridge = NULL;
> +	struct drm_bridge *last_bridge __free(drm_bridge_put) = NULL;

Ah, I have seen your patch about this. Thank you for the reminder, I will fix this in v10.

>
>> @@ -1029,8 +1147,102 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
>>   		return ret;
>>   	}
>>
>> +	if (last_bridge)
>> +		connector->fwnode = fwnode_handle_get(of_fwnode_handle(last_bridge->of_node));
>> +
>>   	drm_connector_attach_encoder(connector, encoder);
>>
>> +	return 0;
>> +}
>> +
>> +static int cdn_dp_parse_next_bridge_dt(struct cdn_dp_device *dp)
>> +{
>> +	struct device_node *np = dp->dev->of_node;
>> +	struct device_node *port __free(device_node) = of_graph_get_port_by_id(np, 1);
>> +	struct drm_bridge *bridge;
>> +	int count = 0;
>> +	int ret = 0;
>> +	int i;
>> +
>> +	/* If device use extcon, do not use hpd bridge */
>> +	for (i = 0; i < dp->ports; i++) {
>> +		if (dp->port[i]->extcon) {
>> +			dp->bridge_count = 1;
>> +			return 0;
>> +		}
>> +	}
>> +
>> +
>> +	/* One endpoint may correspond to one next bridge. */
>> +	for_each_of_graph_port_endpoint(port, dp_ep) {
>> +		struct device_node *next_bridge_node __free(device_node) =
>> +			of_graph_get_remote_port_parent(dp_ep);
>> +
>> +		bridge = of_drm_find_bridge(next_bridge_node);
>> +		if (!bridge) {
>> +			ret = -EPROBE_DEFER;
>> +			goto out;
>> +		}
>> +
>> +		dp->next_bridge_valid = true;
>> +		dp->next_bridge_list[count].bridge = bridge;
> You are storing a reference to a drm_bridge, so have to increment the
> refcount:
>
> 		dp->next_bridge_list[count].bridge = drm_bridge_get(bridge);
> 		                                     ^^^^^^^^^^^^^^
>
> FYI there is a plan to replace of_drm_find_bridge() with a function that
> increases the bridge refcount before returning the bridge, but it's not
> there yet. When that will happen, the explicit drm_bridge_get() won't be
> needed anymore and this code can be updated accordingly.
>
> Also you have to call drm_bridge_put() to release that reference when the
> pointer goes away. I guess that should happen in cdn_dp_unbind().

You're right, this is indeed a pitfall. I will fix it in v10.

>
>> +static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
>> +{
> In this function you do:
> ...(see below)...
>
>> +	struct cdn_dp_device *dp = dev_get_drvdata(dev);
>> +	struct drm_bridge *bridge, *next_bridge;
>> +	struct drm_encoder *encoder;
>> +	struct cdn_dp_port *port;
>> +	struct drm_device *drm_dev = data;
>> +	struct cdn_dp_bridge *dp_bridge;
>> +	int ret, i;
>> +
>> +	ret = cdn_dp_parse_dt(dp);
>> +	if (ret < 0)
> .> +		return ret;
>> +
>> +	ret = cdn_dp_parse_next_bridge_dt(dp);
> 1. compute the next bridges and store them in dp->next_bridge_list[]
> ...
>
>> +	if (ret)
>> +		return ret;
>> +
>> +	dp->drm_dev = drm_dev;
>> +	dp->connected = false;
>> +	dp->active = false;
>> +	dp->active_port = -1;
>> +	dp->fw_loaded = false;
>> +
>> +	for (i = 0; i < dp->bridge_count; i++) {
>> +		dp_bridge = devm_drm_bridge_alloc(dev, struct cdn_dp_bridge, bridge,
>> +						    &cdn_dp_bridge_funcs);
>> +		if (IS_ERR(dp_bridge))
>> +			return PTR_ERR(dp_bridge);
>> +		dp_bridge->id = i;
>> +		dp_bridge->parent = dp;
>> +		if (!dp->next_bridge_valid)
>> +			dp_bridge->connected = true;
>> +		dp->bridge_list[i] = dp_bridge;
>> +	}
>> +
>> +	for (i = 0; i < dp->bridge_count; i++) {
>> +		encoder = &dp->bridge_list[i]->encoder.encoder;
>> +		bridge = &dp->bridge_list[i]->bridge;
>> +		next_bridge = dp->next_bridge_list[i].bridge;
>> +		ret = cdn_bridge_add(dev, bridge, next_bridge, encoder);
> ...
> 2. pass the dp->next_bridge_list[i].bridge to cdn_bridge_add
> 3. not use  dp->next_bridge_list[i] elsewhere
>
> So you may want to change this function to parse into a local array, with
> function scope. If you do this, the drm_bridge_get/put() I mentioned above
> should still exist, but would be localized to this function, thus even
> easier to handle.
>
> Even better, you can parse the DT one bridge at a time inside the for loop,
> so you don't need to store any next_bridge pointer array. This will need a
> bit of rework of cdn_dp_parse_next_bridge_dt() though, and I haven't
> checked in detail so it might be not worth.

The next_bridge is obtained through of_drm_find_bridge(). According to your description just now, drm_bridge_put() needs to be called in cdn_dp_unbind(). So if I understand correctly, we do need to store this pointer.


>
> [...]
>
>> +struct cdn_dp_bridge {
>> +	struct cdn_dp_device *parent;
>> +	struct drm_bridge bridge;
>> +	struct rockchip_encoder encoder;
>> +	bool connected;
>> +	bool enabled;
>> +	int id;
>> +};
>> +
>> +struct cdn_dp_next_bridge {
>> +	struct cdn_dp_device *parent;
>> +	struct drm_bridge *bridge;
>> +	int id;
> The @parent and @id fields are unused if I'm not mistaken.
>
> If it is the case then you can... (see below)
>
>>   struct cdn_dp_device {
>>   	struct device *dev;
>>   	struct drm_device *drm_dev;
>> -	struct drm_bridge bridge;
>> -	struct rockchip_encoder encoder;
>> +	int bridge_count;
>> +	struct cdn_dp_bridge *bridge_list[MAX_PHY];
>> +	struct cdn_dp_next_bridge next_bridge_list[MAX_PHY];
> ...replace this line with:
> 	struct drm_bridge *next_bridge[MAX_PHY];
>
> Unless of course you just don't store the next_bridge at all, as I
> suggested above, and which looks way easier and more efficient.

Yes, the structure cdn_dp_next_bridge is only reserved for future expansion. I will replace it with a simpler struct drm_bridge in v10.

-- 
Best,
Chaoyi



From zhangqing at rock-chips.com  Tue Nov 11 17:59:36 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Wed, 12 Nov 2025 09:59:36 +0800
Subject: [RESEND PATCH v8 0/4] rockchip: add can for RK3576 Soc
Message-ID: <20251112015940.3695638-1-zhangqing@rock-chips.com>

rk3576 can is a new controller,new register layout and Bit position
definition:
Support CAN protocol.
Support Dma.

There are major differences from the previous rk3568.
All errata on the rk3568 have been fixed and redesigned.

RK3576 CANFD requires authorization and permission. The software
code is not open by default and needs to be authorized separately.

Change in V8:
[PATCH v8 1/4]: Drop CANFD, correction format warning.
[PATCH v8 2/4]: Drop fifo_setup of rkcanfd_devtype_data.
[PATCH v8 3/4]: Drop CANFD.
[PATCH v8 4/4]: Drop CANFD.

Change in V7:
[PATCH v7 1/4]: Correction format warning.
[PATCH v7 2/4]: No change.
[PATCH v7 3/4]: Correct the writing of some registers and
                correct the annotations.
[PATCH v7 4/4]: Optimize the structure parameters and
                ensure error handling.

Change in V6:
[PATCH v6 1/4]: Fix dma is support only for rk3576.
[PATCH v6 2/4]: Fix the compilation warning.
[PATCH v6 3/4]: Fix the compilation warning.
[PATCH v6 4/4]: Fix the compilation warning.

Change in V5:
[PATCH v5 1/4]: Add rk3576 canfd to rockchip,rk3568v2-canfd.yaml, remove
                rockchip,rk3576-canfd.yaml
[PATCH v5 2/4]: Encapsulate some hardware operation functions into
                rkcanfd_devtype_data to provide differentiated
                implementations for different models
                (such as RK3568v2/v3)..
[PATCH v5 3/4]: Add rk3576 canfd,fix the register naming rule,
                Delete the variables used by rockchip itself.
[PATCH v5 4/4]: Fix .h sorting.


Change in V4:
[PATCH v4 1/3]: Correct the format and add explanations.
[PATCH v4 2/3]: No change.
[PATCH v4 3/3]: No change.

Change in V3:
[PATCH v3 1/3]: Add documentation for the rk3576 CAN-FD.
[PATCH v3 2/3]: Adjust the differentiated code section and
                add dma function.
[PATCH v3 3/3]: Remove dma, no use dma by default.

Change in V2:
[PATCH v2 1/2]: remove rk3576_canfd.c, use the rockchip_canfd driver
[PATCH v2 2/2]: code style.

Elaine Zhang (4):
  dt-bindings: can: rockchip_canfd: add rk3576 CAN controller
  net: can: rockchip: Refactor the rkcanfd_devtype_data structure
  net: can: rockchip: add can for RK3576 Soc
  net: can: rockchip: support dma for rk3576 rx

 .../net/can/rockchip,rk3568v2-canfd.yaml      |  52 +-
 .../net/can/rockchip/rockchip_canfd-core.c    | 581 ++++++++++++++++--
 drivers/net/can/rockchip/rockchip_canfd-rx.c  | 212 +++++++
 drivers/net/can/rockchip/rockchip_canfd-tx.c  |  20 +
 drivers/net/can/rockchip/rockchip_canfd.h     | 277 +++++++++
 5 files changed, 1094 insertions(+), 48 deletions(-)

-- 
2.34.1



From zhangqing at rock-chips.com  Tue Nov 11 17:59:37 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Wed, 12 Nov 2025 09:59:37 +0800
Subject: [RESEND PATCH v8 1/4] dt-bindings: can: rockchip_canfd: add rk3576 CAN controller
In-Reply-To: <20251112015940.3695638-1-zhangqing@rock-chips.com>
References: <20251112015940.3695638-1-zhangqing@rock-chips.com>
Message-ID: <20251112015940.3695638-2-zhangqing@rock-chips.com>

Add documentation for the rockchip rk3576 CAN controller.

Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
---
 .../bindings/net/can/rockchip,rk3568v2-canfd.yaml  | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml b/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml
index a077c0330013..22e10494e7d1 100644
--- a/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml
+++ b/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml
@@ -10,13 +10,12 @@ title:
 maintainers:
   - Marc Kleine-Budde <mkl at pengutronix.de>
 
-allOf:
-  - $ref: can-controller.yaml#
-
 properties:
   compatible:
     oneOf:
-      - const: rockchip,rk3568v2-canfd
+      - enum:
+          - rockchip,rk3568v2-canfd
+          - rockchip,rk3576-can
       - items:
           - const: rockchip,rk3568v3-canfd
           - const: rockchip,rk3568v2-canfd
@@ -43,6 +42,13 @@ properties:
       - const: core
       - const: apb
 
+  dmas:
+    maxItems: 1
+
+  dma-names:
+    items:
+      - const: rx
+
 required:
   - compatible
   - reg
-- 
2.34.1



From zhangqing at rock-chips.com  Tue Nov 11 17:59:38 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Wed, 12 Nov 2025 09:59:38 +0800
Subject: [RESEND PATCH v8 2/4] net: can: rockchip: Refactor the rkcanfd_devtype_data structure
In-Reply-To: <20251112015940.3695638-1-zhangqing@rock-chips.com>
References: <20251112015940.3695638-1-zhangqing@rock-chips.com>
Message-ID: <20251112015940.3695638-3-zhangqing@rock-chips.com>

Add new function pointer:
Encapsulate some hardware operation functions into
rkcanfd_devtype_data to provide differentiated implementations for
different models (such as RK3568v2/v3).

Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
---
 .../net/can/rockchip/rockchip_canfd-core.c    | 100 ++++++++++--------
 drivers/net/can/rockchip/rockchip_canfd.h     |  10 ++
 2 files changed, 68 insertions(+), 42 deletions(-)

diff --git a/drivers/net/can/rockchip/rockchip_canfd-core.c b/drivers/net/can/rockchip/rockchip_canfd-core.c
index 046f0a0ae4d4..761cb36148ff 100644
--- a/drivers/net/can/rockchip/rockchip_canfd-core.c
+++ b/drivers/net/can/rockchip/rockchip_canfd-core.c
@@ -24,32 +24,6 @@
 
 #include "rockchip_canfd.h"
 
-static const struct rkcanfd_devtype_data rkcanfd_devtype_data_rk3568v2 = {
-	.model = RKCANFD_MODEL_RK3568V2,
-	.quirks = RKCANFD_QUIRK_RK3568_ERRATUM_1 | RKCANFD_QUIRK_RK3568_ERRATUM_2 |
-		RKCANFD_QUIRK_RK3568_ERRATUM_3 | RKCANFD_QUIRK_RK3568_ERRATUM_4 |
-		RKCANFD_QUIRK_RK3568_ERRATUM_5 | RKCANFD_QUIRK_RK3568_ERRATUM_6 |
-		RKCANFD_QUIRK_RK3568_ERRATUM_7 | RKCANFD_QUIRK_RK3568_ERRATUM_8 |
-		RKCANFD_QUIRK_RK3568_ERRATUM_9 | RKCANFD_QUIRK_RK3568_ERRATUM_10 |
-		RKCANFD_QUIRK_RK3568_ERRATUM_11 | RKCANFD_QUIRK_RK3568_ERRATUM_12 |
-		RKCANFD_QUIRK_CANFD_BROKEN,
-};
-
-/* The rk3568 CAN-FD errata sheet as of Tue 07 Nov 2023 11:25:31 +08:00
- * states that only the rk3568v2 is affected by erratum 5, but tests
- * with the rk3568v2 and rk3568v3 show that the RX_FIFO_CNT is
- * sometimes too high. In contrast to the errata sheet mark rk3568v3
- * as effected by erratum 5, too.
- */
-static const struct rkcanfd_devtype_data rkcanfd_devtype_data_rk3568v3 = {
-	.model = RKCANFD_MODEL_RK3568V3,
-	.quirks = RKCANFD_QUIRK_RK3568_ERRATUM_1 | RKCANFD_QUIRK_RK3568_ERRATUM_2 |
-		RKCANFD_QUIRK_RK3568_ERRATUM_5 | RKCANFD_QUIRK_RK3568_ERRATUM_7 |
-		RKCANFD_QUIRK_RK3568_ERRATUM_8 | RKCANFD_QUIRK_RK3568_ERRATUM_10 |
-		RKCANFD_QUIRK_RK3568_ERRATUM_11 | RKCANFD_QUIRK_RK3568_ERRATUM_12 |
-		RKCANFD_QUIRK_CANFD_BROKEN,
-};
-
 static const char *__rkcanfd_get_model_str(enum rkcanfd_model model)
 {
 	switch (model) {
@@ -212,7 +186,7 @@ static int rkcanfd_get_berr_counter(const struct net_device *ndev,
 	if (err)
 		return err;
 
-	rkcanfd_get_berr_counter_corrected(priv, bec);
+	priv->devtype_data.get_berr_counter(priv, bec);
 
 	pm_runtime_put(ndev->dev.parent);
 
@@ -302,7 +276,7 @@ static void rkcanfd_chip_start(struct rkcanfd_priv *priv)
 
 	rkcanfd_set_bittiming(priv);
 
-	rkcanfd_chip_interrupts_disable(priv);
+	priv->devtype_data.interrupts_disable(priv);
 	rkcanfd_chip_set_work_mode(priv);
 
 	priv->can.state = CAN_STATE_ERROR_ACTIVE;
@@ -316,7 +290,7 @@ static void __rkcanfd_chip_stop(struct rkcanfd_priv *priv, const enum can_state
 	priv->can.state = state;
 
 	rkcanfd_chip_set_reset_mode(priv);
-	rkcanfd_chip_interrupts_disable(priv);
+	priv->devtype_data.interrupts_disable(priv);
 }
 
 static void rkcanfd_chip_stop(struct rkcanfd_priv *priv, const enum can_state state)
@@ -342,8 +316,8 @@ static int rkcanfd_set_mode(struct net_device *ndev,
 
 	switch (mode) {
 	case CAN_MODE_START:
-		rkcanfd_chip_start(priv);
-		rkcanfd_chip_interrupts_enable(priv);
+		priv->devtype_data.chip_start(priv);
+		priv->devtype_data.interrupts_enable(priv);
 		netif_wake_queue(ndev);
 		break;
 
@@ -537,7 +511,7 @@ static int rkcanfd_handle_error_int(struct rkcanfd_priv *priv)
 		if (cf) {
 			struct can_berr_counter bec;
 
-			rkcanfd_get_berr_counter_corrected(priv, &bec);
+			priv->devtype_data.get_berr_counter(priv, &bec);
 			cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR | CAN_ERR_CNT;
 			cf->data[6] = bec.txerr;
 			cf->data[7] = bec.rxerr;
@@ -567,7 +541,7 @@ static int rkcanfd_handle_state_error_int(struct rkcanfd_priv *priv)
 	u32 timestamp;
 	int err;
 
-	rkcanfd_get_berr_counter_corrected(priv, &bec);
+	priv->devtype_data.get_berr_counter(priv, &bec);
 	can_state_get_by_berr_counter(ndev, &bec, &tx_state, &rx_state);
 
 	new_state = max(tx_state, rx_state);
@@ -581,7 +555,7 @@ static int rkcanfd_handle_state_error_int(struct rkcanfd_priv *priv)
 	can_change_state(ndev, cf, tx_state, rx_state);
 
 	if (new_state == CAN_STATE_BUS_OFF) {
-		rkcanfd_chip_stop(priv, CAN_STATE_BUS_OFF);
+		priv->devtype_data.chip_stop(priv, CAN_STATE_BUS_OFF);
 		can_bus_off(ndev);
 	}
 
@@ -620,7 +594,7 @@ rkcanfd_handle_rx_fifo_overflow_int(struct rkcanfd_priv *priv)
 	if (!skb)
 		return 0;
 
-	rkcanfd_get_berr_counter_corrected(priv, &bec);
+	priv->devtype_data.get_berr_counter(priv, &bec);
 
 	cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
 	cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
@@ -719,21 +693,21 @@ static int rkcanfd_open(struct net_device *ndev)
 	if (err)
 		goto out_close_candev;
 
-	rkcanfd_chip_start(priv);
+	priv->devtype_data.chip_start(priv);
 	can_rx_offload_enable(&priv->offload);
 
-	err = request_irq(ndev->irq, rkcanfd_irq, IRQF_SHARED, ndev->name, priv);
+	err = request_irq(ndev->irq, priv->devtype_data.irq, IRQF_SHARED, ndev->name, priv);
 	if (err)
 		goto out_rkcanfd_chip_stop;
 
-	rkcanfd_chip_interrupts_enable(priv);
+	priv->devtype_data.interrupts_enable(priv);
 
 	netif_start_queue(ndev);
 
 	return 0;
 
 out_rkcanfd_chip_stop:
-	rkcanfd_chip_stop_sync(priv, CAN_STATE_STOPPED);
+	priv->devtype_data.chip_stop_sync(priv, CAN_STATE_STOPPED);
 	pm_runtime_put(ndev->dev.parent);
 out_close_candev:
 	close_candev(ndev);
@@ -746,10 +720,10 @@ static int rkcanfd_stop(struct net_device *ndev)
 
 	netif_stop_queue(ndev);
 
-	rkcanfd_chip_interrupts_disable(priv);
+	priv->devtype_data.interrupts_disable(priv);
 	free_irq(ndev->irq, priv);
 	can_rx_offload_disable(&priv->offload);
-	rkcanfd_chip_stop_sync(priv, CAN_STATE_STOPPED);
+	priv->devtype_data.chip_stop_sync(priv, CAN_STATE_STOPPED);
 	close_candev(ndev);
 
 	pm_runtime_put(ndev->dev.parent);
@@ -818,7 +792,7 @@ static int rkcanfd_register(struct rkcanfd_priv *priv)
 	if (err)
 		goto out_pm_runtime_put_sync;
 
-	rkcanfd_register_done(priv);
+	priv->devtype_data.register_done(priv);
 
 	pm_runtime_put(ndev->dev.parent);
 
@@ -840,6 +814,48 @@ static inline void rkcanfd_unregister(struct rkcanfd_priv *priv)
 	pm_runtime_disable(ndev->dev.parent);
 }
 
+static const struct rkcanfd_devtype_data rkcanfd_devtype_data_rk3568v2 = {
+	.model = RKCANFD_MODEL_RK3568V2,
+	.quirks = RKCANFD_QUIRK_RK3568_ERRATUM_1 | RKCANFD_QUIRK_RK3568_ERRATUM_2 |
+		RKCANFD_QUIRK_RK3568_ERRATUM_3 | RKCANFD_QUIRK_RK3568_ERRATUM_4 |
+		RKCANFD_QUIRK_RK3568_ERRATUM_5 | RKCANFD_QUIRK_RK3568_ERRATUM_6 |
+		RKCANFD_QUIRK_RK3568_ERRATUM_7 | RKCANFD_QUIRK_RK3568_ERRATUM_8 |
+		RKCANFD_QUIRK_RK3568_ERRATUM_9 | RKCANFD_QUIRK_RK3568_ERRATUM_10 |
+		RKCANFD_QUIRK_RK3568_ERRATUM_11 | RKCANFD_QUIRK_RK3568_ERRATUM_12 |
+		RKCANFD_QUIRK_CANFD_BROKEN,
+	.get_berr_counter = rkcanfd_get_berr_counter_corrected,
+	.interrupts_enable = rkcanfd_chip_interrupts_enable,
+	.interrupts_disable = rkcanfd_chip_interrupts_disable,
+	.chip_start = rkcanfd_chip_start,
+	.chip_stop = rkcanfd_chip_stop,
+	.chip_stop_sync = rkcanfd_chip_stop_sync,
+	.irq = rkcanfd_irq,
+	.register_done = rkcanfd_register_done,
+};
+
+/* The rk3568 CAN-FD errata sheet as of Tue 07 Nov 2023 11:25:31 +08:00
+ * states that only the rk3568v2 is affected by erratum 5, but tests
+ * with the rk3568v2 and rk3568v3 show that the RX_FIFO_CNT is
+ * sometimes too high. In contrast to the errata sheet mark rk3568v3
+ * as effected by erratum 5, too.
+ */
+static const struct rkcanfd_devtype_data rkcanfd_devtype_data_rk3568v3 = {
+	.model = RKCANFD_MODEL_RK3568V3,
+	.quirks = RKCANFD_QUIRK_RK3568_ERRATUM_1 | RKCANFD_QUIRK_RK3568_ERRATUM_2 |
+		RKCANFD_QUIRK_RK3568_ERRATUM_5 | RKCANFD_QUIRK_RK3568_ERRATUM_7 |
+		RKCANFD_QUIRK_RK3568_ERRATUM_8 | RKCANFD_QUIRK_RK3568_ERRATUM_10 |
+		RKCANFD_QUIRK_RK3568_ERRATUM_11 | RKCANFD_QUIRK_RK3568_ERRATUM_12 |
+		RKCANFD_QUIRK_CANFD_BROKEN,
+	.get_berr_counter = rkcanfd_get_berr_counter_corrected,
+	.interrupts_enable = rkcanfd_chip_interrupts_enable,
+	.interrupts_disable = rkcanfd_chip_interrupts_disable,
+	.chip_start = rkcanfd_chip_start,
+	.chip_stop = rkcanfd_chip_stop,
+	.chip_stop_sync = rkcanfd_chip_stop_sync,
+	.irq = rkcanfd_irq,
+	.register_done = rkcanfd_register_done,
+};
+
 static const struct of_device_id rkcanfd_of_match[] = {
 	{
 		.compatible = "rockchip,rk3568v2-canfd",
diff --git a/drivers/net/can/rockchip/rockchip_canfd.h b/drivers/net/can/rockchip/rockchip_canfd.h
index 93131c7d7f54..72f26b96add0 100644
--- a/drivers/net/can/rockchip/rockchip_canfd.h
+++ b/drivers/net/can/rockchip/rockchip_canfd.h
@@ -436,9 +436,19 @@ enum rkcanfd_model {
 	RKCANFD_MODEL_RK3568V3 = 0x35683,
 };
 
+struct rkcanfd_priv;
+
 struct rkcanfd_devtype_data {
 	enum rkcanfd_model model;
 	u32 quirks;
+	void (*get_berr_counter)(struct rkcanfd_priv *priv, struct can_berr_counter *bec);
+	void (*interrupts_enable)(const struct rkcanfd_priv *priv);
+	void (*interrupts_disable)(const struct rkcanfd_priv *priv);
+	void (*chip_start)(struct rkcanfd_priv *priv);
+	void (*chip_stop)(struct rkcanfd_priv *priv, const enum can_state state);
+	void (*chip_stop_sync)(struct rkcanfd_priv *priv, const enum can_state state);
+	irqreturn_t (*irq)(int irq, void *dev_id);
+	void (*register_done)(const struct rkcanfd_priv *priv);
 };
 
 struct rkcanfd_fifo_header {
-- 
2.34.1



From zhangqing at rock-chips.com  Tue Nov 11 17:59:39 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Wed, 12 Nov 2025 09:59:39 +0800
Subject: [RESEND PATCH v8 3/4] net: can: rockchip: add can for RK3576 Soc
In-Reply-To: <20251112015940.3695638-1-zhangqing@rock-chips.com>
References: <20251112015940.3695638-1-zhangqing@rock-chips.com>
Message-ID: <20251112015940.3695638-4-zhangqing@rock-chips.com>

Is new controller, new register layout and Bit position definition:
Support CAN protocol, ISO 11898-1
Support transmit or receive error count
Support acceptance filter, more functional
Support interrupt and all interrupt can be masked
Support error code check
Support self test\silent\loop-back mode
Support auto retransmission mode
Support auto bus on after bus-off state
Support 2 transmit buffers
Support Internal Storage Mode
Support DMA

Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
---
 .../net/can/rockchip/rockchip_canfd-core.c    | 419 ++++++++++++++++++
 drivers/net/can/rockchip/rockchip_canfd-rx.c  | 103 +++++
 drivers/net/can/rockchip/rockchip_canfd-tx.c  |  20 +
 drivers/net/can/rockchip/rockchip_canfd.h     | 258 +++++++++++
 4 files changed, 800 insertions(+)

diff --git a/drivers/net/can/rockchip/rockchip_canfd-core.c b/drivers/net/can/rockchip/rockchip_canfd-core.c
index 761cb36148ff..58fffcf97b20 100644
--- a/drivers/net/can/rockchip/rockchip_canfd-core.c
+++ b/drivers/net/can/rockchip/rockchip_canfd-core.c
@@ -31,6 +31,8 @@ static const char *__rkcanfd_get_model_str(enum rkcanfd_model model)
 		return "rk3568v2";
 	case RKCANFD_MODEL_RK3568V3:
 		return "rk3568v3";
+	case RKCAN_MODEL_RK3576:
+		return "rk3576";
 	}
 
 	return "<unknown>";
@@ -176,6 +178,27 @@ static void rkcanfd_get_berr_counter_corrected(struct rkcanfd_priv *priv,
 		    !!(reg_state & RKCANFD_REG_STATE_ERROR_WARNING_STATE));
 }
 
+static void rk3576can_get_berr_counter_corrected(struct rkcanfd_priv *priv,
+						 struct can_berr_counter *bec)
+{
+	struct can_berr_counter bec_raw;
+	u32 reg_state;
+
+	bec->rxerr = rkcanfd_read(priv, RK3576CAN_REG_RXERRORCNT);
+	bec->txerr = rkcanfd_read(priv, RK3576CAN_REG_TXERRORCNT);
+	bec_raw = *bec;
+
+	priv->bec = *bec;
+
+	reg_state = rkcanfd_read(priv, RKCANFD_REG_STATE);
+	netdev_vdbg(priv->ndev,
+		    "%s: Raw/Cor: txerr=%3u/%3u rxerr=%3u/%3u Bus Off=%u Warning=%u\n",
+		    __func__,
+		    bec_raw.txerr, bec->txerr, bec_raw.rxerr, bec->rxerr,
+		    !!(reg_state & RK3576CAN_REG_STATE_BUS_OFF_STATE),
+		    !!(reg_state & RK3576CAN_REG_STATE_ERROR_WARNING_STATE));
+}
+
 static int rkcanfd_get_berr_counter(const struct net_device *ndev,
 				    struct can_berr_counter *bec)
 {
@@ -206,6 +229,11 @@ static void rkcanfd_chip_interrupts_disable(const struct rkcanfd_priv *priv)
 	rkcanfd_write(priv, RKCANFD_REG_INT_MASK, RKCANFD_REG_INT_ALL);
 }
 
+static void rk3576can_chip_interrupts_disable(const struct rkcanfd_priv *priv)
+{
+	rkcanfd_write(priv, RK3576CAN_REG_INT_MASK, RK3576CAN_REG_INT_ALL);
+}
+
 static void rkcanfd_chip_fifo_setup(struct rkcanfd_priv *priv)
 {
 	u32 reg;
@@ -220,6 +248,48 @@ static void rkcanfd_chip_fifo_setup(struct rkcanfd_priv *priv)
 	netdev_reset_queue(priv->ndev);
 }
 
+static void rk3576can_chip_fifo_setup(struct rkcanfd_priv *priv)
+{
+	u32 reg_ism, reg_water;
+
+	reg_ism = FIELD_PREP(RK3576CAN_REG_STR_CTL_ISM_SEL,
+			     RK3576CAN_REG_STR_CTL_ISM_SEL_CANFD_FIXED) |
+		  RK3576CAN_REG_STR_CTL_STORAGE_TIMEOUT_MODE;
+	reg_water = RK3576CAN_ISM_WATERMASK_CANFD;
+
+	/* internal sram mode */
+	rkcanfd_write(priv, RK3576CAN_REG_STR_CTL, reg_ism);
+	rkcanfd_write(priv, RK3576CAN_REG_STR_WTM, reg_water);
+	WRITE_ONCE(priv->tx_head, 0);
+	WRITE_ONCE(priv->tx_tail, 0);
+	netdev_reset_queue(priv->ndev);
+}
+
+static void rk3576can_atf_config(struct rkcanfd_priv *priv, int mode)
+{
+	int i;
+
+	switch (mode) {
+	case RK3576CAN_REG_ATFM_MASK_SEL_MASK_MODE:
+		for (i = 0; i < 5; i++) {
+			rkcanfd_write(priv, RK3576CAN_REG_ATF(i), 0);
+			rkcanfd_write(priv, RK3576CAN_REG_ATFM(i), RK3576CAN_REG_ATFM_ID);
+		}
+		break;
+	case RK3576CAN_REG_ATFM_MASK_SEL_LIST_MODE:
+		for (i = 0; i < 5; i++) {
+			rkcanfd_write(priv, RK3576CAN_REG_ATF(i), 0);
+			rkcanfd_write(priv, RK3576CAN_REG_ATFM(i), RK3576CAN_REG_ATFM_MASK_SEL);
+		}
+		break;
+	default:
+		rkcanfd_write(priv, RK3576CAN_REG_ATF_CTL, RK3576CAN_REG_ATF_CTL_ATF_DIS_ALL);
+		return;
+	}
+
+	rkcanfd_write(priv, RK3576CAN_REG_ATF_CTL, 0);
+}
+
 static void rkcanfd_chip_start(struct rkcanfd_priv *priv)
 {
 	u32 reg;
@@ -285,6 +355,61 @@ static void rkcanfd_chip_start(struct rkcanfd_priv *priv)
 		   rkcanfd_read(priv, RKCANFD_REG_MODE));
 }
 
+static void rk3576can_chip_start(struct rkcanfd_priv *priv)
+
+{
+	u32 reg;
+
+	rkcanfd_chip_set_reset_mode(priv);
+
+	/* Receiving Filter: accept all */
+	rk3576can_atf_config(priv, RK3576CAN_REG_ATFM_MASK_SEL_MASK_MODE);
+
+	/* enable:
+	 * - WORK_MODE: transition from reset to working mode
+	 */
+	reg = rkcanfd_read(priv, RKCANFD_REG_MODE);
+	priv->reg_mode_default = reg | RKCANFD_REG_MODE_WORK_MODE;
+
+	if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
+		priv->reg_mode_default |= RKCANFD_REG_MODE_LBACK_MODE;
+		rkcanfd_write(priv, RK3576CAN_REG_ERROR_MASK,
+			      RK3576CAN_REG_ERROR_MASK_ACK_ERROR);
+	}
+
+	/* mask, i.e. ignore:
+	 * - RX_FINISH_INT - Rx finish interrupt
+	 */
+	priv->reg_int_mask_default = RK3576CAN_REG_INT_RX_FINISH_INT;
+
+	/* Do not mask the bus error interrupt if the bus error
+	 * reporting is requested.
+	 */
+	if (!(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING))
+		priv->reg_int_mask_default |= RKCANFD_REG_INT_ERROR_INT;
+
+	memset(&priv->bec, 0x0, sizeof(priv->bec));
+
+	rk3576can_chip_fifo_setup(priv);
+
+	rkcanfd_write(priv, RK3576CAN_REG_AUTO_RETX_CFG,
+		      RK3576CAN_REG_AUTO_RETX_CFG_AUTO_RETX_EN);
+
+	rkcanfd_write(priv, RK3576CAN_REG_BRS_CFG,
+		      RK3576CAN_REG_BRS_CFG_BRS_NEGSYNC_EN |
+		      RK3576CAN_REG_BRS_CFG_BRS_POSSYNC_EN);
+
+	rkcanfd_set_bittiming(priv);
+
+	priv->devtype_data.interrupts_disable(priv);
+	rkcanfd_chip_set_work_mode(priv);
+
+	priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+	netdev_dbg(priv->ndev, "%s: reg_mode=0x%08x\n", __func__,
+		   rkcanfd_read(priv, RKCANFD_REG_MODE));
+}
+
 static void __rkcanfd_chip_stop(struct rkcanfd_priv *priv, const enum can_state state)
 {
 	priv->can.state = state;
@@ -301,6 +426,13 @@ static void rkcanfd_chip_stop(struct rkcanfd_priv *priv, const enum can_state st
 	__rkcanfd_chip_stop(priv, state);
 }
 
+static void rk3576can_chip_stop(struct rkcanfd_priv *priv, const enum can_state state)
+{
+	priv->can.state = state;
+
+	__rkcanfd_chip_stop(priv, state);
+}
+
 static void rkcanfd_chip_stop_sync(struct rkcanfd_priv *priv, const enum can_state state)
 {
 	priv->can.state = state;
@@ -309,6 +441,13 @@ static void rkcanfd_chip_stop_sync(struct rkcanfd_priv *priv, const enum can_sta
 	__rkcanfd_chip_stop(priv, state);
 }
 
+static void rk3576can_chip_stop_sync(struct rkcanfd_priv *priv, const enum can_state state)
+{
+	priv->can.state = state;
+
+	__rkcanfd_chip_stop(priv, state);
+}
+
 static int rkcanfd_set_mode(struct net_device *ndev,
 			    enum can_mode mode)
 {
@@ -364,6 +503,9 @@ static const char *rkcanfd_get_error_type_str(unsigned int type)
 #define RKCAN_ERROR_CODE(reg_ec, code) \
 	((reg_ec) & RKCANFD_REG_ERROR_CODE_##code ? __stringify(code) " " : "")
 
+#define RK3576CAN_ERROR_CODE(reg_ec, code) \
+	((reg_ec) & RK3576CAN_REG_ERROR_CODE_##code ? __stringify(code) " " : "")
+
 static void
 rkcanfd_handle_error_int_reg_ec(struct rkcanfd_priv *priv, struct can_frame *cf,
 				const u32 reg_ec)
@@ -493,6 +635,128 @@ rkcanfd_handle_error_int_reg_ec(struct rkcanfd_priv *priv, struct can_frame *cf,
 	}
 }
 
+static void
+rk3576can_handle_error_int_reg_ec(struct rkcanfd_priv *priv, struct can_frame *cf,
+				  const u32 reg_ec)
+{
+	struct net_device_stats *stats = &priv->ndev->stats;
+	unsigned int type;
+	u32 reg_state, reg_cmd;
+
+	type = FIELD_GET(RK3576CAN_REG_ERROR_CODE_TYPE, reg_ec);
+	reg_cmd = rkcanfd_read(priv, RK3576CAN_REG_CMD);
+	reg_state = rkcanfd_read(priv, RK3576CAN_REG_STATE);
+
+	netdev_dbg(priv->ndev, "%s Error in %s %s Phase: %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s(0x%08x) CMD=%u RX=%u TX=%u Error-Warning=%u Bus-Off=%u\n",
+		   rkcanfd_get_error_type_str(type),
+		   reg_ec & RK3576CAN_REG_ERROR_CODE_DIRECTION_RX ? "RX" : "TX",
+		   reg_ec & RK3576CAN_REG_ERROR_CODE_PHASE ? "Data" : "Arbitration",
+		   RK3576CAN_ERROR_CODE(reg_ec, TX_ACK_EOF),
+		   RK3576CAN_ERROR_CODE(reg_ec, TX_CRC),
+		   RK3576CAN_ERROR_CODE(reg_ec, TX_STUFF_COUNT),
+		   RK3576CAN_ERROR_CODE(reg_ec, TX_DATA),
+		   RK3576CAN_ERROR_CODE(reg_ec, TX_SOF_DLC),
+		   RK3576CAN_ERROR_CODE(reg_ec, TX_IDLE),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_ERROR),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_OVERLOAD),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_SPACE),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_EOF),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_ACK_LIM),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_ACK),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_CRC_LIM),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_CRC),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_STUFF_COUNT),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_DATA),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_DLC),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_BRS_ESI),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_RES),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_FDF),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_ID2_RTR),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_SOF_IDE),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_BUS_IDLE),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_BUS_INT),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_STOP),
+		   reg_ec, reg_cmd,
+		   !!(reg_state & RK3576CAN_REG_STATE_RX_PERIOD),
+		   !!(reg_state & RK3576CAN_REG_STATE_TX_PERIOD),
+		   !!(reg_state & RK3576CAN_REG_STATE_ERROR_WARNING_STATE),
+		   !!(reg_state & RK3576CAN_REG_STATE_BUS_OFF_STATE));
+
+	priv->can.can_stats.bus_error++;
+
+	if (reg_ec & RK3576CAN_REG_ERROR_CODE_DIRECTION_RX)
+		stats->rx_errors++;
+	else
+		stats->tx_errors++;
+
+	if (!cf)
+		return;
+
+	if (reg_ec & RK3576CAN_REG_ERROR_CODE_DIRECTION_RX) {
+		if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_SOF_IDE)
+			cf->data[3] = CAN_ERR_PROT_LOC_SOF;
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_ID2_RTR)
+			cf->data[3] = CAN_ERR_PROT_LOC_RTR;
+		/* RKCANFD_REG_ERROR_CODE_RX_FDF */
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_RES)
+			cf->data[3] = CAN_ERR_PROT_LOC_RES0;
+		/* RKCANFD_REG_ERROR_CODE_RX_BRS_ESI */
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_DLC)
+			cf->data[3] = CAN_ERR_PROT_LOC_DLC;
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_DATA)
+			cf->data[3] = CAN_ERR_PROT_LOC_DATA;
+		/* RKCANFD_REG_ERROR_CODE_RX_STUFF_COUNT */
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_CRC)
+			cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_CRC_LIM)
+			cf->data[3] = CAN_ERR_PROT_LOC_ACK_DEL;
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_ACK)
+			cf->data[3] = CAN_ERR_PROT_LOC_ACK;
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_ACK_LIM)
+			cf->data[3] = CAN_ERR_PROT_LOC_ACK_DEL;
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_EOF)
+			cf->data[3] = CAN_ERR_PROT_LOC_EOF;
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_SPACE)
+			cf->data[3] = CAN_ERR_PROT_LOC_EOF;
+	} else {
+		cf->data[2] |= CAN_ERR_PROT_TX;
+
+		if (reg_ec & RK3576CAN_REG_ERROR_CODE_TX_SOF_DLC)
+			cf->data[3] = CAN_ERR_PROT_LOC_SOF;
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_TX_DATA)
+			cf->data[3] = CAN_ERR_PROT_LOC_DATA;
+		/* RKCANFD_REG_ERROR_CODE_TX_STUFF_COUNT */
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_TX_CRC)
+			cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_TX_ACK_EOF)
+			cf->data[3] = CAN_ERR_PROT_LOC_ACK_DEL;
+	}
+
+	switch (reg_ec & RK3576CAN_REG_ERROR_CODE_TYPE) {
+	case FIELD_PREP_CONST(RK3576CAN_REG_ERROR_CODE_TYPE,
+			      RK3576CAN_REG_ERROR_CODE_TYPE_BIT):
+
+		cf->data[2] |= CAN_ERR_PROT_BIT;
+		break;
+	case FIELD_PREP_CONST(RK3576CAN_REG_ERROR_CODE_TYPE,
+			      RK3576CAN_REG_ERROR_CODE_TYPE_STUFF):
+		cf->data[2] |= CAN_ERR_PROT_STUFF;
+		break;
+	case FIELD_PREP_CONST(RK3576CAN_REG_ERROR_CODE_TYPE,
+			      RK3576CAN_REG_ERROR_CODE_TYPE_FORM):
+		cf->data[2] |= CAN_ERR_PROT_FORM;
+		break;
+	case FIELD_PREP_CONST(RK3576CAN_REG_ERROR_CODE_TYPE,
+			      RK3576CAN_REG_ERROR_CODE_TYPE_ACK):
+		cf->can_id |= CAN_ERR_ACK;
+		break;
+	case FIELD_PREP_CONST(RK3576CAN_REG_ERROR_CODE_TYPE,
+			      RK3576CAN_REG_ERROR_CODE_TYPE_CRC):
+		cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
+		break;
+	}
+}
+
 static int rkcanfd_handle_error_int(struct rkcanfd_priv *priv)
 {
 	struct net_device_stats *stats = &priv->ndev->stats;
@@ -530,6 +794,41 @@ static int rkcanfd_handle_error_int(struct rkcanfd_priv *priv)
 	return 0;
 }
 
+static int rkcanfd_handle_rk3576_error_int(struct rkcanfd_priv *priv)
+{
+	struct net_device_stats *stats = &priv->ndev->stats;
+	struct can_frame *cf = NULL;
+	u32 reg_ec;
+	struct sk_buff *skb;
+	int err;
+
+	reg_ec = rkcanfd_read(priv, RK3576CAN_REG_ERROR_CODE);
+	if (!reg_ec)
+		return 0;
+
+	if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) {
+		skb = alloc_can_err_skb(priv->ndev, &cf);
+		if (cf) {
+			struct can_berr_counter bec;
+
+			priv->devtype_data.get_berr_counter(priv, &bec);
+			cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR | CAN_ERR_CNT;
+			cf->data[6] = bec.txerr;
+			cf->data[7] = bec.rxerr;
+		}
+	}
+
+	rk3576can_handle_error_int_reg_ec(priv, cf, reg_ec);
+	if (!cf)
+		return 0;
+
+	err = can_rx_offload_queue_tail(&priv->offload, skb);
+	if (err)
+		stats->rx_fifo_errors++;
+
+	return 0;
+}
+
 static int rkcanfd_handle_state_error_int(struct rkcanfd_priv *priv)
 {
 	struct net_device_stats *stats = &priv->ndev->stats;
@@ -575,6 +874,50 @@ static int rkcanfd_handle_state_error_int(struct rkcanfd_priv *priv)
 	return 0;
 }
 
+static int rkcanfd_handle_rk3576_state_error_int(struct rkcanfd_priv *priv)
+{
+	struct net_device_stats *stats = &priv->ndev->stats;
+	enum can_state new_state, rx_state, tx_state;
+	struct net_device *ndev = priv->ndev;
+	struct can_berr_counter bec;
+	struct can_frame *cf = NULL;
+	struct sk_buff *skb;
+	int err;
+
+	priv->devtype_data.get_berr_counter(priv, &bec);
+	can_state_get_by_berr_counter(ndev, &bec, &tx_state, &rx_state);
+
+	new_state = max(tx_state, rx_state);
+	if (new_state == priv->can.state)
+		return 0;
+
+	/* The skb allocation might fail, but can_change_state()
+	 * handles cf == NULL.
+	 */
+	skb = alloc_can_err_skb(priv->ndev, &cf);
+	can_change_state(ndev, cf, tx_state, rx_state);
+
+	if (new_state == CAN_STATE_BUS_OFF) {
+		priv->devtype_data.chip_stop(priv, CAN_STATE_BUS_OFF);
+		can_bus_off(ndev);
+	}
+
+	if (!skb)
+		return 0;
+
+	if (new_state != CAN_STATE_BUS_OFF) {
+		cf->can_id |= CAN_ERR_CNT;
+		cf->data[6] = bec.txerr;
+		cf->data[7] = bec.rxerr;
+	}
+
+	err = can_rx_offload_queue_tail(&priv->offload, skb);
+	if (err)
+		stats->rx_fifo_errors++;
+
+	return 0;
+}
+
 static int
 rkcanfd_handle_rx_fifo_overflow_int(struct rkcanfd_priv *priv)
 {
@@ -621,6 +964,55 @@ rkcanfd_handle_rx_fifo_overflow_int(struct rkcanfd_priv *priv)
 	err; \
 })
 
+static irqreturn_t rk3576can_irq(int irq, void *dev_id)
+{
+	struct rkcanfd_priv *priv = dev_id;
+	u32 reg_int_unmasked, reg_int;
+
+	reg_int_unmasked = rkcanfd_read(priv, RK3576CAN_REG_INT);
+	reg_int = reg_int_unmasked & ~priv->reg_int_mask_default;
+
+	if (!reg_int)
+		return IRQ_NONE;
+
+	rkcanfd_write(priv, RK3576CAN_REG_INT, reg_int);
+
+	if (reg_int & (RK3576CAN_REG_INT_RXSTR_TIMEOUT_INT |
+		       RK3576CAN_REG_INT_ISM_WTM_INT |
+		       RK3576CAN_REG_INT_RX_FIFO_FULL_INT)) {
+		rkcanfd_write(priv, RK3576CAN_REG_INT_MASK,
+			      priv->reg_int_mask_default | RK3576CAN_REG_INT_ISM_WTM_INT |
+			      RK3576CAN_REG_INT_RXSTR_TIMEOUT_INT |
+			      RK3576CAN_REG_INT_RX_FINISH_INT);
+		rkcanfd_handle(priv, rk3576_rx_int);
+	}
+
+	if (reg_int & RK3576CAN_REG_INT_TX_FINISH_INT)
+		rkcanfd_handle(priv, rk3576_tx_int);
+
+	if (reg_int & RK3576CAN_REG_INT_ERROR_INT)
+		rkcanfd_handle(priv, rk3576_error_int);
+
+	if (reg_int & (RK3576CAN_REG_INT_BUS_OFF_INT |
+		       RK3576CAN_REG_INT_PASSIVE_ERROR_INT |
+		       RK3576CAN_REG_INT_ERROR_WARNING_INT) ||
+	    priv->can.state > CAN_STATE_ERROR_ACTIVE)
+		rkcanfd_handle(priv, rk3576_state_error_int);
+
+	if (reg_int & RK3576CAN_REG_INT_WAKEUP_INT)
+		netdev_info(priv->ndev, "%s: WAKEUP_INT\n", __func__);
+
+	if (reg_int & RK3576CAN_REG_INT_BUS_OFF_RECOVERY_INT)
+		netdev_info(priv->ndev, "%s: BUS_OFF_RECOVERY_INT\n", __func__);
+
+	if (reg_int & RK3576CAN_REG_INT_OVERLOAD_INT)
+		netdev_info(priv->ndev, "%s: OVERLOAD_INT\n", __func__);
+
+	can_rx_offload_irq_finish(&priv->offload);
+
+	return IRQ_HANDLED;
+}
+
 static irqreturn_t rkcanfd_irq(int irq, void *dev_id)
 {
 	struct rkcanfd_priv *priv = dev_id;
@@ -775,6 +1167,16 @@ static void rkcanfd_register_done(const struct rkcanfd_priv *priv)
 			    RKCANFD_ERRATUM_5_SYSCLOCK_HZ_MIN / MEGA);
 }
 
+static void rk3576can_register_done(const struct rkcanfd_priv *priv)
+{
+	u32 dev_id;
+
+	dev_id = rkcanfd_read(priv, RK3576CAN_REG_RTL_VERSION);
+	netdev_info(priv->ndev,
+		    "Rockchip-CANFD %s rev%u.\n",
+		    rkcanfd_get_model_str(priv), dev_id);
+}
+
 static int rkcanfd_register(struct rkcanfd_priv *priv)
 {
 	struct net_device *ndev = priv->ndev;
@@ -856,6 +1258,20 @@ static const struct rkcanfd_devtype_data rkcanfd_devtype_data_rk3568v3 = {
 	.register_done = rkcanfd_register_done,
 };
 
+/* The rk3576 CAN-FD */
+static const struct rkcanfd_devtype_data rkcan_devtype_data_rk3576 = {
+	.model = RKCAN_MODEL_RK3576,
+	.quirks = RKCANFD_QUIRK_CANFD_BROKEN,
+	.get_berr_counter = rk3576can_get_berr_counter_corrected,
+	.interrupts_enable = rkcanfd_chip_interrupts_enable,
+	.interrupts_disable = rk3576can_chip_interrupts_disable,
+	.chip_start = rk3576can_chip_start,
+	.chip_stop = rk3576can_chip_stop,
+	.chip_stop_sync = rk3576can_chip_stop_sync,
+	.irq = rk3576can_irq,
+	.register_done = rk3576can_register_done,
+};
+
 static const struct of_device_id rkcanfd_of_match[] = {
 	{
 		.compatible = "rockchip,rk3568v2-canfd",
@@ -863,6 +1279,9 @@ static const struct of_device_id rkcanfd_of_match[] = {
 	}, {
 		.compatible = "rockchip,rk3568v3-canfd",
 		.data = &rkcanfd_devtype_data_rk3568v3,
+	},  {
+		.compatible = "rockchip,rk3576-can",
+		.data = &rkcan_devtype_data_rk3576,
 	}, {
 		/* sentinel */
 	},
diff --git a/drivers/net/can/rockchip/rockchip_canfd-rx.c b/drivers/net/can/rockchip/rockchip_canfd-rx.c
index 475c0409e215..6bc4b0185502 100644
--- a/drivers/net/can/rockchip/rockchip_canfd-rx.c
+++ b/drivers/net/can/rockchip/rockchip_canfd-rx.c
@@ -91,6 +91,47 @@ rkcanfd_fifo_header_to_cfd_header(const struct rkcanfd_priv *priv,
 	return len + cfd->len;
 }
 
+static unsigned int
+rk3576can_fifo_header_to_cfd_header(const struct rkcanfd_priv *priv,
+				    const struct rk3576can_fifo_header *header,
+				    struct canfd_frame *cfd)
+{
+	unsigned int len = sizeof(*cfd) - sizeof(cfd->data);
+	u8 dlc;
+
+	if (header->frameinfo & RK3576CAN_REG_RXFRD_FRAMEINFO_FRAME_FORMAT)
+		cfd->can_id = FIELD_GET(RKCANFD_REG_FD_ID_EFF, header->id) |
+			CAN_EFF_FLAG;
+	else
+		cfd->can_id = FIELD_GET(RKCANFD_REG_FD_ID_SFF, header->id);
+
+	dlc = FIELD_GET(RK3576CAN_REG_RXFRD_FRAMEINFO_DATA_LENGTH,
+			header->frameinfo);
+
+	/* CAN-FD */
+	if (header->frameinfo & RK3576CAN_REG_RXFRD_FRAMEINFO_FDF) {
+		cfd->len = can_fd_dlc2len(dlc);
+
+		/* The cfd is not allocated by alloc_canfd_skb(), so
+		 * set CANFD_FDF here.
+		 */
+		cfd->flags |= CANFD_FDF;
+
+		if (header->frameinfo & RK3576CAN_REG_RXFRD_FRAMEINFO_BRS)
+			cfd->flags |= CANFD_BRS;
+	} else {
+		cfd->len = can_cc_dlc2len(dlc);
+
+		if (header->frameinfo & RK3576CAN_REG_RXFRD_FRAMEINFO_RTR) {
+			cfd->can_id |= CAN_RTR_FLAG;
+
+			return len;
+		}
+	}
+
+	return len + cfd->len;
+}
+
 static int rkcanfd_rxstx_filter(struct rkcanfd_priv *priv,
 				const struct canfd_frame *cfd_rx, const u32 ts,
 				bool *tx_done)
@@ -198,6 +239,44 @@ rkcanfd_fifo_header_empty(const struct rkcanfd_fifo_header *header)
 		header->frameinfo == header->ts;
 }
 
+static int rk3576can_handle_rx_int_one(struct rkcanfd_priv *priv)
+{
+	struct net_device_stats *stats = &priv->ndev->stats;
+	struct canfd_frame cfd[1] = { }, *skb_cfd;
+	struct rk3576can_fifo_header header[1] = { };
+	struct sk_buff *skb;
+	unsigned int len;
+	int err;
+
+	/* read header into separate struct and convert it later */
+	rkcanfd_read_rep(priv, RKCANFD_REG_RX_FIFO_RDATA,
+			 header, sizeof(*header));
+	/* read data directly into cfd */
+	rkcanfd_read_rep(priv, RKCANFD_REG_RX_FIFO_RDATA,
+			 cfd->data, sizeof(cfd->data));
+
+	len = rk3576can_fifo_header_to_cfd_header(priv, header, cfd);
+
+	if (header->frameinfo & RK3576CAN_REG_RXFRD_FRAMEINFO_FDF)
+		skb = alloc_canfd_skb(priv->ndev, &skb_cfd);
+	else
+		skb = alloc_can_skb(priv->ndev, (struct can_frame **)&skb_cfd);
+
+	if (!skb) {
+		stats->rx_dropped++;
+
+		return 0;
+	}
+
+	memcpy(skb_cfd, cfd, len);
+
+	err = can_rx_offload_queue_tail(&priv->offload, skb);
+	if (err)
+		stats->rx_fifo_errors++;
+
+	return 0;
+}
+
 static int rkcanfd_handle_rx_int_one(struct rkcanfd_priv *priv)
 {
 	struct net_device_stats *stats = &priv->ndev->stats;
@@ -284,6 +363,15 @@ rkcanfd_rx_fifo_get_len(const struct rkcanfd_priv *priv)
 	return FIELD_GET(RKCANFD_REG_RX_FIFO_CTRL_RX_FIFO_CNT, reg);
 }
 
+static inline unsigned int
+rk3576can_rx_fifo_get_len(const struct rkcanfd_priv *priv)
+{
+	const u32 reg = rkcanfd_read(priv, RK3576CAN_REG_STR_STATE);
+	int val = FIELD_GET(RK3576CAN_REG_STR_STATE_INTM_LEFT_CNT, reg);
+
+	return DIV_ROUND_UP(val, RK3576CAN_REG_STR_STATE_INTM_LEFT_CNT_UNIT);
+}
+
 int rkcanfd_handle_rx_int(struct rkcanfd_priv *priv)
 {
 	unsigned int len;
@@ -297,3 +385,18 @@ int rkcanfd_handle_rx_int(struct rkcanfd_priv *priv)
 
 	return 0;
 }
+
+int rkcanfd_handle_rk3576_rx_int(struct rkcanfd_priv *priv)
+{
+	unsigned int len;
+	int err;
+
+	while ((len = rk3576can_rx_fifo_get_len(priv))) {
+		err = rk3576can_handle_rx_int_one(priv);
+		if (err)
+			return err;
+	}
+	rkcanfd_write(priv, RK3576CAN_REG_INT_MASK, priv->reg_int_mask_default);
+	return 0;
+}
+
diff --git a/drivers/net/can/rockchip/rockchip_canfd-tx.c b/drivers/net/can/rockchip/rockchip_canfd-tx.c
index 12200dcfd338..de2f673c31ed 100644
--- a/drivers/net/can/rockchip/rockchip_canfd-tx.c
+++ b/drivers/net/can/rockchip/rockchip_canfd-tx.c
@@ -165,3 +165,23 @@ void rkcanfd_handle_tx_done_one(struct rkcanfd_priv *priv, const u32 ts,
 							    frame_len_p);
 	stats->tx_packets++;
 }
+
+int rkcanfd_handle_rk3576_tx_int(struct rkcanfd_priv *priv)
+{
+	struct net_device_stats *stats = &priv->ndev->stats;
+	unsigned int tx_tail;
+	unsigned int frame_len = 0;
+
+	tx_tail = rkcanfd_get_tx_tail(priv);
+
+	stats->tx_bytes +=
+		can_rx_offload_get_echo_skb_queue_tail(&priv->offload,
+						       tx_tail, &frame_len);
+	stats->tx_packets++;
+	WRITE_ONCE(priv->tx_tail, priv->tx_tail + 1);
+	netif_subqueue_completed_wake(priv->ndev, 0, 1, frame_len,
+				      rkcanfd_get_effective_tx_free(priv),
+				      RKCANFD_TX_START_THRESHOLD);
+	return 0;
+}
+
diff --git a/drivers/net/can/rockchip/rockchip_canfd.h b/drivers/net/can/rockchip/rockchip_canfd.h
index 72f26b96add0..77c673cfea3b 100644
--- a/drivers/net/can/rockchip/rockchip_canfd.h
+++ b/drivers/net/can/rockchip/rockchip_canfd.h
@@ -287,6 +287,256 @@
 #define RKCANFD_REG_RX_FIFO_RDATA 0x400
 #define RKCANFD_REG_TXE_FIFO_RDATA 0x500
 
+#define RK3576CAN_REG_MODE 0x000
+#define RK3576CAN_REG_CMD 0x004
+
+#define RK3576CAN_REG_STATE 0x008
+#define RK3576CAN_REG_STATE_SLEEP_STATE BIT(5)
+#define RK3576CAN_REG_STATE_BUS_OFF_STATE BIT(4)
+#define RK3576CAN_REG_STATE_ERROR_WARNING_STATE BIT(3)
+#define RK3576CAN_REG_STATE_TX_PERIOD BIT(2)
+#define RK3576CAN_REG_STATE_RX_PERIOD BIT(1)
+#define RK3576CAN_REG_STATE_TX_BUFFER_FULL BIT(0)
+
+#define RK3576CAN_REG_INT 0x00c
+#define RK3576CAN_REG_INT_BUSOFF_RCY_INT BIT(19)
+#define RK3576CAN_REG_INT_ESM_WTM_INT BIT(18)
+#define RK3576CAN_REG_INT_ISM_WTM_INT BIT(17)
+#define RK3576CAN_REG_INT_BUSINT_INT BIT(16)
+#define RK3576CAN_REG_INT_RXSTR_TIMEOUT_INT BIT(15)
+#define RK3576CAN_REG_INT_MFI_TIMEOUT_INT BIT(14)
+#define RK3576CAN_REG_INT_MFI_INT BIT(13)
+#define RK3576CAN_REG_INT_AUTO_RETX_FAIL_INT BIT(12)
+#define RK3576CAN_REG_INT_WAKEUP_INT BIT(11)
+#define RK3576CAN_REG_INT_BUS_OFF_RECOVERY_INT BIT(10)
+#define RK3576CAN_REG_INT_BUS_OFF_INT BIT(9)
+#define RK3576CAN_REG_INT_RX_FIFO_OVERFLOW_INT BIT(8)
+#define RK3576CAN_REG_INT_RX_FIFO_FULL_INT BIT(7)
+#define RK3576CAN_REG_INT_ERROR_INT BIT(6)
+#define RK3576CAN_REG_INT_TX_ARBIT_FAIL_INT BIT(5)
+#define RK3576CAN_REG_INT_PASSIVE_ERROR_INT BIT(4)
+#define RK3576CAN_REG_INT_OVERLOAD_INT BIT(3)
+#define RK3576CAN_REG_INT_ERROR_WARNING_INT BIT(2)
+#define RK3576CAN_REG_INT_TX_FINISH_INT BIT(1)
+#define RK3576CAN_REG_INT_RX_FINISH_INT BIT(0)
+
+#define RK3576CAN_REG_INT_ALL \
+	(RK3576CAN_REG_INT_BUSOFF_RCY_INT | \
+	 RK3576CAN_REG_INT_ESM_WTM_INT | \
+	 RK3576CAN_REG_INT_ISM_WTM_INT | \
+	 RK3576CAN_REG_INT_BUSINT_INT | \
+	 RK3576CAN_REG_INT_RXSTR_TIMEOUT_INT | \
+	 RK3576CAN_REG_INT_MFI_TIMEOUT_INT | \
+	 RK3576CAN_REG_INT_MFI_INT | \
+	 RK3576CAN_REG_INT_AUTO_RETX_FAIL_INT | \
+	 RK3576CAN_REG_INT_WAKEUP_INT | \
+	 RK3576CAN_REG_INT_BUS_OFF_RECOVERY_INT | \
+	 RK3576CAN_REG_INT_BUS_OFF_INT | \
+	 RK3576CAN_REG_INT_RX_FIFO_OVERFLOW_INT | \
+	 RK3576CAN_REG_INT_RX_FIFO_FULL_INT | \
+	 RK3576CAN_REG_INT_ERROR_INT | \
+	 RK3576CAN_REG_INT_TX_ARBIT_FAIL_INT | \
+	 RK3576CAN_REG_INT_PASSIVE_ERROR_INT | \
+	 RK3576CAN_REG_INT_OVERLOAD_INT | \
+	 RK3576CAN_REG_INT_ERROR_WARNING_INT | \
+	 RK3576CAN_REG_INT_TX_FINISH_INT | \
+	 RK3576CAN_REG_INT_RX_FINISH_INT)
+
+#define RK3576CAN_REG_INT_ALL_ERROR \
+	(RK3576CAN_REG_INT_BUS_OFF_INT | \
+	 RK3576CAN_REG_INT_ERROR_INT | \
+	 RK3576CAN_REG_INT_PASSIVE_ERROR_INT | \
+	 RK3576CAN_REG_INT_ERROR_WARNING_INT)
+
+#define RK3576CAN_REG_INT_MASK 0x010
+
+#define RK3576CAN_REG_FD_NOMINAL_BITTIMING 0x100
+#define RK3576CAN_REG_FD_NOMINAL_BITTIMING_SAMPLE_MODE BIT(31)
+#define RK3576CAN_REG_FD_NOMINAL_BITTIMING_SJW GENMASK(30, 24)
+#define RK3576CAN_REG_FD_NOMINAL_BITTIMING_BRP GENMASK(23, 16)
+#define RK3576CAN_REG_FD_NOMINAL_BITTIMING_TSEG2 GENMASK(14, 8)
+#define RK3576CAN_REG_FD_NOMINAL_BITTIMING_TSEG1 GENMASK(7, 0)
+
+#define RK3576CAN_REG_FD_DATA_BITTIMING 0x104
+#define RK3576CAN_REG_FD_DATA_BITTIMING_BRS_TSEG1 GENMASK(31, 24)
+#define RK3576CAN_REG_FD_DATA_BITTIMING_BRS_MODE BIT(23)
+#define RK3576CAN_REG_FD_DATA_BITTIMING_ACKSLOT_SYNC_DIS BIT(22)
+#define RK3576CAN_REG_FD_DATA_BITTIMING_SJW GENMASK(20, 17)
+#define RK3576CAN_REG_FD_DATA_BITTIMING_BRP GENMASK(16, 9)
+#define RK3576CAN_REG_FD_DATA_BITTIMING_TSEG2 GENMASK(8, 5)
+#define RK3576CAN_REG_FD_DATA_BITTIMING_TSEG1 GENMASK(4, 0)
+
+#define RK3576CAN_REG_TRANSMIT_DELAY_COMPENSATION 0x108
+#define RK3576CAN_REG_TRANSMIT_DELAY_COMPENSATION_TDC_OFFSET GENMASK(6, 1)
+#define RK3576CAN_REG_TRANSMIT_DELAY_COMPENSATION_TDC_ENABLE BIT(0)
+
+#define RK3576CAN_REG_BRS_CFG 0x10c
+#define RK3576CAN_REG_BRS_CFG_TRIPLE_SYNC_MODE BIT(31)
+#define RK3576CAN_REG_BRS_CFG_SP2_DTSEG1 GENMASK(30, 26)
+#define RK3576CAN_REG_BRS_CFG_SP2_NTSEG1 GENMASK(25, 18)
+#define RK3576CAN_REG_BRS_CFG_SP1_DTSEG1 GENMASK(17, 13)
+#define RK3576CAN_REG_BRS_CFG_SP1_NTSEG1 GENMASK(12, 5)
+#define RK3576CAN_REG_BRS_CFG_RESYNC_MODE BIT(3)
+#define RK3576CAN_REG_BRS_CFG_BRS_POSSYNC_EN BIT(1)
+#define RK3576CAN_REG_BRS_CFG_BRS_NEGSYNC_EN BIT(0)
+
+#define RK3576CAN_REG_LOOP_CNT 0x110
+
+#define RK3576CAN_REG_DMA_CTRL 0x11c
+#define RK3576CAN_REG_DMA_CTRL_DMA_RX_EN BIT(9)
+#define RK3576CAN_REG_DMA_CTRL_DMA_THR GENMASK(8, 0)
+
+#define RK3576CAN_REG_FD_TXFRAMEINFO 0x200
+
+#define RK3576CAN_REG_FD_TXID 0x204
+#define RK3576CAN_REG_FD_ID_EFF GENMASK(28, 0)
+#define RK3576CAN_REG_FD_ID_SFF GENMASK(11, 0)
+
+#define RK3576CAN_REG_FD_TXDATA0 0x208
+#define RK3576CAN_REG_FD_TXDATA1 0x20c
+#define RK3576CAN_REG_FD_TXDATA2 0x210
+#define RK3576CAN_REG_FD_TXDATA3 0x214
+#define RK3576CAN_REG_FD_TXDATA4 0x218
+#define RK3576CAN_REG_FD_TXDATA5 0x21c
+#define RK3576CAN_REG_FD_TXDATA6 0x220
+#define RK3576CAN_REG_FD_TXDATA7 0x224
+#define RK3576CAN_REG_FD_TXDATA8 0x228
+#define RK3576CAN_REG_FD_TXDATA9 0x22c
+#define RK3576CAN_REG_FD_TXDATA10 0x230
+#define RK3576CAN_REG_FD_TXDATA11 0x234
+#define RK3576CAN_REG_FD_TXDATA12 0x238
+#define RK3576CAN_REG_FD_TXDATA13 0x23c
+#define RK3576CAN_REG_FD_TXDATA14 0x240
+#define RK3576CAN_REG_FD_TXDATA15 0x244
+
+#define RK3576CAN_REG_RXFRD 0x400
+#define RK3576CAN_REG_RXFRD_FRAMEINFO_FRAME_FORMAT BIT(23)
+#define RK3576CAN_REG_RXFRD_FRAMEINFO_RTR BIT(22)
+#define RK3576CAN_REG_RXFRD_FRAMEINFO_FDF BIT(21)
+#define RK3576CAN_REG_RXFRD_FRAMEINFO_BRS BIT(20)
+#define RK3576CAN_REG_RXFRD_FRAMEINFO_DATA_LENGTH GENMASK(27, 24)
+
+#define RK3576CAN_REG_STR_CTL 0x600
+#define RK3576CAN_REG_STR_CTL_STORAGE_TIMEOUT_MODE BIT(8)
+#define RK3576CAN_REG_STR_CTL_ESM_SEL_MASK GENMASK(7, 6)
+#define RK3576CAN_REG_STR_CTL_RX_STORAGE_RESET BIT(4)
+#define RK3576CAN_REG_STR_CTL_ISM_SEL GENMASK(3, 2)
+#define RK3576CAN_REG_STR_CTL_ISM_SEL_FLEXIBLE 0x0
+#define RK3576CAN_REG_STR_CTL_ISM_SEL_CAN_FIXED 0x1
+#define RK3576CAN_REG_STR_CTL_ISM_SEL_CANFD_FIXED 0x2
+#define RK3576CAN_REG_STR_CTL_EXT_STORAGE_MODE BIT(1)
+#define RK3576CAN_REG_STR_CTL_BUFFER_MODE_ENABLE BIT(0)
+
+#define RK3576CAN_REG_STR_STATE 0x604
+#define RK3576CAN_REG_STR_STATE_INTM_FRAME_CNT GENMASK(25, 17)
+#define RK3576CAN_REG_STR_STATE_INTM_LEFT_CNT GENMASK(16, 8)
+#define RK3576CAN_REG_STR_STATE_INTM_LEFT_CNT_UNIT 18
+#define RK3576CAN_REG_STR_STATE_EXTM_FULL BIT(3)
+#define RK3576CAN_REG_STR_STATE_EXTM_EMPTY BIT(2)
+#define RK3576CAN_REG_STR_STATE_INTM_FULL BIT(1)
+#define RK3576CAN_REG_STR_STATE_INTM_EMPTY BIT(0)
+
+#define RK3576CAN_REG_STR_TIMEOUT 0x608
+
+#define RK3576CAN_REG_STR_WTM 0x60c
+#define RK3576CAN_REG_ATF(n) (0x700 + ((n) << 2))
+#define RK3576CAN_REG_ATFM(n) (0x714 + ((n) << 2))
+#define RK3576CAN_REG_ATFM_MASK_SEL BIT(31)
+#define RK3576CAN_REG_ATFM_RTR_EN BIT(30)
+#define RK3576CAN_REG_ATFM_RTR BIT(29)
+#define RK3576CAN_REG_ATFM_MASK_SEL_MASK_MODE 0x0
+#define RK3576CAN_REG_ATFM_MASK_SEL_LIST_MODE 0x1
+#define RK3576CAN_REG_ATFM_ID GENMASK(28, 0)
+
+#define RK3576CAN_REG_ATF_DLC 0x728
+#define RK3576CAN_REG_ATF_DLC_ATF_DLC_MODE BIT(5)
+#define RK3576CAN_REG_ATF_DLC_ATF_DLC_EN BIT(4)
+#define RK3576CAN_REG_ATF_DLC_ATF_DLC GENMASK(3, 0)
+
+#define RK3576CAN_REG_ATF_CTL 0x72c
+#define RK3576CAN_REG_ATF_CTL_ATF_DIS(n) BIT(n)
+#define RK3576CAN_REG_ATF_CTL_ATF_DIS_ALL GENMASK(15, 0)
+
+#define RK3576CAN_REG_SPACE_CTRL 0x800
+
+#define RK3576CAN_REG_AUTO_RETX_CFG 0x808
+#define RK3576CAN_REG_AUTO_RETX_CFG_RETX_TIME_LIMIT GENMASK(18, 3)
+#define RK3576CAN_REG_AUTO_RETX_CFG_RETX_LIMIT_EN BIT(1)
+#define RK3576CAN_REG_AUTO_RETX_CFG_AUTO_RETX_EN BIT(0)
+
+#define RK3576CAN_REG_AUTO_RETX_STATE0 0x80c
+#define RK3576CAN_REG_AUTO_RETX_STATE0_AUTO_RETX_CNT GENMASK(15, 0)
+
+#define RK3576CAN_REG_AUTO_RETX_STATE1 0x810
+#define RK3576CAN_REG_OLF_CFG 0x814
+#define RK3576CAN_REG_RXINT_CTRL 0x818
+#define RK3576CAN_REG_RXINT_TIMEOUT 0x81c
+#define RK3576CAN_REG_OTHER_CFG 0x820
+#define RK3576CAN_REG_WAVE_FILTER_CFG 0x824
+#define RK3576CAN_REG_RBC_CFG 0x828
+#define RK3576CAN_REG_TXCRC_CFG 0x82c
+
+#define RK3576CAN_REG_BUSOFFRCY_CFG 0x830
+#define RK3576CAN_REG_BUSOFF_RCY_THR 0x834
+
+#define RK3576CAN_REG_ERROR_CODE 0x900
+#define RK3576CAN_REG_ERROR_MASK 0x904
+#define RK3576CAN_REG_ERROR_MASK_ACK_ERROR BIT(4)
+#define RK3576CAN_REG_ERROR_MASK_FORM_ERROR BIT(3)
+#define RK3576CAN_REG_ERROR_MASK_CRC_ERROR BIT(2)
+#define RK3576CAN_REG_ERROR_MASK_STUFF_ERROR BIT(1)
+#define RK3576CAN_REG_ERROR_MASK_BIT_ERROR BIT(0)
+
+#define RK3576CAN_REG_RXERRORCNT 0x910
+#define RK3576CAN_REG_TXERRORCNT 0x914
+#define RK3576CAN_REG_RX_RXSRAM_RDATA 0xc00
+#define RK3576CAN_REG_RTL_VERSION 0xf0c
+
+#define RK3576CAN_REG_ERROR_CODE_PHASE BIT(29)
+#define RK3576CAN_REG_ERROR_CODE_TYPE GENMASK(28, 26)
+#define RK3576CAN_REG_ERROR_CODE_TYPE_BIT 0x0
+#define RK3576CAN_REG_ERROR_CODE_TYPE_STUFF 0x1
+#define RK3576CAN_REG_ERROR_CODE_TYPE_FORM 0x2
+#define RK3576CAN_REG_ERROR_CODE_TYPE_ACK 0x3
+#define RK3576CAN_REG_ERROR_CODE_TYPE_CRC 0x4
+#define RK3576CAN_REG_ERROR_CODE_DIRECTION_RX BIT(25)
+#define RK3576CAN_REG_ERROR_CODE_TX GENMASK(24, 19)
+#define RK3576CAN_REG_ERROR_CODE_TX_ACK_EOF BIT(24)
+#define RK3576CAN_REG_ERROR_CODE_TX_CRC BIT(23)
+#define RK3576CAN_REG_ERROR_CODE_TX_STUFF_COUNT BIT(22)
+#define RK3576CAN_REG_ERROR_CODE_TX_DATA BIT(21)
+#define RK3576CAN_REG_ERROR_CODE_TX_SOF_DLC BIT(20)
+#define RK3576CAN_REG_ERROR_CODE_TX_IDLE BIT(19)
+#define RK3576CAN_REG_ERROR_CODE_RX GENMASK(18, 0)
+#define RK3576CAN_REG_ERROR_CODE_RX_ERROR BIT(18)
+#define RK3576CAN_REG_ERROR_CODE_RX_OVERLOAD BIT(17)
+#define RK3576CAN_REG_ERROR_CODE_RX_SPACE BIT(16)
+#define RK3576CAN_REG_ERROR_CODE_RX_EOF BIT(15)
+#define RK3576CAN_REG_ERROR_CODE_RX_ACK_LIM BIT(14)
+#define RK3576CAN_REG_ERROR_CODE_RX_ACK BIT(13)
+#define RK3576CAN_REG_ERROR_CODE_RX_CRC_LIM BIT(12)
+#define RK3576CAN_REG_ERROR_CODE_RX_CRC BIT(11)
+#define RK3576CAN_REG_ERROR_CODE_RX_STUFF_COUNT BIT(10)
+#define RK3576CAN_REG_ERROR_CODE_RX_DATA BIT(9)
+#define RK3576CAN_REG_ERROR_CODE_RX_DLC BIT(8)
+#define RK3576CAN_REG_ERROR_CODE_RX_BRS_ESI BIT(7)
+#define RK3576CAN_REG_ERROR_CODE_RX_RES BIT(6)
+#define RK3576CAN_REG_ERROR_CODE_RX_FDF BIT(5)
+#define RK3576CAN_REG_ERROR_CODE_RX_ID2_RTR BIT(4)
+#define RK3576CAN_REG_ERROR_CODE_RX_SOF_IDE BIT(3)
+#define RK3576CAN_REG_ERROR_CODE_RX_BUS_IDLE BIT(2)
+#define RK3576CAN_REG_ERROR_CODE_RX_BUS_INT BIT(1)
+#define RK3576CAN_REG_ERROR_CODE_RX_STOP BIT(0)
+
+#define RK3576CAN_ISM_WATERMASK_CAN 0x6c /* word */
+#define RK3576CAN_ISM_WATERMASK_CANFD 0x6c /* word */
+
+#define RK3576CAN_SRAM_MAX_DEPTH 256 /* word */
+
+#define RK3576CAN_CANFD_FILTER GENMASK(28, 0)
+
+#define RK3576CAN_CANFD_FIFO_CNT GENMASK(7, 0)
+
 #define DEVICE_NAME "rockchip_canfd"
 #define RKCANFD_NAPI_WEIGHT 32
 #define RKCANFD_TXFIFO_DEPTH 2
@@ -434,6 +684,7 @@
 enum rkcanfd_model {
 	RKCANFD_MODEL_RK3568V2 = 0x35682,
 	RKCANFD_MODEL_RK3568V3 = 0x35683,
+	RKCAN_MODEL_RK3576 = 0x3576,
 };
 
 struct rkcanfd_priv;
@@ -457,6 +708,11 @@ struct rkcanfd_fifo_header {
 	u32 ts;
 };
 
+struct rk3576can_fifo_header {
+	u32 frameinfo;
+	u32 id;
+};
+
 struct rkcanfd_stats {
 	struct u64_stats_sync syncp;
 
@@ -546,6 +802,8 @@ rkcanfd_get_tx_free(const struct rkcanfd_priv *priv)
 void rkcanfd_ethtool_init(struct rkcanfd_priv *priv);
 
 int rkcanfd_handle_rx_int(struct rkcanfd_priv *priv);
+int rkcanfd_handle_rk3576_tx_int(struct rkcanfd_priv *priv);
+int rkcanfd_handle_rk3576_rx_int(struct rkcanfd_priv *priv);
 
 void rkcanfd_skb_set_timestamp(const struct rkcanfd_priv *priv,
 			       struct sk_buff *skb, const u32 timestamp);
-- 
2.34.1



From zhangqing at rock-chips.com  Tue Nov 11 17:59:40 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Wed, 12 Nov 2025 09:59:40 +0800
Subject: [RESEND PATCH v8 4/4] net: can: rockchip: support dma for rk3576 rx
In-Reply-To: <20251112015940.3695638-1-zhangqing@rock-chips.com>
References: <20251112015940.3695638-1-zhangqing@rock-chips.com>
Message-ID: <20251112015940.3695638-5-zhangqing@rock-chips.com>

The new can controller of rk3576 supports rx dma.

Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
---
 .../net/can/rockchip/rockchip_canfd-core.c    |  62 +++++++++-
 drivers/net/can/rockchip/rockchip_canfd-rx.c  | 109 ++++++++++++++++++
 drivers/net/can/rockchip/rockchip_canfd.h     |   9 ++
 3 files changed, 178 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/rockchip/rockchip_canfd-core.c b/drivers/net/can/rockchip/rockchip_canfd-core.c
index 58fffcf97b20..8284bf05efba 100644
--- a/drivers/net/can/rockchip/rockchip_canfd-core.c
+++ b/drivers/net/can/rockchip/rockchip_canfd-core.c
@@ -399,6 +399,9 @@ static void rk3576can_chip_start(struct rkcanfd_priv *priv)
 		      RK3576CAN_REG_BRS_CFG_BRS_NEGSYNC_EN |
 		      RK3576CAN_REG_BRS_CFG_BRS_POSSYNC_EN);
 
+	if (priv->dma_thr)
+		rkcanfd_write(priv, RK3576CAN_REG_DMA_CTRL,
+			      RK3576CAN_REG_DMA_CTRL_DMA_RX_EN | priv->dma_thr);
 	rkcanfd_set_bittiming(priv);
 
 	priv->devtype_data.interrupts_disable(priv);
@@ -1288,10 +1291,34 @@ static const struct of_device_id rkcanfd_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, rkcanfd_of_match);
 
+static int rk3576_canfd_dma_init(struct rkcanfd_priv *priv, struct resource *res)
+{
+	struct dma_slave_config rxconf = {
+		.direction = DMA_DEV_TO_MEM,
+		.src_addr = res->start + RK3576CAN_REG_RXFRD,
+		.src_addr_width = 4,
+		.dst_addr_width = 4,
+		.src_maxburst = 9,
+	};
+
+	priv->dma_thr = rxconf.src_maxburst - 1;
+	priv->dma_size = RK3576CAN_REG_STR_STATE_INTM_LEFT_CNT_UNIT * 4;
+	priv->rxbuf = dma_alloc_coherent(priv->ndev->dev.parent,
+					 priv->dma_size * RK3576CAN_SRAM_MAX_FIFO_CNT,
+					 &priv->rx_dma_dst_addr, GFP_KERNEL);
+	if (!priv->rxbuf) {
+		priv->rxbuf = NULL;
+		return -ENOMEM;
+	}
+	dmaengine_slave_config(priv->rxchan, &rxconf);
+	return 0;
+}
+
 static int rkcanfd_probe(struct platform_device *pdev)
 {
 	struct rkcanfd_priv *priv;
 	struct net_device *ndev;
+	struct resource *res;
 	const void *match;
 	int err;
 
@@ -1313,7 +1340,7 @@ static int rkcanfd_probe(struct platform_device *pdev)
 		goto out_free_candev;
 	}
 
-	priv->regs = devm_platform_ioremap_resource(pdev, 0);
+	priv->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
 	if (IS_ERR(priv->regs)) {
 		err = PTR_ERR(priv->regs);
 		goto out_free_candev;
@@ -1348,10 +1375,22 @@ static int rkcanfd_probe(struct platform_device *pdev)
 			priv->can.ctrlmode_supported |= CAN_CTRLMODE_FD;
 	}
 
+	priv->rxchan = dma_request_chan(&pdev->dev, "rx");
+	if (IS_ERR(priv->rxchan)) {
+		netdev_warn(priv->ndev,
+			    "Failed to request RX-DMA channel: %pe, continuing without DMA",
+			    priv->rxchan);
+		priv->rxchan = NULL;
+	} else {
+		err = rk3576_canfd_dma_init(priv, res);
+		if (err)
+			goto out_can_dma_rx_chan_del;
+	}
+
 	err = can_rx_offload_add_manual(ndev, &priv->offload,
 					RKCANFD_NAPI_WEIGHT);
 	if (err)
-		goto out_free_candev;
+		goto out_can_dma_rx_chan_del;
 
 	err = rkcanfd_register(priv);
 	if (err)
@@ -1361,6 +1400,15 @@ static int rkcanfd_probe(struct platform_device *pdev)
 
 out_can_rx_offload_del:
 	can_rx_offload_del(&priv->offload);
+out_can_dma_rx_chan_del:
+	if (priv->rxbuf) {
+		dma_free_coherent(priv->ndev->dev.parent,
+				  priv->dma_size * RK3576CAN_SRAM_MAX_FIFO_CNT,
+				  priv->rxbuf, priv->rx_dma_dst_addr);
+		priv->rxbuf = NULL;
+	}
+	if (priv->rxchan)
+		dma_release_channel(priv->rxchan);
 out_free_candev:
 	free_candev(ndev);
 
@@ -1372,6 +1420,16 @@ static void rkcanfd_remove(struct platform_device *pdev)
 	struct rkcanfd_priv *priv = platform_get_drvdata(pdev);
 	struct net_device *ndev = priv->ndev;
 
+	if (priv->rxbuf) {
+		dma_free_coherent(priv->ndev->dev.parent,
+				  priv->dma_size * RK3576CAN_SRAM_MAX_FIFO_CNT,
+				  priv->rxbuf, priv->rx_dma_dst_addr);
+		priv->rxbuf = NULL;
+	}
+
+	if (priv->rxchan)
+		dma_release_channel(priv->rxchan);
+
 	rkcanfd_unregister(priv);
 	can_rx_offload_del(&priv->offload);
 	free_candev(ndev);
diff --git a/drivers/net/can/rockchip/rockchip_canfd-rx.c b/drivers/net/can/rockchip/rockchip_canfd-rx.c
index 6bc4b0185502..e478b2b482c1 100644
--- a/drivers/net/can/rockchip/rockchip_canfd-rx.c
+++ b/drivers/net/can/rockchip/rockchip_canfd-rx.c
@@ -277,6 +277,71 @@ static int rk3576can_handle_rx_int_one(struct rkcanfd_priv *priv)
 	return 0;
 }
 
+static int rk3576can_handle_rx_dma(struct rkcanfd_priv *priv, u32 addr)
+{
+	struct net_device_stats *stats = &priv->ndev->stats;
+	struct canfd_frame *skb_cfd;
+	struct sk_buff *skb;
+	u32 frameinfo, id, data[16] = {0};
+	u8 dlc;
+	int i;
+
+	frameinfo = *(u32 *)(priv->rxbuf + addr * RK3576CAN_REG_STR_STATE_INTM_LEFT_CNT_UNIT);
+	id = *(u32 *)(priv->rxbuf + 1 + addr * RK3576CAN_REG_STR_STATE_INTM_LEFT_CNT_UNIT);
+	for (i = 0; i < (RK3576CAN_REG_STR_STATE_INTM_LEFT_CNT_UNIT - 2); i++)
+		data[i] = *(u32 *)(priv->rxbuf + 2 + i +
+				   addr * RK3576CAN_REG_STR_STATE_INTM_LEFT_CNT_UNIT);
+
+	if (frameinfo & RK3576CAN_REG_RXFRD_FRAMEINFO_FDF)
+		skb = alloc_canfd_skb(priv->ndev, &skb_cfd);
+	else
+		skb = alloc_can_skb(priv->ndev, (struct can_frame **)&skb_cfd);
+
+	if (!skb) {
+		stats->rx_dropped++;
+
+		return 0;
+	}
+
+	if (frameinfo & RK3576CAN_REG_RXFRD_FRAMEINFO_FRAME_FORMAT)
+		skb_cfd->can_id = FIELD_GET(RKCANFD_REG_FD_ID_EFF, id) |
+			CAN_EFF_FLAG;
+	else
+		skb_cfd->can_id = FIELD_GET(RKCANFD_REG_FD_ID_SFF, id);
+
+	dlc = FIELD_GET(RK3576CAN_REG_RXFRD_FRAMEINFO_DATA_LENGTH,
+			frameinfo);
+
+	/* CAN-FD */
+	if (frameinfo & RK3576CAN_REG_RXFRD_FRAMEINFO_FDF) {
+		skb_cfd->len = can_fd_dlc2len(dlc);
+
+		/* The cfd is not allocated by alloc_canfd_skb(), so
+		 * set CANFD_FDF here.
+		 */
+		skb_cfd->flags |= CANFD_FDF;
+
+		if (frameinfo & RK3576CAN_REG_RXFRD_FRAMEINFO_BRS)
+			skb_cfd->flags |= CANFD_BRS;
+	} else {
+		skb_cfd->len = can_cc_dlc2len(dlc);
+
+		if (frameinfo & RK3576CAN_REG_RXFRD_FRAMEINFO_RTR)
+			skb_cfd->can_id |= CAN_RTR_FLAG;
+	}
+	if (!(skb_cfd->can_id & CAN_RTR_FLAG)) {
+		/* Change CANFD data format to SocketCAN data format */
+		for (i = 0; i < skb_cfd->len; i += 4)
+			*(u32 *)(skb_cfd->data + i) = data[i / 4];
+	}
+
+	stats->rx_packets++;
+	stats->rx_bytes += skb_cfd->len;
+	netif_rx(skb);
+
+	return 0;
+}
+
 static int rkcanfd_handle_rx_int_one(struct rkcanfd_priv *priv)
 {
 	struct net_device_stats *stats = &priv->ndev->stats;
@@ -372,6 +437,43 @@ rk3576can_rx_fifo_get_len(const struct rkcanfd_priv *priv)
 	return DIV_ROUND_UP(val, RK3576CAN_REG_STR_STATE_INTM_LEFT_CNT_UNIT);
 }
 
+static void rk3576_can_rx_dma_callback(void *data)
+{
+	struct rkcanfd_priv *priv = data;
+	int i;
+
+	for (i = 0; i < priv->quota; i++)
+		rk3576can_handle_rx_dma(priv, i);
+
+	rkcanfd_write(priv, RK3576CAN_REG_INT_MASK, priv->reg_int_mask_default);
+}
+
+static int rk3576_can_rx_dma(struct rkcanfd_priv *priv)
+{
+	struct dma_async_tx_descriptor *rxdesc = NULL;
+	const u32 reg = rkcanfd_read(priv, RK3576CAN_REG_STR_STATE);
+	int quota = FIELD_GET(RK3576CAN_REG_STR_STATE_INTM_LEFT_CNT, reg);
+
+	quota = DIV_ROUND_UP(quota, RK3576CAN_REG_STR_STATE_INTM_LEFT_CNT_UNIT);
+	priv->quota = quota;
+	if (priv->quota == 0) {
+		rkcanfd_write(priv, RK3576CAN_REG_INT_MASK, priv->reg_int_mask_default);
+		return 0;
+	}
+
+	rxdesc = dmaengine_prep_slave_single(priv->rxchan, priv->rx_dma_dst_addr,
+					     priv->dma_size * priv->quota, DMA_DEV_TO_MEM, 0);
+	if (!rxdesc)
+		return -ENOMSG;
+
+	rxdesc->callback = rk3576_can_rx_dma_callback;
+	rxdesc->callback_param = priv;
+
+	dmaengine_submit(rxdesc);
+	dma_async_issue_pending(priv->rxchan);
+	return 0;
+}
+
 int rkcanfd_handle_rx_int(struct rkcanfd_priv *priv)
 {
 	unsigned int len;
@@ -391,6 +493,13 @@ int rkcanfd_handle_rk3576_rx_int(struct rkcanfd_priv *priv)
 	unsigned int len;
 	int err;
 
+	if (priv->rxchan) {
+		err = rk3576_can_rx_dma(priv);
+		if (err)
+			return err;
+		else
+			return 0;
+	}
 	while ((len = rk3576can_rx_fifo_get_len(priv))) {
 		err = rk3576can_handle_rx_int_one(priv);
 		if (err)
diff --git a/drivers/net/can/rockchip/rockchip_canfd.h b/drivers/net/can/rockchip/rockchip_canfd.h
index 77c673cfea3b..bdd01150d920 100644
--- a/drivers/net/can/rockchip/rockchip_canfd.h
+++ b/drivers/net/can/rockchip/rockchip_canfd.h
@@ -11,6 +11,8 @@
 #include <linux/can/dev.h>
 #include <linux/can/rx-offload.h>
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
 #include <linux/io.h>
 #include <linux/netdevice.h>
 #include <linux/reset.h>
@@ -532,6 +534,7 @@
 #define RK3576CAN_ISM_WATERMASK_CANFD 0x6c /* word */
 
 #define RK3576CAN_SRAM_MAX_DEPTH 256 /* word */
+#define RK3576CAN_SRAM_MAX_FIFO_CNT (RK3576CAN_SRAM_MAX_DEPTH / 18)
 
 #define RK3576CAN_CANFD_FILTER GENMASK(28, 0)
 
@@ -748,6 +751,12 @@ struct rkcanfd_priv {
 	struct reset_control *reset;
 	struct clk_bulk_data *clks;
 	int clks_num;
+	u32 dma_size;
+	u32 dma_thr;
+	int quota;
+	struct dma_chan *rxchan;
+	u32 *rxbuf;
+	dma_addr_t rx_dma_dst_addr;
 };
 
 static inline u32
-- 
2.34.1



From zhangqing at rock-chips.com  Tue Nov 11 18:21:11 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Wed, 12 Nov 2025 10:21:11 +0800
Subject: [RESEND PATCH v7 4/5] dt-bindings: clock: rockchip: Add RK3506 clock and reset unit
Message-ID: <20251112022111.3828521-1-zhangqing@rock-chips.com>

From: Finley Xiao <finley.xiao at rock-chips.com>

Add device tree bindings for clock and reset unit on RK3506 SoC.
Add clock and reset IDs for RK3506 SoC.

Signed-off-by: Finley Xiao <finley.xiao at rock-chips.com>
Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
---
 .../bindings/clock/rockchip,rk3506-cru.yaml   |  45 +++
 .../dt-bindings/clock/rockchip,rk3506-cru.h   | 285 ++++++++++++++++++
 .../dt-bindings/reset/rockchip,rk3506-cru.h   | 211 +++++++++++++
 3 files changed, 541 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
 create mode 100644 include/dt-bindings/clock/rockchip,rk3506-cru.h
 create mode 100644 include/dt-bindings/reset/rockchip,rk3506-cru.h

diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml b/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
new file mode 100644
index 000000000000..6b4234ee91ef
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
@@ -0,0 +1,45 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/rockchip,rk3506-cru.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip RK3506 Clock and Reset Unit (CRU)
+
+maintainers:
+  - Finley Xiao <finley.xiao at rock-chips.com>
+  - Heiko Stuebner <heiko at sntech.de>
+
+description:
+  The RK3506 CRU generates the clock and also implements reset for SoC
+  peripherals.
+
+properties:
+  compatible:
+    const: rockchip,rk3506-cru
+
+  reg:
+    maxItems: 1
+
+  "#clock-cells":
+    const: 1
+
+  "#reset-cells":
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - "#clock-cells"
+  - "#reset-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller at ff9a0000 {
+      compatible = "rockchip,rk3506-cru";
+      reg = <0xff9a0000 0x20000>;
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+    };
diff --git a/include/dt-bindings/clock/rockchip,rk3506-cru.h b/include/dt-bindings/clock/rockchip,rk3506-cru.h
new file mode 100644
index 000000000000..71d7dda23cc9
--- /dev/null
+++ b/include/dt-bindings/clock/rockchip,rk3506-cru.h
@@ -0,0 +1,285 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2023-2025 Rockchip Electronics Co., Ltd.
+ * Author: Finley Xiao <finley.xiao at rock-chips.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3506_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_RK3506_H
+
+/* cru plls */
+#define PLL_GPLL			0
+#define PLL_V0PLL			1
+#define PLL_V1PLL			2
+
+/* cru-clocks indices */
+#define ARMCLK				3
+#define CLK_DDR				4
+#define XIN24M_GATE			5
+#define CLK_GPLL_GATE			6
+#define CLK_V0PLL_GATE			7
+#define CLK_V1PLL_GATE			8
+#define CLK_GPLL_DIV			9
+#define CLK_GPLL_DIV_100M		10
+#define CLK_V0PLL_DIV			11
+#define CLK_V1PLL_DIV			12
+#define CLK_INT_VOICE_MATRIX0		13
+#define CLK_INT_VOICE_MATRIX1		14
+#define CLK_INT_VOICE_MATRIX2		15
+#define CLK_FRAC_UART_MATRIX0_MUX	16
+#define CLK_FRAC_UART_MATRIX1_MUX	17
+#define CLK_FRAC_VOICE_MATRIX0_MUX	18
+#define CLK_FRAC_VOICE_MATRIX1_MUX	19
+#define CLK_FRAC_COMMON_MATRIX0_MUX	20
+#define CLK_FRAC_COMMON_MATRIX1_MUX	21
+#define CLK_FRAC_COMMON_MATRIX2_MUX	22
+#define CLK_FRAC_UART_MATRIX0		23
+#define CLK_FRAC_UART_MATRIX1		24
+#define CLK_FRAC_VOICE_MATRIX0		25
+#define CLK_FRAC_VOICE_MATRIX1		26
+#define CLK_FRAC_COMMON_MATRIX0		27
+#define CLK_FRAC_COMMON_MATRIX1		28
+#define CLK_FRAC_COMMON_MATRIX2		29
+#define CLK_REF_USBPHY_TOP		30
+#define CLK_REF_DPHY_TOP		31
+#define ACLK_CORE_ROOT			32
+#define PCLK_CORE_ROOT			33
+#define PCLK_DBG			34
+#define PCLK_CORE_GRF			35
+#define PCLK_CORE_CRU			36
+#define CLK_CORE_EMA_DETECT		37
+#define CLK_REF_PVTPLL_CORE		38
+#define PCLK_GPIO1			39
+#define DBCLK_GPIO1			40
+#define ACLK_CORE_PERI_ROOT		41
+#define HCLK_CORE_PERI_ROOT		42
+#define PCLK_CORE_PERI_ROOT		43
+#define CLK_DSMC			44
+#define ACLK_DSMC			45
+#define PCLK_DSMC			46
+#define CLK_FLEXBUS_TX			47
+#define CLK_FLEXBUS_RX			48
+#define ACLK_FLEXBUS			49
+#define HCLK_FLEXBUS			50
+#define ACLK_DSMC_SLV			51
+#define HCLK_DSMC_SLV			52
+#define ACLK_BUS_ROOT			53
+#define HCLK_BUS_ROOT			54
+#define PCLK_BUS_ROOT			55
+#define ACLK_SYSRAM			56
+#define HCLK_SYSRAM			57
+#define ACLK_DMAC0			58
+#define ACLK_DMAC1			59
+#define HCLK_M0				60
+#define PCLK_BUS_GRF			61
+#define PCLK_TIMER			62
+#define CLK_TIMER0_CH0			63
+#define CLK_TIMER0_CH1			64
+#define CLK_TIMER0_CH2			65
+#define CLK_TIMER0_CH3			66
+#define CLK_TIMER0_CH4			67
+#define CLK_TIMER0_CH5			68
+#define PCLK_WDT0			69
+#define TCLK_WDT0			70
+#define PCLK_WDT1			71
+#define TCLK_WDT1			72
+#define PCLK_MAILBOX			73
+#define PCLK_INTMUX			74
+#define PCLK_SPINLOCK			75
+#define PCLK_DDRC			76
+#define HCLK_DDRPHY			77
+#define PCLK_DDRMON			78
+#define CLK_DDRMON_OSC			79
+#define PCLK_STDBY			80
+#define HCLK_USBOTG0			81
+#define HCLK_USBOTG0_PMU		82
+#define CLK_USBOTG0_ADP			83
+#define HCLK_USBOTG1			84
+#define HCLK_USBOTG1_PMU		85
+#define CLK_USBOTG1_ADP			86
+#define PCLK_USBPHY			87
+#define ACLK_DMA2DDR			88
+#define PCLK_DMA2DDR			89
+#define STCLK_M0			90
+#define CLK_DDRPHY			91
+#define CLK_DDRC_SRC			92
+#define ACLK_DDRC_0			93
+#define ACLK_DDRC_1			94
+#define CLK_DDRC			95
+#define CLK_DDRMON			96
+#define HCLK_LSPERI_ROOT		97
+#define PCLK_LSPERI_ROOT		98
+#define PCLK_UART0			99
+#define PCLK_UART1			100
+#define PCLK_UART2			101
+#define PCLK_UART3			102
+#define PCLK_UART4			103
+#define SCLK_UART0			104
+#define SCLK_UART1			105
+#define SCLK_UART2			106
+#define SCLK_UART3			107
+#define SCLK_UART4			108
+#define PCLK_I2C0			109
+#define CLK_I2C0			110
+#define PCLK_I2C1			111
+#define CLK_I2C1			112
+#define PCLK_I2C2			113
+#define CLK_I2C2			114
+#define PCLK_PWM1			115
+#define CLK_PWM1			116
+#define CLK_OSC_PWM1			117
+#define CLK_RC_PWM1			118
+#define CLK_FREQ_PWM1			119
+#define CLK_COUNTER_PWM1		120
+#define PCLK_SPI0			121
+#define CLK_SPI0			122
+#define PCLK_SPI1			123
+#define CLK_SPI1			124
+#define PCLK_GPIO2			125
+#define DBCLK_GPIO2			126
+#define PCLK_GPIO3			127
+#define DBCLK_GPIO3			128
+#define PCLK_GPIO4			129
+#define DBCLK_GPIO4			130
+#define HCLK_CAN0			131
+#define CLK_CAN0			132
+#define HCLK_CAN1			133
+#define CLK_CAN1			134
+#define HCLK_PDM			135
+#define MCLK_PDM			136
+#define CLKOUT_PDM			137
+#define MCLK_SPDIFTX			138
+#define HCLK_SPDIFTX			139
+#define HCLK_SPDIFRX			140
+#define MCLK_SPDIFRX			141
+#define MCLK_SAI0			142
+#define HCLK_SAI0			143
+#define MCLK_OUT_SAI0			144
+#define MCLK_SAI1			145
+#define HCLK_SAI1			146
+#define MCLK_OUT_SAI1			147
+#define HCLK_ASRC0			148
+#define CLK_ASRC0			149
+#define HCLK_ASRC1			150
+#define CLK_ASRC1			151
+#define PCLK_CRU			152
+#define PCLK_PMU_ROOT			153
+#define MCLK_ASRC0			154
+#define MCLK_ASRC1			155
+#define MCLK_ASRC2			156
+#define MCLK_ASRC3			157
+#define LRCK_ASRC0_SRC			158
+#define LRCK_ASRC0_DST			159
+#define LRCK_ASRC1_SRC			160
+#define LRCK_ASRC1_DST			161
+#define ACLK_HSPERI_ROOT		162
+#define HCLK_HSPERI_ROOT		163
+#define PCLK_HSPERI_ROOT		164
+#define CCLK_SRC_SDMMC			165
+#define HCLK_SDMMC			166
+#define HCLK_FSPI			167
+#define SCLK_FSPI			168
+#define PCLK_SPI2			169
+#define ACLK_MAC0			170
+#define ACLK_MAC1			171
+#define PCLK_MAC0			172
+#define PCLK_MAC1			173
+#define CLK_MAC_ROOT			174
+#define CLK_MAC0			175
+#define CLK_MAC1			176
+#define MCLK_SAI2			177
+#define HCLK_SAI2			178
+#define MCLK_OUT_SAI2			179
+#define MCLK_SAI3_SRC			180
+#define HCLK_SAI3			181
+#define MCLK_SAI3			182
+#define MCLK_OUT_SAI3			183
+#define MCLK_SAI4_SRC			184
+#define HCLK_SAI4			185
+#define MCLK_SAI4			186
+#define HCLK_DSM			187
+#define MCLK_DSM			188
+#define PCLK_AUDIO_ADC			189
+#define MCLK_AUDIO_ADC			190
+#define MCLK_AUDIO_ADC_DIV4		191
+#define PCLK_SARADC			192
+#define CLK_SARADC			193
+#define PCLK_OTPC_NS			194
+#define CLK_SBPI_OTPC_NS		195
+#define CLK_USER_OTPC_NS		196
+#define PCLK_UART5			197
+#define SCLK_UART5			198
+#define PCLK_GPIO234_IOC		199
+#define CLK_MAC_PTP_ROOT		200
+#define CLK_MAC0_PTP			201
+#define CLK_MAC1_PTP			202
+#define CLK_SPI2			203
+#define ACLK_VIO_ROOT			204
+#define HCLK_VIO_ROOT			205
+#define PCLK_VIO_ROOT			206
+#define HCLK_RGA			207
+#define ACLK_RGA			208
+#define CLK_CORE_RGA			209
+#define ACLK_VOP			210
+#define HCLK_VOP			211
+#define DCLK_VOP			212
+#define PCLK_DPHY			213
+#define PCLK_DSI_HOST			214
+#define PCLK_TSADC			215
+#define CLK_TSADC			216
+#define CLK_TSADC_TSEN			217
+#define PCLK_GPIO1_IOC			218
+#define PCLK_OTPC_S			219
+#define CLK_SBPI_OTPC_S			220
+#define CLK_USER_OTPC_S			221
+#define PCLK_OTP_MASK			222
+#define PCLK_KEYREADER			223
+#define HCLK_BOOTROM			224
+#define PCLK_DDR_SERVICE		225
+#define HCLK_CRYPTO_S			226
+#define HCLK_KEYLAD			227
+#define CLK_CORE_CRYPTO			228
+#define CLK_PKA_CRYPTO			229
+#define CLK_CORE_CRYPTO_S		230
+#define CLK_PKA_CRYPTO_S		231
+#define ACLK_CRYPTO_S			232
+#define HCLK_RNG_S			233
+#define CLK_CORE_CRYPTO_NS		234
+#define CLK_PKA_CRYPTO_NS		235
+#define ACLK_CRYPTO_NS			236
+#define HCLK_CRYPTO_NS			237
+#define HCLK_RNG			238
+#define CLK_PMU				239
+#define PCLK_PMU			240
+#define CLK_PMU_32K			241
+#define PCLK_PMU_CRU			242
+#define PCLK_PMU_GRF			243
+#define PCLK_GPIO0_IOC			244
+#define PCLK_GPIO0			245
+#define DBCLK_GPIO0			246
+#define PCLK_GPIO1_SHADOW		247
+#define DBCLK_GPIO1_SHADOW		248
+#define PCLK_PMU_HP_TIMER		249
+#define CLK_PMU_HP_TIMER		250
+#define CLK_PMU_HP_TIMER_32K		251
+#define PCLK_PWM0			252
+#define CLK_PWM0			253
+#define CLK_OSC_PWM0			254
+#define CLK_RC_PWM0			255
+#define CLK_MAC_OUT			256
+#define CLK_REF_OUT0			257
+#define CLK_REF_OUT1			258
+#define CLK_32K_FRAC			259
+#define CLK_32K_RC			260
+#define CLK_32K				261
+#define CLK_32K_PMU			262
+#define PCLK_TOUCH_KEY			263
+#define CLK_TOUCH_KEY			264
+#define CLK_REF_PHY_PLL			265
+#define CLK_REF_PHY_PMU_MUX		266
+#define CLK_WIFI_OUT			267
+#define CLK_V0PLL_REF			268
+#define CLK_V1PLL_REF			269
+#define CLK_32K_FRAC_MUX		270
+
+#endif
diff --git a/include/dt-bindings/reset/rockchip,rk3506-cru.h b/include/dt-bindings/reset/rockchip,rk3506-cru.h
new file mode 100644
index 000000000000..31c0d4aa410f
--- /dev/null
+++ b/include/dt-bindings/reset/rockchip,rk3506-cru.h
@@ -0,0 +1,211 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2023-2025 Rockchip Electronics Co., Ltd.
+ * Author: Finley Xiao <finley.xiao at rock-chips.com>
+ */
+
+#ifndef _DT_BINDINGS_REST_ROCKCHIP_RK3506_H
+#define _DT_BINDINGS_REST_ROCKCHIP_RK3506_H
+
+/* CRU-->SOFTRST_CON00 */
+#define SRST_NCOREPORESET0_AC	0
+#define SRST_NCOREPORESET1_AC	1
+#define SRST_NCOREPORESET2_AC	2
+#define SRST_NCORESET0_AC	3
+#define SRST_NCORESET1_AC	4
+#define SRST_NCORESET2_AC	5
+#define SRST_NL2RESET_AC	6
+#define SRST_A_CORE_BIU_AC	7
+#define SRST_H_M0_AC		8
+
+/* CRU-->SOFTRST_CON02 */
+#define SRST_NDBGRESET		9
+#define SRST_P_CORE_BIU		10
+#define SRST_PMU		11
+
+/* CRU-->SOFTRST_CON03 */
+#define SRST_P_DBG		12
+#define SRST_POT_DBG		13
+#define SRST_P_CORE_GRF		14
+#define SRST_CORE_EMA_DETECT	15
+#define SRST_REF_PVTPLL_CORE	16
+#define SRST_P_GPIO1		17
+#define SRST_DB_GPIO1		18
+
+/* CRU-->SOFTRST_CON04 */
+#define SRST_A_CORE_PERI_BIU	19
+#define SRST_A_DSMC		20
+#define SRST_P_DSMC		21
+#define SRST_FLEXBUS		22
+#define SRST_A_FLEXBUS		23
+#define SRST_H_FLEXBUS		24
+#define SRST_A_DSMC_SLV		25
+#define SRST_H_DSMC_SLV		26
+#define SRST_DSMC_SLV		27
+
+/* CRU-->SOFTRST_CON05 */
+#define SRST_A_BUS_BIU		28
+#define SRST_H_BUS_BIU		29
+#define SRST_P_BUS_BIU		30
+#define SRST_A_SYSRAM		31
+#define SRST_H_SYSRAM		32
+#define SRST_A_DMAC0		33
+#define SRST_A_DMAC1		34
+#define SRST_H_M0		35
+#define SRST_M0_JTAG		36
+#define SRST_H_CRYPTO		37
+
+/* CRU-->SOFTRST_CON06 */
+#define SRST_H_RNG		38
+#define SRST_P_BUS_GRF		39
+#define SRST_P_TIMER0		40
+#define SRST_TIMER0_CH0		41
+#define SRST_TIMER0_CH1		42
+#define SRST_TIMER0_CH2		43
+#define SRST_TIMER0_CH3		44
+#define SRST_TIMER0_CH4		45
+#define SRST_TIMER0_CH5		46
+#define SRST_P_WDT0		47
+#define SRST_T_WDT0		48
+#define SRST_P_WDT1		49
+#define SRST_T_WDT1		50
+#define SRST_P_MAILBOX		51
+#define SRST_P_INTMUX		52
+#define SRST_P_SPINLOCK		53
+
+/* CRU-->SOFTRST_CON07 */
+#define SRST_P_DDRC		54
+#define SRST_H_DDRPHY		55
+#define SRST_P_DDRMON		56
+#define SRST_DDRMON_OSC		57
+#define SRST_P_DDR_LPC		58
+#define SRST_H_USBOTG0		59
+#define SRST_USBOTG0_ADP	60
+#define SRST_H_USBOTG1		61
+#define SRST_USBOTG1_ADP	62
+#define SRST_P_USBPHY		63
+#define SRST_USBPHY_POR		64
+#define SRST_USBPHY_OTG0	65
+#define SRST_USBPHY_OTG1	66
+
+/* CRU-->SOFTRST_CON08 */
+#define SRST_A_DMA2DDR		67
+#define SRST_P_DMA2DDR		68
+
+/* CRU-->SOFTRST_CON09 */
+#define SRST_USBOTG0_UTMI	69
+#define SRST_USBOTG1_UTMI	70
+
+/* CRU-->SOFTRST_CON10 */
+#define SRST_A_DDRC_0		71
+#define SRST_A_DDRC_1		72
+#define SRST_A_DDR_BIU		73
+#define SRST_DDRC		74
+#define SRST_DDRMON		75
+
+/* CRU-->SOFTRST_CON11 */
+#define SRST_H_LSPERI_BIU	76
+#define SRST_P_UART0		77
+#define SRST_P_UART1		78
+#define SRST_P_UART2		79
+#define SRST_P_UART3		80
+#define SRST_P_UART4		81
+#define SRST_UART0		82
+#define SRST_UART1		83
+#define SRST_UART2		84
+#define SRST_UART3		85
+#define SRST_UART4		86
+#define SRST_P_I2C0		87
+#define SRST_I2C0		88
+
+/* CRU-->SOFTRST_CON12 */
+#define SRST_P_I2C1		89
+#define SRST_I2C1		90
+#define SRST_P_I2C2		91
+#define SRST_I2C2		92
+#define SRST_P_PWM1		93
+#define SRST_PWM1		94
+#define SRST_P_SPI0		95
+#define SRST_SPI0		96
+#define SRST_P_SPI1		97
+#define SRST_SPI1		98
+#define SRST_P_GPIO2		99
+#define SRST_DB_GPIO2		100
+
+/* CRU-->SOFTRST_CON13 */
+#define SRST_P_GPIO3		101
+#define SRST_DB_GPIO3		102
+#define SRST_P_GPIO4		103
+#define SRST_DB_GPIO4		104
+#define SRST_H_CAN0		105
+#define SRST_CAN0		106
+#define SRST_H_CAN1		107
+#define SRST_CAN1		108
+#define SRST_H_PDM		109
+#define SRST_M_PDM		110
+#define SRST_PDM		111
+#define SRST_SPDIFTX		112
+#define SRST_H_SPDIFTX		113
+#define SRST_H_SPDIFRX		114
+#define SRST_SPDIFRX		115
+#define SRST_M_SAI0		116
+
+/* CRU-->SOFTRST_CON14 */
+#define SRST_H_SAI0		117
+#define SRST_M_SAI1		118
+#define SRST_H_SAI1		119
+#define SRST_H_ASRC0		120
+#define SRST_ASRC0		121
+#define SRST_H_ASRC1		122
+#define SRST_ASRC1		123
+
+/* CRU-->SOFTRST_CON17 */
+#define SRST_H_HSPERI_BIU	124
+#define SRST_H_SDMMC		125
+#define SRST_H_FSPI		126
+#define SRST_S_FSPI		127
+#define SRST_P_SPI2		128
+#define SRST_A_MAC0		129
+#define SRST_A_MAC1		130
+
+/* CRU-->SOFTRST_CON18 */
+#define SRST_M_SAI2		131
+#define SRST_H_SAI2		132
+#define SRST_H_SAI3		133
+#define SRST_M_SAI3		134
+#define SRST_H_SAI4		135
+#define SRST_M_SAI4		136
+#define SRST_H_DSM		137
+#define SRST_M_DSM		138
+#define SRST_P_AUDIO_ADC	139
+#define SRST_M_AUDIO_ADC	140
+
+/* CRU-->SOFTRST_CON19 */
+#define SRST_P_SARADC		141
+#define SRST_SARADC		142
+#define SRST_SARADC_PHY		143
+#define SRST_P_OTPC_NS		144
+#define SRST_SBPI_OTPC_NS	145
+#define SRST_USER_OTPC_NS	146
+#define SRST_P_UART5		147
+#define SRST_UART5		148
+#define SRST_P_GPIO234_IOC	149
+
+/* CRU-->SOFTRST_CON21 */
+#define SRST_A_VIO_BIU		150
+#define SRST_H_VIO_BIU		151
+#define SRST_H_RGA		152
+#define SRST_A_RGA		153
+#define SRST_CORE_RGA		154
+#define SRST_A_VOP		155
+#define SRST_H_VOP		156
+#define SRST_VOP		157
+#define SRST_P_DPHY		158
+#define SRST_P_DSI_HOST		159
+#define SRST_P_TSADC		160
+#define SRST_TSADC		161
+
+/* CRU-->SOFTRST_CON22 */
+#define SRST_P_GPIO1_IOC	162
+
+#endif
-- 
2.34.1



From hans.zhang at cixtech.com  Tue Nov 11 18:49:47 2025
From: hans.zhang at cixtech.com (Hans Zhang)
Date: Wed, 12 Nov 2025 10:49:47 +0800
Subject: [PATCH 3/4] PCI: dw-rockchip: Configure L1sub support
In-Reply-To: <20251111221621.2208606-4-helgaas@kernel.org>
References: <20251111221621.2208606-1-helgaas@kernel.org>
 <20251111221621.2208606-4-helgaas@kernel.org>
Message-ID: <e8ef529b-b2e9-4c39-8137-60795fda7773@cixtech.com>



On 11/12/2025 6:16 AM, Bjorn Helgaas wrote:
> EXTERNAL EMAIL
> 
> From: Shawn Lin <shawn.lin at rock-chips.com>
> 
> L1 PM Substates for RC mode require support in the dw-rockchip driver
> including proper handling of the CLKREQ# sideband signal. It is mostly
> handled by hardware, but software still needs to set the clkreq fields
> in the PCIE_CLIENT_POWER_CON register to match the hardware implementation.
> 
> For more details, see section '18.6.6.4 L1 Substate' in the RK3658 TRM 1.1
> Part 2, or section '11.6.6.4 L1 Substate' in the RK3588 TRM 1.0 Part2.
> 
> Meanwhile, for the EP mode, we haven't prepared enough to actually support
> L1 PM Substates yet. So disable it now until proper support is added later.
> 
> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
> [bhelgaas: set pci->l1ss_support so DWC core preserves L1SS Capability bits;
> drop corresponding code here]
> Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
> Link: https://patch.msgid.link/1761187883-150120-1-git-send-email-shawn.lin at rock-chips.com


Reviewed-by: Hans Zhang <hans.zhang at cixtech.com>

Best regards,
Hans

> ---
>   drivers/pci/controller/dwc/pcie-dw-rockchip.c | 38 +++++++++++++++++++
>   1 file changed, 38 insertions(+)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> index 3e2752c7dd09..62a095752833 100644
> --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> @@ -62,6 +62,12 @@
>   /* Interrupt Mask Register Related to Miscellaneous Operation */
>   #define PCIE_CLIENT_INTR_MASK_MISC     0x24
> 
> +/* Power Management Control Register */
> +#define PCIE_CLIENT_POWER_CON          0x2c
> +#define  PCIE_CLKREQ_READY             FIELD_PREP_WM16(BIT(0), 1)
> +#define  PCIE_CLKREQ_NOT_READY         FIELD_PREP_WM16(BIT(0), 0)
> +#define  PCIE_CLKREQ_PULL_DOWN         FIELD_PREP_WM16(GENMASK(13, 12), 1)
> +
>   /* Hot Reset Control Register */
>   #define PCIE_CLIENT_HOT_RESET_CTRL     0x180
>   #define  PCIE_LTSSM_APP_DLY2_EN                BIT(1)
> @@ -85,6 +91,7 @@ struct rockchip_pcie {
>          struct regulator *vpcie3v3;
>          struct irq_domain *irq_domain;
>          const struct rockchip_pcie_of_data *data;
> +       bool supports_clkreq;
>   };
> 
>   struct rockchip_pcie_of_data {
> @@ -200,6 +207,32 @@ static bool rockchip_pcie_link_up(struct dw_pcie *pci)
>          return FIELD_GET(PCIE_LINKUP_MASK, val) == PCIE_LINKUP;
>   }
> 
> +/*
> + * See e.g. section '11.6.6.4 L1 Substate' in the RK3588 TRM V1.0 for the steps
> + * needed to support L1 substates. Currently, just enable L1 substates for RC
> + * mode if CLKREQ# is properly connected and supports-clkreq is present in DT.
> + * For EP mode, there are more things should be done to actually save power in
> + * L1 substates, so disable L1 substates until there is proper support.
> + */
> +static void rockchip_pcie_configure_l1sub(struct dw_pcie *pci)
> +{
> +       struct rockchip_pcie *rockchip = to_rockchip_pcie(pci);
> +
> +       /* Enable L1 substates if CLKREQ# is properly connected */
> +       if (rockchip->supports_clkreq &&
> +           rockchip->data->mode == DW_PCIE_RC_TYPE ) {
> +               rockchip_pcie_writel_apb(rockchip, PCIE_CLKREQ_READY,
> +                                        PCIE_CLIENT_POWER_CON);
> +               pci->l1ss_support = true;
> +               return;
> +       }
> +
> +       /* Otherwise, pull down CLKREQ# */
> +       rockchip_pcie_writel_apb(rockchip,
> +                                PCIE_CLKREQ_PULL_DOWN | PCIE_CLKREQ_NOT_READY,
> +                                PCIE_CLIENT_POWER_CON);
> +}
> +
>   static void rockchip_pcie_enable_l0s(struct dw_pcie *pci)
>   {
>          u32 cap, lnkcap;
> @@ -264,6 +297,7 @@ static int rockchip_pcie_host_init(struct dw_pcie_rp *pp)
>          irq_set_chained_handler_and_data(irq, rockchip_pcie_intx_handler,
>                                           rockchip);
> 
> +       rockchip_pcie_configure_l1sub(pci);
>          rockchip_pcie_enable_l0s(pci);
> 
>          return 0;
> @@ -301,6 +335,7 @@ static void rockchip_pcie_ep_init(struct dw_pcie_ep *ep)
>          struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
>          enum pci_barno bar;
> 
> +       rockchip_pcie_configure_l1sub(pci);
>          rockchip_pcie_enable_l0s(pci);
>          rockchip_pcie_ep_hide_broken_ats_cap_rk3588(ep);
> 
> @@ -412,6 +447,9 @@ static int rockchip_pcie_resource_get(struct platform_device *pdev,
>                  return dev_err_probe(&pdev->dev, PTR_ERR(rockchip->rst),
>                                       "failed to get reset lines\n");
> 
> +       rockchip->supports_clkreq = of_property_read_bool(pdev->dev.of_node,
> +                                                         "supports-clkreq");
> +
>          return 0;
>   }
> 
> --
> 2.43.0
> 



From chaoyi.chen at rock-chips.com  Tue Nov 11 18:50:57 2025
From: chaoyi.chen at rock-chips.com (Chaoyi Chen)
Date: Wed, 12 Nov 2025 10:50:57 +0800
Subject: [PATCH v9 04/10] dt-bindings: phy: rockchip: rk3399-typec-phy:
 Support mode-switch
In-Reply-To: <868f09fd-8fe8-4c01-952f-6317604c43a3@kernel.org>
References: <20251111105040.94-1-kernel@airkyi.com>
 <20251111105040.94-5-kernel@airkyi.com>
 <868f09fd-8fe8-4c01-952f-6317604c43a3@kernel.org>
Message-ID: <d4861ef9-a25c-491c-9a00-d65fe75d2677@rock-chips.com>

On 11/11/2025 7:09 PM, Krzysztof Kozlowski wrote:

> On 11/11/2025 11:50, Chaoyi Chen wrote:
>> While an external Type-C controller is still required to detect cable
>> attachment and report USB PD events, the actual mode and orientation
>> switching is performed internally by the PHY through software
>> configuration. This allows the PHY to act as a Type-C multiplexer for
>> both data role and DP altmode configuration.
>>
>> To reflect this hardware design, this patch introduces a new
>> "mode-switch" property for the dp-port node in the device tree bindings.
>> This property indicates that the connected PHY is capable of handling
>> Type-C mode switching itself.
>>
>> Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
>>
>> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> There are never blank lines between tags.
>
Sorry for that. I will pay attention to this in future submissions.

-- 
Best,
Chaoyi



From naoki at radxa.com  Tue Nov 11 19:51:32 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Wed, 12 Nov 2025 03:51:32 +0000
Subject: [PATCH v2 4/4] arm64: dts: rockchip: Make eeprom read-only for Radxa ROCK 3C/5A/5C
In-Reply-To: <20251112035133.28753-1-naoki@radxa.com>
References: <20251112035133.28753-1-naoki@radxa.com>
Message-ID: <20251112035133.28753-5-naoki@radxa.com>

Make the BL24C16 EEPROM chips found on Radxa ROCK 3C, 5A and 5C SBCs
read-only, [1] [2] [3] because they contain factory-programmed data
that isn't supposed to be modified by the end users. [4]

[1] https://dl.radxa.com/rock3/docs/hw/3c/v1400/radxa_rock_3c_v1400_schematic.pdf p.13
[2] https://dl.radxa.com/rock5/5a/docs/hw/radxa_rock5a_V1.1_sch.pdf p.19
[3] https://dl.radxa.com/rock5/5c/docs/hw/v1100/radxa_rock_5c_schematic_v1100.pdf p.18
[4] https://github.com/radxa/u-boot/blob/next-dev-v2024.10/drivers/misc/radxa-i2c-eeprom.c

Fixes: ee219017ddb50 ("arm64: dts: rockchip: Add Radxa ROCK 3C")
Fixes: 89c880808cff8 ("arm64: dts: rockchip: add I2C EEPROM to rock-5a")
Fixes: 3ddf5cdb77e6e ("arm64: dts: rockchip: add Radxa ROCK 5C")
Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
Changes in v2:
- Reword commit message (Dragan Simic)
---
 arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts  | 1 +
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 1 +
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts | 1 +
 3 files changed, 3 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
index 80ac40555e023..fa28b32f69108 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
@@ -466,6 +466,7 @@ eeprom: eeprom at 50 {
 		compatible = "belling,bl24c16a", "atmel,24c16";
 		reg = <0x50>;
 		pagesize = <16>;
+		read-only;
 		vcc-supply = <&vcca1v8_pmu>;
 	};
 };
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
index 041a0fff22ccb..d844a842d4cce 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
@@ -233,6 +233,7 @@ eeprom: eeprom at 50 {
 		compatible = "belling,bl24c16a", "atmel,24c16";
 		reg = <0x50>;
 		pagesize = <16>;
+		read-only;
 		vcc-supply = <&vcc_3v3_pmu>;
 	};
 };
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
index dd7317bab6135..665eecce063a8 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
@@ -325,6 +325,7 @@ eeprom at 50 {
 		compatible = "belling,bl24c16a", "atmel,24c16";
 		reg = <0x50>;
 		pagesize = <16>;
+		read-only;
 		vcc-supply = <&vcc_3v3_pmu>;
 	};
 };
-- 
2.43.0



From naoki at radxa.com  Tue Nov 11 19:51:30 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Wed, 12 Nov 2025 03:51:30 +0000
Subject: [PATCH v2 2/4] arm64: dts: rockchip: Add eeprom vcc-supply for Radxa ROCK 5A
In-Reply-To: <20251112035133.28753-1-naoki@radxa.com>
References: <20251112035133.28753-1-naoki@radxa.com>
Message-ID: <20251112035133.28753-3-naoki@radxa.com>

The VCC supply for the BL24C16 EEPROM chip found on Radxa ROCK 5A is
vcc_3v3_pmu, which is routed to vcc_3v3_s3 via a zero-ohm resistor. [1]
Describe this supply.

[1] https://dl.radxa.com/rock5/5a/docs/hw/radxa_rock5a_V1.1_sch.pdf p.4, p.19

Fixes: 89c880808cff8 ("arm64: dts: rockchip: add I2C EEPROM to rock-5a")
Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
Changes in v2:
- Reword commit message (Dragan Simic)
---
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
index 428c6f0232a34..041a0fff22ccb 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
@@ -233,6 +233,7 @@ eeprom: eeprom at 50 {
 		compatible = "belling,bl24c16a", "atmel,24c16";
 		reg = <0x50>;
 		pagesize = <16>;
+		vcc-supply = <&vcc_3v3_pmu>;
 	};
 };
 
@@ -600,7 +601,7 @@ regulator-state-mem {
 				};
 			};
 
-			vcc_3v3_s3: dcdc-reg8 {
+			vcc_3v3_pmu: vcc_3v3_s3: dcdc-reg8 {
 				regulator-name = "vcc_3v3_s3";
 				regulator-always-on;
 				regulator-boot-on;
-- 
2.43.0



From naoki at radxa.com  Tue Nov 11 19:51:28 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Wed, 12 Nov 2025 03:51:28 +0000
Subject: [PATCH v2 0/4] Fix and improve EEPROM chip descriptions for Radxa ROCK 3C, 5A and 5C
Message-ID: <20251112035133.28753-1-naoki@radxa.com>

This patch series fixes incorrect or missing entries related to the
eeprom on the Radxa ROCK 3C, 5A, and 5C.

FUKAUMI Naoki (4):
  arm64: dts: rockchip: Move the EEPROM to correct I2C bus on Radxa ROCK
    5A
  arm64: dts: rockchip: Add eeprom vcc-supply for Radxa ROCK 5A
  arm64: dts: rockchip: Add eeprom vcc-supply for Radxa ROCK 3C
  arm64: dts: rockchip: Make eeprom read-only for Radxa ROCK 3C/5A/5C

 arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts  |  2 ++
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 16 +++++++++-------
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts |  1 +
 3 files changed, 12 insertions(+), 7 deletions(-)

-- 
2.43.0



From naoki at radxa.com  Tue Nov 11 19:51:31 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Wed, 12 Nov 2025 03:51:31 +0000
Subject: [PATCH v2 3/4] arm64: dts: rockchip: Add eeprom vcc-supply for Radxa ROCK 3C
In-Reply-To: <20251112035133.28753-1-naoki@radxa.com>
References: <20251112035133.28753-1-naoki@radxa.com>
Message-ID: <20251112035133.28753-4-naoki@radxa.com>

The VCC supply for the BL24C16 EEPROM chip found on Radxa ROCK 3C is
vcca1v8_pmu. [1] Describe this supply.

[1] https://dl.radxa.com/rock3/docs/hw/3c/v1400/radxa_rock_3c_v1400_schematic.pdf p.13

Fixes: ee219017ddb50 ("arm64: dts: rockchip: Add Radxa ROCK 3C")
Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
Changes in v2:
- Reword commit message (Dragan Simic)
---
 arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
index 6224d72813e59..80ac40555e023 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
@@ -466,6 +466,7 @@ eeprom: eeprom at 50 {
 		compatible = "belling,bl24c16a", "atmel,24c16";
 		reg = <0x50>;
 		pagesize = <16>;
+		vcc-supply = <&vcca1v8_pmu>;
 	};
 };
 
-- 
2.43.0



From naoki at radxa.com  Tue Nov 11 19:51:29 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Wed, 12 Nov 2025 03:51:29 +0000
Subject: [PATCH v2 1/4] arm64: dts: rockchip: Move the EEPROM to correct I2C bus on Radxa ROCK 5A
In-Reply-To: <20251112035133.28753-1-naoki@radxa.com>
References: <20251112035133.28753-1-naoki@radxa.com>
Message-ID: <20251112035133.28753-2-naoki@radxa.com>

The BL24C16 EEPROM chip found on Radxa ROCK 5A is connected to the
i2c0 bus, [1] so move the eeprom node from the i2c2 bus to the i2c0
bus.

[1] Link: https://dl.radxa.com/rock5/5a/docs/hw/radxa_rock5a_V1.1_sch.pdf p.19

Fixes: 89c880808cff8 ("arm64: dts: rockchip: add I2C EEPROM to rock-5a")
Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
Changes in v2:
- Reword commit message (Dragan Simic)
---
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
index 19a08f7794e67..428c6f0232a34 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
@@ -228,6 +228,12 @@ regulator-state-mem {
 			regulator-off-in-suspend;
 		};
 	};
+
+	eeprom: eeprom at 50 {
+		compatible = "belling,bl24c16a", "atmel,24c16";
+		reg = <0x50>;
+		pagesize = <16>;
+	};
 };
 
 &i2c2 {
@@ -249,12 +255,6 @@ regulator-state-mem {
 			regulator-off-in-suspend;
 		};
 	};
-
-	eeprom: eeprom at 50 {
-		compatible = "belling,bl24c16a", "atmel,24c16";
-		reg = <0x50>;
-		pagesize = <16>;
-	};
 };
 
 &i2c3 {
-- 
2.43.0



From shawn.lin at rock-chips.com  Tue Nov 11 23:44:20 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Wed, 12 Nov 2025 15:44:20 +0800
Subject: [PATCH 2/2] mmc: sdhci-of-dwcmshc: reduce CIT for better performance
In-Reply-To: <1762933460-204066-1-git-send-email-shawn.lin@rock-chips.com>
References: <1762933460-204066-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1762933460-204066-2-git-send-email-shawn.lin@rock-chips.com>

CQHCI_SSC1.CIT indicates to the CQE the polling period to use for
periodic SEND_QUEUE_STATUS (CMD13) polling. Some eMMCs have only one
hardware queue, and CMD13 can only query one slot at a time for data
transmission, which cannot be processed in parallel. Modifying the
CMD13 query interval can increase the query frequency and improve
random write performance.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
---

 drivers/mmc/host/cqhci.h            | 1 +
 drivers/mmc/host/sdhci-of-dwcmshc.c | 5 +++++
 2 files changed, 6 insertions(+)

diff --git a/drivers/mmc/host/cqhci.h b/drivers/mmc/host/cqhci.h
index ce189a1..3668856 100644
--- a/drivers/mmc/host/cqhci.h
+++ b/drivers/mmc/host/cqhci.h
@@ -93,6 +93,7 @@
 /* send status config 1 */
 #define CQHCI_SSC1			0x40
 #define CQHCI_SSC1_CBC_MASK		GENMASK(19, 16)
+#define CQHCI_SSC1_CIT_MASK		GENMASK(15, 0)
 
 /* send status config 2 */
 #define CQHCI_SSC2			0x44
diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c
index e276a4e..cad5165 100644
--- a/drivers/mmc/host/sdhci-of-dwcmshc.c
+++ b/drivers/mmc/host/sdhci-of-dwcmshc.c
@@ -631,6 +631,11 @@ static void rk35xx_sdhci_cqe_pre_enable(struct mmc_host *mmc)
 	struct dwcmshc_priv *dwc_priv = sdhci_pltfm_priv(pltfm_host);
 	u32 reg;
 
+	/* Set Send Status Command Idle Timer to 10.66us (256 * 1 / 24) */
+	reg = sdhci_readl(host, dwc_priv->vendor_specific_area2 + CQHCI_SSC1);
+	reg = (reg & ~CQHCI_SSC1_CIT_MASK) | 0x0100;
+	sdhci_writel(host, reg, dwc_priv->vendor_specific_area2 + CQHCI_SSC1);
+
 	reg = sdhci_readl(host, dwc_priv->vendor_specific_area2 + CQHCI_CFG);
 	reg |= CQHCI_ENABLE;
 	sdhci_writel(host, reg, dwc_priv->vendor_specific_area2 + CQHCI_CFG);
-- 
2.7.4



From shawn.lin at rock-chips.com  Tue Nov 11 23:44:19 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Wed, 12 Nov 2025 15:44:19 +0800
Subject: [PATCH 1/2] mmc: sdhci-of-dwcmshc: Disable internal clock auto gate for Rockchip SOCs
Message-ID: <1762933460-204066-1-git-send-email-shawn.lin@rock-chips.com>

Enabling CMDQ support can lead to random occurrences of the error log when
there are RPMB access and data flush executed:

"mmc2: Timeout waiting for hardware interrupt."

Enabling CMDQ and then issuing a DCMD as the final command before disabling
it causes the eMMC controller to auto-gate its internal clock. Chip simulation
shows this results in a state machine mismatch after CMDQ mode exit, triggering
data-timeout errors for all subsequent read and write operations.

Therefore, the auto-clock-gate function must be disabled whenever CMDQ is
enabled.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
---

 drivers/mmc/host/sdhci-of-dwcmshc.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c
index c66a8df..e276a4e 100644
--- a/drivers/mmc/host/sdhci-of-dwcmshc.c
+++ b/drivers/mmc/host/sdhci-of-dwcmshc.c
@@ -713,10 +713,11 @@ static void dwcmshc_rk3568_set_clock(struct sdhci_host *host, unsigned int clock
 
 	sdhci_set_clock(host, clock);
 
-	/* Disable cmd conflict check */
+	/* Disable cmd conflict check and internal clock gate */
 	reg = dwc_priv->vendor_specific_area1 + DWCMSHC_HOST_CTRL3;
 	extra = sdhci_readl(host, reg);
 	extra &= ~BIT(0);
+	extra |= BIT(4);
 	sdhci_writel(host, extra, reg);
 
 	if (clock <= 52000000) {
-- 
2.7.4



From geraldogabriel at gmail.com  Wed Nov 12 00:03:19 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Wed, 12 Nov 2025 05:03:19 -0300
Subject: [PATCH] arm64: dts: rockchip: align bindings to PCIe spec
In-Reply-To: <AGsAmwCFJj0ZQ4vKzrqC84rs.3.1762847224180.Hmail.ye.zhang@rock-chips.com>
References: <4b5ffcccfef2a61838aa563521672a171acb27b2.1762321976.git.geraldogabriel@gmail.com>
 <ba120577-42da-424d-8102-9d085c1494c8@rock-chips.com>
 <aQsIXcQzeYop6a0B@geday>
 <67b605b0-7046-448a-bc9b-d3ac56333809@rock-chips.com>
 <aQ1c7ZDycxiOIy8Y@geday>
 <d9e257bd-806c-48b4-bb22-f1342e9fc15a@rock-chips.com>
 <aRLEbfsmXnGwyigS@geday>
 <AGsAmwCFJj0ZQ4vKzrqC84rs.3.1762847224180.Hmail.ye.zhang@rock-chips.com>
Message-ID: <aRQ_R90S8T82th45@geday>

On Tue, Nov 11, 2025 at 03:47:04PM +0800, ?? wrote:
> Hi Geraldo,
> 
> In standard GPIO operations, the typical practice is to set the output level first before configuring the direction as output. This approach helps avoid outputting an uncertain voltage level at the instant when the direction switches from input to output.

Thanks for the explanation Ye Zhang, it makes sense to me. It avoids the
pin to not be floating so to speak. I kept hammering at this problem, by
the way is PCIe PERST# side-band signal refusing to co-operate and
failing PCIe initial link-training.

You're not going to like this:

diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
index 47174eb3ba76..fea2c55992e8 100644
--- a/drivers/gpio/gpio-rockchip.c
+++ b/drivers/gpio/gpio-rockchip.c
@@ -183,11 +183,13 @@ static int rockchip_gpio_set(struct gpio_chip *gc, unsigned int offset,
 	struct rockchip_pin_bank *bank = gpiochip_get_data(gc);
 	unsigned long flags;
 
+	rockchip_gpio_set_direction(gc, offset, true);
+
 	raw_spin_lock_irqsave(&bank->slock, flags);
 	rockchip_gpio_writel_bit(bank, offset, value, bank->gpio_regs->port_dr);
 	raw_spin_unlock_irqrestore(&bank->slock, flags);
 
-	return 0;
+	return rockchip_gpio_set_direction(gc, offset, false);
 }
 
 static int rockchip_gpio_get(struct gpio_chip *gc, unsigned int offset)

By setting direction INPUT, then writing out, then setting OUTPUT again
miraculously it doesn't fail initial link training, with no other
changes that already have been rejected by PCI folks and Shawn Lin.

Everything works as expected. Is this an explainable behaviour by
Rockchip GPIO core?

The problem I am observing is that once I set PERST# it becomes
unsettable again. So that's why those open-drain/open-source hacks
worked (gpiolib will hack the pull polarity to INPUT).

Thanks,
Geraldo Nascimento

> 
> Additionally, for Rockchip's GPIO controller specifically, setting the level value should not be affected by the direction setting - the data register write should be effective regardless of whether the pin is configured as input or output.


From mahesh.vaidya at altera.com  Wed Nov 12 00:06:09 2025
From: mahesh.vaidya at altera.com (Mahesh Vaidya)
Date: Wed, 12 Nov 2025 13:36:09 +0530
Subject: [PATCH v6 0/2] PCI: Configure Root Port MPS during host probing
In-Reply-To: <20251104165125.174168-1-18255117159@163.com>
References: <20251104165125.174168-1-18255117159@163.com>
Message-ID: <e940eae5-16bb-46e1-83aa-47c6ff747083@altera.com>


On 04-11-2025 22:21, Hans Zhang wrote:
> Current PCIe initialization exhibits a key optimization gap: Root Ports
> may operate with non-optimal Maximum Payload Size (MPS) settings. While
> downstream device configuration is handled during bus enumeration, Root
> Port MPS values inherited from firmware or hardware defaults often fail
> to utilize the full capabilities supported by controller hardware. This
> results in suboptimal data transfer efficiency throughout the PCIe
> hierarchy.
>
> This patch series addresses this by:
>
> 1.  Core PCI enhancement (Patch 1):
> - Proactively configures Root Port MPS during host controller probing
> - Sets initial MPS to hardware maximum (128 << dev->pcie_mpss)
> - Conditional on PCIe bus tuning being enabled (PCIE_BUS_TUNE_OFF unset)
> - Maintains backward compatibility via PCIE_BUS_TUNE_OFF check
> - Preserves standard MPS negotiation during downstream enumeration
>
> 2.  Driver cleanup (Patch 2):
> - Removes redundant MPS configuration from Meson PCIe controller driver
> - Functionality is now centralized in PCI core
> - Simplifies driver maintenance long-term
>
> ---
> Changes for v6:
> - Modify the commit message and comments. (Bjorn)
> - Patch 1/2 code logic: Add !bridge check to configure MPS only for Root Ports
>    without an upstream bridge (root bridges), avoiding incorrect handling of
>    non-root-bridge Root Ports (Niklas).
Tested this patch series on Agilex 7.

Tested-by: Mahesh Vaidya <mahesh.vaidya at altera.com>

>
> Changes for v5:
> https://patchwork.kernel.org/project/linux-pci/patch/20250620155507.1022099-1-18255117159 at 163.com/
>
> - Use pcie_set_mps directly instead of pcie_write_mps.
> - The patch 1 commit message were modified.
>
> Changes for v4:
> https://patchwork.kernel.org/project/linux-pci/patch/20250510155607.390687-1-18255117159 at 163.com/
>
> - The patch [v4 1/2] add a comment to explain why it was done this way.
> - The patch [v4 2/2] have not been modified.
> - Drop patch [v3 3/3]. The Maintainer of the pci-aardvark.c file suggests
>    that this patch cannot be submitted. In addition, Mani also suggests
>    dropping this patch until this series of issues is resolved.
>
> Changes for v3:
> https://patchwork.kernel.org/project/linux-pci/patch/20250506173439.292460-1-18255117159 at 163.com/
>
> - The new split is patch 2/3 and 3/3.
> - Modify the patch 1/3 according to Niklas' suggestion.
>
> Changes for v2:
> https://patchwork.kernel.org/project/linux-pci/patch/20250425095708.32662-1-18255117159 at 163.com/
>
> - According to the Maintainer's suggestion, limit the setting of MPS
>    changes to platforms with controller drivers.
> - Delete the MPS code set by the SOC manufacturer.
> ---
>
> Hans Zhang (2):
>    PCI: Configure Root Port MPS during host probing
>    PCI: dwc: Remove redundant MPS configuration
>
>   drivers/pci/controller/dwc/pci-meson.c | 17 -----------------
>   drivers/pci/probe.c                    | 12 ++++++++++++
>   2 files changed, 12 insertions(+), 17 deletions(-)
>
>
> base-commit: 691d401c7e0e5ea34ac6f8151bc0696db1b2500a


From hans.zhang at cixtech.com  Wed Nov 12 00:16:20 2025
From: hans.zhang at cixtech.com (Hans Zhang)
Date: Wed, 12 Nov 2025 16:16:20 +0800
Subject: [PATCH v6 0/2] PCI: Configure Root Port MPS during host probing
In-Reply-To: <e940eae5-16bb-46e1-83aa-47c6ff747083@altera.com>
References: <20251104165125.174168-1-18255117159@163.com>
 <e940eae5-16bb-46e1-83aa-47c6ff747083@altera.com>
Message-ID: <58b37b3a-7bb7-46bb-8ad4-f4d2f152bf1f@cixtech.com>



On 11/12/2025 4:06 PM, Mahesh Vaidya wrote:
> [You don't often get email from mahesh.vaidya at altera.com. Learn why this 
> is important at https://aka.ms/LearnAboutSenderIdentification ]
> 
> EXTERNAL EMAIL
> 
> On 04-11-2025 22:21, Hans Zhang wrote:
>> Current PCIe initialization exhibits a key optimization gap: Root Ports
>> may operate with non-optimal Maximum Payload Size (MPS) settings. While
>> downstream device configuration is handled during bus enumeration, Root
>> Port MPS values inherited from firmware or hardware defaults often fail
>> to utilize the full capabilities supported by controller hardware. This
>> results in suboptimal data transfer efficiency throughout the PCIe
>> hierarchy.
>>
>> This patch series addresses this by:
>>
>> 1.? Core PCI enhancement (Patch 1):
>> - Proactively configures Root Port MPS during host controller probing
>> - Sets initial MPS to hardware maximum (128 << dev->pcie_mpss)
>> - Conditional on PCIe bus tuning being enabled (PCIE_BUS_TUNE_OFF unset)
>> - Maintains backward compatibility via PCIE_BUS_TUNE_OFF check
>> - Preserves standard MPS negotiation during downstream enumeration
>>
>> 2.? Driver cleanup (Patch 2):
>> - Removes redundant MPS configuration from Meson PCIe controller driver
>> - Functionality is now centralized in PCI core
>> - Simplifies driver maintenance long-term
>>
>> ---
>> Changes for v6:
>> - Modify the commit message and comments. (Bjorn)
>> - Patch 1/2 code logic: Add !bridge check to configure MPS only for 
>> Root Ports
>> ?? without an upstream bridge (root bridges), avoiding incorrect 
>> handling of
>> ?? non-root-bridge Root Ports (Niklas).
> Tested this patch series on Agilex 7.
> 
> Tested-by: Mahesh Vaidya <mahesh.vaidya at altera.com>
> 

Hi Mahesh,

Thank you for your test.

Best regards,
Hans

>>
>> Changes for v5:
>> https://patchwork.kernel.org/project/linux-pci/ 
>> patch/20250620155507.1022099-1-18255117159 at 163.com/
>>
>> - Use pcie_set_mps directly instead of pcie_write_mps.
>> - The patch 1 commit message were modified.
>>
>> Changes for v4:
>> https://patchwork.kernel.org/project/linux-pci/ 
>> patch/20250510155607.390687-1-18255117159 at 163.com/
>>
>> - The patch [v4 1/2] add a comment to explain why it was done this way.
>> - The patch [v4 2/2] have not been modified.
>> - Drop patch [v3 3/3]. The Maintainer of the pci-aardvark.c file suggests
>> ?? that this patch cannot be submitted. In addition, Mani also suggests
>> ?? dropping this patch until this series of issues is resolved.
>>
>> Changes for v3:
>> https://patchwork.kernel.org/project/linux-pci/ 
>> patch/20250506173439.292460-1-18255117159 at 163.com/
>>
>> - The new split is patch 2/3 and 3/3.
>> - Modify the patch 1/3 according to Niklas' suggestion.
>>
>> Changes for v2:
>> https://patchwork.kernel.org/project/linux-pci/ 
>> patch/20250425095708.32662-1-18255117159 at 163.com/
>>
>> - According to the Maintainer's suggestion, limit the setting of MPS
>> ?? changes to platforms with controller drivers.
>> - Delete the MPS code set by the SOC manufacturer.
>> ---
>>
>> Hans Zhang (2):
>> ?? PCI: Configure Root Port MPS during host probing
>> ?? PCI: dwc: Remove redundant MPS configuration
>>
>> ? drivers/pci/controller/dwc/pci-meson.c | 17 -----------------
>> ? drivers/pci/probe.c??????????????????? | 12 ++++++++++++
>> ? 2 files changed, 12 insertions(+), 17 deletions(-)
>>
>>
>> base-commit: 691d401c7e0e5ea34ac6f8151bc0696db1b2500a
> 



From cassel at kernel.org  Wed Nov 12 00:22:36 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Wed, 12 Nov 2025 09:22:36 +0100
Subject: [PATCH 1/4] PCI: dwc: Advertise L1 PM Substates only if driver
 requests it
In-Reply-To: <20251111221621.2208606-2-helgaas@kernel.org>
References: <20251111221621.2208606-1-helgaas@kernel.org>
 <20251111221621.2208606-2-helgaas@kernel.org>
Message-ID: <aRRDzKFVTFTIuvvh@ryzen>

On Tue, Nov 11, 2025 at 04:16:08PM -0600, Bjorn Helgaas wrote:
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -1060,6 +1060,8 @@ int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
>  		PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
>  	dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
>  
> +	dw_pcie_config_l1ss(pci);

The name dw_pcie_config_l1ss() sounds like we are enabling l1ss.

I know naming is hard.

Perhaps dw_pcie_disable_unsupported_l1ss() ?

Or something similar.


> --- a/drivers/pci/controller/dwc/pcie-qcom.c
> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> @@ -1067,6 +1067,8 @@ static int qcom_pcie_init_2_7_0(struct qcom_pcie *pcie)
>  	val &= ~REQ_NOT_ENTR_L1;
>  	writel(val, pcie->parf + PARF_PM_CTRL);
>  
> +	pci->l1ss_support = true;
> +
>  	val = readl(pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
>  	val |= EN;
>  	writel(val, pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);

While it seems like ops_2_7_0 is the only type that explicitly does a
register write to enable L1ss, other versions might have the register
as enabled by default, so it would be nice if Mani could confirm exactly
which versions that should set l1ss_support = true.


Kind regards,
Niklas


From krzk at kernel.org  Wed Nov 12 00:24:01 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 12 Nov 2025 09:24:01 +0100
Subject: [RESEND PATCH v7 4/5] dt-bindings: clock: rockchip: Add RK3506
 clock and reset unit
In-Reply-To: <20251112022111.3828521-1-zhangqing@rock-chips.com>
References: <20251112022111.3828521-1-zhangqing@rock-chips.com>
Message-ID: <88893633-ca4f-42d2-8d69-7f065ea34bf0@kernel.org>

On 12/11/2025 03:21, Elaine Zhang wrote:
> From: Finley Xiao <finley.xiao at rock-chips.com>
> 
> Add device tree bindings for clock and reset unit on RK3506 SoC.
> Add clock and reset IDs for RK3506 SoC.
> 
> Signed-off-by: Finley Xiao <finley.xiao at rock-chips.com>
> Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>


You just again ignored Conor's feedback and resent only this, so his
questions are buried in the archives.

NAK

Best regards,
Krzysztof


From krzk at kernel.org  Wed Nov 12 00:24:52 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 12 Nov 2025 09:24:52 +0100
Subject: [RESEND PATCH v8 0/4] rockchip: add can for RK3576 Soc
In-Reply-To: <20251112015940.3695638-1-zhangqing@rock-chips.com>
References: <20251112015940.3695638-1-zhangqing@rock-chips.com>
Message-ID: <177ca4e1-fa11-4b24-b72d-1af6c7c2f1c6@kernel.org>

On 12/11/2025 02:59, Elaine Zhang wrote:
> rk3576 can is a new controller,new register layout and Bit position
> definition:
> Support CAN protocol.
> Support Dma.
> 
> There are major differences from the previous rk3568.
> All errata on the rk3568 have been fixed and redesigned.
> 
> RK3576 CANFD requires authorization and permission. The software
> code is not open by default and needs to be authorized separately.
> 
> Change in V8:
> [PATCH v8 1/4]: Drop CANFD, correction format warning.
> [PATCH v8 2/4]: Drop fifo_setup of rkcanfd_devtype_data.
> [PATCH v8 3/4]: Drop CANFD.
> [PATCH v8 4/4]: Drop CANFD.


Please implement the feedback I asked at v8. Stop resending the same
over and over, bypassing people's review.

Best regards,
Krzysztof


From cassel at kernel.org  Wed Nov 12 00:29:20 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Wed, 12 Nov 2025 09:29:20 +0100
Subject: [PATCH 2/4] PCI: tegra194: Remove unnecessary L1SS disable code
In-Reply-To: <20251111221621.2208606-3-helgaas@kernel.org>
References: <20251111221621.2208606-1-helgaas@kernel.org>
 <20251111221621.2208606-3-helgaas@kernel.org>
Message-ID: <aRRFYEgBigYDlfQh@ryzen>

On Tue, Nov 11, 2025 at 04:16:09PM -0600, Bjorn Helgaas wrote:
> From: Bjorn Helgaas <bhelgaas at google.com>
> 
> The DWC core clears the L1 Substates Supported bits unless the driver sets
> the "dw_pcie.l1ss_support" flag.
> 
> The tegra194 init_host_aspm() sets "dw_pcie.l1ss_support" if the platform
> has the "supports-clkreq" DT property.  If "supports-clkreq" is absent,
> "dw_pcie.l1ss_support" is not set, and the DWC core will clear the L1
> Substates Supported bits.
> 
> The tegra194 code to clear the L1 Substates Supported bits is unnecessary,
> so remove it.
> 
> Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
> ---

Since init_host_aspm() is now the only place using struct tegra_pcie_dw
struct member cfg_link_cap_l1sub, I think that you can remove this struct
member, and instead make this a local variable in init_host_aspm().

Other than that, looks good to me:
Reviewed-by: Niklas Cassel <cassel at kernel.org>


From diederik at cknow-tech.com  Wed Nov 12 00:30:19 2025
From: diederik at cknow-tech.com (Diederik de Haas)
Date: Wed, 12 Nov 2025 09:30:19 +0100
Subject: [PATCH 3/4] PCI: dw-rockchip: Configure L1sub support
In-Reply-To: <20251111221621.2208606-4-helgaas@kernel.org>
References: <20251111221621.2208606-1-helgaas@kernel.org>
 <20251111221621.2208606-4-helgaas@kernel.org>
Message-ID: <DE6KQEJ3S9R8.F3LC0FHN4GJ2@cknow-tech.com>

On Tue Nov 11, 2025 at 11:16 PM CET, Bjorn Helgaas wrote:
> From: Shawn Lin <shawn.lin at rock-chips.com>
>
> L1 PM Substates for RC mode require support in the dw-rockchip driver
> including proper handling of the CLKREQ# sideband signal. It is mostly
> handled by hardware, but software still needs to set the clkreq fields
> in the PCIE_CLIENT_POWER_CON register to match the hardware implementation.
>
> For more details, see section '18.6.6.4 L1 Substate' in the RK3658 TRM 1.1

s/RK3658/RK3568/

Sorry,
  Diederik

> Part 2, or section '11.6.6.4 L1 Substate' in the RK3588 TRM 1.0 Part2.
>
> Meanwhile, for the EP mode, we haven't prepared enough to actually support
> L1 PM Substates yet. So disable it now until proper support is added later.
>
> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
> [bhelgaas: set pci->l1ss_support so DWC core preserves L1SS Capability bits;
> drop corresponding code here]
> Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
> Link: https://patch.msgid.link/1761187883-150120-1-git-send-email-shawn.lin at rock-chips.com
> ---
>  drivers/pci/controller/dwc/pcie-dw-rockchip.c | 38 +++++++++++++++++++
>  1 file changed, 38 insertions(+)
>
> diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> index 3e2752c7dd09..62a095752833 100644
> --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> @@ -62,6 +62,12 @@
>  /* Interrupt Mask Register Related to Miscellaneous Operation */
>  #define PCIE_CLIENT_INTR_MASK_MISC	0x24
>  
> +/* Power Management Control Register */
> +#define PCIE_CLIENT_POWER_CON		0x2c
> +#define  PCIE_CLKREQ_READY		FIELD_PREP_WM16(BIT(0), 1)
> +#define  PCIE_CLKREQ_NOT_READY		FIELD_PREP_WM16(BIT(0), 0)
> +#define  PCIE_CLKREQ_PULL_DOWN		FIELD_PREP_WM16(GENMASK(13, 12), 1)
> +
>  /* Hot Reset Control Register */
>  #define PCIE_CLIENT_HOT_RESET_CTRL	0x180
>  #define  PCIE_LTSSM_APP_DLY2_EN		BIT(1)
> @@ -85,6 +91,7 @@ struct rockchip_pcie {
>  	struct regulator *vpcie3v3;
>  	struct irq_domain *irq_domain;
>  	const struct rockchip_pcie_of_data *data;
> +	bool supports_clkreq;
>  };
>  
>  struct rockchip_pcie_of_data {
> @@ -200,6 +207,32 @@ static bool rockchip_pcie_link_up(struct dw_pcie *pci)
>  	return FIELD_GET(PCIE_LINKUP_MASK, val) == PCIE_LINKUP;
>  }
>  
> +/*
> + * See e.g. section '11.6.6.4 L1 Substate' in the RK3588 TRM V1.0 for the steps
> + * needed to support L1 substates. Currently, just enable L1 substates for RC
> + * mode if CLKREQ# is properly connected and supports-clkreq is present in DT.
> + * For EP mode, there are more things should be done to actually save power in
> + * L1 substates, so disable L1 substates until there is proper support.
> + */
> +static void rockchip_pcie_configure_l1sub(struct dw_pcie *pci)
> +{
> +	struct rockchip_pcie *rockchip = to_rockchip_pcie(pci);
> +
> +	/* Enable L1 substates if CLKREQ# is properly connected */
> +	if (rockchip->supports_clkreq &&
> +	    rockchip->data->mode == DW_PCIE_RC_TYPE ) {
> +		rockchip_pcie_writel_apb(rockchip, PCIE_CLKREQ_READY,
> +					 PCIE_CLIENT_POWER_CON);
> +		pci->l1ss_support = true;
> +		return;
> +	}
> +
> +	/* Otherwise, pull down CLKREQ# */
> +	rockchip_pcie_writel_apb(rockchip,
> +				 PCIE_CLKREQ_PULL_DOWN | PCIE_CLKREQ_NOT_READY,
> +				 PCIE_CLIENT_POWER_CON);
> +}
> +
>  static void rockchip_pcie_enable_l0s(struct dw_pcie *pci)
>  {
>  	u32 cap, lnkcap;
> @@ -264,6 +297,7 @@ static int rockchip_pcie_host_init(struct dw_pcie_rp *pp)
>  	irq_set_chained_handler_and_data(irq, rockchip_pcie_intx_handler,
>  					 rockchip);
>  
> +	rockchip_pcie_configure_l1sub(pci);
>  	rockchip_pcie_enable_l0s(pci);
>  
>  	return 0;
> @@ -301,6 +335,7 @@ static void rockchip_pcie_ep_init(struct dw_pcie_ep *ep)
>  	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
>  	enum pci_barno bar;
>  
> +	rockchip_pcie_configure_l1sub(pci);
>  	rockchip_pcie_enable_l0s(pci);
>  	rockchip_pcie_ep_hide_broken_ats_cap_rk3588(ep);
>  
> @@ -412,6 +447,9 @@ static int rockchip_pcie_resource_get(struct platform_device *pdev,
>  		return dev_err_probe(&pdev->dev, PTR_ERR(rockchip->rst),
>  				     "failed to get reset lines\n");
>  
> +	rockchip->supports_clkreq = of_property_read_bool(pdev->dev.of_node,
> +							  "supports-clkreq");
> +
>  	return 0;
>  }
>  



From shawn.lin at rock-chips.com  Wed Nov 12 00:31:30 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Wed, 12 Nov 2025 16:31:30 +0800
Subject: [PATCH v6 1/2] PCI: Configure Root Port MPS during host probing
In-Reply-To: <20251104165125.174168-2-18255117159@163.com>
References: <20251104165125.174168-1-18255117159@163.com>
 <20251104165125.174168-2-18255117159@163.com>
Message-ID: <ef433574-3e81-4636-82c8-9bc3552addca@rock-chips.com>

? 2025/11/05 ??? 0:51, Hans Zhang ??:
> Current PCIe initialization logic may leave Root Ports (root bridges)
> operating with non-optimal Maximum Payload Size (MPS) settings. Existing
> code in pci_configure_mps() returns early for devices without an upstream
> bridge (!bridge) which includes Root Ports, so their MPS values remain
> at firmware/hardware defaults. This fails to utilize the controller's full
> capabilities, leading to suboptimal data transfer efficiency across the
> PCIe hierarchy.
> 
> With this patch, during the host controller probing phase:
> - When PCIe bus tuning is enabled (not PCIE_BUS_TUNE_OFF), and
> - The device is a Root Port without an upstream bridge (!bridge),
> The Root Port's MPS is set to its hardware-supported maximum value
> (128 << dev->pcie_mpss).
> 
> Note that this initial maximum MPS setting may be reduced later, during
> downstream device enumeration, if any downstream device does not suppor
> the Root Port's maximum MPS.
> 
> This change ensures Root Ports are properly initialized before downstream
> devices negotiate MPS, while maintaining backward compatibility via the
> PCIE_BUS_TUNE_OFF check.
> 

Tested-by: Shawn Lin <shawn.lin at rock-chips.com>

> Suggested-by: Niklas Cassel <cassel at kernel.org>
> Suggested-by: Manivannan Sadhasivam <mani at kernel.org>
> Signed-off-by: Hans Zhang <18255117159 at 163.com>
> ---
>   drivers/pci/probe.c | 12 ++++++++++++
>   1 file changed, 12 insertions(+)
> 
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index 0ce98e18b5a8..2459def3af9b 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -2196,6 +2196,18 @@ static void pci_configure_mps(struct pci_dev *dev)
>   		return;
>   	}
>   
> +	/*
> +	 * Unless MPS strategy is PCIE_BUS_TUNE_OFF (don't touch MPS at all),
> +	 * start off by setting Root Ports' MPS to MPSS. This only applies to
> +	 * Root Ports without an upstream bridge (root bridges), as other Root
> +	 * Ports will have downstream bridges. Depending on the MPS strategy
> +	 * and MPSS of downstream devices, the Root Port's MPS may be
> +	 * overridden later.
> +	 */
> +	if (!bridge && pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT &&
> +	    pcie_bus_config != PCIE_BUS_TUNE_OFF)
> +		pcie_set_mps(dev, 128 << dev->pcie_mpss);
> +
>   	if (!bridge || !pci_is_pcie(bridge))
>   		return;
>   



From cassel at kernel.org  Wed Nov 12 00:36:03 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Wed, 12 Nov 2025 09:36:03 +0100
Subject: [PATCH 3/4] PCI: dw-rockchip: Configure L1sub support
In-Reply-To: <20251111221621.2208606-4-helgaas@kernel.org>
References: <20251111221621.2208606-1-helgaas@kernel.org>
 <20251111221621.2208606-4-helgaas@kernel.org>
Message-ID: <aRRG8wv13HxOCqgA@ryzen>

On Tue, Nov 11, 2025 at 04:16:10PM -0600, Bjorn Helgaas wrote:
> From: Shawn Lin <shawn.lin at rock-chips.com>
> 
> L1 PM Substates for RC mode require support in the dw-rockchip driver
> including proper handling of the CLKREQ# sideband signal. It is mostly
> handled by hardware, but software still needs to set the clkreq fields
> in the PCIE_CLIENT_POWER_CON register to match the hardware implementation.
> 
> For more details, see section '18.6.6.4 L1 Substate' in the RK3658 TRM 1.1
> Part 2, or section '11.6.6.4 L1 Substate' in the RK3588 TRM 1.0 Part2.
> 
> Meanwhile, for the EP mode, we haven't prepared enough to actually support
> L1 PM Substates yet. So disable it now until proper support is added later.

Considering that patch 1/4 is disabling L1ss for EP mode, I think we can
remove this last sentence.


> 
> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
> [bhelgaas: set pci->l1ss_support so DWC core preserves L1SS Capability bits;
> drop corresponding code here]
> Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
> Link: https://patch.msgid.link/1761187883-150120-1-git-send-email-shawn.lin at rock-chips.com
> ---
>  drivers/pci/controller/dwc/pcie-dw-rockchip.c | 38 +++++++++++++++++++
>  1 file changed, 38 insertions(+)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> index 3e2752c7dd09..62a095752833 100644
> --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> @@ -62,6 +62,12 @@
>  /* Interrupt Mask Register Related to Miscellaneous Operation */
>  #define PCIE_CLIENT_INTR_MASK_MISC	0x24
>  
> +/* Power Management Control Register */
> +#define PCIE_CLIENT_POWER_CON		0x2c
> +#define  PCIE_CLKREQ_READY		FIELD_PREP_WM16(BIT(0), 1)
> +#define  PCIE_CLKREQ_NOT_READY		FIELD_PREP_WM16(BIT(0), 0)
> +#define  PCIE_CLKREQ_PULL_DOWN		FIELD_PREP_WM16(GENMASK(13, 12), 1)
> +
>  /* Hot Reset Control Register */
>  #define PCIE_CLIENT_HOT_RESET_CTRL	0x180
>  #define  PCIE_LTSSM_APP_DLY2_EN		BIT(1)
> @@ -85,6 +91,7 @@ struct rockchip_pcie {
>  	struct regulator *vpcie3v3;
>  	struct irq_domain *irq_domain;
>  	const struct rockchip_pcie_of_data *data;
> +	bool supports_clkreq;
>  };
>  
>  struct rockchip_pcie_of_data {
> @@ -200,6 +207,32 @@ static bool rockchip_pcie_link_up(struct dw_pcie *pci)
>  	return FIELD_GET(PCIE_LINKUP_MASK, val) == PCIE_LINKUP;
>  }
>  
> +/*
> + * See e.g. section '11.6.6.4 L1 Substate' in the RK3588 TRM V1.0 for the steps
> + * needed to support L1 substates. Currently, just enable L1 substates for RC
> + * mode if CLKREQ# is properly connected and supports-clkreq is present in DT.
> + * For EP mode, there are more things should be done to actually save power in
> + * L1 substates, so disable L1 substates until there is proper support.
> + */
> +static void rockchip_pcie_configure_l1sub(struct dw_pcie *pci)
> +{
> +	struct rockchip_pcie *rockchip = to_rockchip_pcie(pci);
> +
> +	/* Enable L1 substates if CLKREQ# is properly connected */
> +	if (rockchip->supports_clkreq &&
> +	    rockchip->data->mode == DW_PCIE_RC_TYPE ) {

Superfluous space before '('

Considering that DWC core clears L1ss cap, and according to Shawn, there
is more code needed to support L1ss in EP mode, perhaps simply drop the
function call from rockchip_pcie_ep_init(), then we can drop
'rockchip->data->mode == DW_PCIE_RC_TYPE' from the above if statement.


> +		rockchip_pcie_writel_apb(rockchip, PCIE_CLKREQ_READY,
> +					 PCIE_CLIENT_POWER_CON);
> +		pci->l1ss_support = true;
> +		return;
> +	}
> +
> +	/* Otherwise, pull down CLKREQ# */
> +	rockchip_pcie_writel_apb(rockchip,
> +				 PCIE_CLKREQ_PULL_DOWN | PCIE_CLKREQ_NOT_READY,
> +				 PCIE_CLIENT_POWER_CON);
> +}
> +
>  static void rockchip_pcie_enable_l0s(struct dw_pcie *pci)
>  {
>  	u32 cap, lnkcap;
> @@ -264,6 +297,7 @@ static int rockchip_pcie_host_init(struct dw_pcie_rp *pp)
>  	irq_set_chained_handler_and_data(irq, rockchip_pcie_intx_handler,
>  					 rockchip);
>  
> +	rockchip_pcie_configure_l1sub(pci);
>  	rockchip_pcie_enable_l0s(pci);
>  
>  	return 0;
> @@ -301,6 +335,7 @@ static void rockchip_pcie_ep_init(struct dw_pcie_ep *ep)
>  	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
>  	enum pci_barno bar;
>  
> +	rockchip_pcie_configure_l1sub(pci);

Considering that DWC core clears L1ss cap, and according to Shawn, there
is more code needed to support L1ss in EP mode, perhaps simply drop this
function call?


>  	rockchip_pcie_enable_l0s(pci);
>  	rockchip_pcie_ep_hide_broken_ats_cap_rk3588(ep);
>  
> @@ -412,6 +447,9 @@ static int rockchip_pcie_resource_get(struct platform_device *pdev,
>  		return dev_err_probe(&pdev->dev, PTR_ERR(rockchip->rst),
>  				     "failed to get reset lines\n");
>  
> +	rockchip->supports_clkreq = of_property_read_bool(pdev->dev.of_node,
> +							  "supports-clkreq");
> +
>  	return 0;
>  }
>  
> -- 
> 2.43.0
> 


From cassel at kernel.org  Wed Nov 12 00:40:06 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Wed, 12 Nov 2025 09:40:06 +0100
Subject: [PATCH v3] PCI: dw-rockchip: Prevent advertising L1 Substates
 support
In-Reply-To: <20251111214336.GA2190667@bhelgaas>
References: <aRM1VOodnSpaob3P@ryzen>
 <20251111214336.GA2190667@bhelgaas>
Message-ID: <aRRH5i2oq1FBSs_7@ryzen>

On Tue, Nov 11, 2025 at 03:43:36PM -0600, Bjorn Helgaas wrote:
> On Tue, Nov 11, 2025 at 02:08:36PM +0100, Niklas Cassel wrote:
> > On Tue, Oct 21, 2025 at 08:05:17AM +0530, Manivannan Sadhasivam wrote:
> > > On Fri, 17 Oct 2025 18:32:53 +0200, Niklas Cassel wrote:
> > > > The L1 substates support requires additional steps to work, namely:
> > > > -Proper handling of the CLKREQ# sideband signal. (It is mostly handled by
> > > >  hardware, but software still needs to set the clkreq fields in the
> > > >  PCIE_CLIENT_POWER_CON register to match the hardware implementation.)
> > > > -Program the frequency of the aux clock into the
> > > >  DSP_PCIE_PL_AUX_CLK_FREQ_OFF register. (During L1 substates the core_clk
> > > >  is turned off and the aux_clk is used instead.)
> > > > 
> > > > [...]
> > > 
> > > Applied, thanks!
> > > 
> > > [1/1] PCI: dw-rockchip: Prevent advertising L1 Substates support
> > >       commit: 40331c63e7901a2cc75ce6b5d24d50601efb833d
> > 
> > Last update in this thread was "Applied, thanks!"
> >
> > and the patch was applied to pci/controller/dw-rockchip
> > 
> > since then it seems to have been demoted to
> > pci/controller/dw-rockchip-pend
> 
> That was Oct 20, and we had some conversation about a more generic
> approach after that, so I moved it to dw-rockchip-pend while we worked
> that out.
> 
> I fleshed it out the generic approach and will post it soon.

Ok, thank you!


Kind regards,
Niklas


From andyshrk at 163.com  Wed Nov 12 00:50:23 2025
From: andyshrk at 163.com (Andy Yan)
Date: Wed, 12 Nov 2025 16:50:23 +0800
Subject: [PATCH] drm/rockchip: vop2: Use OVL_LAYER_SEL configuration instead of use win_mask calculate used layers
Message-ID: <20251112085024.2480111-1-andyshrk@163.com>

From: Andy Yan <andy.yan at rock-chips.com>

When there are multiple Video Ports, and only one of them is working
(for example, VP1 is working while VP0 is not), in this case, the
win_mask of VP0 is 0. However, we have already set the port mux for VP0
according to vp0->nlayers, and at the same time, in the OVL_LAYER_SEL
register, there are windows will also be assigned to layers which will
map to the inactive VPs. In this situation, vp0->win_mask is zero as it
now working, it is more reliable to calculate the used layers based on
the configuration of the OVL_LAYER_SEL register.

Note: as the configuration of OVL_LAYER_SEL is take effect when the
vsync is come, so we use the value backup in vop2->old_layer_sel instead
of read OVL_LAYER_SEL directly.

Fixes: 3e89a8c68354 ("drm/rockchip: vop2: Fix the update of LAYER/PORT select registers when there are multi display output on rk3588/rk3568")
Reported-by: Diederik de Haas <diederik at cknow-tech.com>
Closes: https://bugs.kde.org/show_bug.cgi?id=511274
Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
---

 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 49 +++++++++++++++++---
 1 file changed, 42 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
index d22ce11a4235..f3950e8476a7 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
@@ -1369,6 +1369,25 @@ static const struct vop2_regs_dump rk3588_regs_dump[] = {
 	},
 };
 
+/*
+ * phys_id is used to identify a main window(Cluster Win/Smart Win, not
+ * include the sub win of a cluster or the multi area) that can do overlay
+ * in main overlay stage.
+ */
+static struct vop2_win *vop2_find_win_by_phys_id(struct vop2 *vop2, uint8_t phys_id)
+{
+	struct vop2_win *win;
+	int i;
+
+	for (i = 0; i < vop2->data->win_size; i++) {
+		win = &vop2->win[i];
+		if (win->data->phys_id == phys_id)
+			return win;
+	}
+
+	return NULL;
+}
+
 static unsigned long rk3568_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags)
 {
 	struct vop2 *vop2 = vp->vop2;
@@ -1842,15 +1861,31 @@ static void vop2_parse_alpha(struct vop2_alpha_config *alpha_config,
 	alpha->dst_alpha_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE;
 }
 
-static int vop2_find_start_mixer_id_for_vp(struct vop2 *vop2, u8 port_id)
+static int vop2_find_start_mixer_id_for_vp(struct vop2_video_port *vp)
 {
-	struct vop2_video_port *vp;
-	int used_layer = 0;
+	struct vop2 *vop2 = vp->vop2;
+	struct vop2_win *win;
+	u32 layer_sel = vop2->old_layer_sel;
+	u32 used_layer = 0;
+	unsigned long win_mask = vp->win_mask;
+	unsigned long phys_id;
+	bool match;
 	int i;
 
-	for (i = 0; i < port_id; i++) {
-		vp = &vop2->vps[i];
-		used_layer += hweight32(vp->win_mask);
+	for (i = 0; i < 31; i += 4) {
+		match = false;
+		for_each_set_bit(phys_id, &win_mask, ROCKCHIP_VOP2_ESMART3) {
+			win = vop2_find_win_by_phys_id(vop2, phys_id);
+			if (win->data->layer_sel_id[vp->id] == ((layer_sel >> i) & 0xf)) {
+				match = true;
+				break;
+			}
+		}
+
+		if (!match)
+			used_layer += 1;
+		else
+			break;
 	}
 
 	return used_layer;
@@ -1935,7 +1970,7 @@ static void vop2_setup_alpha(struct vop2_video_port *vp)
 	u32 dst_global_alpha = DRM_BLEND_ALPHA_OPAQUE;
 
 	if (vop2->version <= VOP_VERSION_RK3588)
-		mixer_id = vop2_find_start_mixer_id_for_vp(vop2, vp->id);
+		mixer_id = vop2_find_start_mixer_id_for_vp(vp);
 	else
 		mixer_id = 0;
 
-- 
2.43.0

base-commit: ded94ec6167e84195507237100f6278941e36fdd
branch: drm-misc-next-2025-1016



From mkl at pengutronix.de  Wed Nov 12 00:52:41 2025
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Wed, 12 Nov 2025 09:52:41 +0100
Subject: [RESEND PATCH v8 0/4] rockchip: add can for RK3576 Soc
In-Reply-To: <20251112015940.3695638-1-zhangqing@rock-chips.com>
References: <20251112015940.3695638-1-zhangqing@rock-chips.com>
Message-ID: <20251112-intrepid-toad-of-prestige-2e67d5-mkl@pengutronix.de>

On 12.11.2025 09:59:36, Elaine Zhang wrote:
> rk3576 can is a new controller,new register layout and Bit position
> definition:
> Support CAN protocol.
> Support Dma.
>
> There are major differences from the previous rk3568.
> All errata on the rk3568 have been fixed and redesigned.
>
> RK3576 CANFD requires authorization and permission. The software
> code is not open by default and needs to be authorized separately.

If you change your patches it's not a "RESEND", but a vN+1.

Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde          |
Embedded Linux                   | https://www.pengutronix.de |
Vertretung N?rnberg              | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-9   |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251112/187bc79f/attachment.sig>

From mkl at pengutronix.de  Wed Nov 12 00:53:09 2025
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Wed, 12 Nov 2025 09:53:09 +0100
Subject: [RESEND PATCH v8 1/4] dt-bindings: can: rockchip_canfd: add
 rk3576 CAN controller
In-Reply-To: <20251112015940.3695638-2-zhangqing@rock-chips.com>
References: <20251112015940.3695638-1-zhangqing@rock-chips.com>
 <20251112015940.3695638-2-zhangqing@rock-chips.com>
Message-ID: <20251112-faithful-olive-orangutan-0dd207-mkl@pengutronix.de>

On 12.11.2025 09:59:37, Elaine Zhang wrote:
> Add documentation for the rockchip rk3576 CAN controller.
>
> Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
> ---
>  .../bindings/net/can/rockchip,rk3568v2-canfd.yaml  | 14 ++++++++++----
>  1 file changed, 10 insertions(+), 4 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml b/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml
> index a077c0330013..22e10494e7d1 100644
> --- a/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml
> +++ b/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml
> @@ -10,13 +10,12 @@ title:
>  maintainers:
>    - Marc Kleine-Budde <mkl at pengutronix.de>
>
> -allOf:
> -  - $ref: can-controller.yaml#
> -

What happened to the allOf?

>  properties:
>    compatible:
>      oneOf:
> -      - const: rockchip,rk3568v2-canfd
> +      - enum:
> +          - rockchip,rk3568v2-canfd
> +          - rockchip,rk3576-can
>        - items:
>            - const: rockchip,rk3568v3-canfd
>            - const: rockchip,rk3568v2-canfd
> @@ -43,6 +42,13 @@ properties:
>        - const: core
>        - const: apb
>
> +  dmas:
> +    maxItems: 1
> +
> +  dma-names:
> +    items:
> +      - const: rx
> +
>  required:
>    - compatible
>    - reg

regards,
Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde          |
Embedded Linux                   | https://www.pengutronix.de |
Vertretung N?rnberg              | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-9   |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251112/5532d5a6/attachment.sig>

From diederik at cknow-tech.com  Wed Nov 12 01:40:28 2025
From: diederik at cknow-tech.com (Diederik de Haas)
Date: Wed, 12 Nov 2025 10:40:28 +0100
Subject: [PATCH v2] arm64: dts: rockchip: Turn all LEDs on at boot for
 Radxa boards
In-Reply-To: <774C3AB9F17BAE47+14f8b8ba-ba78-410e-b44c-4d077585d05a@radxa.com>
References: <20251111054112.55505-1-naoki@radxa.com>
 <DE5W0143QGG2.3C7SW89IJKZ4P@cknow-tech.com>
 <516e919a-42af-8707-4e75-a808df8971fd@manjaro.org>
 <B0C8C5A69B9F465E+ba0ad139-d3d9-4492-ac9a-cc58f8f35074@radxa.com>
 <41275775-9e6e-9202-4c79-6140a56e41d5@manjaro.org>
 <572f341f-a5fa-4f1c-ad60-a5fe3e046d6d@cherry.de>
 <774C3AB9F17BAE47+14f8b8ba-ba78-410e-b44c-4d077585d05a@radxa.com>
Message-ID: <DE6M84A93WTV.O5IW3BG8TZRW@cknow-tech.com>

Hi Naoki,

On Wed Nov 12, 2025 at 12:42 AM CET, FUKAUMI Naoki wrote:
> On 11/12/25 03:32, Quentin Schulz wrote:
>> On 11/11/25 5:14 PM, Dragan Simic wrote:
>>> On Tuesday, November 11, 2025 16:32 CET, FUKAUMI Naoki 
>>> <naoki at radxa.com> wrote:
>>>> On 11/11/25 23:46, Dragan Simic wrote:
>>>>> On Tuesday, November 11, 2025 14:07 CET, "Diederik de Haas" 
>>>>> <diederik at cknow-tech.com> wrote:
>>>>>> On Tue Nov 11, 2025 at 6:41 AM CET, FUKAUMI Naoki wrote:
>>>>>>> Radxa's boards turn all LEDs on at boot(loader), but some boards 
>>>>>>> don't have `default-state` property in Linux kernel tree but
>>>>>>> have it in U-Boot tree instead[1].
>>>>>>>
>>>>>>> This patch adds `default-state = "on"` for (almost) all LEDs (with a
>>>>>>> few exceptions which should be "off" such as RGB LEDs on E25 and LAN/
>>>>>>> WAN LEDs on E20C/E52C).
>>>>>>
>>>>>> I'm missing the *why* these changes would be an improvement.
>>>>>>
>>>>>> Personally, for both 'heartbeat' and 'netdev' triggers, I want them to
>>>>>> be off by default and once it gets a 'heartbeat' or a 'netdev' 
>>>>>> trigger, THEN I want the LED to be on/blinking.
>>>>>
>>>>> That's a good question for Naoki.? My own preference would also
>>>>> be to have the device's power LED turned on by U-Boot as quickly
>>>>> as possible after supplying power to the board or turning it on
>>>>> by pressing the power button.? I'm actually not a big fan of
>>>>> having all the LEDs shining for a couple of seconds or so, which
>>>>> may actually look like some error condition to me.
>>>>>
>>>>> Having all that in mind, I may suggest that just the U-Boot's
>>>>> behavior is changed to turn the power LEDs on only.
>>>>
>>>> I can't quite explain it, but...
>>>>
>>>> - 1st (Power) LED
>>>>
>>>> The 1st (power) LED turns on automatically/immediately without software
>>>> intervention. (On some boards, this LED cannot be controlled by software
>>>> at all.)
>>>>
>>>> In DTS, this should be described using `default-state = "on"`. The use
>>>> of the Linux-specific property `linux,default-trigger = "default-on"` is
>>>> unsuitable for non-Linux environments.
>>>>
>>>> - 2nd (Heartbeat) LED
>>>>
>>>> The 2nd (heartbeat) LED can be controlled by software. It should be lit
>>>> up as quickly as possible to indicate that the very first software
>>>> (e.g., the bootloader) is running.
>>>>
>>>> On Linux, usually this is used as `linux,default-trigger = "heartbeat"`.
>>>> It indicates that kernel is running (regardless of the `default-state`
>>>> setting), and its behavior can be modified in user space.
>>>
>>> As discussed already in the #linux-rockchip IRC channel, [1] perhaps
>>> the best option would be to have the power LEDs turned on as quickly
>>> upon powering on the board as possible, and to have U-Boot pulsate
>>> the heartbeat LEDs using the LED_BOOT feature.? In such a scenario,
>>> no other LEDs would be turned on early, and the LED-related DT parts
>>> specific to U-Boot would be migrated to the kernel DTs.
>>>
>>> [1] https://libera.catirclogs.org/linux-rockchip/2025-11-11#38997824;
>> 
>> The LED_BOOT feature (guarded by the Kconfig symbol of the same name) in 
>> U-Boot only applies if /options/u-boot/boot-led property is set.
>
> For the default state of the heartbeat LED, I'm thinking of using 
> LED_BOOT (/options/u-boot/boot-led), but I'm concerned that this is 
> U-Boot-specific.

If U-Boot wants to use the heartbeat LED to signal the *bootloader* is
running, I guess that's fine. And if you want to make it solid or
blinking, that seems best discussed on the U-Boot ML.

I still consider the bootloader and the kernel stages separate.
And I haven't seen an argument why I should change *my* opinion on the
heartbeat and netdev triggers (default-state) wrt the kernel.

I don't think that what U-Boot does or doesn't do, should determine what
the Linux kernel does or doesn't do.
I have no plans to use another bootloader then U-Boot, but it's possible
that people do, so what the Linux kernel does should be independent from
what the/a specific bootloader does.

And as I said before, *I* want LEDs with netdev and heartbeat triggers,
to be off (at the start, which is indeed the default value).
I use the heartbeat trigger to:
1) See the kernel has started (and has gotten to the point the heartbeat
   'infrastructure' has been set up
2) Wait for the blinking to slow down as that (generally) means it's
   pretty much done with the boot process and the SSH server should
   probably be running then, so I can login
3) When the heartbeat LED is solid, that means the system has crashed
   (f.e. due to overheating ...)

And also, if you're going to change/override other people's choices, a
motivation as to why would be 'nice'.

>> <more discussion about LED functionality in U-Boot ...>
>
> As you know, default "default-state" is "off".
>   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/leds/common.yaml?h=v6.17#n74
>
> As far as I understand, there should not be any workarounds for specific 
> implementations.
>   https://lore.kernel.org/linux-rockchip/3389401.44csPzL39Z at phil/
>
> So removing `default-state = "off"` is acceptable, right?

I don't see/understand the connection with 'workarounds for specific
implementations' with removing ``default-state = "off"``.

IMO it's perfectly fine to remove ``default-state = "off"``, although
having it explicitly may be useful, especially if the commit that set
that property specified *why* it should be "off".

Relatedly, when a node does not have the 'default-state' property, I
would _assume_ the author wanted/intended it to be "off". Ideally it
would be described in the commit message, but that is optional.
But if that is changed, then it should be motivated *why*.

Cheers,
  Diederik

>
> Best regards,
>
> --
> FUKAUMI Naoki
> Radxa Computer (Shenzhen) Co., Ltd.
>
>> If one wants to detect via an LED the current boot stage (U-Boot 
>> reached, kernel started), then we need to NOT use LED_BOOT feature and 
>> have U-Boot set the "boot" LED the opposite state than the default HW 
>> state, i.e. if the LED is on without any running SW (power applied to 
>> the device, empty boot media), then U-Boot should set it to off. Then 
>> the kernel simply needs to start the heartbeat mode whenever ready. If 
>> the default HW state is off, then U-Boot should set it on. I haven't 
>> looked into the kernel side of things, but there could be a window 
>> during which default-state property is applied before the heartbeat is 
>> actually started.
>> 
>> The logic exposed in the previous paragraph should provide visual cues 
>> on the current boot stage.
>> 
>> Note that LEDs with linux,default-trigger = "pattern" (with default- 
>> state property) will be blinking once auto-configured in U-Boot as well 
>> according to my reading of the led-uclass.c.
>> 
>> Hope this helps.
>> 
>> Cheers,
>> Quentin
>> 



From zhangqing at rock-chips.com  Wed Nov 12 02:06:26 2025
From: zhangqing at rock-chips.com (zhangqing)
Date: Wed, 12 Nov 2025 18:06:26 +0800
Subject: [RESEND PATCH v8 1/4] dt-bindings: can: rockchip_canfd: add
 rk3576 CAN controller
In-Reply-To: <20251112-faithful-olive-orangutan-0dd207-mkl@pengutronix.de>
References: <20251112015940.3695638-1-zhangqing@rock-chips.com>
 <20251112015940.3695638-2-zhangqing@rock-chips.com>
 <20251112-faithful-olive-orangutan-0dd207-mkl@pengutronix.de>
Message-ID: <65ff0185-e471-40ba-8991-43b1a42b1d30@rock-chips.com>


? 2025/11/12 16:53, Marc Kleine-Budde ??:
> On 12.11.2025 09:59:37, Elaine Zhang wrote:
>> Add documentation for the rockchip rk3576 CAN controller.
>>
>> Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
>> ---
>>   .../bindings/net/can/rockchip,rk3568v2-canfd.yaml  | 14 ++++++++++----
>>   1 file changed, 10 insertions(+), 4 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml b/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml
>> index a077c0330013..22e10494e7d1 100644
>> --- a/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml
>> +++ b/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml
>> @@ -10,13 +10,12 @@ title:
>>   maintainers:
>>     - Marc Kleine-Budde <mkl at pengutronix.de>
>>
>> -allOf:
>> -  - $ref: can-controller.yaml#
>> -
> What happened to the allOf?
This is a misoperation and will be corrected in version V9.
To speed up the review of the current version, V9 will also remove dma.
>
>>   properties:
>>     compatible:
>>       oneOf:
>> -      - const: rockchip,rk3568v2-canfd
>> +      - enum:
>> +          - rockchip,rk3568v2-canfd
>> +          - rockchip,rk3576-can
>>         - items:
>>             - const: rockchip,rk3568v3-canfd
>>             - const: rockchip,rk3568v2-canfd
>> @@ -43,6 +42,13 @@ properties:
>>         - const: core
>>         - const: apb
>>
>> +  dmas:
>> +    maxItems: 1
>> +
>> +  dma-names:
>> +    items:
>> +      - const: rx
>> +
>>   required:
>>     - compatible
>>     - reg
> regards,
> Marc
>
-- 
??
???????????
Rockchip Electronics Co.,Ltd
????????????????89????A?21??
Add:No.21 Building, A District, No.89 Software Boulevard Fuzhou, Fujian 350003, P.R.China
Tel:+86-0591-83991906-8601
???350003
E-mail:elaine.zhang at rock-chips.com
****************************************************************************
??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

IMPORTANT NOTICE: This email is from Fuzhou Rockchip Electronics Co., Ltd .The contents of this email and any attachments may contain information that is privileged, confidential and/or exempt from disclosure under applicable law and relevant NDA. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution, or use of the information is STRICTLY PROHIBITED. Please immediately contact the sender as soon as possible and destroy the material in its entirety in any format. Thank you.

****************************************************************************



From quentin.schulz at cherry.de  Wed Nov 12 02:34:39 2025
From: quentin.schulz at cherry.de (Quentin Schulz)
Date: Wed, 12 Nov 2025 11:34:39 +0100
Subject: [PATCH v2] arm64: dts: rockchip: Turn all LEDs on at boot for
 Radxa boards
In-Reply-To: <DE6M84A93WTV.O5IW3BG8TZRW@cknow-tech.com>
References: <20251111054112.55505-1-naoki@radxa.com>
 <DE5W0143QGG2.3C7SW89IJKZ4P@cknow-tech.com>
 <516e919a-42af-8707-4e75-a808df8971fd@manjaro.org>
 <B0C8C5A69B9F465E+ba0ad139-d3d9-4492-ac9a-cc58f8f35074@radxa.com>
 <41275775-9e6e-9202-4c79-6140a56e41d5@manjaro.org>
 <572f341f-a5fa-4f1c-ad60-a5fe3e046d6d@cherry.de>
 <774C3AB9F17BAE47+14f8b8ba-ba78-410e-b44c-4d077585d05a@radxa.com>
 <DE6M84A93WTV.O5IW3BG8TZRW@cknow-tech.com>
Message-ID: <1459ebad-c087-49ac-a316-14436fac4bc6@cherry.de>

Hi all,

On 11/12/25 10:40 AM, Diederik de Haas wrote:
> [You don't often get email from diederik at cknow-tech.com. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
> 
> Hi Naoki,
> 
> On Wed Nov 12, 2025 at 12:42 AM CET, FUKAUMI Naoki wrote:
>> On 11/12/25 03:32, Quentin Schulz wrote:
>>> On 11/11/25 5:14 PM, Dragan Simic wrote:
>>>> On Tuesday, November 11, 2025 16:32 CET, FUKAUMI Naoki
>>>> <naoki at radxa.com> wrote:
>>>>> On 11/11/25 23:46, Dragan Simic wrote:
>>>>>> On Tuesday, November 11, 2025 14:07 CET, "Diederik de Haas"
>>>>>> <diederik at cknow-tech.com> wrote:
>>>>>>> On Tue Nov 11, 2025 at 6:41 AM CET, FUKAUMI Naoki wrote:
>>>>>>>> Radxa's boards turn all LEDs on at boot(loader), but some boards
>>>>>>>> don't have `default-state` property in Linux kernel tree but
>>>>>>>> have it in U-Boot tree instead[1].
>>>>>>>>
>>>>>>>> This patch adds `default-state = "on"` for (almost) all LEDs (with a
>>>>>>>> few exceptions which should be "off" such as RGB LEDs on E25 and LAN/
>>>>>>>> WAN LEDs on E20C/E52C).
>>>>>>>
>>>>>>> I'm missing the *why* these changes would be an improvement.
>>>>>>>
>>>>>>> Personally, for both 'heartbeat' and 'netdev' triggers, I want them to
>>>>>>> be off by default and once it gets a 'heartbeat' or a 'netdev'
>>>>>>> trigger, THEN I want the LED to be on/blinking.
>>>>>>
>>>>>> That's a good question for Naoki.  My own preference would also
>>>>>> be to have the device's power LED turned on by U-Boot as quickly
>>>>>> as possible after supplying power to the board or turning it on
>>>>>> by pressing the power button.  I'm actually not a big fan of
>>>>>> having all the LEDs shining for a couple of seconds or so, which
>>>>>> may actually look like some error condition to me.
>>>>>>
>>>>>> Having all that in mind, I may suggest that just the U-Boot's
>>>>>> behavior is changed to turn the power LEDs on only.
>>>>>
>>>>> I can't quite explain it, but...
>>>>>
>>>>> - 1st (Power) LED
>>>>>
>>>>> The 1st (power) LED turns on automatically/immediately without software
>>>>> intervention. (On some boards, this LED cannot be controlled by software
>>>>> at all.)
>>>>>
>>>>> In DTS, this should be described using `default-state = "on"`. The use
>>>>> of the Linux-specific property `linux,default-trigger = "default-on"` is
>>>>> unsuitable for non-Linux environments.
>>>>>

I think the wording in the binding can be understood two ways.

The binding says the following about the default-state property:

"""
       The initial state of the LED. If the LED is already on or off and the
       default-state property is set the to same value, then no glitch 
should be
       produced where the LED momentarily turns off (or on). The "keep" 
setting
       will keep the LED at whatever its current state is, without 
producing a
       glitch.
"""

I think the issue here is around the meaning of "initial state". I 
believe Naoki is probably thinking about the **HW** initial state of the 
LED, which is whatever is the state of the LED without SW control. I 
think Diederik is thinking about this being the state of the LED right 
when the SW takes over and configures the LED before the trigger is setup.

In the first interpretation, there's no need for an "improvement" for 
the patches as they would just fix correctness of the DT wrt HW state at 
boot.

In the second interpretation, a change of this value must be justified 
as people will simply disagree forever and we could end up with people 
reverting other people's patches after each release. If it's just a 
matter of taste, I believe the typical answer is keeping the status quo.

We should find a way to make this binding not up to interpretation.

Additionally, if the LED cannot be controlled on some boards, I don't 
think it should be part of the DT.

>>>>> - 2nd (Heartbeat) LED
>>>>>
>>>>> The 2nd (heartbeat) LED can be controlled by software. It should be lit
>>>>> up as quickly as possible to indicate that the very first software
>>>>> (e.g., the bootloader) is running.
>>>>>

My understanding is Naoki wants to use default-state = on, for the 
bootloader to turn it on as soon as it takes over control of the LEDs.

>>>>> On Linux, usually this is used as `linux,default-trigger = "heartbeat"`.
>>>>> It indicates that kernel is running (regardless of the `default-state`
>>>>> setting), and its behavior can be modified in user space.
>>>>
>>>> As discussed already in the #linux-rockchip IRC channel, [1] perhaps
>>>> the best option would be to have the power LEDs turned on as quickly
>>>> upon powering on the board as possible, and to have U-Boot pulsate
>>>> the heartbeat LEDs using the LED_BOOT feature.  In such a scenario,
>>>> no other LEDs would be turned on early, and the LED-related DT parts
>>>> specific to U-Boot would be migrated to the kernel DTs.
>>>>
>>>> [1] https://libera.catirclogs.org/linux-rockchip/2025-11-11#38997824;
>>>
>>> The LED_BOOT feature (guarded by the Kconfig symbol of the same name) in
>>> U-Boot only applies if /options/u-boot/boot-led property is set.
>>
>> For the default state of the heartbeat LED, I'm thinking of using
>> LED_BOOT (/options/u-boot/boot-led), but I'm concerned that this is
>> U-Boot-specific.
> 
> If U-Boot wants to use the heartbeat LED to signal the *bootloader* is
> running, I guess that's fine. And if you want to make it solid or
> blinking, that seems best discussed on the U-Boot ML.
> 

The solution may still involve configuring the Device Tree, and we're 
trying to have U-Boot-specific changes to the Device Tree in U-Boot 
source tree to a minimum.

> I still consider the bootloader and the kernel stages separate.

They do however share most of their Device Tree (for Rockchip at least) 
and the least (ideally no) changes we can have in U-Boot the better.

> And I haven't seen an argument why I should change *my* opinion on the
> heartbeat and netdev triggers (default-state) wrt the kernel.
> 

Device Tree is not kernel specific as you said already.

> I don't think that what U-Boot does or doesn't do, should determine what
> the Linux kernel does or doesn't do.

It shouldn't, but (most of) the Device Tree is shared, so you cannot 
just dismiss U-Boot behavior when talking about Linux behavior based on 
Device Tree interpretation. We may have a need for a bootloader-specific 
property. We have a Linux-specific one after all 
(linux,default-trigger). Though... that does seem to be on the edge of 
what the DT is made for (description of the HW, not logic/policy).

> I have no plans to use another bootloader then U-Boot, but it's possible
> that people do, so what the Linux kernel does should be independent from
> what the/a specific bootloader does.
> 

Barebox also uses upstream DT as far as I know and supports some Radxa 
products (Rock 5B/5T/..., CM3, Rock (RK3188), Rock 3A from the 
arch/arm/boards/radxa-* directories). Zephyr has support for RK3568, 
RK3588, and other SoCs, and uses upstream DT as well.

Again, we're talking about modifications of the Device Tree here, so 
typically I would expect all consumers of that DT to be interpreting the 
properties the same way, except if you have OS-specific properties/nodes 
(think u-boot,config-compatible nodes, linux, prefixed properties, 
bootph- properties, ...).

> And as I said before, *I* want LEDs with netdev and heartbeat triggers,
> to be off (at the start, which is indeed the default value).
> I use the heartbeat trigger to:
> 1) See the kernel has started (and has gotten to the point the heartbeat
>     'infrastructure' has been set up
> 2) Wait for the blinking to slow down as that (generally) means it's
>     pretty much done with the boot process and the SSH server should
>     probably be running then, so I can login
> 3) When the heartbeat LED is solid, that means the system has crashed
>     (f.e. due to overheating ...)
> 

If the *HW* default state of the LED is off and the default-state 
property is off, then you won't be able to tell apart a completely 
bricked board and one that is stuck somewhere between U-Boot proper and 
the Linux kernel taking over that LED.

> And also, if you're going to change/override other people's choices, a
> motivation as to why would be 'nice'.
> 
>>> <more discussion about LED functionality in U-Boot ...>
>>
>> As you know, default "default-state" is "off".
>>    https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/leds/common.yaml?h=v6.17#n74
>>
>> As far as I understand, there should not be any workarounds for specific
>> implementations.
>>    https://lore.kernel.org/linux-rockchip/3389401.44csPzL39Z at phil/
>>
>> So removing `default-state = "off"` is acceptable, right?
> 
> I don't see/understand the connection with 'workarounds for specific
> implementations' with removing ``default-state = "off"``.
> 
> IMO it's perfectly fine to remove ``default-state = "off"``, although
> having it explicitly may be useful, especially if the commit that set
> that property specified *why* it should be "off".
> 

The status property defaults to okay, and we do not want them to be 
listed explicitly. Not sure if there's consensus on applying this to all 
properties which have defaults, across all subsystems.

> Relatedly, when a node does not have the 'default-state' property, I
> would _assume_ the author wanted/intended it to be "off". Ideally it
> would be described in the commit message, but that is optional.

The lack of a property doesn't necessarily mean it was forgotten, agreed.

> But if that is changed, then it should be motivated *why*.
> 

Agreed.

Cheers,
Quentin


From hans.zhang at cixtech.com  Wed Nov 12 03:04:10 2025
From: hans.zhang at cixtech.com (Hans Zhang)
Date: Wed, 12 Nov 2025 19:04:10 +0800
Subject: [PATCH v6 1/2] PCI: Configure Root Port MPS during host probing
In-Reply-To: <ef433574-3e81-4636-82c8-9bc3552addca@rock-chips.com>
References: <20251104165125.174168-1-18255117159@163.com>
 <20251104165125.174168-2-18255117159@163.com>
 <ef433574-3e81-4636-82c8-9bc3552addca@rock-chips.com>
Message-ID: <6bd16478-4bf9-436a-b862-02d1ebac3d29@cixtech.com>



On 11/12/2025 4:31 PM, Shawn Lin wrote:
> EXTERNAL EMAIL
> 
> ? 2025/11/05 ??? 0:51, Hans Zhang ??:
>> Current PCIe initialization logic may leave Root Ports (root bridges)
>> operating with non-optimal Maximum Payload Size (MPS) settings. Existing
>> code in pci_configure_mps() returns early for devices without an upstream
>> bridge (!bridge) which includes Root Ports, so their MPS values remain
>> at firmware/hardware defaults. This fails to utilize the controller's 
>> full
>> capabilities, leading to suboptimal data transfer efficiency across the
>> PCIe hierarchy.
>>
>> With this patch, during the host controller probing phase:
>> - When PCIe bus tuning is enabled (not PCIE_BUS_TUNE_OFF), and
>> - The device is a Root Port without an upstream bridge (!bridge),
>> The Root Port's MPS is set to its hardware-supported maximum value
>> (128 << dev->pcie_mpss).
>>
>> Note that this initial maximum MPS setting may be reduced later, during
>> downstream device enumeration, if any downstream device does not suppor
>> the Root Port's maximum MPS.
>>
>> This change ensures Root Ports are properly initialized before downstream
>> devices negotiate MPS, while maintaining backward compatibility via the
>> PCIE_BUS_TUNE_OFF check.
>>
> 
> Tested-by: Shawn Lin <shawn.lin at rock-chips.com>

Hi Shawn,

Thank you for your test.

Best regards,
Hans

> 
>> Suggested-by: Niklas Cassel <cassel at kernel.org>
>> Suggested-by: Manivannan Sadhasivam <mani at kernel.org>
>> Signed-off-by: Hans Zhang <18255117159 at 163.com>
>> ---
>> ? drivers/pci/probe.c | 12 ++++++++++++
>> ? 1 file changed, 12 insertions(+)
>>
>> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
>> index 0ce98e18b5a8..2459def3af9b 100644
>> --- a/drivers/pci/probe.c
>> +++ b/drivers/pci/probe.c
>> @@ -2196,6 +2196,18 @@ static void pci_configure_mps(struct pci_dev *dev)
>> ????????????? return;
>> ????? }
>>
>> +???? /*
>> +????? * Unless MPS strategy is PCIE_BUS_TUNE_OFF (don't touch MPS at 
>> all),
>> +????? * start off by setting Root Ports' MPS to MPSS. This only 
>> applies to
>> +????? * Root Ports without an upstream bridge (root bridges), as 
>> other Root
>> +????? * Ports will have downstream bridges. Depending on the MPS 
>> strategy
>> +????? * and MPSS of downstream devices, the Root Port's MPS may be
>> +????? * overridden later.
>> +????? */
>> +???? if (!bridge && pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT &&
>> +???????? pcie_bus_config != PCIE_BUS_TUNE_OFF)
>> +???????????? pcie_set_mps(dev, 128 << dev->pcie_mpss);
>> +
>> ????? if (!bridge || !pci_is_pcie(bridge))
>> ????????????? return;
>>
> 
> 



From naoki at radxa.com  Wed Nov 12 03:36:54 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Wed, 12 Nov 2025 20:36:54 +0900
Subject: [PATCH v2] arm64: dts: rockchip: Turn all LEDs on at boot for
 Radxa boards
In-Reply-To: <1459ebad-c087-49ac-a316-14436fac4bc6@cherry.de>
References: <20251111054112.55505-1-naoki@radxa.com>
 <DE5W0143QGG2.3C7SW89IJKZ4P@cknow-tech.com>
 <516e919a-42af-8707-4e75-a808df8971fd@manjaro.org>
 <B0C8C5A69B9F465E+ba0ad139-d3d9-4492-ac9a-cc58f8f35074@radxa.com>
 <41275775-9e6e-9202-4c79-6140a56e41d5@manjaro.org>
 <572f341f-a5fa-4f1c-ad60-a5fe3e046d6d@cherry.de>
 <774C3AB9F17BAE47+14f8b8ba-ba78-410e-b44c-4d077585d05a@radxa.com>
 <DE6M84A93WTV.O5IW3BG8TZRW@cknow-tech.com>
 <1459ebad-c087-49ac-a316-14436fac4bc6@cherry.de>
Message-ID: <B53A83D8C3B50A70+1b9d2253-6cf6-476f-b8f7-98552db461c7@radxa.com>

Hi all,

My goal is to minimize the DTS fragments 
(u-boot/arch/arm/dts/*-u-boot.dtsi) in U-Boot, consolidate them 
upstream, and improve clarity/visibility.

On 11/12/25 19:34, Quentin Schulz wrote:
> Hi all,
> 
> On 11/12/25 10:40 AM, Diederik de Haas wrote:
>> [You don't often get email from diederik at cknow-tech.com. Learn why 
>> this is important at https://aka.ms/LearnAboutSenderIdentification ]
>>
>> Hi Naoki,
>>
>> On Wed Nov 12, 2025 at 12:42 AM CET, FUKAUMI Naoki wrote:
>>> On 11/12/25 03:32, Quentin Schulz wrote:
>>>> On 11/11/25 5:14 PM, Dragan Simic wrote:
>>>>> On Tuesday, November 11, 2025 16:32 CET, FUKAUMI Naoki
>>>>> <naoki at radxa.com> wrote:
>>>>>> On 11/11/25 23:46, Dragan Simic wrote:
>>>>>>> On Tuesday, November 11, 2025 14:07 CET, "Diederik de Haas"
>>>>>>> <diederik at cknow-tech.com> wrote:
>>>>>>>> On Tue Nov 11, 2025 at 6:41 AM CET, FUKAUMI Naoki wrote:
>>>>>>>>> Radxa's boards turn all LEDs on at boot(loader), but some boards
>>>>>>>>> don't have `default-state` property in Linux kernel tree but
>>>>>>>>> have it in U-Boot tree instead[1].
>>>>>>>>>
>>>>>>>>> This patch adds `default-state = "on"` for (almost) all LEDs 
>>>>>>>>> (with a
>>>>>>>>> few exceptions which should be "off" such as RGB LEDs on E25 
>>>>>>>>> and LAN/
>>>>>>>>> WAN LEDs on E20C/E52C).
>>>>>>>>
>>>>>>>> I'm missing the *why* these changes would be an improvement.
>>>>>>>>
>>>>>>>> Personally, for both 'heartbeat' and 'netdev' triggers, I want 
>>>>>>>> them to
>>>>>>>> be off by default and once it gets a 'heartbeat' or a 'netdev'
>>>>>>>> trigger, THEN I want the LED to be on/blinking.
>>>>>>>
>>>>>>> That's a good question for Naoki.? My own preference would also
>>>>>>> be to have the device's power LED turned on by U-Boot as quickly
>>>>>>> as possible after supplying power to the board or turning it on
>>>>>>> by pressing the power button.? I'm actually not a big fan of
>>>>>>> having all the LEDs shining for a couple of seconds or so, which
>>>>>>> may actually look like some error condition to me.
>>>>>>>
>>>>>>> Having all that in mind, I may suggest that just the U-Boot's
>>>>>>> behavior is changed to turn the power LEDs on only.
>>>>>>
>>>>>> I can't quite explain it, but...
>>>>>>
>>>>>> - 1st (Power) LED
>>>>>>
>>>>>> The 1st (power) LED turns on automatically/immediately without 
>>>>>> software
>>>>>> intervention. (On some boards, this LED cannot be controlled by 
>>>>>> software
>>>>>> at all.)

I'm not saying the DTS has anything about LEDs that can't be controlled 
by software, nor am I trying to add such a thing to the DTS.

I'm just pointing out that the power LED is always on right after 
power-up. This makes it useless for determining if the software is running.

>>>>>> In DTS, this should be described using `default-state = "on"`. The 
>>>>>> use
>>>>>> of the Linux-specific property `linux,default-trigger = "default- 
>>>>>> on"` is
>>>>>> unsuitable for non-Linux environments.
>>>>>>
> 
> I think the wording in the binding can be understood two ways.
> 
> The binding says the following about the default-state property:
> 
> """
>  ????? The initial state of the LED. If the LED is already on or off and 
> the
>  ????? default-state property is set the to same value, then no glitch 
> should be
>  ????? produced where the LED momentarily turns off (or on). The "keep" 
> setting
>  ????? will keep the LED at whatever its current state is, without 
> producing a
>  ????? glitch.
> """
> 
> I think the issue here is around the meaning of "initial state". I 
> believe Naoki is probably thinking about the **HW** initial state of the 
> LED, which is whatever is the state of the LED without SW control. I 
> think Diederik is thinking about this being the state of the LED right 
> when the SW takes over and configures the LED before the trigger is setup.
> 
> In the first interpretation, there's no need for an "improvement" for 
> the patches as they would just fix correctness of the DT wrt HW state at 
> boot.
> 
> In the second interpretation, a change of this value must be justified 
> as people will simply disagree forever and we could end up with people 
> reverting other people's patches after each release. If it's just a 
> matter of taste, I believe the typical answer is keeping the status quo.
> 
> We should find a way to make this binding not up to interpretation.
> 
> Additionally, if the LED cannot be controlled on some boards, I don't 
> think it should be part of the DT.
> 
>>>>>> - 2nd (Heartbeat) LED
>>>>>>
>>>>>> The 2nd (heartbeat) LED can be controlled by software. It should 
>>>>>> be lit
>>>>>> up as quickly as possible to indicate that the very first software
>>>>>> (e.g., the bootloader) is running.
>>>>>>
> 
> My understanding is Naoki wants to use default-state = on, for the 
> bootloader to turn it on as soon as it takes over control of the LEDs.
> 
>>>>>> On Linux, usually this is used as `linux,default-trigger = 
>>>>>> "heartbeat"`.
>>>>>> It indicates that kernel is running (regardless of the `default- 
>>>>>> state`
>>>>>> setting), and its behavior can be modified in user space.
>>>>>
>>>>> As discussed already in the #linux-rockchip IRC channel, [1] perhaps
>>>>> the best option would be to have the power LEDs turned on as quickly
>>>>> upon powering on the board as possible, and to have U-Boot pulsate
>>>>> the heartbeat LEDs using the LED_BOOT feature.? In such a scenario,
>>>>> no other LEDs would be turned on early, and the LED-related DT parts
>>>>> specific to U-Boot would be migrated to the kernel DTs.
>>>>>
>>>>> [1] https://libera.catirclogs.org/linux-rockchip/2025-11-11#38997824;
>>>>
>>>> The LED_BOOT feature (guarded by the Kconfig symbol of the same 
>>>> name) in
>>>> U-Boot only applies if /options/u-boot/boot-led property is set.
>>>
>>> For the default state of the heartbeat LED, I'm thinking of using
>>> LED_BOOT (/options/u-boot/boot-led), but I'm concerned that this is
>>> U-Boot-specific.
>>
>> If U-Boot wants to use the heartbeat LED to signal the *bootloader* is
>> running, I guess that's fine. And if you want to make it solid or
>> blinking, that seems best discussed on the U-Boot ML.
>>
> 
> The solution may still involve configuring the Device Tree, and we're 
> trying to have U-Boot-specific changes to the Device Tree in U-Boot 
> source tree to a minimum.
> 
>> I still consider the bootloader and the kernel stages separate.
> 
> They do however share most of their Device Tree (for Rockchip at least) 
> and the least (ideally no) changes we can have in U-Boot the better.
> 
>> And I haven't seen an argument why I should change *my* opinion on the
>> heartbeat and netdev triggers (default-state) wrt the kernel.
>>
> 
> Device Tree is not kernel specific as you said already.
> 
>> I don't think that what U-Boot does or doesn't do, should determine what
>> the Linux kernel does or doesn't do.
> 
> It shouldn't, but (most of) the Device Tree is shared, so you cannot 
> just dismiss U-Boot behavior when talking about Linux behavior based on 
> Device Tree interpretation. We may have a need for a bootloader-specific 
> property. We have a Linux-specific one after all (linux,default- 
> trigger). Though... that does seem to be on the edge of what the DT is 
> made for (description of the HW, not logic/policy).
> 
>> I have no plans to use another bootloader then U-Boot, but it's possible
>> that people do, so what the Linux kernel does should be independent from
>> what the/a specific bootloader does.

Each software should be independent, but hardware (state) cannot be 
independent.

> Barebox also uses upstream DT as far as I know and supports some Radxa 
> products (Rock 5B/5T/..., CM3, Rock (RK3188), Rock 3A from the arch/arm/ 
> boards/radxa-* directories). Zephyr has support for RK3568, RK3588, and 
> other SoCs, and uses upstream DT as well.
> 
> Again, we're talking about modifications of the Device Tree here, so 
> typically I would expect all consumers of that DT to be interpreting the 
> properties the same way, except if you have OS-specific properties/nodes 
> (think u-boot,config-compatible nodes, linux, prefixed properties, 
> bootph- properties, ...).
> 
>> And as I said before, *I* want LEDs with netdev and heartbeat triggers,
>> to be off (at the start, which is indeed the default value).

If you are using U-Boot, heartbeat LED is already on by U-Boot,
e.g.
  https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3588s-rock-5a-u-boot.dtsi#L10-12

But it's not visible in DTS in Linux,
e.g.
  https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts?h=v6.17#n55

I think this situation should be fixed.

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

>> I use the heartbeat trigger to:
>> 1) See the kernel has started (and has gotten to the point the heartbeat
>> ??? 'infrastructure' has been set up
>> 2) Wait for the blinking to slow down as that (generally) means it's
>> ??? pretty much done with the boot process and the SSH server should
>> ??? probably be running then, so I can login
>> 3) When the heartbeat LED is solid, that means the system has crashed
>> ??? (f.e. due to overheating ...)
>>
> 
> If the *HW* default state of the LED is off and the default-state 
> property is off, then you won't be able to tell apart a completely 
> bricked board and one that is stuck somewhere between U-Boot proper and 
> the Linux kernel taking over that LED.
> 
>> And also, if you're going to change/override other people's choices, a
>> motivation as to why would be 'nice'.
>>
>>>> <more discussion about LED functionality in U-Boot ...>
>>>
>>> As you know, default "default-state" is "off".
>>> ?? https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/ 
>>> linux.git/tree/Documentation/devicetree/bindings/leds/common.yaml? 
>>> h=v6.17#n74
>>>
>>> As far as I understand, there should not be any workarounds for specific
>>> implementations.
>>> ?? https://lore.kernel.org/linux-rockchip/3389401.44csPzL39Z at phil/
>>>
>>> So removing `default-state = "off"` is acceptable, right?
>>
>> I don't see/understand the connection with 'workarounds for specific
>> implementations' with removing ``default-state = "off"``.
>>
>> IMO it's perfectly fine to remove ``default-state = "off"``, although
>> having it explicitly may be useful, especially if the commit that set
>> that property specified *why* it should be "off".
>>
> 
> The status property defaults to okay, and we do not want them to be 
> listed explicitly. Not sure if there's consensus on applying this to all 
> properties which have defaults, across all subsystems.
> 
>> Relatedly, when a node does not have the 'default-state' property, I
>> would _assume_ the author wanted/intended it to be "off". Ideally it
>> would be described in the commit message, but that is optional.
> 
> The lack of a property doesn't necessarily mean it was forgotten, agreed.
> 
>> But if that is changed, then it should be motivated *why*.
>>
> 
> Agreed.
> 
> Cheers,
> Quentin
> 



From ulf.hansson at linaro.org  Wed Nov 12 03:47:28 2025
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Wed, 12 Nov 2025 12:47:28 +0100
Subject: [PATCH] mmc: dw_mmc-rockchip: Add memory clock auto-gating support
In-Reply-To: <1762242094-55346-1-git-send-email-shawn.lin@rock-chips.com>
References: <1762242094-55346-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <CAPDyKFrGPYKB4eY+r6LKxbujJQt-5F_Ha4paeV0AT3kmY6DQwA@mail.gmail.com>

On Tue, 4 Nov 2025 at 08:41, Shawn Lin <shawn.lin at rock-chips.com> wrote:
>
> Per design recommendations, the memory clock can be gated when there
> is no in-flight transfer, which helps save power. This feature is
> introduced alongside internal phase support, and this patch enables it.
>
> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>

Applied for next, thanks!

Kind regards
Uffe


> ---
>
>  drivers/mmc/host/dw_mmc-rockchip.c | 6 ++++++
>  1 file changed, 6 insertions(+)
>
> diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c
> index 6813549..62c68cd 100644
> --- a/drivers/mmc/host/dw_mmc-rockchip.c
> +++ b/drivers/mmc/host/dw_mmc-rockchip.c
> @@ -19,6 +19,8 @@
>  #define RK3288_CLKGEN_DIV              2
>  #define SDMMC_TIMING_CON0              0x130
>  #define SDMMC_TIMING_CON1              0x134
> +#define SDMMC_MISC_CON                 0x138
> +#define MEM_CLK_AUTOGATE_ENABLE                BIT(5)
>  #define ROCKCHIP_MMC_DELAY_SEL         BIT(10)
>  #define ROCKCHIP_MMC_DEGREE_MASK       0x3
>  #define ROCKCHIP_MMC_DEGREE_OFFSET     1
> @@ -470,6 +472,7 @@ static int dw_mci_rk3576_parse_dt(struct dw_mci *host)
>
>  static int dw_mci_rockchip_init(struct dw_mci *host)
>  {
> +       struct dw_mci_rockchip_priv_data *priv = host->priv;
>         int ret, i;
>
>         /* It is slot 8 on Rockchip SoCs */
> @@ -494,6 +497,9 @@ static int dw_mci_rockchip_init(struct dw_mci *host)
>                         dev_warn(host->dev, "no valid minimum freq: %d\n", ret);
>         }
>
> +       if (priv->internal_phase)
> +               mci_writel(host, MISC_CON, MEM_CLK_AUTOGATE_ENABLE);
> +
>         return 0;
>  }
>
> --
> 2.7.4
>


From ulf.hansson at linaro.org  Wed Nov 12 04:03:44 2025
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Wed, 12 Nov 2025 13:03:44 +0100
Subject: [PATCH 2/2] mmc: sdhci-of-dwcmshc: reduce CIT for better performance
In-Reply-To: <1762933460-204066-2-git-send-email-shawn.lin@rock-chips.com>
References: <1762933460-204066-1-git-send-email-shawn.lin@rock-chips.com> <1762933460-204066-2-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <CAPDyKFqAwP=SDrQ_umkYk0qA50rVt=WJ5giDt8mt+RyBSCQDpQ@mail.gmail.com>

+ cqhci maintainers (Adrian, Asutosh, Ritesh)

On Wed, 12 Nov 2025 at 08:44, Shawn Lin <shawn.lin at rock-chips.com> wrote:
>
> CQHCI_SSC1.CIT indicates to the CQE the polling period to use for
> periodic SEND_QUEUE_STATUS (CMD13) polling. Some eMMCs have only one
> hardware queue, and CMD13 can only query one slot at a time for data
> transmission, which cannot be processed in parallel. Modifying the
> CMD13 query interval can increase the query frequency and improve
> random write performance.
>
> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>

No strong opinion on this, but I looped in the cqhci maintainers to
allow them to chime in.

Kind regards
Uffe

> ---
>
>  drivers/mmc/host/cqhci.h            | 1 +
>  drivers/mmc/host/sdhci-of-dwcmshc.c | 5 +++++
>  2 files changed, 6 insertions(+)
>
> diff --git a/drivers/mmc/host/cqhci.h b/drivers/mmc/host/cqhci.h
> index ce189a1..3668856 100644
> --- a/drivers/mmc/host/cqhci.h
> +++ b/drivers/mmc/host/cqhci.h
> @@ -93,6 +93,7 @@
>  /* send status config 1 */
>  #define CQHCI_SSC1                     0x40
>  #define CQHCI_SSC1_CBC_MASK            GENMASK(19, 16)
> +#define CQHCI_SSC1_CIT_MASK            GENMASK(15, 0)
>
>  /* send status config 2 */
>  #define CQHCI_SSC2                     0x44
> diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c
> index e276a4e..cad5165 100644
> --- a/drivers/mmc/host/sdhci-of-dwcmshc.c
> +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c
> @@ -631,6 +631,11 @@ static void rk35xx_sdhci_cqe_pre_enable(struct mmc_host *mmc)
>         struct dwcmshc_priv *dwc_priv = sdhci_pltfm_priv(pltfm_host);
>         u32 reg;
>
> +       /* Set Send Status Command Idle Timer to 10.66us (256 * 1 / 24) */
> +       reg = sdhci_readl(host, dwc_priv->vendor_specific_area2 + CQHCI_SSC1);
> +       reg = (reg & ~CQHCI_SSC1_CIT_MASK) | 0x0100;
> +       sdhci_writel(host, reg, dwc_priv->vendor_specific_area2 + CQHCI_SSC1);
> +
>         reg = sdhci_readl(host, dwc_priv->vendor_specific_area2 + CQHCI_CFG);
>         reg |= CQHCI_ENABLE;
>         sdhci_writel(host, reg, dwc_priv->vendor_specific_area2 + CQHCI_CFG);
> --
> 2.7.4
>


From diederik at cknow-tech.com  Wed Nov 12 05:21:23 2025
From: diederik at cknow-tech.com (Diederik de Haas)
Date: Wed, 12 Nov 2025 14:21:23 +0100
Subject: [PATCH v2] arm64: dts: rockchip: Turn all LEDs on at boot for
 Radxa boards
In-Reply-To: <B53A83D8C3B50A70+1b9d2253-6cf6-476f-b8f7-98552db461c7@radxa.com>
References: <20251111054112.55505-1-naoki@radxa.com>
 <DE5W0143QGG2.3C7SW89IJKZ4P@cknow-tech.com>
 <516e919a-42af-8707-4e75-a808df8971fd@manjaro.org>
 <B0C8C5A69B9F465E+ba0ad139-d3d9-4492-ac9a-cc58f8f35074@radxa.com>
 <41275775-9e6e-9202-4c79-6140a56e41d5@manjaro.org>
 <572f341f-a5fa-4f1c-ad60-a5fe3e046d6d@cherry.de>
 <774C3AB9F17BAE47+14f8b8ba-ba78-410e-b44c-4d077585d05a@radxa.com>
 <DE6M84A93WTV.O5IW3BG8TZRW@cknow-tech.com>
 <1459ebad-c087-49ac-a316-14436fac4bc6@cherry.de>
 <B53A83D8C3B50A70+1b9d2253-6cf6-476f-b8f7-98552db461c7@radxa.com>
Message-ID: <DE6QX9I0TJSX.3KBGD0MQ10A3P@cknow-tech.com>

Hi,

On Wed Nov 12, 2025 at 12:36 PM CET, FUKAUMI Naoki wrote:
> My goal is to minimize the DTS fragments 
> (u-boot/arch/arm/dts/*-u-boot.dtsi) in U-Boot, consolidate them 
> upstream, and improve clarity/visibility.

Long story short: I was wrong.

It was mostly Quentin's argument/reminder that the DT is about
describing the hardware.
I think Quentin's point about 'initial state' was right on point,
certainly from my perspective and where my logic error came from.

Cheers,
  Diederik

> On 11/12/25 19:34, Quentin Schulz wrote:
>> On 11/12/25 10:40 AM, Diederik de Haas wrote:
>>> [You don't often get email from diederik at cknow-tech.com. Learn why 
>>> this is important at https://aka.ms/LearnAboutSenderIdentification ]
>>>
>>> On Wed Nov 12, 2025 at 12:42 AM CET, FUKAUMI Naoki wrote:
>>>> On 11/12/25 03:32, Quentin Schulz wrote:
>>>>> On 11/11/25 5:14 PM, Dragan Simic wrote:
>>>>>> On Tuesday, November 11, 2025 16:32 CET, FUKAUMI Naoki
>>>>>> <naoki at radxa.com> wrote:
>>>>>>> On 11/11/25 23:46, Dragan Simic wrote:
>>>>>>>> On Tuesday, November 11, 2025 14:07 CET, "Diederik de Haas"
>>>>>>>> <diederik at cknow-tech.com> wrote:
>>>>>>>>> On Tue Nov 11, 2025 at 6:41 AM CET, FUKAUMI Naoki wrote:
>>>>>>>>>> Radxa's boards turn all LEDs on at boot(loader), but some boards
>>>>>>>>>> don't have `default-state` property in Linux kernel tree but
>>>>>>>>>> have it in U-Boot tree instead[1].
>>>>>>>>>>
>>>>>>>>>> This patch adds `default-state = "on"` for (almost) all LEDs 
>>>>>>>>>> (with a
>>>>>>>>>> few exceptions which should be "off" such as RGB LEDs on E25 
>>>>>>>>>> and LAN/
>>>>>>>>>> WAN LEDs on E20C/E52C).
>>>>>>>>>
>>>>>>>>> I'm missing the *why* these changes would be an improvement.
>>>>>>>>>
>>>>>>>>> Personally, for both 'heartbeat' and 'netdev' triggers, I want 
>>>>>>>>> them to
>>>>>>>>> be off by default and once it gets a 'heartbeat' or a 'netdev'
>>>>>>>>> trigger, THEN I want the LED to be on/blinking.
>>>>>>>>
>>>>>>>> That's a good question for Naoki.? My own preference would also
>>>>>>>> be to have the device's power LED turned on by U-Boot as quickly
>>>>>>>> as possible after supplying power to the board or turning it on
>>>>>>>> by pressing the power button.? I'm actually not a big fan of
>>>>>>>> having all the LEDs shining for a couple of seconds or so, which
>>>>>>>> may actually look like some error condition to me.
>>>>>>>>
>>>>>>>> Having all that in mind, I may suggest that just the U-Boot's
>>>>>>>> behavior is changed to turn the power LEDs on only.
>>>>>>>
>>>>>>> I can't quite explain it, but...
>>>>>>>
>>>>>>> - 1st (Power) LED
>>>>>>>
>>>>>>> The 1st (power) LED turns on automatically/immediately without 
>>>>>>> software
>>>>>>> intervention. (On some boards, this LED cannot be controlled by 
>>>>>>> software
>>>>>>> at all.)
>
> I'm not saying the DTS has anything about LEDs that can't be controlled 
> by software, nor am I trying to add such a thing to the DTS.
>
> I'm just pointing out that the power LED is always on right after 
> power-up. This makes it useless for determining if the software is running.
>
>>>>>>> In DTS, this should be described using `default-state = "on"`. The 
>>>>>>> use
>>>>>>> of the Linux-specific property `linux,default-trigger = "default- 
>>>>>>> on"` is
>>>>>>> unsuitable for non-Linux environments.
>>>>>>>
>> 
>> I think the wording in the binding can be understood two ways.
>> 
>> The binding says the following about the default-state property:
>> 
>> """
>>  ????? The initial state of the LED. If the LED is already on or off and 
>> the
>>  ????? default-state property is set the to same value, then no glitch 
>> should be
>>  ????? produced where the LED momentarily turns off (or on). The "keep" 
>> setting
>>  ????? will keep the LED at whatever its current state is, without 
>> producing a
>>  ????? glitch.
>> """
>> 
>> I think the issue here is around the meaning of "initial state". I 
>> believe Naoki is probably thinking about the **HW** initial state of the 
>> LED, which is whatever is the state of the LED without SW control. I 
>> think Diederik is thinking about this being the state of the LED right 
>> when the SW takes over and configures the LED before the trigger is setup.
>> 
>> In the first interpretation, there's no need for an "improvement" for 
>> the patches as they would just fix correctness of the DT wrt HW state at 
>> boot.
>> 
>> In the second interpretation, a change of this value must be justified 
>> as people will simply disagree forever and we could end up with people 
>> reverting other people's patches after each release. If it's just a 
>> matter of taste, I believe the typical answer is keeping the status quo.
>> 
>> We should find a way to make this binding not up to interpretation.
>> 
>> Additionally, if the LED cannot be controlled on some boards, I don't 
>> think it should be part of the DT.
>> 
>>>>>>> - 2nd (Heartbeat) LED
>>>>>>>
>>>>>>> The 2nd (heartbeat) LED can be controlled by software. It should 
>>>>>>> be lit
>>>>>>> up as quickly as possible to indicate that the very first software
>>>>>>> (e.g., the bootloader) is running.
>>>>>>>
>> 
>> My understanding is Naoki wants to use default-state = on, for the 
>> bootloader to turn it on as soon as it takes over control of the LEDs.
>> 
>>>>>>> On Linux, usually this is used as `linux,default-trigger = 
>>>>>>> "heartbeat"`.
>>>>>>> It indicates that kernel is running (regardless of the `default- 
>>>>>>> state`
>>>>>>> setting), and its behavior can be modified in user space.
>>>>>>
>>>>>> As discussed already in the #linux-rockchip IRC channel, [1] perhaps
>>>>>> the best option would be to have the power LEDs turned on as quickly
>>>>>> upon powering on the board as possible, and to have U-Boot pulsate
>>>>>> the heartbeat LEDs using the LED_BOOT feature.? In such a scenario,
>>>>>> no other LEDs would be turned on early, and the LED-related DT parts
>>>>>> specific to U-Boot would be migrated to the kernel DTs.
>>>>>>
>>>>>> [1] https://libera.catirclogs.org/linux-rockchip/2025-11-11#38997824;
>>>>>
>>>>> The LED_BOOT feature (guarded by the Kconfig symbol of the same 
>>>>> name) in
>>>>> U-Boot only applies if /options/u-boot/boot-led property is set.
>>>>
>>>> For the default state of the heartbeat LED, I'm thinking of using
>>>> LED_BOOT (/options/u-boot/boot-led), but I'm concerned that this is
>>>> U-Boot-specific.
>>>
>>> If U-Boot wants to use the heartbeat LED to signal the *bootloader* is
>>> running, I guess that's fine. And if you want to make it solid or
>>> blinking, that seems best discussed on the U-Boot ML.
>>>
>> 
>> The solution may still involve configuring the Device Tree, and we're 
>> trying to have U-Boot-specific changes to the Device Tree in U-Boot 
>> source tree to a minimum.
>> 
>>> I still consider the bootloader and the kernel stages separate.
>> 
>> They do however share most of their Device Tree (for Rockchip at least) 
>> and the least (ideally no) changes we can have in U-Boot the better.
>> 
>>> And I haven't seen an argument why I should change *my* opinion on the
>>> heartbeat and netdev triggers (default-state) wrt the kernel.
>>>
>> 
>> Device Tree is not kernel specific as you said already.
>> 
>>> I don't think that what U-Boot does or doesn't do, should determine what
>>> the Linux kernel does or doesn't do.
>> 
>> It shouldn't, but (most of) the Device Tree is shared, so you cannot 
>> just dismiss U-Boot behavior when talking about Linux behavior based on 
>> Device Tree interpretation. We may have a need for a bootloader-specific 
>> property. We have a Linux-specific one after all (linux,default- 
>> trigger). Though... that does seem to be on the edge of what the DT is 
>> made for (description of the HW, not logic/policy).
>> 
>>> I have no plans to use another bootloader then U-Boot, but it's possible
>>> that people do, so what the Linux kernel does should be independent from
>>> what the/a specific bootloader does.
>
> Each software should be independent, but hardware (state) cannot be 
> independent.
>
>> Barebox also uses upstream DT as far as I know and supports some Radxa 
>> products (Rock 5B/5T/..., CM3, Rock (RK3188), Rock 3A from the arch/arm/ 
>> boards/radxa-* directories). Zephyr has support for RK3568, RK3588, and 
>> other SoCs, and uses upstream DT as well.
>> 
>> Again, we're talking about modifications of the Device Tree here, so 
>> typically I would expect all consumers of that DT to be interpreting the 
>> properties the same way, except if you have OS-specific properties/nodes 
>> (think u-boot,config-compatible nodes, linux, prefixed properties, 
>> bootph- properties, ...).
>> 
>>> And as I said before, *I* want LEDs with netdev and heartbeat triggers,
>>> to be off (at the start, which is indeed the default value).
>
> If you are using U-Boot, heartbeat LED is already on by U-Boot,
> e.g.
>   https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3588s-rock-5a-u-boot.dtsi#L10-12
>
> But it's not visible in DTS in Linux,
> e.g.
>   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts?h=v6.17#n55
>
> I think this situation should be fixed.
>
> Best regards,
>
> --
> FUKAUMI Naoki
> Radxa Computer (Shenzhen) Co., Ltd.
>
>>> I use the heartbeat trigger to:
>>> 1) See the kernel has started (and has gotten to the point the heartbeat
>>> ??? 'infrastructure' has been set up
>>> 2) Wait for the blinking to slow down as that (generally) means it's
>>> ??? pretty much done with the boot process and the SSH server should
>>> ??? probably be running then, so I can login
>>> 3) When the heartbeat LED is solid, that means the system has crashed
>>> ??? (f.e. due to overheating ...)
>>>
>> 
>> If the *HW* default state of the LED is off and the default-state 
>> property is off, then you won't be able to tell apart a completely 
>> bricked board and one that is stuck somewhere between U-Boot proper and 
>> the Linux kernel taking over that LED.
>> 
>>> And also, if you're going to change/override other people's choices, a
>>> motivation as to why would be 'nice'.
>>>
>>>>> <more discussion about LED functionality in U-Boot ...>
>>>>
>>>> As you know, default "default-state" is "off".
>>>> ?? https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/ 
>>>> linux.git/tree/Documentation/devicetree/bindings/leds/common.yaml? 
>>>> h=v6.17#n74
>>>>
>>>> As far as I understand, there should not be any workarounds for specific
>>>> implementations.
>>>> ?? https://lore.kernel.org/linux-rockchip/3389401.44csPzL39Z at phil/
>>>>
>>>> So removing `default-state = "off"` is acceptable, right?
>>>
>>> I don't see/understand the connection with 'workarounds for specific
>>> implementations' with removing ``default-state = "off"``.
>>>
>>> IMO it's perfectly fine to remove ``default-state = "off"``, although
>>> having it explicitly may be useful, especially if the commit that set
>>> that property specified *why* it should be "off".
>>>
>> 
>> The status property defaults to okay, and we do not want them to be 
>> listed explicitly. Not sure if there's consensus on applying this to all 
>> properties which have defaults, across all subsystems.
>> 
>>> Relatedly, when a node does not have the 'default-state' property, I
>>> would _assume_ the author wanted/intended it to be "off". Ideally it
>>> would be described in the commit message, but that is optional.
>> 
>> The lack of a property doesn't necessarily mean it was forgotten, agreed.
>> 
>>> But if that is changed, then it should be motivated *why*.
>>>
>> 
>> Agreed.
>> 
>> Cheers,
>> Quentin
>> 



From diederik at cknow-tech.com  Wed Nov 12 05:23:49 2025
From: diederik at cknow-tech.com (Diederik de Haas)
Date: Wed, 12 Nov 2025 14:23:49 +0100
Subject: [PATCH] drm/rockchip: vop2: Use OVL_LAYER_SEL configuration
 instead of use win_mask calculate used layers
In-Reply-To: <20251112085024.2480111-1-andyshrk@163.com>
References: <20251112085024.2480111-1-andyshrk@163.com>
Message-ID: <DE6QZ4EILEX2.1MQSX07ZMQLCW@cknow-tech.com>

Hi Andy,

On Wed Nov 12, 2025 at 9:50 AM CET, Andy Yan wrote:
> From: Andy Yan <andy.yan at rock-chips.com>
>
> When there are multiple Video Ports, and only one of them is working
> (for example, VP1 is working while VP0 is not), in this case, the
> win_mask of VP0 is 0. However, we have already set the port mux for VP0
> according to vp0->nlayers, and at the same time, in the OVL_LAYER_SEL
> register, there are windows will also be assigned to layers which will
> map to the inactive VPs. In this situation, vp0->win_mask is zero as it
> now working, it is more reliable to calculate the used layers based on
> the configuration of the OVL_LAYER_SEL register.

Thanks a lot for this patch!
I've tested it on my PineTab2 and the 'black box under cursor' problem
is now fixed :-) So feel free to add my

Tested-by: Diederik de Haas <diederik at cknow-tech.com>

Cheers,
  Diederik

> Note: as the configuration of OVL_LAYER_SEL is take effect when the
> vsync is come, so we use the value backup in vop2->old_layer_sel instead
> of read OVL_LAYER_SEL directly.
>
> Fixes: 3e89a8c68354 ("drm/rockchip: vop2: Fix the update of LAYER/PORT select registers when there are multi display output on rk3588/rk3568")
> Reported-by: Diederik de Haas <diederik at cknow-tech.com>
> Closes: https://bugs.kde.org/show_bug.cgi?id=511274
> Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
> ---
>
>  drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 49 +++++++++++++++++---
>  1 file changed, 42 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
> index d22ce11a4235..f3950e8476a7 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
> @@ -1369,6 +1369,25 @@ static const struct vop2_regs_dump rk3588_regs_dump[] = {
>  	},
>  };
>  
> +/*
> + * phys_id is used to identify a main window(Cluster Win/Smart Win, not
> + * include the sub win of a cluster or the multi area) that can do overlay
> + * in main overlay stage.
> + */
> +static struct vop2_win *vop2_find_win_by_phys_id(struct vop2 *vop2, uint8_t phys_id)
> +{
> +	struct vop2_win *win;
> +	int i;
> +
> +	for (i = 0; i < vop2->data->win_size; i++) {
> +		win = &vop2->win[i];
> +		if (win->data->phys_id == phys_id)
> +			return win;
> +	}
> +
> +	return NULL;
> +}
> +
>  static unsigned long rk3568_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags)
>  {
>  	struct vop2 *vop2 = vp->vop2;
> @@ -1842,15 +1861,31 @@ static void vop2_parse_alpha(struct vop2_alpha_config *alpha_config,
>  	alpha->dst_alpha_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE;
>  }
>  
> -static int vop2_find_start_mixer_id_for_vp(struct vop2 *vop2, u8 port_id)
> +static int vop2_find_start_mixer_id_for_vp(struct vop2_video_port *vp)
>  {
> -	struct vop2_video_port *vp;
> -	int used_layer = 0;
> +	struct vop2 *vop2 = vp->vop2;
> +	struct vop2_win *win;
> +	u32 layer_sel = vop2->old_layer_sel;
> +	u32 used_layer = 0;
> +	unsigned long win_mask = vp->win_mask;
> +	unsigned long phys_id;
> +	bool match;
>  	int i;
>  
> -	for (i = 0; i < port_id; i++) {
> -		vp = &vop2->vps[i];
> -		used_layer += hweight32(vp->win_mask);
> +	for (i = 0; i < 31; i += 4) {
> +		match = false;
> +		for_each_set_bit(phys_id, &win_mask, ROCKCHIP_VOP2_ESMART3) {
> +			win = vop2_find_win_by_phys_id(vop2, phys_id);
> +			if (win->data->layer_sel_id[vp->id] == ((layer_sel >> i) & 0xf)) {
> +				match = true;
> +				break;
> +			}
> +		}
> +
> +		if (!match)
> +			used_layer += 1;
> +		else
> +			break;
>  	}
>  
>  	return used_layer;
> @@ -1935,7 +1970,7 @@ static void vop2_setup_alpha(struct vop2_video_port *vp)
>  	u32 dst_global_alpha = DRM_BLEND_ALPHA_OPAQUE;
>  
>  	if (vop2->version <= VOP_VERSION_RK3588)
> -		mixer_id = vop2_find_start_mixer_id_for_vp(vop2, vp->id);
> +		mixer_id = vop2_find_start_mixer_id_for_vp(vp);
>  	else
>  		mixer_id = 0;
>  



From foss+kernel at 0leil.net  Wed Nov 12 07:01:53 2025
From: foss+kernel at 0leil.net (Quentin Schulz)
Date: Wed, 12 Nov 2025 16:01:53 +0100
Subject: [PATCH] arm64: dts: rockchip: disable HS400 on RK3588 Tiger
Message-ID: <20251112-tiger-hs200-v1-1-b50adac107c0@cherry.de>

From: Quentin Schulz <quentin.schulz at cherry.de>

We've had reports from the field that some RK3588 Tiger have random
issues with eMMC errors.

Applying commit a28352cf2d2f ("mmc: sdhci-of-dwcmshc: Change
DLL_STRBIN_TAPNUM_DEFAULT to 0x4") didn't help and seemed to have made
things worse for our board.

Our HW department checked the eMMC lines and reported that they are too
long and don't look great so signal integrity is probably not the best.

Note that not all Tigers with the same eMMC chip have errors, so the
suspicion is that we're really on the edge in terms of signal integrity
and only a handful devices are failing. Additionally, we have RK3588
Jaguars with the same eMMC chip but the layout is different and we also
haven't received reports about those so far.

Lowering the max-frequency to 150MHz from 200MHz instead of simply
disabling HS400 was briefly tested and seem to work as well. We've
disabled HS400 downstream and haven't received reports since so we'll go
with that instead of lowering the max-frequency.

Signed-off-by: Quentin Schulz <quentin.schulz at cherry.de>
---
 arch/arm64/boot/dts/rockchip/rk3588-tiger.dtsi | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-tiger.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-tiger.dtsi
index b44e89e1bb159..365c1d958f2d5 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-tiger.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-tiger.dtsi
@@ -382,14 +382,12 @@ &sdhci {
 	cap-mmc-highspeed;
 	mmc-ddr-1_8v;
 	mmc-hs200-1_8v;
-	mmc-hs400-1_8v;
-	mmc-hs400-enhanced-strobe;
 	mmc-pwrseq = <&emmc_pwrseq>;
 	no-sdio;
 	no-sd;
 	non-removable;
 	pinctrl-names = "default";
-	pinctrl-0 = <&emmc_bus8 &emmc_cmd &emmc_clk &emmc_data_strobe>;
+	pinctrl-0 = <&emmc_bus8 &emmc_cmd &emmc_clk>;
 	vmmc-supply = <&vcc_3v3_s3>;
 	vqmmc-supply = <&vcc_1v8_s3>;
 	status = "okay";

---
base-commit: 6bff916a7e9b6b7f6bd06eb5722e6dfbb777f13e
change-id: 20251112-tiger-hs200-e5b87e1e5835

Best regards,
-- 
Quentin Schulz <quentin.schulz at cherry.de>



From naoki at radxa.com  Wed Nov 12 07:04:39 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Thu, 13 Nov 2025 00:04:39 +0900
Subject: [PATCH v2] arm64: dts: rockchip: Turn all LEDs on at boot for
 Radxa boards
In-Reply-To: <20251111054112.55505-1-naoki@radxa.com>
References: <20251111054112.55505-1-naoki@radxa.com>
Message-ID: <96E7FE4AEF8C8BB4+b7161fa3-d05c-4ee6-9d15-7583de0d9fdf@radxa.com>

Hi all,

How about this?

----
Subject: Consolidates and clarifies LED device tree descriptions on 
Radxa boards

Currently, on Radxa boards, the power LED is turned on immediately after 
power-up, independent of software control. The heartbeat LED and other 
available LEDs are subsequently turned on by the initial software, such 
as U-Boot, to indicate software is running.

However, the device tree description for this behavior is inconsistent 
and fragmented, with definitions split between the main Linux DTS files 
and separate U-Boot files (u-boot/arch/arm/dts/*-u-boot.dtsi).

This patch series addresses this inconsistency and fragmentation by 
consolidating the description within the upstream device tree, thereby 
improving overall clarity.

Patch 1 addresses the inconsistency for the power LED by using 
default-state = "on" instead of linux,default-trigger = "default-on".

Patch 2 addresses the fragmentation for the heartbeat LED by 
consolidating its default-state = "on" definition into the main Linux DTS.

Patch 3 addresses inconsistency by removing redundant default-state = 
"off" definitions, as this is already the default configuration. 
(Alternatively, the opposite could be done: explicitly adding 
default-state = "off" for other LEDs.)
----

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

On 11/11/25 14:41, FUKAUMI Naoki wrote:
> Radxa's boards turn all LEDs on at boot(loader), but some boards don't
> have `default-state` property in Linux kernel tree but have it in
> U-Boot tree instead[1].
> 
> This patch adds `default-state = "on"` for (almost) all LEDs (with a
> few exceptions which should be "off" such as RGB LEDs on E25 and LAN/
> WAN LEDs on E20C/E52C).
> 
> Also, remove following redundant properties:
>   linux,default-trigger = "default-on"; // use default-state = "on"
>   default-state = "off"; // default is "off"
> 
> [1]
>   https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3328-rock-pi-e-base-u-boot.dtsi#L10-12
>   https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3399-rock-4c-plus-u-boot.dtsi#L11-17
>   https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3399-rock-pi-4-u-boot.dtsi#L11-13
>   https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3566-radxa-cm3-io-u-boot.dtsi#L10-12
>   https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3566-rock-3c-u-boot.dtsi#L14-16
>   https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3568-radxa-e25-u-boot.dtsi#L7-24
>   https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3568-rock-3a-u-boot.dtsi#L11-13
>   https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3588-rock-5b-u-boot.dtsi#L11-13
>   https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3588s-rock-5a-u-boot.dtsi#L10-12
> 
> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> ---
> Changes in v2:
> - Add more URLs for reference
> - Reword commit message
> ---
>   arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts    | 1 -
>   arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts    | 1 +
>   arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts | 3 ++-
>   arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi   | 1 +
>   arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts   | 2 --
>   arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts      | 1 -
>   arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts | 1 +
>   arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts      | 1 +
>   arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi  | 1 +
>   arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts      | 1 +
>   arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts      | 3 ++-
>   arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts   | 2 --
>   arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts   | 3 ++-
>   arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi     | 1 +
>   arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts      | 1 +
>   arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts     | 3 ++-
>   16 files changed, 16 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
> index 7a32972bc2496..c1e3098b9a7bc 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
> @@ -35,7 +35,6 @@ green-led {
>   			function = LED_FUNCTION_POWER;
>   			gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
>   			label = "rockpis:green:power";
> -			linux,default-trigger = "default-on";
>   		};
>   
>   		blue-led {
> diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
> index a4bdd87d0729f..d3d6f34b66fb0 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
> @@ -59,6 +59,7 @@ leds {
>   
>   		led-0 {
>   			color = <LED_COLOR_ID_BLUE>;
> +			default-state = "on";
>   			gpios = <&gpio3 RK_PA5 GPIO_ACTIVE_LOW>;
>   			linux,default-trigger = "heartbeat";
>   		};
> diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts
> index 962b8b231c960..a83ffbef22a7b 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts
> @@ -39,14 +39,15 @@ leds {
>   		led-0 {
>   			function = LED_FUNCTION_POWER;
>   			color = <LED_COLOR_ID_GREEN>;
> +			default-state = "on";
>   			gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_LOW>;
> -			linux,default-trigger = "default-on";
>   		};
>   
>   		/* USER_LED2 */
>   		led-1 {
>   			function = LED_FUNCTION_STATUS;
>   			color = <LED_COLOR_ID_BLUE>;
> +			default-state = "on";
>   			gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
>   			linux,default-trigger = "heartbeat";
>   		};
> diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
> index 046dbe3290178..ef434c23fe85c 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
> @@ -35,6 +35,7 @@ leds {
>   		led-0 {
>   			function = LED_FUNCTION_STATUS;
>   			color = <LED_COLOR_ID_BLUE>;
> +			default-state = "on";
>   			gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
>   			linux,default-trigger = "heartbeat";
>   		};
> diff --git a/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts b/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts
> index b324527561558..79d316a1d8495 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts
> @@ -62,7 +62,6 @@ leds {
>   
>   		led-lan {
>   			color = <LED_COLOR_ID_GREEN>;
> -			default-state = "off";
>   			function = LED_FUNCTION_LAN;
>   			gpios = <&gpio4 RK_PB5 GPIO_ACTIVE_HIGH>;
>   			linux,default-trigger = "netdev";
> @@ -78,7 +77,6 @@ led-sys {
>   
>   		led-wan {
>   			color = <LED_COLOR_ID_GREEN>;
> -			default-state = "off";
>   			function = LED_FUNCTION_WAN;
>   			gpios = <&gpio4 RK_PC0 GPIO_ACTIVE_HIGH>;
>   			linux,default-trigger = "netdev";
> diff --git a/arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts b/arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts
> index c03ae1dd34560..0b696d49b71fa 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts
> @@ -45,7 +45,6 @@ led-1 {
>   		default-state = "on";
>   		function = LED_FUNCTION_STATUS;
>   		gpios = <&gpio3 RK_PC1 GPIO_ACTIVE_LOW>;
> -		linux,default-trigger = "default-on";
>   	};
>   };
>   
> diff --git a/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts b/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
> index b5b253f04cdf5..9e7212b70e3f1 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
> @@ -46,6 +46,7 @@ leds {
>   		led-1 {
>   			gpios = <&gpio4 RK_PA4 GPIO_ACTIVE_LOW>;
>   			color = <LED_COLOR_ID_GREEN>;
> +			default-state = "on";
>   			function = LED_FUNCTION_ACTIVITY;
>   			linux,default-trigger = "heartbeat";
>   			pinctrl-names = "default";
> diff --git a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
> index 6224d72813e59..3ec108bcf89a1 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
> @@ -47,6 +47,7 @@ led-0 {
>   			gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
>   			function = LED_FUNCTION_HEARTBEAT;
>   			color = <LED_COLOR_ID_BLUE>;
> +			default-state = "on";
>   			linux,default-trigger = "heartbeat";
>   			pinctrl-names = "default";
>   			pinctrl-0 = <&user_led2>;
> diff --git a/arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi b/arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi
> index 729e38b9f620e..140582f8e1034 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi
> @@ -23,6 +23,7 @@ led_user: led-0 {
>   			gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
>   			function = LED_FUNCTION_HEARTBEAT;
>   			color = <LED_COLOR_ID_GREEN>;
> +			default-state = "on";
>   			linux,default-trigger = "heartbeat";
>   			pinctrl-names = "default";
>   			pinctrl-0 = <&led_user_en>;
> diff --git a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
> index 44cfdfeed6681..e6c18df0fa582 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
> @@ -47,6 +47,7 @@ led_user: led-0 {
>   			gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
>   			function = LED_FUNCTION_HEARTBEAT;
>   			color = <LED_COLOR_ID_BLUE>;
> +			default-state = "on";
>   			linux,default-trigger = "heartbeat";
>   			pinctrl-names = "default";
>   			pinctrl-0 = <&led_user_en>;
> diff --git a/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts b/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts
> index 9bc33422ced50..99d3a8be8f18c 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts
> @@ -52,13 +52,14 @@ leds: leds {
>   
>   		power-led {
>   			color = <LED_COLOR_ID_GREEN>;
> +			default-state = "on";
>   			function = LED_FUNCTION_STATUS;
>   			gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>;
> -			linux,default-trigger = "default-on";
>   		};
>   
>   		user-led {
>   			color = <LED_COLOR_ID_BLUE>;
> +			default-state = "on";
>   			function = LED_FUNCTION_HEARTBEAT;
>   			gpios = <&gpio0 RK_PC4 GPIO_ACTIVE_LOW>;
>   			linux,default-trigger = "heartbeat";
> diff --git a/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts b/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts
> index 854c118418eb8..f737769d4a007 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts
> @@ -71,7 +71,6 @@ leds-1 {
>   
>   		led-1 {
>   			color = <LED_COLOR_ID_GREEN>;
> -			default-state = "off";
>   			function = LED_FUNCTION_LAN;
>   			linux,default-trigger = "netdev";
>   			pwms = <&pwm14 0 1000000 PWM_POLARITY_INVERTED>;
> @@ -80,7 +79,6 @@ led-1 {
>   
>   		led-2 {
>   			color = <LED_COLOR_ID_GREEN>;
> -			default-state = "off";
>   			function = LED_FUNCTION_WAN;
>   			linux,default-trigger = "netdev";
>   			pwms = <&pwm11 0 1000000 PWM_POLARITY_INVERTED>;
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
> index bc8140883de47..86477346c3f5a 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
> @@ -88,11 +88,12 @@ gpio-leds {
>   		pinctrl-0 = <&led_pins>;
>   
>   		power-led1 {
> +			default-state = "on";
>   			gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
> -			linux,default-trigger = "default-on";
>   		};
>   
>   		hdd-led2 {
> +			default-state = "on";
>   			gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>;
>   			linux,default-trigger = "disk-activity";
>   		};
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi
> index e5c474e4d02a6..8c4a4270f9f93 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi
> @@ -30,6 +30,7 @@ leds {
>   		led_rgb_b {
>   			function = LED_FUNCTION_STATUS;
>   			color = <LED_COLOR_ID_BLUE>;
> +			default-state = "on";
>   			gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
>   			linux,default-trigger = "heartbeat";
>   		};
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts
> index 0dd90c744380b..87e9d4b86dad4 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts
> @@ -33,6 +33,7 @@ leds {
>   		led_rgb_b {
>   			function = LED_FUNCTION_STATUS;
>   			color = <LED_COLOR_ID_BLUE>;
> +			default-state = "on";
>   			gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
>   			linux,default-trigger = "heartbeat";
>   		};
> diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
> index 19a08f7794e67..46c81e796b100 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
> @@ -54,6 +54,7 @@ leds {
>   
>   		io-led {
>   			color = <LED_COLOR_ID_BLUE>;
> +			default-state = "on";
>   			function = LED_FUNCTION_STATUS;
>   			gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
>   			linux,default-trigger = "heartbeat";
> @@ -61,9 +62,9 @@ io-led {
>   
>   		power-led {
>   			color = <LED_COLOR_ID_GREEN>;
> +			default-state = "on";
>   			function = LED_FUNCTION_POWER;
>   			gpios = <&gpio3 RK_PC4 GPIO_ACTIVE_HIGH>;
> -			linux,default-trigger = "default-on";
>   		};
>   	};
>   



From mani at kernel.org  Wed Nov 12 09:51:07 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Wed, 12 Nov 2025 23:21:07 +0530
Subject: [PATCH 1/4] PCI: dwc: Advertise L1 PM Substates only if driver
 requests it
In-Reply-To: <aRRDzKFVTFTIuvvh@ryzen>
References: <20251111221621.2208606-1-helgaas@kernel.org>
 <20251111221621.2208606-2-helgaas@kernel.org>
 <aRRDzKFVTFTIuvvh@ryzen>
Message-ID: <22srj63j7fzmsebwxwjnnxnpmdn2iwxo36gkrl36gdm7ge2xif@dmrdbfgu3hn3>

On Wed, Nov 12, 2025 at 09:22:36AM +0100, Niklas Cassel wrote:
> On Tue, Nov 11, 2025 at 04:16:08PM -0600, Bjorn Helgaas wrote:
> > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > @@ -1060,6 +1060,8 @@ int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
> >  		PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
> >  	dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
> >  
> > +	dw_pcie_config_l1ss(pci);
> 
> The name dw_pcie_config_l1ss() sounds like we are enabling l1ss.
> 
> I know naming is hard.
> 
> Perhaps dw_pcie_disable_unsupported_l1ss() ?
> 
> Or something similar.
> 
> 
> > --- a/drivers/pci/controller/dwc/pcie-qcom.c
> > +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> > @@ -1067,6 +1067,8 @@ static int qcom_pcie_init_2_7_0(struct qcom_pcie *pcie)
> >  	val &= ~REQ_NOT_ENTR_L1;
> >  	writel(val, pcie->parf + PARF_PM_CTRL);
> >  
> > +	pci->l1ss_support = true;
> > +
> >  	val = readl(pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
> >  	val |= EN;
> >  	writel(val, pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
> 
> While it seems like ops_2_7_0 is the only type that explicitly does a
> register write to enable L1ss, other versions might have the register
> as enabled by default, so it would be nice if Mani could confirm exactly
> which versions that should set l1ss_support = true.
> 

Yes, on the rest of the platforms, this bit is supposed to be enabled by
default. AFAIK, all Qcom platforms should support L1SS, atleast the
non-IPQ/APQ ones.

We should set it for below cfgs:

cfg_fw_managed
cfg_sc8280xp
cfg_1_34_0
cfg_1_9_0
cfg_2_7_0

I excluded msm8996 due to one recent bug report.

- Mani

-- 
????????? ????????


From conor at kernel.org  Wed Nov 12 11:04:26 2025
From: conor at kernel.org (Conor Dooley)
Date: Wed, 12 Nov 2025 19:04:26 +0000
Subject: [RESEND PATCH v8 1/4] dt-bindings: can: rockchip_canfd: add
 rk3576 CAN controller
In-Reply-To: <20251112015940.3695638-2-zhangqing@rock-chips.com>
References: <20251112015940.3695638-1-zhangqing@rock-chips.com>
 <20251112015940.3695638-2-zhangqing@rock-chips.com>
Message-ID: <20251112-surely-enroll-02a3a3646084@spud>

On Wed, Nov 12, 2025 at 09:59:37AM +0800, Elaine Zhang wrote:
> Add documentation for the rockchip rk3576 CAN controller.
> 
> Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
> ---
>  .../bindings/net/can/rockchip,rk3568v2-canfd.yaml  | 14 ++++++++++----
>  1 file changed, 10 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml b/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml
> index a077c0330013..22e10494e7d1 100644
> --- a/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml
> +++ b/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml
> @@ -10,13 +10,12 @@ title:
>  maintainers:
>    - Marc Kleine-Budde <mkl at pengutronix.de>
>  
> -allOf:
> -  - $ref: can-controller.yaml#

Since in the other mail it was stated that this was removed in error
pw-bot: changes-requested
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251112/14cc9a15/attachment-0001.sig>

From heiko at sntech.de  Wed Nov 12 13:33:44 2025
From: heiko at sntech.de (Heiko =?UTF-8?B?U3TDvGJuZXI=?=)
Date: Wed, 12 Nov 2025 22:33:44 +0100
Subject: [PATCH 2/6] arm64: dts: rockchip: Fix the 1Ghz ethernet on Qnap TS433
In-Reply-To: <e4d3127b-c879-4931-9ea0-de7449bc508c@lunn.ch>
References: <20250925092923.2184187-1-heiko@sntech.de>
 <da752790-da17-4d26-b9b2-8240b38b3276@kwiboo.se>
 <e4d3127b-c879-4931-9ea0-de7449bc508c@lunn.ch>
Message-ID: <3380318.aeNJFYEL58@diego>

Am Donnerstag, 25. September 2025, 19:11:29 Mitteleurop?ische Normalzeit schrieb Andrew Lunn:
> On Thu, Sep 25, 2025 at 06:58:06PM +0200, Jonas Karlman wrote:
> > Hi Heiko,
> > 
> > On 9/25/2025 11:29 AM, Heiko Stuebner wrote:
> > > While I want to remember that the dwmac on the TS433 was working at some
> > > point, it seems I had my network always connected to the 2.5G nic after
> > > that "point". And testing now revealed that the gmac does not actually
> > > manages to transfer data.
> > > 
> > > Currently the gmac is set to rgmii-id with no rx-/tx-delay values set
> > > which makes the driver use default values. Setting the delays to 0
> > > also does not provide a working interface.
> > > 
> > > The vendor kernel is running with phy-mode set to rgmii and delays of
> > >     tx_delay = 0x3c, rx_delay = 0x2f
> > > 
> > > As Andrew points out often, those delay values "are magic" and rgmii-id
> > > should definitly be used "with small values" for delays, if really needed.
> > > 
> > > The Rockchip vendor-kernel actually contains additional code in the dwmac
> > > driver to use the loopback function of a phy to find a window of usable
> > > delay values. Code can be found for example on [0] and the process is
> > > described in a document called "Rockchip GMAC RGMII Delayline Guide"
> > > which has made its way onto the internet in a lot of places [1].
> > > 
> > > So I used this process, with the interface set to rgmii-id to get values
> > > for this mode, which are in face lower than the ones for rgmii with
> > >     tx_delay = 0x21, rx_delay = 0x15
> > > and results in a working interface on the dwmac.
> > > 
> > > [0] https://github.com/armbian/linux-rockchip/blob/rk-6.1-rkr6.1/drivers/net/ethernet/stmicro/stmmac/dwmac-rk-tool.c
> > > [1] https://gitlab.com/firefly-linux/docs/-/blob/rk356x/firefly/Common/GMAC/Rockchip_Developer_Guide_Linux_GMAC_RGMII_Delayline_EN.pdf
> > > 
> > > Cc: Andrew Lunn <andrew at lunn.ch>
> > > Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> > > ---
> > >  arch/arm64/boot/dts/rockchip/rk3568-qnap-ts433.dts | 2 ++
> > >  1 file changed, 2 insertions(+)
> > > 
> > > diff --git a/arch/arm64/boot/dts/rockchip/rk3568-qnap-ts433.dts b/arch/arm64/boot/dts/rockchip/rk3568-qnap-ts433.dts
> > > index 5656554ca284..e8af92a011d6 100644
> > > --- a/arch/arm64/boot/dts/rockchip/rk3568-qnap-ts433.dts
> > > +++ b/arch/arm64/boot/dts/rockchip/rk3568-qnap-ts433.dts
> > > @@ -257,6 +257,8 @@ &gmac0_tx_bus2
> > >  		     &gmac0_rx_bus2
> > >  		     &gmac0_rgmii_clk
> > >  		     &gmac0_rgmii_bus>;
> > > +	rx_delay = <0x15>;
> > > +	tx_delay = <0x21>;
> > 
> > I do not understand why defining rx/tx_delay would change anything.
> 
> I was also wondering why these two properties are added but no change
> to phy-mode.
> 
> > 
> > Setting these should currently not have any effect on the driver code
> > when phy-mode=rgmii-id is used, see below (next-20250924, dwmac-rk.c):
> > 
> > 
> > 	switch (bsp_priv->phy_iface) {
> > 	case PHY_INTERFACE_MODE_RGMII:
> > 		dev_info(dev, "init for RGMII\n");
> > 		bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay,
> > 					    bsp_priv->rx_delay);
> > 		break;
> > 	case PHY_INTERFACE_MODE_RGMII_ID:
> > 		dev_info(dev, "init for RGMII_ID\n");
> > 		bsp_priv->ops->set_to_rgmii(bsp_priv, 0, 0);
> > 		break;
> 
> And this explains it, thanks.
> 
> > I have played around with a few patches that changes this and apply the
> > rx/tx_delay for rgmii-id modes (both Linux and U-Boot), see top of [2]
> > for Linux patches. Will try to get them on ML in a few days.
> 
> We should not really be expanding the use of rx_delay and
> tx_delay. The standardized properties {tx|rx}-internal-delay-ps should
> be used.

as Jonas wrote the delays do nothing for rgmii-id. So the whole thing
must have been me doing something wonky, because on re-testing
everything, it is as expected - no delays necessary and ethernet just
works.

So I'll drop this patch altogether and adapt the TS233 one.

Heiko

Heiko




From heiko at sntech.de  Wed Nov 12 13:42:01 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 12 Nov 2025 22:42:01 +0100
Subject: [PATCH v2 0/5] Some cleanups and addition of another Qnap TSx33 device
Message-ID: <20251112214206.423244-1-heiko@sntech.de>

This fixes the 2nd network adapter on the TS433 and adds the TS233
a 2-bay device being otherwise similar to the TS433.

changes in v2:
- add Conor's Ack on the TS233 binding
- drop TS433 ethernet-delay patch, as that was unneeded and resulted
  from me doing wonky stuff during testing and are completely useless
- drop tx/rx-delays from new TS233 dts as well

Heiko Stuebner (5):
  arm64: dts: rockchip: move cpu_thermal node to the correct position
  arm64: dts: rockchip: describe mcu eeprom cells on rk3568-ts433
  arm64: dts: rockchip: move common qnap tsx33 parts to dtsi
  dt-bindings: arm: rockchip: add TS233 to RK3568-based QNAP NAS devices
  arm64: dts: rockchip: add QNAP TS233 devicetree

 .../devicetree/bindings/arm/rockchip.yaml     |   6 +-
 arch/arm64/boot/dts/rockchip/Makefile         |   1 +
 .../boot/dts/rockchip/rk3568-qnap-ts233.dts   | 131 ++++
 .../boot/dts/rockchip/rk3568-qnap-ts433.dts   | 604 ++---------------
 .../boot/dts/rockchip/rk3568-qnap-tsx33.dtsi  | 608 ++++++++++++++++++
 5 files changed, 781 insertions(+), 569 deletions(-)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-qnap-ts233.dts
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-qnap-tsx33.dtsi

-- 
2.47.2



From heiko at sntech.de  Wed Nov 12 13:42:03 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 12 Nov 2025 22:42:03 +0100
Subject: [PATCH v2 2/5] arm64: dts: rockchip: describe mcu eeprom cells on rk3568-ts433
In-Reply-To: <20251112214206.423244-1-heiko@sntech.de>
References: <20251112214206.423244-1-heiko@sntech.de>
Message-ID: <20251112214206.423244-3-heiko@sntech.de>

The MCU's eeprom contains the unit's serial and a number of slots for
mac-addresses. As the MCU seems to be used in different devices, up to
8 mac addresses can live there and the unused slots are actually
initialized with empty mac-address strings like 00:00:00:00:05:09 .

Interestingly on the TS-433, the PCIe ethernet adapter brings its own
memory to hold its mac, and the gmac0 is supposed to get its mac from
the second mac-slot, while the first one stays empty.

Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
 .../boot/dts/rockchip/rk3568-qnap-ts433.dts   | 62 +++++++++++++++++++
 1 file changed, 62 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-qnap-ts433.dts b/arch/arm64/boot/dts/rockchip/rk3568-qnap-ts433.dts
index 5656554ca284..224db87973b2 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-qnap-ts433.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-qnap-ts433.dts
@@ -655,6 +655,68 @@ fan: fan-0 {
 			#cooling-cells = <2>;
 			cooling-levels = <0 64 89 128 166 204 221 238>;
 		};
+
+		nvmem-layout {
+			compatible = "fixed-layout";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			serial-number at 0 {
+				reg = <0x0 0x13>;
+			};
+
+			ext-port at 22 {
+				reg = <0x22 0x2>;
+			};
+
+			mac0: mac at 24 {
+				compatible = "mac-base";
+				reg = <0x24 0x11>;
+				#nvmem-cell-cells = <1>;
+			};
+
+			mac1: mac at 35 {
+				compatible = "mac-base";
+				reg = <0x35 0x11>;
+				#nvmem-cell-cells = <1>;
+			};
+
+			mac2: mac at 46 {
+				compatible = "mac-base";
+				reg = <0x46 0x11>;
+				#nvmem-cell-cells = <1>;
+			};
+
+			mac3: mac at 57 {
+				compatible = "mac-base";
+				reg = <0x57 0x11>;
+				#nvmem-cell-cells = <1>;
+			};
+
+			mac4: mac at 68 {
+				compatible = "mac-base";
+				reg = <0x68 0x11>;
+				#nvmem-cell-cells = <1>;
+			};
+
+			mac5: mac at 79 {
+				compatible = "mac-base";
+				reg = <0x79 0x11>;
+				#nvmem-cell-cells = <1>;
+			};
+
+			mac6: mac at 8a {
+				compatible = "mac-base";
+				reg = <0x8a 0x11>;
+				#nvmem-cell-cells = <1>;
+			};
+
+			mac7: mac at 9b {
+				compatible = "mac-base";
+				reg = <0x9b 0x11>;
+				#nvmem-cell-cells = <1>;
+			};
+		};
 	};
 };
 
-- 
2.47.2



From heiko at sntech.de  Wed Nov 12 13:42:04 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 12 Nov 2025 22:42:04 +0100
Subject: [PATCH v2 3/5] arm64: dts: rockchip: move common qnap tsx33 parts to dtsi
In-Reply-To: <20251112214206.423244-1-heiko@sntech.de>
References: <20251112214206.423244-1-heiko@sntech.de>
Message-ID: <20251112214206.423244-4-heiko@sntech.de>

The NAS series based around the rk3568 contains a number of models with
1-4 drives, that reuse most of the board structure.

Therefore move the shared parts to a dtsi, to be included by the devices.

As the smallest device is the 1-bay TS133, keep everything > slot1 in
the individual devicetree.

Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
 .../boot/dts/rockchip/rk3568-qnap-ts433.dts   | 666 +-----------------
 .../boot/dts/rockchip/rk3568-qnap-tsx33.dtsi  | 608 ++++++++++++++++
 2 files changed, 645 insertions(+), 629 deletions(-)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-qnap-tsx33.dtsi

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-qnap-ts433.dts b/arch/arm64/boot/dts/rockchip/rk3568-qnap-ts433.dts
index 224db87973b2..d1e3b7e7a280 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-qnap-ts433.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-qnap-ts433.dts
@@ -6,10 +6,7 @@
 
 /dts-v1/;
 
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/leds/common.h>
-#include <dt-bindings/gpio/gpio.h>
-#include "rk3568.dtsi"
+#include "rk3568-qnap-tsx33.dtsi"
 
 / {
 	model = "Qnap TS-433-4G NAS System 4-Bay";
@@ -17,83 +14,6 @@ / {
 
 	aliases {
 		ethernet0 = &gmac0;
-		mmc0 = &sdhci;
-		rtc0 = &rtc_rv8263;
-	};
-
-	chosen {
-		stdout-path = "serial2:115200n8";
-	};
-
-	keys {
-		compatible = "gpio-keys";
-		pinctrl-0 = <&copy_button_pin>, <&reset_button_pin>;
-		pinctrl-names = "default";
-
-		key-copy {
-			label = "copy";
-			gpios = <&gpio0 RK_PB6 GPIO_ACTIVE_LOW>;
-			linux,code = <KEY_COPY>;
-		};
-
-		key-reset {
-			label = "reset";
-			gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_LOW>;
-			linux,code = <KEY_RESTART>;
-		};
-	};
-
-	leds {
-		compatible = "gpio-leds";
-
-		led-0 {
-			color = <LED_COLOR_ID_GREEN>;
-			function = LED_FUNCTION_DISK;
-			gpios = <&gpio1 RK_PD5 GPIO_ACTIVE_LOW>;
-			label = "hdd1:green:disk";
-			linux,default-trigger = "disk-activity";
-			pinctrl-names = "default";
-			pinctrl-0 = <&hdd1_led_pin>;
-		};
-
-		led-1 {
-			color = <LED_COLOR_ID_GREEN>;
-			function = LED_FUNCTION_DISK;
-			gpios = <&gpio1 RK_PD6 GPIO_ACTIVE_LOW>;
-			label = "hdd2:green:disk";
-			linux,default-trigger = "disk-activity";
-			pinctrl-names = "default";
-			pinctrl-0 = <&hdd2_led_pin>;
-		};
-
-		led-2 {
-			color = <LED_COLOR_ID_GREEN>;
-			function = LED_FUNCTION_DISK;
-			gpios = <&gpio1 RK_PD7 GPIO_ACTIVE_LOW>;
-			label = "hdd3:green:disk";
-			linux,default-trigger = "disk-activity";
-			pinctrl-names = "default";
-			pinctrl-0 = <&hdd3_led_pin>;
-		};
-
-		led-3 {
-			color = <LED_COLOR_ID_GREEN>;
-			function = LED_FUNCTION_DISK;
-			gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>;
-			label = "hdd4:green:disk";
-			linux,default-trigger = "disk-activity";
-			pinctrl-names = "default";
-			pinctrl-0 = <&hdd4_led_pin>;
-		};
-	};
-
-	dc_12v: regulator-dc-12v {
-		compatible = "regulator-fixed";
-		regulator-name = "dc_12v";
-		regulator-always-on;
-		regulator-boot-on;
-		regulator-min-microvolt = <12000000>;
-		regulator-max-microvolt = <12000000>;
 	};
 
 	vcc3v3_pcie: regulator-vcc3v3-pcie {
@@ -105,74 +25,6 @@ vcc3v3_pcie: regulator-vcc3v3-pcie {
 		gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>;
 		vin-supply = <&dc_12v>;
 	};
-
-	vcc3v3_sys: regulator-vcc3v3-sys {
-		compatible = "regulator-fixed";
-		regulator-name = "vcc3v3_sys";
-		regulator-always-on;
-		regulator-boot-on;
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		vin-supply = <&dc_12v>;
-	};
-
-	vcc5v0_host: regulator-vcc5v0-host {
-		compatible = "regulator-fixed";
-		enable-active-high;
-		pinctrl-names = "default";
-		pinctrl-0 = <&vcc5v0_host_en>;
-		gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
-		regulator-name = "vcc5v0_host";
-		regulator-always-on;
-		regulator-boot-on;
-		regulator-min-microvolt = <5000000>;
-		regulator-max-microvolt = <5000000>;
-		vin-supply = <&vcc5v0_usb>;
-	};
-
-	vcc5v0_otg: regulator-vcc5v0-otg {
-		compatible = "regulator-fixed";
-		enable-active-high;
-		gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&vcc5v0_otg_en>;
-		regulator-name = "vcc5v0_otg";
-		regulator-always-on;
-		regulator-boot-on;
-		regulator-min-microvolt = <5000000>;
-		regulator-max-microvolt = <5000000>;
-		vin-supply = <&vcc5v0_usb>;
-	};
-
-	vcc5v0_sys: regulator-vcc5v0-sys {
-		compatible = "regulator-fixed";
-		regulator-name = "vcc5v0_sys";
-		regulator-always-on;
-		regulator-boot-on;
-		regulator-min-microvolt = <5000000>;
-		regulator-max-microvolt = <5000000>;
-		vin-supply = <&dc_12v>;
-	};
-
-	vcc5v0_usb: regulator-vcc5v0-usb {
-		compatible = "regulator-fixed";
-		regulator-name = "vcc5v0_usb";
-		regulator-always-on;
-		regulator-boot-on;
-		regulator-min-microvolt = <5000000>;
-		regulator-max-microvolt = <5000000>;
-		vin-supply = <&dc_12v>;
-	};
-};
-
-/* connected to usb_host0_xhci */
-&combphy0 {
-	status = "okay";
-};
-
-/* connected to sata1 */
-&combphy1 {
-	status = "okay";
 };
 
 /* connected to sata2 */
@@ -180,70 +32,6 @@ &combphy2 {
 	status = "okay";
 };
 
-&cpu0 {
-	cpu-supply = <&vdd_cpu>;
-};
-
-&cpu1 {
-	cpu-supply = <&vdd_cpu>;
-};
-
-&cpu2 {
-	cpu-supply = <&vdd_cpu>;
-};
-
-&cpu3 {
-	cpu-supply = <&vdd_cpu>;
-};
-
-/*
- * The MCU can provide system temperature too, but only by polling and of
- * course also cannot set trip points. So attach to the cpu thermal-zone
- * instead to control the fan.
- */
-&cpu_thermal {
-	trips {
-		case_fan0: case-fan0 {
-			hysteresis = <2000>;
-			temperature = <35000>;
-			type = "active";
-		};
-
-		case_fan1: case-fan1 {
-			hysteresis = <2000>;
-			temperature = <45000>;
-			type = "active";
-		};
-
-		case_fan2: case-fan2 {
-			hysteresis = <2000>;
-			temperature = <65000>;
-			type = "active";
-		};
-	};
-
-	cooling-maps {
-		/*
-		 * Always provide some air movement, due to small case
-		 * full of harddrives.
-		 */
-		map1 {
-			cooling-device = <&fan THERMAL_NO_LIMIT 1>;
-			trip = <&case_fan0>;
-		};
-
-		map2 {
-			cooling-device = <&fan 2 3>;
-			trip = <&case_fan1>;
-		};
-
-		map3 {
-			cooling-device = <&fan 4 THERMAL_NO_LIMIT>;
-			trip = <&case_fan2>;
-		};
-	};
-};
-
 &gmac0 {
 	assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>;
 	assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>, <&cru CLK_MAC0_2TOP>;
@@ -260,263 +48,7 @@ &gmac0_rgmii_clk
 	status = "okay";
 };
 
-&gpu {
-	mali-supply = <&vdd_gpu>;
-	status = "okay";
-};
-
-&i2c0 {
-	status = "okay";
-
-	pmic at 20 {
-		compatible = "rockchip,rk809";
-		reg = <0x20>;
-		interrupt-parent = <&gpio0>;
-		interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
-		#clock-cells = <1>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&pmic_int_l>;
-		system-power-controller;
-		vcc1-supply = <&vcc3v3_sys>;
-		vcc2-supply = <&vcc3v3_sys>;
-		vcc3-supply = <&vcc3v3_sys>;
-		vcc4-supply = <&vcc3v3_sys>;
-		vcc5-supply = <&vcc3v3_sys>;
-		vcc6-supply = <&vcc3v3_sys>;
-		vcc7-supply = <&vcc3v3_sys>;
-		vcc8-supply = <&vcc3v3_sys>;
-		vcc9-supply = <&vcc3v3_sys>;
-		wakeup-source;
-
-		regulators {
-			vdd_logic: DCDC_REG1 {
-				regulator-name = "vdd_logic";
-				regulator-always-on;
-				regulator-boot-on;
-				regulator-initial-mode = <0x2>;
-				regulator-min-microvolt = <500000>;
-				regulator-max-microvolt = <1350000>;
-				regulator-ramp-delay = <6001>;
-
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			vdd_gpu: DCDC_REG2 {
-				regulator-name = "vdd_gpu";
-				regulator-always-on;
-				regulator-initial-mode = <0x2>;
-				regulator-min-microvolt = <500000>;
-				regulator-max-microvolt = <1350000>;
-				regulator-ramp-delay = <6001>;
-
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			vcc_ddr: DCDC_REG3 {
-				regulator-name = "vcc_ddr";
-				regulator-always-on;
-				regulator-boot-on;
-				regulator-initial-mode = <0x2>;
-
-				regulator-state-mem {
-					regulator-on-in-suspend;
-				};
-			};
-
-			vdd_npu: DCDC_REG4 {
-				regulator-name = "vdd_npu";
-				regulator-initial-mode = <0x2>;
-				regulator-min-microvolt = <500000>;
-				regulator-max-microvolt = <1350000>;
-				regulator-ramp-delay = <6001>;
-
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			vcc_1v8: DCDC_REG5 {
-				regulator-name = "vcc_1v8";
-				regulator-always-on;
-				regulator-boot-on;
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			vdda0v9_image: LDO_REG1 {
-				regulator-name = "vdda0v9_image";
-				regulator-always-on;
-				regulator-min-microvolt = <900000>;
-				regulator-max-microvolt = <900000>;
-
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			vdda_0v9: LDO_REG2 {
-				regulator-name = "vdda_0v9";
-				regulator-always-on;
-				regulator-boot-on;
-				regulator-min-microvolt = <900000>;
-				regulator-max-microvolt = <900000>;
-
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			vdda0v9_pmu: LDO_REG3 {
-				regulator-name = "vdda0v9_pmu";
-				regulator-always-on;
-				regulator-boot-on;
-				regulator-min-microvolt = <900000>;
-				regulator-max-microvolt = <900000>;
-
-				regulator-state-mem {
-					regulator-on-in-suspend;
-					regulator-suspend-microvolt = <900000>;
-				};
-			};
-
-			vccio_acodec: LDO_REG4 {
-				regulator-name = "vccio_acodec";
-				regulator-always-on;
-				regulator-boot-on;
-				regulator-min-microvolt = <3300000>;
-				regulator-max-microvolt = <3300000>;
-
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			vccio_sd: LDO_REG5 {
-				regulator-name = "vccio_sd";
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <3300000>;
-
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			vcc3v3_pmu: LDO_REG6 {
-				regulator-name = "vcc3v3_pmu";
-				regulator-always-on;
-				regulator-boot-on;
-				regulator-min-microvolt = <3300000>;
-				regulator-max-microvolt = <3300000>;
-
-				regulator-state-mem {
-					regulator-on-in-suspend;
-					regulator-suspend-microvolt = <3300000>;
-				};
-			};
-
-			vcca_1v8: LDO_REG7 {
-				regulator-name = "vcca_1v8";
-				regulator-always-on;
-				regulator-boot-on;
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			vcca1v8_pmu: LDO_REG8 {
-				regulator-name = "vcca1v8_pmu";
-				regulator-always-on;
-				regulator-boot-on;
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-
-				regulator-state-mem {
-					regulator-on-in-suspend;
-					regulator-suspend-microvolt = <1800000>;
-				};
-			};
-
-			vcca1v8_image: LDO_REG9 {
-				regulator-name = "vcca1v8_image";
-				regulator-always-on;
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <1800000>;
-
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			vcc_3v3: SWITCH_REG1 {
-				regulator-name = "vcc_3v3";
-				regulator-always-on;
-				regulator-boot-on;
-
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-
-			vcc3v3_sd: SWITCH_REG2 {
-				regulator-name = "vcc3v3_sd";
-				/*
-				 * turning this off, breaks access to both
-				 * PCIe controllers, refclk generator perhaps
-				 */
-				regulator-always-on;
-				regulator-boot-on;
-
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
-		};
-	};
-
-	vdd_cpu: regulator at 40 {
-		compatible = "silergy,syr827";
-		reg = <0x40>;
-		fcs,suspend-voltage-selector = <1>;
-		regulator-name = "vdd_cpu";
-		regulator-always-on;
-		regulator-boot-on;
-		regulator-min-microvolt = <712500>;
-		regulator-max-microvolt = <1390000>;
-		regulator-ramp-delay = <2300>;
-		vin-supply = <&vcc5v0_sys>;
-	};
-};
-
 &i2c1 {
-	status = "okay";
-
-	rtc_rv8263: rtc at 51 {
-		compatible = "microcrystal,rv8263";
-		reg = <0x51>;
-		wakeup-source;
-	};
-
-	/* eeprom for vital-product-data on the mainboard */
-	eeprom at 54 {
-		compatible = "giantec,gt24c04a", "atmel,24c04";
-		reg = <0x54>;
-		label = "VPD_MB";
-		num-addresses = <2>;
-		pagesize = <16>;
-		read-only;
-	};
-
 	/* eeprom for vital-product-data on the backplane */
 	eeprom at 56 {
 		compatible = "giantec,gt24c04a", "atmel,24c04";
@@ -528,6 +60,42 @@ eeprom at 56 {
 	};
 };
 
+&leds {
+	led-1 {
+		color = <LED_COLOR_ID_GREEN>;
+		function = LED_FUNCTION_DISK;
+		gpios = <&gpio1 RK_PD6 GPIO_ACTIVE_LOW>;
+		label = "hdd2:green:disk";
+		linux,default-trigger = "disk-activity";
+		pinctrl-names = "default";
+		pinctrl-0 = <&hdd2_led_pin>;
+	};
+
+	led-2 {
+		color = <LED_COLOR_ID_GREEN>;
+		function = LED_FUNCTION_DISK;
+		gpios = <&gpio1 RK_PD7 GPIO_ACTIVE_LOW>;
+		label = "hdd3:green:disk";
+		linux,default-trigger = "disk-activity";
+		pinctrl-names = "default";
+		pinctrl-0 = <&hdd3_led_pin>;
+	};
+
+	led-3 {
+		color = <LED_COLOR_ID_GREEN>;
+		function = LED_FUNCTION_DISK;
+		gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>;
+		label = "hdd4:green:disk";
+		linux,default-trigger = "disk-activity";
+		pinctrl-names = "default";
+		pinctrl-0 = <&hdd4_led_pin>;
+	};
+};
+
+&mcu {
+	compatible = "qnap,ts433-mcu";
+};
+
 &mdio0 {
 	rgmii_phy0: ethernet-phy at 3 {
 		/* Motorcomm YT8521 phy */
@@ -567,21 +135,7 @@ eth_phy0_reset_pin: eth-phy0-reset-pin {
 		};
 	};
 
-	keys {
-		copy_button_pin: copy-button-pin {
-			rockchip,pins = <0 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>;
-		};
-
-		reset_button_pin: reset-button-pin {
-			rockchip,pins = <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>;
-		};
-	};
-
 	leds {
-		hdd1_led_pin: hdd1-led-pin {
-			rockchip,pins = <1 RK_PD5 RK_FUNC_GPIO &pcfg_pull_up>;
-		};
-
 		hdd2_led_pin: hdd2-led-pin {
 			rockchip,pins = <1 RK_PD6 RK_FUNC_GPIO &pcfg_pull_up>;
 		};
@@ -594,152 +148,12 @@ hdd4_led_pin: hdd4_led-pin {
 			rockchip,pins = <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>;
 		};
 	};
-
-	pmic {
-		pmic_int_l: pmic-int-l {
-			rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
-		};
-	};
-
-	usb {
-		vcc5v0_host_en: vcc5v0-host-en {
-			rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
-		};
-
-		vcc5v0_otg_en: vcc5v0-otg-en {
-			rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
-		};
-	};
-};
-
-&pmu_io_domains {
-	vccio4-supply = <&vcc_1v8>;
-	vccio6-supply = <&vcc_1v8>;
-	status = "okay";
-};
-
-&sata1 {
-	status = "okay";
 };
 
 &sata2 {
 	status = "okay";
 };
 
-&sdhci {
-	bus-width = <8>;
-	max-frequency = <200000000>;
-	non-removable;
-	pinctrl-names = "default";
-	pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
-	status = "okay";
-};
-
-&tsadc {
-	rockchip,hw-tshut-mode = <1>;
-	rockchip,hw-tshut-polarity = <0>;
-	status = "okay";
-};
-
-/*
- * Connected to an MCU, that provides access to more LEDs,
- * buzzer, fan control and more.
- */
-&uart0 {
-	status = "okay";
-
-	mcu {
-		compatible = "qnap,ts433-mcu";
-
-		fan: fan-0 {
-			#cooling-cells = <2>;
-			cooling-levels = <0 64 89 128 166 204 221 238>;
-		};
-
-		nvmem-layout {
-			compatible = "fixed-layout";
-			#address-cells = <1>;
-			#size-cells = <1>;
-
-			serial-number at 0 {
-				reg = <0x0 0x13>;
-			};
-
-			ext-port at 22 {
-				reg = <0x22 0x2>;
-			};
-
-			mac0: mac at 24 {
-				compatible = "mac-base";
-				reg = <0x24 0x11>;
-				#nvmem-cell-cells = <1>;
-			};
-
-			mac1: mac at 35 {
-				compatible = "mac-base";
-				reg = <0x35 0x11>;
-				#nvmem-cell-cells = <1>;
-			};
-
-			mac2: mac at 46 {
-				compatible = "mac-base";
-				reg = <0x46 0x11>;
-				#nvmem-cell-cells = <1>;
-			};
-
-			mac3: mac at 57 {
-				compatible = "mac-base";
-				reg = <0x57 0x11>;
-				#nvmem-cell-cells = <1>;
-			};
-
-			mac4: mac at 68 {
-				compatible = "mac-base";
-				reg = <0x68 0x11>;
-				#nvmem-cell-cells = <1>;
-			};
-
-			mac5: mac at 79 {
-				compatible = "mac-base";
-				reg = <0x79 0x11>;
-				#nvmem-cell-cells = <1>;
-			};
-
-			mac6: mac at 8a {
-				compatible = "mac-base";
-				reg = <0x8a 0x11>;
-				#nvmem-cell-cells = <1>;
-			};
-
-			mac7: mac at 9b {
-				compatible = "mac-base";
-				reg = <0x9b 0x11>;
-				#nvmem-cell-cells = <1>;
-			};
-		};
-	};
-};
-
-/*
- * Pins available on CN3 connector at TTL voltage level (3V3).
- * ,_  _.
- * |1234|  1=TX 2=VCC
- * `----'  3=RX 4=GND
- */
-&uart2 {
-	status = "okay";
-};
-
-&usb2phy0 {
-	status = "okay";
-};
-
-/* connected to usb_host0_xhci */
-&usb2phy0_otg {
-	phy-supply = <&vcc5v0_otg>;
-	status = "okay";
-};
-
 &usb2phy1 {
 	status = "okay";
 };
@@ -765,12 +179,6 @@ &usb_host0_ohci {
 	status = "okay";
 };
 
-/* front port */
-&usb_host0_xhci {
-	dr_mode = "host";
-	status = "okay";
-};
-
 /* left port backside */
 &usb_host1_ehci {
 	status = "okay";
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-qnap-tsx33.dtsi b/arch/arm64/boot/dts/rockchip/rk3568-qnap-tsx33.dtsi
new file mode 100644
index 000000000000..f009275c72c8
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3568-qnap-tsx33.dtsi
@@ -0,0 +1,608 @@
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/gpio/gpio.h>
+#include "rk3568.dtsi"
+
+/ {
+	aliases {
+		mmc0 = &sdhci;
+		rtc0 = &rtc_rv8263;
+	};
+
+	chosen {
+		stdout-path = "serial2:115200n8";
+	};
+
+	keys {
+		compatible = "gpio-keys";
+		pinctrl-0 = <&copy_button_pin>, <&reset_button_pin>;
+		pinctrl-names = "default";
+
+		key-copy {
+			label = "copy";
+			gpios = <&gpio0 RK_PB6 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_COPY>;
+		};
+
+		key-reset {
+			label = "reset";
+			gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+		};
+	};
+
+	leds: leds {
+		compatible = "gpio-leds";
+
+		led-0 {
+			color = <LED_COLOR_ID_GREEN>;
+			function = LED_FUNCTION_DISK;
+			gpios = <&gpio1 RK_PD5 GPIO_ACTIVE_LOW>;
+			label = "hdd1:green:disk";
+			linux,default-trigger = "disk-activity";
+			pinctrl-names = "default";
+			pinctrl-0 = <&hdd1_led_pin>;
+		};
+	};
+
+	dc_12v: regulator-dc-12v {
+		compatible = "regulator-fixed";
+		regulator-name = "dc_12v";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+	};
+
+	vcc3v3_sys: regulator-vcc3v3-sys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&dc_12v>;
+	};
+
+	vcc5v0_host: regulator-vcc5v0-host {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc5v0_host_en>;
+		gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
+		regulator-name = "vcc5v0_host";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc5v0_usb>;
+	};
+
+	vcc5v0_otg: regulator-vcc5v0-otg {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc5v0_otg_en>;
+		regulator-name = "vcc5v0_otg";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc5v0_usb>;
+	};
+
+	vcc5v0_sys: regulator-vcc5v0-sys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&dc_12v>;
+	};
+
+	vcc5v0_usb: regulator-vcc5v0-usb {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_usb";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&dc_12v>;
+	};
+};
+
+/* connected to usb_host0_xhci */
+&combphy0 {
+	status = "okay";
+};
+
+/* connected to sata1 */
+&combphy1 {
+	status = "okay";
+};
+
+&cpu0 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu1 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu2 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu3 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+/*
+ * The MCU can provide system temperature too, but only by polling and of
+ * course also cannot set trip points. So attach to the cpu thermal-zone
+ * instead to control the fan.
+ */
+&cpu_thermal {
+	trips {
+		case_fan0: case-fan0 {
+			hysteresis = <2000>;
+			temperature = <35000>;
+			type = "active";
+		};
+
+		case_fan1: case-fan1 {
+			hysteresis = <2000>;
+			temperature = <45000>;
+			type = "active";
+		};
+
+		case_fan2: case-fan2 {
+			hysteresis = <2000>;
+			temperature = <65000>;
+			type = "active";
+		};
+	};
+
+	cooling-maps {
+		/*
+		 * Always provide some air movement, due to small case
+		 * full of harddrives.
+		 */
+		map1 {
+			cooling-device = <&fan THERMAL_NO_LIMIT 1>;
+			trip = <&case_fan0>;
+		};
+
+		map2 {
+			cooling-device = <&fan 2 3>;
+			trip = <&case_fan1>;
+		};
+
+		map3 {
+			cooling-device = <&fan 4 THERMAL_NO_LIMIT>;
+			trip = <&case_fan2>;
+		};
+	};
+};
+
+&gpu {
+	mali-supply = <&vdd_gpu>;
+	status = "okay";
+};
+
+&i2c0 {
+	status = "okay";
+
+	pmic at 20 {
+		compatible = "rockchip,rk809";
+		reg = <0x20>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
+		#clock-cells = <1>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_int_l>;
+		system-power-controller;
+		vcc1-supply = <&vcc3v3_sys>;
+		vcc2-supply = <&vcc3v3_sys>;
+		vcc3-supply = <&vcc3v3_sys>;
+		vcc4-supply = <&vcc3v3_sys>;
+		vcc5-supply = <&vcc3v3_sys>;
+		vcc6-supply = <&vcc3v3_sys>;
+		vcc7-supply = <&vcc3v3_sys>;
+		vcc8-supply = <&vcc3v3_sys>;
+		vcc9-supply = <&vcc3v3_sys>;
+		wakeup-source;
+
+		regulators {
+			vdd_logic: DCDC_REG1 {
+				regulator-name = "vdd_logic";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-initial-mode = <0x2>;
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_gpu: DCDC_REG2 {
+				regulator-name = "vdd_gpu";
+				regulator-always-on;
+				regulator-initial-mode = <0x2>;
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_ddr: DCDC_REG3 {
+				regulator-name = "vcc_ddr";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-initial-mode = <0x2>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			vdd_npu: DCDC_REG4 {
+				regulator-name = "vdd_npu";
+				regulator-initial-mode = <0x2>;
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_1v8: DCDC_REG5 {
+				regulator-name = "vcc_1v8";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda0v9_image: LDO_REG1 {
+				regulator-name = "vdda0v9_image";
+				regulator-always-on;
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda_0v9: LDO_REG2 {
+				regulator-name = "vdda_0v9";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda0v9_pmu: LDO_REG3 {
+				regulator-name = "vdda0v9_pmu";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <900000>;
+				};
+			};
+
+			vccio_acodec: LDO_REG4 {
+				regulator-name = "vccio_acodec";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vccio_sd: LDO_REG5 {
+				regulator-name = "vccio_sd";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc3v3_pmu: LDO_REG6 {
+				regulator-name = "vcc3v3_pmu";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vcca_1v8: LDO_REG7 {
+				regulator-name = "vcca_1v8";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcca1v8_pmu: LDO_REG8 {
+				regulator-name = "vcca1v8_pmu";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vcca1v8_image: LDO_REG9 {
+				regulator-name = "vcca1v8_image";
+				regulator-always-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_3v3: SWITCH_REG1 {
+				regulator-name = "vcc_3v3";
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc3v3_sd: SWITCH_REG2 {
+				regulator-name = "vcc3v3_sd";
+				/*
+				 * turning this off, breaks access to both
+				 * PCIe controllers, refclk generator perhaps
+				 */
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+		};
+	};
+
+	vdd_cpu: regulator at 40 {
+		compatible = "silergy,syr827";
+		reg = <0x40>;
+		fcs,suspend-voltage-selector = <1>;
+		regulator-name = "vdd_cpu";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <712500>;
+		regulator-max-microvolt = <1390000>;
+		regulator-ramp-delay = <2300>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+};
+
+&i2c1 {
+	status = "okay";
+
+	rtc_rv8263: rtc at 51 {
+		compatible = "microcrystal,rv8263";
+		reg = <0x51>;
+		wakeup-source;
+	};
+
+	/* eeprom for vital-product-data on the mainboard */
+	eeprom at 54 {
+		compatible = "giantec,gt24c04a", "atmel,24c04";
+		reg = <0x54>;
+		label = "VPD_MB";
+		num-addresses = <2>;
+		pagesize = <16>;
+		read-only;
+	};
+};
+
+&pinctrl {
+	keys {
+		copy_button_pin: copy-button-pin {
+			rockchip,pins = <0 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+
+		reset_button_pin: reset-button-pin {
+			rockchip,pins = <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	leds {
+		hdd1_led_pin: hdd1-led-pin {
+			rockchip,pins = <1 RK_PD5 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	pmic {
+		pmic_int_l: pmic-int-l {
+			rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	usb {
+		vcc5v0_host_en: vcc5v0-host-en {
+			rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		vcc5v0_otg_en: vcc5v0-otg-en {
+			rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
+
+&pmu_io_domains {
+	vccio4-supply = <&vcc_1v8>;
+	vccio6-supply = <&vcc_1v8>;
+	status = "okay";
+};
+
+&sata1 {
+	status = "okay";
+};
+
+&sdhci {
+	bus-width = <8>;
+	max-frequency = <200000000>;
+	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
+	status = "okay";
+};
+
+&tsadc {
+	rockchip,hw-tshut-mode = <1>;
+	rockchip,hw-tshut-polarity = <0>;
+	status = "okay";
+};
+
+/*
+ * Connected to an MCU, that provides access to more LEDs,
+ * buzzer, fan control and more.
+ */
+&uart0 {
+	status = "okay";
+
+	mcu: mcu {
+		fan: fan-0 {
+			#cooling-cells = <2>;
+			cooling-levels = <0 64 89 128 166 204 221 238>;
+		};
+
+		nvmem-layout {
+			compatible = "fixed-layout";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			serial-number at 0 {
+				reg = <0x0 0x13>;
+			};
+
+			ext-port at 22 {
+				reg = <0x22 0x2>;
+			};
+
+			mac0: mac at 24 {
+				compatible = "mac-base";
+				reg = <0x24 0x11>;
+				#nvmem-cell-cells = <1>;
+			};
+
+			mac1: mac at 35 {
+				compatible = "mac-base";
+				reg = <0x35 0x11>;
+				#nvmem-cell-cells = <1>;
+			};
+
+			mac2: mac at 46 {
+				compatible = "mac-base";
+				reg = <0x46 0x11>;
+				#nvmem-cell-cells = <1>;
+			};
+
+			mac3: mac at 57 {
+				compatible = "mac-base";
+				reg = <0x57 0x11>;
+				#nvmem-cell-cells = <1>;
+			};
+
+			mac4: mac at 68 {
+				compatible = "mac-base";
+				reg = <0x68 0x11>;
+				#nvmem-cell-cells = <1>;
+			};
+
+			mac5: mac at 79 {
+				compatible = "mac-base";
+				reg = <0x79 0x11>;
+				#nvmem-cell-cells = <1>;
+			};
+
+			mac6: mac at 8a {
+				compatible = "mac-base";
+				reg = <0x8a 0x11>;
+				#nvmem-cell-cells = <1>;
+			};
+
+			mac7: mac at 9b {
+				compatible = "mac-base";
+				reg = <0x9b 0x11>;
+				#nvmem-cell-cells = <1>;
+			};
+		};
+	};
+};
+
+/*
+ * Pins available on CN3 connector at TTL voltage level (3V3).
+ * ,_  _.
+ * |1234|  1=TX 2=VCC
+ * `----'  3=RX 4=GND
+ */
+&uart2 {
+	status = "okay";
+};
+
+&usb2phy0 {
+	status = "okay";
+};
+
+/* connected to usb_host0_xhci */
+&usb2phy0_otg {
+	phy-supply = <&vcc5v0_otg>;
+	status = "okay";
+};
+
+/* front port */
+&usb_host0_xhci {
+	dr_mode = "host";
+	status = "okay";
+};
-- 
2.47.2



From heiko at sntech.de  Wed Nov 12 13:42:02 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 12 Nov 2025 22:42:02 +0100
Subject: [PATCH v2 1/5] arm64: dts: rockchip: move cpu_thermal node to the correct position
In-Reply-To: <20251112214206.423244-1-heiko@sntech.de>
References: <20251112214206.423244-1-heiko@sntech.de>
Message-ID: <20251112214206.423244-2-heiko@sntech.de>

The &cpu_thermal node was added at the wrong position, move it to
the correctly sorted one.

Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
 .../boot/dts/rockchip/rk3568-qnap-ts433.dts   | 96 +++++++++----------
 1 file changed, 48 insertions(+), 48 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-qnap-ts433.dts b/arch/arm64/boot/dts/rockchip/rk3568-qnap-ts433.dts
index 6ae4316761c4..5656554ca284 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-qnap-ts433.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-qnap-ts433.dts
@@ -196,6 +196,54 @@ &cpu3 {
 	cpu-supply = <&vdd_cpu>;
 };
 
+/*
+ * The MCU can provide system temperature too, but only by polling and of
+ * course also cannot set trip points. So attach to the cpu thermal-zone
+ * instead to control the fan.
+ */
+&cpu_thermal {
+	trips {
+		case_fan0: case-fan0 {
+			hysteresis = <2000>;
+			temperature = <35000>;
+			type = "active";
+		};
+
+		case_fan1: case-fan1 {
+			hysteresis = <2000>;
+			temperature = <45000>;
+			type = "active";
+		};
+
+		case_fan2: case-fan2 {
+			hysteresis = <2000>;
+			temperature = <65000>;
+			type = "active";
+		};
+	};
+
+	cooling-maps {
+		/*
+		 * Always provide some air movement, due to small case
+		 * full of harddrives.
+		 */
+		map1 {
+			cooling-device = <&fan THERMAL_NO_LIMIT 1>;
+			trip = <&case_fan0>;
+		};
+
+		map2 {
+			cooling-device = <&fan 2 3>;
+			trip = <&case_fan1>;
+		};
+
+		map3 {
+			cooling-device = <&fan 4 THERMAL_NO_LIMIT>;
+			trip = <&case_fan2>;
+		};
+	};
+};
+
 &gmac0 {
 	assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>;
 	assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>, <&cru CLK_MAC0_2TOP>;
@@ -492,54 +540,6 @@ rgmii_phy0: ethernet-phy at 3 {
 	};
 };
 
-/*
- * The MCU can provide system temperature too, but only by polling and of
- * course also cannot set trip points. So attach to the cpu thermal-zone
- * instead to control the fan.
- */
-&cpu_thermal {
-	trips {
-		case_fan0: case-fan0 {
-			hysteresis = <2000>;
-			temperature = <35000>;
-			type = "active";
-		};
-
-		case_fan1: case-fan1 {
-			hysteresis = <2000>;
-			temperature = <45000>;
-			type = "active";
-		};
-
-		case_fan2: case-fan2 {
-			hysteresis = <2000>;
-			temperature = <65000>;
-			type = "active";
-		};
-	};
-
-	cooling-maps {
-		/*
-		 * Always provide some air movement, due to small case
-		 * full of harddrives.
-		 */
-		map1 {
-			cooling-device = <&fan THERMAL_NO_LIMIT 1>;
-			trip = <&case_fan0>;
-		};
-
-		map2 {
-			cooling-device = <&fan 2 3>;
-			trip = <&case_fan1>;
-		};
-
-		map3 {
-			cooling-device = <&fan 4 THERMAL_NO_LIMIT>;
-			trip = <&case_fan2>;
-		};
-	};
-};
-
 &pcie30phy {
 	data-lanes = <1 2>;
 	status = "okay";
-- 
2.47.2



From heiko at sntech.de  Wed Nov 12 13:42:05 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 12 Nov 2025 22:42:05 +0100
Subject: [PATCH v2 4/5] dt-bindings: arm: rockchip: add TS233 to RK3568-based QNAP NAS devices
In-Reply-To: <20251112214206.423244-1-heiko@sntech.de>
References: <20251112214206.423244-1-heiko@sntech.de>
Message-ID: <20251112214206.423244-5-heiko@sntech.de>

QNAP builds a number of variants of the RK3568-based NAS design.

Add the 2-bay TS233 variant.

Acked-by: Conor Dooley <conor.dooley at microchip.com>
Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
 Documentation/devicetree/bindings/arm/rockchip.yaml | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
index 6aceaa8acbb2..790f910aa38b 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.yaml
+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
@@ -868,9 +868,11 @@ properties:
           - const: prt,mecsbc
           - const: rockchip,rk3568
 
-      - description: QNAP TS-433-4G 4-Bay NAS
+      - description: QNAP TS-x33 NAS devices
         items:
-          - const: qnap,ts433
+          - enum:
+              - qnap,ts233
+              - qnap,ts433
           - const: rockchip,rk3568
 
       - description: Radxa Compute Module 3 (CM3)
-- 
2.47.2



From heiko at sntech.de  Wed Nov 12 13:42:06 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 12 Nov 2025 22:42:06 +0100
Subject: [PATCH v2 5/5] arm64: dts: rockchip: add QNAP TS233 devicetree
In-Reply-To: <20251112214206.423244-1-heiko@sntech.de>
References: <20251112214206.423244-1-heiko@sntech.de>
Message-ID: <20251112214206.423244-6-heiko@sntech.de>

The TS233 is a 2 bay NAS similar to the TS433. Architecture-wise it really
seems to be the same minus the additional PCIe connected components the
TS433 has.

So it just uses two of the SoCs SATA ports and the SoC's gigabit ethernet.

Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
 arch/arm64/boot/dts/rockchip/Makefile         |   1 +
 .../boot/dts/rockchip/rk3568-qnap-ts233.dts   | 131 ++++++++++++++++++
 2 files changed, 132 insertions(+)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-qnap-ts233.dts

diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index ad684e3831bc..d1d384df00b7 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -142,6 +142,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-nanopi-r5c.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-nanopi-r5s.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-odroid-m1.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-photonicat.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-qnap-ts233.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-qnap-ts433.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-radxa-e25.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-roc-pc.dtb
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-qnap-ts233.dts b/arch/arm64/boot/dts/rockchip/rk3568-qnap-ts233.dts
new file mode 100644
index 000000000000..f16d1c628793
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3568-qnap-ts233.dts
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
+ * Copyright (c) 2024 Heiko Stuebner <heiko at sntech.de>
+ */
+
+/dts-v1/;
+
+#include "rk3568-qnap-tsx33.dtsi"
+
+/ {
+	model = "Qnap TS-233-2G NAS System 2-Bay";
+	compatible = "qnap,ts233", "rockchip,rk3568";
+
+	aliases {
+		ethernet0 = &gmac0;
+	};
+};
+
+/* connected to sata2 */
+&combphy2 {
+	status = "okay";
+};
+
+&gmac0 {
+	assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>;
+	assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>, <&cru CLK_MAC0_2TOP>;
+	assigned-clock-rates = <0>, <125000000>;
+	clock_in_out = "output";
+	phy-handle = <&rgmii_phy0>;
+	phy-mode = "rgmii-id";
+	pinctrl-names = "default";
+	pinctrl-0 = <&gmac0_miim
+		     &gmac0_tx_bus2
+		     &gmac0_rx_bus2
+		     &gmac0_rgmii_clk
+		     &gmac0_rgmii_bus>;
+	status = "okay";
+};
+
+&i2c1 {
+	/* eeprom for vital-product-data on the backplane */
+	eeprom at 56 {
+		compatible = "giantec,gt24c04a", "atmel,24c04";
+		reg = <0x56>;
+		label = "VPD_BP";
+		num-addresses = <2>;
+		pagesize = <16>;
+		read-only;
+	};
+};
+
+&leds {
+	led-1 {
+		color = <LED_COLOR_ID_GREEN>;
+		function = LED_FUNCTION_DISK;
+		gpios = <&gpio1 RK_PD6 GPIO_ACTIVE_LOW>;
+		label = "hdd2:green:disk";
+		linux,default-trigger = "disk-activity";
+		pinctrl-names = "default";
+		pinctrl-0 = <&hdd2_led_pin>;
+	};
+};
+
+&mcu {
+	compatible = "qnap,ts233-mcu";
+};
+
+&mdio0 {
+	rgmii_phy0: ethernet-phy at 3 {
+		/* Motorcomm YT8521 phy */
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0x3>;
+		pinctrl-0 = <&eth_phy0_reset_pin>;
+		pinctrl-names = "default";
+		reset-assert-us = <10000>;
+		reset-gpios = <&gpio0 RK_PC6 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&pinctrl {
+	gmac0 {
+		eth_phy0_reset_pin: eth-phy0-reset-pin {
+			rockchip,pins = <0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	leds {
+		hdd2_led_pin: hdd2-led-pin {
+			rockchip,pins = <1 RK_PD6 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+};
+
+&sata2 {
+	status = "okay";
+};
+
+&usb2phy1 {
+	status = "okay";
+};
+
+/* connected to usb_host1_ehci/ohci */
+&usb2phy1_host {
+	phy-supply = <&vcc5v0_host>;
+	status = "okay";
+};
+
+/* connected to usb_host0_ehci/ohci */
+&usb2phy1_otg {
+	phy-supply = <&vcc5v0_host>;
+	status = "okay";
+};
+
+/* right port backside */
+&usb_host0_ehci {
+	status = "okay";
+};
+
+&usb_host0_ohci {
+	status = "okay";
+};
+
+/* left port backside */
+&usb_host1_ehci {
+	status = "okay";
+};
+
+&usb_host1_ohci {
+	status = "okay";
+};
-- 
2.47.2



From geraldogabriel at gmail.com  Wed Nov 12 17:09:03 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Wed, 12 Nov 2025 22:09:03 -0300
Subject: [PATCH] arm64: dts: rockchip: align bindings to PCIe spec
In-Reply-To: <aRQ_R90S8T82th45@geday>
References: <4b5ffcccfef2a61838aa563521672a171acb27b2.1762321976.git.geraldogabriel@gmail.com>
 <ba120577-42da-424d-8102-9d085c1494c8@rock-chips.com>
 <aQsIXcQzeYop6a0B@geday>
 <67b605b0-7046-448a-bc9b-d3ac56333809@rock-chips.com>
 <aQ1c7ZDycxiOIy8Y@geday>
 <d9e257bd-806c-48b4-bb22-f1342e9fc15a@rock-chips.com>
 <aRLEbfsmXnGwyigS@geday>
 <AGsAmwCFJj0ZQ4vKzrqC84rs.3.1762847224180.Hmail.ye.zhang@rock-chips.com>
 <aRQ_R90S8T82th45@geday>
Message-ID: <aRUvr0UggTYkkCZ_@geday>

On Wed, Nov 12, 2025 at 05:03:32AM -0300, Geraldo Nascimento wrote:
> On Tue, Nov 11, 2025 at 03:47:04PM +0800, ?? wrote:
> > Hi Geraldo,
> > 
> > In standard GPIO operations, the typical practice is to set the output level first before configuring the direction as output. This approach helps avoid outputting an uncertain voltage level at the instant when the direction switches from input to output.
> 
> Thanks for the explanation Ye Zhang, it makes sense to me. It avoids the
> pin to not be floating so to speak. I kept hammering at this problem, by
> the way is PCIe PERST# side-band signal refusing to co-operate and
> failing PCIe initial link-training.
> 
> You're not going to like this:
> 
> diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
> index 47174eb3ba76..fea2c55992e8 100644
> --- a/drivers/gpio/gpio-rockchip.c
> +++ b/drivers/gpio/gpio-rockchip.c
> @@ -183,11 +183,13 @@ static int rockchip_gpio_set(struct gpio_chip *gc, unsigned int offset,
>  	struct rockchip_pin_bank *bank = gpiochip_get_data(gc);
>  	unsigned long flags;
>  
> +	rockchip_gpio_set_direction(gc, offset, true);
> +
>  	raw_spin_lock_irqsave(&bank->slock, flags);
>  	rockchip_gpio_writel_bit(bank, offset, value, bank->gpio_regs->port_dr);
>  	raw_spin_unlock_irqrestore(&bank->slock, flags);
>  
> -	return 0;
> +	return rockchip_gpio_set_direction(gc, offset, false);
>  }
>  
>  static int rockchip_gpio_get(struct gpio_chip *gc, unsigned int offset)
> 
> By setting direction INPUT, then writing out, then setting OUTPUT again
> miraculously it doesn't fail initial link training, with no other
> changes that already have been rejected by PCI folks and Shawn Lin.

Hi Ye, Shawn,

Here's more contained workaround without resorting to clearing DDR to
INPUT for every GPIO:

diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c
index ee1822ca01db..1d89131ec6ac 100644
--- a/drivers/pci/controller/pcie-rockchip-host.c
+++ b/drivers/pci/controller/pcie-rockchip-host.c
@@ -315,7 +315,8 @@ static int rockchip_pcie_host_init_port(struct rockchip_pcie *rockchip)
 			    PCIE_CLIENT_CONFIG);
 
 	msleep(PCIE_T_PVPERL_MS);
-	gpiod_set_value_cansleep(rockchip->perst_gpio, 1);
+	gpiod_direction_input(rockchip->perst_gpio);
+	gpiod_direction_output(rockchip->perst_gpio, 1);
 
 	msleep(PCIE_RESET_CONFIG_WAIT_MS);
 
This results in working PCIe for me, pass initial link training.

I think I need to provide more details:

GPIO in question is GPIO0-12 / GPIO0-PB4. On RK3399PRO VMARC schematic
it's called PCIE_PERST#_3.3V and it's in the PMUIO1 domain.

Without workaround I have about 6 milliseconds, from driver probe and
parsing of DT that sets initial value 0 for GPIO, to deassert PERST#
by setting it high. Which is why just removing msleep(PCIE_T_PVPERL_MS)
produced working PCIe for me.

After the ~6 ms it becomes necessary to hack direction to input then
setting direction to output to properly deassert PERST# and proceed
with initial link training - which is why, again, hacking PERST# as
either open-drain with pull-up or open-source with pull-down worked:
gpiolib hacks that by setting direction INPUT.

Thanks,
Geraldo Nascimento


From shawn.lin at rock-chips.com  Wed Nov 12 19:00:28 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Thu, 13 Nov 2025 11:00:28 +0800
Subject: [PATCH] phy: rockchip: naneng-combphy: Fix PCIe L1ss support
Message-ID: <1763002828-212219-1-git-send-email-shawn.lin@rock-chips.com>

Need to control the delay PLL turnoff time if PCIe works on
L1 PM substates.

Fixes: bbcca4fac873 ("phy: rockchip: naneng-combphy: Add RK3528 support")
Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
---

 drivers/phy/rockchip/phy-rockchip-naneng-combphy.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
index a3ef198..af9a5c7 100644
--- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
+++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
@@ -21,6 +21,9 @@
 #define REF_CLOCK_100MHz		(100 * HZ_PER_MHZ)
 
 /* RK3528 COMBO PHY REG */
+#define RK3528_PHYREG5				0x14
+#define RK3528_PHYREG5_GATE_TX_PCK_SEL		BIT(3)
+#define RK3528_PHYREG5_GATE_TX_PCK_DLY_PLL_OFF	BIT(3)
 #define RK3528_PHYREG6				0x18
 #define RK3528_PHYREG6_PLL_KVCO			GENMASK(12, 10)
 #define RK3528_PHYREG6_PLL_KVCO_VALUE		0x2
@@ -504,6 +507,11 @@ static int rk3528_combphy_cfg(struct rockchip_combphy_priv *priv)
 	case REF_CLOCK_100MHz:
 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
 		if (priv->type == PHY_TYPE_PCIE) {
+			/* Gate_tx_pck_sel length select for L1ss support */
+			rockchip_combphy_updatel(priv, RK3528_PHYREG5_GATE_TX_PCK_SEL,
+						 RK3528_PHYREG5_GATE_TX_PCK_DLY_PLL_OFF,
+						 RK3528_PHYREG5);
+
 			/* PLL KVCO tuning fine */
 			val = FIELD_PREP(RK3528_PHYREG6_PLL_KVCO, RK3528_PHYREG6_PLL_KVCO_VALUE);
 			rockchip_combphy_updatel(priv, RK3528_PHYREG6_PLL_KVCO, val,
-- 
2.7.4



From shawn.lin at rock-chips.com  Wed Nov 12 19:27:58 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Thu, 13 Nov 2025 11:27:58 +0800
Subject: [PATCH] phy: rockchip: naneng-combphy: Fix PCIe L1ss support
Message-ID: <1763004478-218446-1-git-send-email-shawn.lin@rock-chips.com>

Need to control the delay PLL turnoff time if PCIe works on
L1 PM substates.

Fixes: f13bff25161b ("phy: rockchip-naneng-combo: Support rk3562")
Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
---

 drivers/phy/rockchip/phy-rockchip-naneng-combphy.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
index af9a5c7..5b6f80e 100644
--- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
+++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
@@ -106,6 +106,10 @@
 #define RK3568_PHYREG18				0x44
 #define RK3568_PHYREG18_PLL_LOOP		0x32
 
+#define RK3568_PHYREG30				0x74
+#define RK3568_PHYREG30_GATE_TX_PCK_SEL         BIT(7)
+#define RK3568_PHYREG30_GATE_TX_PCK_DLY_PLL_OFF BIT(7)
+
 #define RK3568_PHYREG32				0x7C
 #define RK3568_PHYREG32_SSC_MASK		GENMASK(7, 4)
 #define RK3568_PHYREG32_SSC_DIR_MASK		GENMASK(5, 4)
@@ -665,6 +669,11 @@ static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv)
 	case REF_CLOCK_100MHz:
 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
 		if (priv->type == PHY_TYPE_PCIE) {
+			/* Gate_tx_pck_sel length select for L1ss support */
+			rockchip_combphy_updatel(priv, RK3568_PHYREG30_GATE_TX_PCK_SEL,
+						 RK3568_PHYREG30_GATE_TX_PCK_DLY_PLL_OFF,
+						 RK3568_PHYREG30);
+
 			/* PLL KVCO tuning fine */
 			val = FIELD_PREP(RK3568_PHYREG33_PLL_KVCO_MASK,
 					 RK3568_PHYREG33_PLL_KVCO_VALUE);
-- 
2.7.4



From shawn.lin at rock-chips.com  Wed Nov 12 20:52:55 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Thu, 13 Nov 2025 12:52:55 +0800
Subject: [PATCH] scsi: ufs: rockchip: Reset controller on PRE_CHANGE of hce enable notify
Message-ID: <1763009575-237552-1-git-send-email-shawn.lin@rock-chips.com>

This fixes the dme-reset failed when doing recoverying, because device
reset is not enough, we could occasionally see the error below:

ufshcd-rockchip 2a2d0000.ufs: uic cmd 0x14 with arg3 0x0 completion timeout
ufshcd-rockchip 2a2d0000.ufs: dme-reset: error code -110
ufshcd-rockchip 2a2d0000.ufs: DME_RESET failed
ufshcd-rockchip 2a2d0000.ufs: ufshcd_host_reset_and_restore: Host init failed -110

Fix this by resetting the controller on PRE_CHANGE stage of hce enable
notify.

Fixes: d3cbe455d6eb ("scsi: ufs: rockchip: Initial support for UFS")
Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
---

 drivers/ufs/host/ufs-rockchip.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/ufs/host/ufs-rockchip.c b/drivers/ufs/host/ufs-rockchip.c
index 8754085..8cecb28 100644
--- a/drivers/ufs/host/ufs-rockchip.c
+++ b/drivers/ufs/host/ufs-rockchip.c
@@ -20,9 +20,17 @@
 #include "ufshcd-pltfrm.h"
 #include "ufs-rockchip.h"
 
+static void ufs_rockchip_controller_reset(struct ufs_rockchip_host *host)
+{
+	reset_control_assert(host->rst);
+	udelay(1);
+	reset_control_deassert(host->rst);
+}
+
 static int ufs_rockchip_hce_enable_notify(struct ufs_hba *hba,
 					 enum ufs_notify_change_status status)
 {
+	struct ufs_rockchip_host *host = ufshcd_get_variant(hba);
 	int err = 0;
 
 	if (status == POST_CHANGE) {
@@ -37,6 +45,9 @@ static int ufs_rockchip_hce_enable_notify(struct ufs_hba *hba,
 		return ufshcd_vops_phy_initialization(hba);
 	}
 
+	/* PRE_CHANGE */
+	ufs_rockchip_controller_reset(host);
+
 	return 0;
 }
 
@@ -156,9 +167,7 @@ static int ufs_rockchip_common_init(struct ufs_hba *hba)
 		return dev_err_probe(dev, PTR_ERR(host->rst),
 				"failed to get reset control\n");
 
-	reset_control_assert(host->rst);
-	udelay(1);
-	reset_control_deassert(host->rst);
+	ufs_rockchip_controller_reset(host);
 
 	host->ref_out_clk = devm_clk_get_enabled(dev, "ref_out");
 	if (IS_ERR(host->ref_out_clk))
@@ -282,9 +291,7 @@ static int ufs_rockchip_runtime_resume(struct device *dev)
 		return err;
 	}
 
-	reset_control_assert(host->rst);
-	udelay(1);
-	reset_control_deassert(host->rst);
+	ufs_rockchip_controller_reset(host);
 
 	return ufshcd_runtime_resume(dev);
 }
-- 
2.7.4



From shawn.lin at rock-chips.com  Wed Nov 12 21:18:11 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Thu, 13 Nov 2025 13:18:11 +0800
Subject: [PATCH] scsi: ufs: rockchip: Fix compile error without CONFIG_GPIOLIB
Message-ID: <1763011091-243727-1-git-send-email-shawn.lin@rock-chips.com>

drivers/ufs/host/ufs-rockchip.c:168:19: error: implicit declaration of function
'devm_gpiod_get'; did you mean 'em_pd_get'? [-Werror=implicit-function-declaration]

drivers/ufs/host/ufs-rockchip.c:214:2: error: implicit declaration of function
'gpiod_set_value_cansleep'; did you mean 'gpio_set_value_cansleep'?
[-Werror=implicit-function-declaration]

Reported-by: kernel test robot <lkp at intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202511130238.LlA0MKxW-lkp at intel.com/
Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
---

 drivers/ufs/host/ufs-rockchip.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/ufs/host/ufs-rockchip.c b/drivers/ufs/host/ufs-rockchip.c
index 8cecb28..7fff345 100644
--- a/drivers/ufs/host/ufs-rockchip.c
+++ b/drivers/ufs/host/ufs-rockchip.c
@@ -7,6 +7,7 @@
 
 #include <linux/clk.h>
 #include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/mfd/syscon.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
-- 
2.7.4



From zhangqing at rock-chips.com  Wed Nov 12 23:54:16 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Thu, 13 Nov 2025 15:54:16 +0800
Subject: [PATCH v9 0/3] rockchip: add can for RK3576 Soc
Message-ID: <20251113075419.482940-1-zhangqing@rock-chips.com>

rk3576 can is a new controller,new register layout and Bit position
definition:
Support CAN protocol.

There are major differences from the previous rk3568.
All errata on the rk3568 have been fixed and redesigned.

RK3576 CANFD requires authorization and permission. The software
code is not open by default and needs to be authorized separately.

Change in V9(Drop dma):
[PATCH v9 1/3]: Drop dma, fix "allOf:"
[PATCH v9 2/3]: No change.
[PATCH v9 3/3]: Drop dma for commit message.

Change in V8:
[PATCH v8 1/4]: Drop CANFD, correction format warning.
[PATCH v8 2/4]: Drop fifo_setup of rkcanfd_devtype_data.
[PATCH v8 3/4]: Drop CANFD.
[PATCH v8 4/4]: Drop CANFD.

Change in V7:
[PATCH v7 1/4]: Correction format warning.
[PATCH v7 2/4]: No change.
[PATCH v7 3/4]: Correct the writing of some registers and
                correct the annotations.
[PATCH v7 4/4]: Optimize the structure parameters and
                ensure error handling.

Change in V6:
[PATCH v6 1/4]: Fix dma is support only for rk3576.
[PATCH v6 2/4]: Fix the compilation warning.
[PATCH v6 3/4]: Fix the compilation warning.
[PATCH v6 4/4]: Fix the compilation warning.

Change in V5:
[PATCH v5 1/4]: Add rk3576 canfd to rockchip,rk3568v2-canfd.yaml, remove
                rockchip,rk3576-canfd.yaml
[PATCH v5 2/4]: Encapsulate some hardware operation functions into
                rkcanfd_devtype_data to provide differentiated
                implementations for different models
                (such as RK3568v2/v3)..
[PATCH v5 3/4]: Add rk3576 canfd,fix the register naming rule,
                Delete the variables used by rockchip itself.
[PATCH v5 4/4]: Fix .h sorting.


Change in V4:
[PATCH v4 1/3]: Correct the format and add explanations.
[PATCH v4 2/3]: No change.
[PATCH v4 3/3]: No change.

Change in V3:
[PATCH v3 1/3]: Add documentation for the rk3576 CAN-FD.
[PATCH v3 2/3]: Adjust the differentiated code section and
                add dma function.
[PATCH v3 3/3]: Remove dma, no use dma by default.

Change in V2:
[PATCH v2 1/2]: remove rk3576_canfd.c, use the rockchip_canfd driver
[PATCH v2 2/2]: code style.

Elaine Zhang (3):
  dt-bindings: can: rockchip_canfd: add rk3576 CAN controller
  net: can: rockchip: Refactor the rkcanfd_devtype_data structure
  net: can: rockchip: add can for RK3576 Soc

 .../net/can/rockchip,rk3568v2-canfd.yaml      |   4 +-
 .../net/can/rockchip/rockchip_canfd-core.c    | 519 ++++++++++++++++--
 drivers/net/can/rockchip/rockchip_canfd-rx.c  | 103 ++++
 drivers/net/can/rockchip/rockchip_canfd-tx.c  |  20 +
 drivers/net/can/rockchip/rockchip_canfd.h     | 268 +++++++++
 5 files changed, 871 insertions(+), 43 deletions(-)

-- 
2.34.1



From zhangqing at rock-chips.com  Wed Nov 12 23:54:17 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Thu, 13 Nov 2025 15:54:17 +0800
Subject: [PATCH v9 1/3] dt-bindings: can: rockchip_canfd: add rk3576 CAN controller
In-Reply-To: <20251113075419.482940-1-zhangqing@rock-chips.com>
References: <20251113075419.482940-1-zhangqing@rock-chips.com>
Message-ID: <20251113075419.482940-2-zhangqing@rock-chips.com>

Add documentation for the rockchip rk3576 CAN controller.

Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
---
 .../devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml  | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml b/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml
index a077c0330013..d63c8c8e3f45 100644
--- a/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml
+++ b/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml
@@ -16,7 +16,9 @@ allOf:
 properties:
   compatible:
     oneOf:
-      - const: rockchip,rk3568v2-canfd
+      - enum:
+          - rockchip,rk3568v2-canfd
+          - rockchip,rk3576-can
       - items:
           - const: rockchip,rk3568v3-canfd
           - const: rockchip,rk3568v2-canfd
-- 
2.34.1



From zhangqing at rock-chips.com  Wed Nov 12 23:54:18 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Thu, 13 Nov 2025 15:54:18 +0800
Subject: [PATCH v9 2/3] net: can: rockchip: Refactor the rkcanfd_devtype_data structure
In-Reply-To: <20251113075419.482940-1-zhangqing@rock-chips.com>
References: <20251113075419.482940-1-zhangqing@rock-chips.com>
Message-ID: <20251113075419.482940-3-zhangqing@rock-chips.com>

Add new function pointer:
Encapsulate some hardware operation functions into
rkcanfd_devtype_data to provide differentiated implementations for
different models (such as RK3568v2/v3).

Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
---
 .../net/can/rockchip/rockchip_canfd-core.c    | 100 ++++++++++--------
 drivers/net/can/rockchip/rockchip_canfd.h     |  10 ++
 2 files changed, 68 insertions(+), 42 deletions(-)

diff --git a/drivers/net/can/rockchip/rockchip_canfd-core.c b/drivers/net/can/rockchip/rockchip_canfd-core.c
index 046f0a0ae4d4..761cb36148ff 100644
--- a/drivers/net/can/rockchip/rockchip_canfd-core.c
+++ b/drivers/net/can/rockchip/rockchip_canfd-core.c
@@ -24,32 +24,6 @@
 
 #include "rockchip_canfd.h"
 
-static const struct rkcanfd_devtype_data rkcanfd_devtype_data_rk3568v2 = {
-	.model = RKCANFD_MODEL_RK3568V2,
-	.quirks = RKCANFD_QUIRK_RK3568_ERRATUM_1 | RKCANFD_QUIRK_RK3568_ERRATUM_2 |
-		RKCANFD_QUIRK_RK3568_ERRATUM_3 | RKCANFD_QUIRK_RK3568_ERRATUM_4 |
-		RKCANFD_QUIRK_RK3568_ERRATUM_5 | RKCANFD_QUIRK_RK3568_ERRATUM_6 |
-		RKCANFD_QUIRK_RK3568_ERRATUM_7 | RKCANFD_QUIRK_RK3568_ERRATUM_8 |
-		RKCANFD_QUIRK_RK3568_ERRATUM_9 | RKCANFD_QUIRK_RK3568_ERRATUM_10 |
-		RKCANFD_QUIRK_RK3568_ERRATUM_11 | RKCANFD_QUIRK_RK3568_ERRATUM_12 |
-		RKCANFD_QUIRK_CANFD_BROKEN,
-};
-
-/* The rk3568 CAN-FD errata sheet as of Tue 07 Nov 2023 11:25:31 +08:00
- * states that only the rk3568v2 is affected by erratum 5, but tests
- * with the rk3568v2 and rk3568v3 show that the RX_FIFO_CNT is
- * sometimes too high. In contrast to the errata sheet mark rk3568v3
- * as effected by erratum 5, too.
- */
-static const struct rkcanfd_devtype_data rkcanfd_devtype_data_rk3568v3 = {
-	.model = RKCANFD_MODEL_RK3568V3,
-	.quirks = RKCANFD_QUIRK_RK3568_ERRATUM_1 | RKCANFD_QUIRK_RK3568_ERRATUM_2 |
-		RKCANFD_QUIRK_RK3568_ERRATUM_5 | RKCANFD_QUIRK_RK3568_ERRATUM_7 |
-		RKCANFD_QUIRK_RK3568_ERRATUM_8 | RKCANFD_QUIRK_RK3568_ERRATUM_10 |
-		RKCANFD_QUIRK_RK3568_ERRATUM_11 | RKCANFD_QUIRK_RK3568_ERRATUM_12 |
-		RKCANFD_QUIRK_CANFD_BROKEN,
-};
-
 static const char *__rkcanfd_get_model_str(enum rkcanfd_model model)
 {
 	switch (model) {
@@ -212,7 +186,7 @@ static int rkcanfd_get_berr_counter(const struct net_device *ndev,
 	if (err)
 		return err;
 
-	rkcanfd_get_berr_counter_corrected(priv, bec);
+	priv->devtype_data.get_berr_counter(priv, bec);
 
 	pm_runtime_put(ndev->dev.parent);
 
@@ -302,7 +276,7 @@ static void rkcanfd_chip_start(struct rkcanfd_priv *priv)
 
 	rkcanfd_set_bittiming(priv);
 
-	rkcanfd_chip_interrupts_disable(priv);
+	priv->devtype_data.interrupts_disable(priv);
 	rkcanfd_chip_set_work_mode(priv);
 
 	priv->can.state = CAN_STATE_ERROR_ACTIVE;
@@ -316,7 +290,7 @@ static void __rkcanfd_chip_stop(struct rkcanfd_priv *priv, const enum can_state
 	priv->can.state = state;
 
 	rkcanfd_chip_set_reset_mode(priv);
-	rkcanfd_chip_interrupts_disable(priv);
+	priv->devtype_data.interrupts_disable(priv);
 }
 
 static void rkcanfd_chip_stop(struct rkcanfd_priv *priv, const enum can_state state)
@@ -342,8 +316,8 @@ static int rkcanfd_set_mode(struct net_device *ndev,
 
 	switch (mode) {
 	case CAN_MODE_START:
-		rkcanfd_chip_start(priv);
-		rkcanfd_chip_interrupts_enable(priv);
+		priv->devtype_data.chip_start(priv);
+		priv->devtype_data.interrupts_enable(priv);
 		netif_wake_queue(ndev);
 		break;
 
@@ -537,7 +511,7 @@ static int rkcanfd_handle_error_int(struct rkcanfd_priv *priv)
 		if (cf) {
 			struct can_berr_counter bec;
 
-			rkcanfd_get_berr_counter_corrected(priv, &bec);
+			priv->devtype_data.get_berr_counter(priv, &bec);
 			cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR | CAN_ERR_CNT;
 			cf->data[6] = bec.txerr;
 			cf->data[7] = bec.rxerr;
@@ -567,7 +541,7 @@ static int rkcanfd_handle_state_error_int(struct rkcanfd_priv *priv)
 	u32 timestamp;
 	int err;
 
-	rkcanfd_get_berr_counter_corrected(priv, &bec);
+	priv->devtype_data.get_berr_counter(priv, &bec);
 	can_state_get_by_berr_counter(ndev, &bec, &tx_state, &rx_state);
 
 	new_state = max(tx_state, rx_state);
@@ -581,7 +555,7 @@ static int rkcanfd_handle_state_error_int(struct rkcanfd_priv *priv)
 	can_change_state(ndev, cf, tx_state, rx_state);
 
 	if (new_state == CAN_STATE_BUS_OFF) {
-		rkcanfd_chip_stop(priv, CAN_STATE_BUS_OFF);
+		priv->devtype_data.chip_stop(priv, CAN_STATE_BUS_OFF);
 		can_bus_off(ndev);
 	}
 
@@ -620,7 +594,7 @@ rkcanfd_handle_rx_fifo_overflow_int(struct rkcanfd_priv *priv)
 	if (!skb)
 		return 0;
 
-	rkcanfd_get_berr_counter_corrected(priv, &bec);
+	priv->devtype_data.get_berr_counter(priv, &bec);
 
 	cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
 	cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
@@ -719,21 +693,21 @@ static int rkcanfd_open(struct net_device *ndev)
 	if (err)
 		goto out_close_candev;
 
-	rkcanfd_chip_start(priv);
+	priv->devtype_data.chip_start(priv);
 	can_rx_offload_enable(&priv->offload);
 
-	err = request_irq(ndev->irq, rkcanfd_irq, IRQF_SHARED, ndev->name, priv);
+	err = request_irq(ndev->irq, priv->devtype_data.irq, IRQF_SHARED, ndev->name, priv);
 	if (err)
 		goto out_rkcanfd_chip_stop;
 
-	rkcanfd_chip_interrupts_enable(priv);
+	priv->devtype_data.interrupts_enable(priv);
 
 	netif_start_queue(ndev);
 
 	return 0;
 
 out_rkcanfd_chip_stop:
-	rkcanfd_chip_stop_sync(priv, CAN_STATE_STOPPED);
+	priv->devtype_data.chip_stop_sync(priv, CAN_STATE_STOPPED);
 	pm_runtime_put(ndev->dev.parent);
 out_close_candev:
 	close_candev(ndev);
@@ -746,10 +720,10 @@ static int rkcanfd_stop(struct net_device *ndev)
 
 	netif_stop_queue(ndev);
 
-	rkcanfd_chip_interrupts_disable(priv);
+	priv->devtype_data.interrupts_disable(priv);
 	free_irq(ndev->irq, priv);
 	can_rx_offload_disable(&priv->offload);
-	rkcanfd_chip_stop_sync(priv, CAN_STATE_STOPPED);
+	priv->devtype_data.chip_stop_sync(priv, CAN_STATE_STOPPED);
 	close_candev(ndev);
 
 	pm_runtime_put(ndev->dev.parent);
@@ -818,7 +792,7 @@ static int rkcanfd_register(struct rkcanfd_priv *priv)
 	if (err)
 		goto out_pm_runtime_put_sync;
 
-	rkcanfd_register_done(priv);
+	priv->devtype_data.register_done(priv);
 
 	pm_runtime_put(ndev->dev.parent);
 
@@ -840,6 +814,48 @@ static inline void rkcanfd_unregister(struct rkcanfd_priv *priv)
 	pm_runtime_disable(ndev->dev.parent);
 }
 
+static const struct rkcanfd_devtype_data rkcanfd_devtype_data_rk3568v2 = {
+	.model = RKCANFD_MODEL_RK3568V2,
+	.quirks = RKCANFD_QUIRK_RK3568_ERRATUM_1 | RKCANFD_QUIRK_RK3568_ERRATUM_2 |
+		RKCANFD_QUIRK_RK3568_ERRATUM_3 | RKCANFD_QUIRK_RK3568_ERRATUM_4 |
+		RKCANFD_QUIRK_RK3568_ERRATUM_5 | RKCANFD_QUIRK_RK3568_ERRATUM_6 |
+		RKCANFD_QUIRK_RK3568_ERRATUM_7 | RKCANFD_QUIRK_RK3568_ERRATUM_8 |
+		RKCANFD_QUIRK_RK3568_ERRATUM_9 | RKCANFD_QUIRK_RK3568_ERRATUM_10 |
+		RKCANFD_QUIRK_RK3568_ERRATUM_11 | RKCANFD_QUIRK_RK3568_ERRATUM_12 |
+		RKCANFD_QUIRK_CANFD_BROKEN,
+	.get_berr_counter = rkcanfd_get_berr_counter_corrected,
+	.interrupts_enable = rkcanfd_chip_interrupts_enable,
+	.interrupts_disable = rkcanfd_chip_interrupts_disable,
+	.chip_start = rkcanfd_chip_start,
+	.chip_stop = rkcanfd_chip_stop,
+	.chip_stop_sync = rkcanfd_chip_stop_sync,
+	.irq = rkcanfd_irq,
+	.register_done = rkcanfd_register_done,
+};
+
+/* The rk3568 CAN-FD errata sheet as of Tue 07 Nov 2023 11:25:31 +08:00
+ * states that only the rk3568v2 is affected by erratum 5, but tests
+ * with the rk3568v2 and rk3568v3 show that the RX_FIFO_CNT is
+ * sometimes too high. In contrast to the errata sheet mark rk3568v3
+ * as effected by erratum 5, too.
+ */
+static const struct rkcanfd_devtype_data rkcanfd_devtype_data_rk3568v3 = {
+	.model = RKCANFD_MODEL_RK3568V3,
+	.quirks = RKCANFD_QUIRK_RK3568_ERRATUM_1 | RKCANFD_QUIRK_RK3568_ERRATUM_2 |
+		RKCANFD_QUIRK_RK3568_ERRATUM_5 | RKCANFD_QUIRK_RK3568_ERRATUM_7 |
+		RKCANFD_QUIRK_RK3568_ERRATUM_8 | RKCANFD_QUIRK_RK3568_ERRATUM_10 |
+		RKCANFD_QUIRK_RK3568_ERRATUM_11 | RKCANFD_QUIRK_RK3568_ERRATUM_12 |
+		RKCANFD_QUIRK_CANFD_BROKEN,
+	.get_berr_counter = rkcanfd_get_berr_counter_corrected,
+	.interrupts_enable = rkcanfd_chip_interrupts_enable,
+	.interrupts_disable = rkcanfd_chip_interrupts_disable,
+	.chip_start = rkcanfd_chip_start,
+	.chip_stop = rkcanfd_chip_stop,
+	.chip_stop_sync = rkcanfd_chip_stop_sync,
+	.irq = rkcanfd_irq,
+	.register_done = rkcanfd_register_done,
+};
+
 static const struct of_device_id rkcanfd_of_match[] = {
 	{
 		.compatible = "rockchip,rk3568v2-canfd",
diff --git a/drivers/net/can/rockchip/rockchip_canfd.h b/drivers/net/can/rockchip/rockchip_canfd.h
index 93131c7d7f54..72f26b96add0 100644
--- a/drivers/net/can/rockchip/rockchip_canfd.h
+++ b/drivers/net/can/rockchip/rockchip_canfd.h
@@ -436,9 +436,19 @@ enum rkcanfd_model {
 	RKCANFD_MODEL_RK3568V3 = 0x35683,
 };
 
+struct rkcanfd_priv;
+
 struct rkcanfd_devtype_data {
 	enum rkcanfd_model model;
 	u32 quirks;
+	void (*get_berr_counter)(struct rkcanfd_priv *priv, struct can_berr_counter *bec);
+	void (*interrupts_enable)(const struct rkcanfd_priv *priv);
+	void (*interrupts_disable)(const struct rkcanfd_priv *priv);
+	void (*chip_start)(struct rkcanfd_priv *priv);
+	void (*chip_stop)(struct rkcanfd_priv *priv, const enum can_state state);
+	void (*chip_stop_sync)(struct rkcanfd_priv *priv, const enum can_state state);
+	irqreturn_t (*irq)(int irq, void *dev_id);
+	void (*register_done)(const struct rkcanfd_priv *priv);
 };
 
 struct rkcanfd_fifo_header {
-- 
2.34.1



From zhangqing at rock-chips.com  Wed Nov 12 23:54:19 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Thu, 13 Nov 2025 15:54:19 +0800
Subject: [PATCH v9 3/3] net: can: rockchip: add can for RK3576 Soc
In-Reply-To: <20251113075419.482940-1-zhangqing@rock-chips.com>
References: <20251113075419.482940-1-zhangqing@rock-chips.com>
Message-ID: <20251113075419.482940-4-zhangqing@rock-chips.com>

Is new controller, new register layout and Bit position definition:
Support CAN protocol, ISO 11898-1
Support transmit or receive error count
Support acceptance filter, more functional
Support interrupt and all interrupt can be masked
Support error code check
Support self test\silent\loop-back mode
Support auto retransmission mode
Support auto bus on after bus-off state
Support 2 transmit buffers
Support Internal Storage Mode

Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
---
 .../net/can/rockchip/rockchip_canfd-core.c    | 419 ++++++++++++++++++
 drivers/net/can/rockchip/rockchip_canfd-rx.c  | 103 +++++
 drivers/net/can/rockchip/rockchip_canfd-tx.c  |  20 +
 drivers/net/can/rockchip/rockchip_canfd.h     | 258 +++++++++++
 4 files changed, 800 insertions(+)

diff --git a/drivers/net/can/rockchip/rockchip_canfd-core.c b/drivers/net/can/rockchip/rockchip_canfd-core.c
index 761cb36148ff..58fffcf97b20 100644
--- a/drivers/net/can/rockchip/rockchip_canfd-core.c
+++ b/drivers/net/can/rockchip/rockchip_canfd-core.c
@@ -31,6 +31,8 @@ static const char *__rkcanfd_get_model_str(enum rkcanfd_model model)
 		return "rk3568v2";
 	case RKCANFD_MODEL_RK3568V3:
 		return "rk3568v3";
+	case RKCAN_MODEL_RK3576:
+		return "rk3576";
 	}
 
 	return "<unknown>";
@@ -176,6 +178,27 @@ static void rkcanfd_get_berr_counter_corrected(struct rkcanfd_priv *priv,
 		    !!(reg_state & RKCANFD_REG_STATE_ERROR_WARNING_STATE));
 }
 
+static void rk3576can_get_berr_counter_corrected(struct rkcanfd_priv *priv,
+						 struct can_berr_counter *bec)
+{
+	struct can_berr_counter bec_raw;
+	u32 reg_state;
+
+	bec->rxerr = rkcanfd_read(priv, RK3576CAN_REG_RXERRORCNT);
+	bec->txerr = rkcanfd_read(priv, RK3576CAN_REG_TXERRORCNT);
+	bec_raw = *bec;
+
+	priv->bec = *bec;
+
+	reg_state = rkcanfd_read(priv, RKCANFD_REG_STATE);
+	netdev_vdbg(priv->ndev,
+		    "%s: Raw/Cor: txerr=%3u/%3u rxerr=%3u/%3u Bus Off=%u Warning=%u\n",
+		    __func__,
+		    bec_raw.txerr, bec->txerr, bec_raw.rxerr, bec->rxerr,
+		    !!(reg_state & RK3576CAN_REG_STATE_BUS_OFF_STATE),
+		    !!(reg_state & RK3576CAN_REG_STATE_ERROR_WARNING_STATE));
+}
+
 static int rkcanfd_get_berr_counter(const struct net_device *ndev,
 				    struct can_berr_counter *bec)
 {
@@ -206,6 +229,11 @@ static void rkcanfd_chip_interrupts_disable(const struct rkcanfd_priv *priv)
 	rkcanfd_write(priv, RKCANFD_REG_INT_MASK, RKCANFD_REG_INT_ALL);
 }
 
+static void rk3576can_chip_interrupts_disable(const struct rkcanfd_priv *priv)
+{
+	rkcanfd_write(priv, RK3576CAN_REG_INT_MASK, RK3576CAN_REG_INT_ALL);
+}
+
 static void rkcanfd_chip_fifo_setup(struct rkcanfd_priv *priv)
 {
 	u32 reg;
@@ -220,6 +248,48 @@ static void rkcanfd_chip_fifo_setup(struct rkcanfd_priv *priv)
 	netdev_reset_queue(priv->ndev);
 }
 
+static void rk3576can_chip_fifo_setup(struct rkcanfd_priv *priv)
+{
+	u32 reg_ism, reg_water;
+
+	reg_ism = FIELD_PREP(RK3576CAN_REG_STR_CTL_ISM_SEL,
+			     RK3576CAN_REG_STR_CTL_ISM_SEL_CANFD_FIXED) |
+		  RK3576CAN_REG_STR_CTL_STORAGE_TIMEOUT_MODE;
+	reg_water = RK3576CAN_ISM_WATERMASK_CANFD;
+
+	/* internal sram mode */
+	rkcanfd_write(priv, RK3576CAN_REG_STR_CTL, reg_ism);
+	rkcanfd_write(priv, RK3576CAN_REG_STR_WTM, reg_water);
+	WRITE_ONCE(priv->tx_head, 0);
+	WRITE_ONCE(priv->tx_tail, 0);
+	netdev_reset_queue(priv->ndev);
+}
+
+static void rk3576can_atf_config(struct rkcanfd_priv *priv, int mode)
+{
+	int i;
+
+	switch (mode) {
+	case RK3576CAN_REG_ATFM_MASK_SEL_MASK_MODE:
+		for (i = 0; i < 5; i++) {
+			rkcanfd_write(priv, RK3576CAN_REG_ATF(i), 0);
+			rkcanfd_write(priv, RK3576CAN_REG_ATFM(i), RK3576CAN_REG_ATFM_ID);
+		}
+		break;
+	case RK3576CAN_REG_ATFM_MASK_SEL_LIST_MODE:
+		for (i = 0; i < 5; i++) {
+			rkcanfd_write(priv, RK3576CAN_REG_ATF(i), 0);
+			rkcanfd_write(priv, RK3576CAN_REG_ATFM(i), RK3576CAN_REG_ATFM_MASK_SEL);
+		}
+		break;
+	default:
+		rkcanfd_write(priv, RK3576CAN_REG_ATF_CTL, RK3576CAN_REG_ATF_CTL_ATF_DIS_ALL);
+		return;
+	}
+
+	rkcanfd_write(priv, RK3576CAN_REG_ATF_CTL, 0);
+}
+
 static void rkcanfd_chip_start(struct rkcanfd_priv *priv)
 {
 	u32 reg;
@@ -285,6 +355,61 @@ static void rkcanfd_chip_start(struct rkcanfd_priv *priv)
 		   rkcanfd_read(priv, RKCANFD_REG_MODE));
 }
 
+static void rk3576can_chip_start(struct rkcanfd_priv *priv)
+
+{
+	u32 reg;
+
+	rkcanfd_chip_set_reset_mode(priv);
+
+	/* Receiving Filter: accept all */
+	rk3576can_atf_config(priv, RK3576CAN_REG_ATFM_MASK_SEL_MASK_MODE);
+
+	/* enable:
+	 * - WORK_MODE: transition from reset to working mode
+	 */
+	reg = rkcanfd_read(priv, RKCANFD_REG_MODE);
+	priv->reg_mode_default = reg | RKCANFD_REG_MODE_WORK_MODE;
+
+	if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
+		priv->reg_mode_default |= RKCANFD_REG_MODE_LBACK_MODE;
+		rkcanfd_write(priv, RK3576CAN_REG_ERROR_MASK,
+			      RK3576CAN_REG_ERROR_MASK_ACK_ERROR);
+	}
+
+	/* mask, i.e. ignore:
+	 * - RX_FINISH_INT - Rx finish interrupt
+	 */
+	priv->reg_int_mask_default = RK3576CAN_REG_INT_RX_FINISH_INT;
+
+	/* Do not mask the bus error interrupt if the bus error
+	 * reporting is requested.
+	 */
+	if (!(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING))
+		priv->reg_int_mask_default |= RKCANFD_REG_INT_ERROR_INT;
+
+	memset(&priv->bec, 0x0, sizeof(priv->bec));
+
+	rk3576can_chip_fifo_setup(priv);
+
+	rkcanfd_write(priv, RK3576CAN_REG_AUTO_RETX_CFG,
+		      RK3576CAN_REG_AUTO_RETX_CFG_AUTO_RETX_EN);
+
+	rkcanfd_write(priv, RK3576CAN_REG_BRS_CFG,
+		      RK3576CAN_REG_BRS_CFG_BRS_NEGSYNC_EN |
+		      RK3576CAN_REG_BRS_CFG_BRS_POSSYNC_EN);
+
+	rkcanfd_set_bittiming(priv);
+
+	priv->devtype_data.interrupts_disable(priv);
+	rkcanfd_chip_set_work_mode(priv);
+
+	priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+	netdev_dbg(priv->ndev, "%s: reg_mode=0x%08x\n", __func__,
+		   rkcanfd_read(priv, RKCANFD_REG_MODE));
+}
+
 static void __rkcanfd_chip_stop(struct rkcanfd_priv *priv, const enum can_state state)
 {
 	priv->can.state = state;
@@ -301,6 +426,13 @@ static void rkcanfd_chip_stop(struct rkcanfd_priv *priv, const enum can_state st
 	__rkcanfd_chip_stop(priv, state);
 }
 
+static void rk3576can_chip_stop(struct rkcanfd_priv *priv, const enum can_state state)
+{
+	priv->can.state = state;
+
+	__rkcanfd_chip_stop(priv, state);
+}
+
 static void rkcanfd_chip_stop_sync(struct rkcanfd_priv *priv, const enum can_state state)
 {
 	priv->can.state = state;
@@ -309,6 +441,13 @@ static void rkcanfd_chip_stop_sync(struct rkcanfd_priv *priv, const enum can_sta
 	__rkcanfd_chip_stop(priv, state);
 }
 
+static void rk3576can_chip_stop_sync(struct rkcanfd_priv *priv, const enum can_state state)
+{
+	priv->can.state = state;
+
+	__rkcanfd_chip_stop(priv, state);
+}
+
 static int rkcanfd_set_mode(struct net_device *ndev,
 			    enum can_mode mode)
 {
@@ -364,6 +503,9 @@ static const char *rkcanfd_get_error_type_str(unsigned int type)
 #define RKCAN_ERROR_CODE(reg_ec, code) \
 	((reg_ec) & RKCANFD_REG_ERROR_CODE_##code ? __stringify(code) " " : "")
 
+#define RK3576CAN_ERROR_CODE(reg_ec, code) \
+	((reg_ec) & RK3576CAN_REG_ERROR_CODE_##code ? __stringify(code) " " : "")
+
 static void
 rkcanfd_handle_error_int_reg_ec(struct rkcanfd_priv *priv, struct can_frame *cf,
 				const u32 reg_ec)
@@ -493,6 +635,128 @@ rkcanfd_handle_error_int_reg_ec(struct rkcanfd_priv *priv, struct can_frame *cf,
 	}
 }
 
+static void
+rk3576can_handle_error_int_reg_ec(struct rkcanfd_priv *priv, struct can_frame *cf,
+				  const u32 reg_ec)
+{
+	struct net_device_stats *stats = &priv->ndev->stats;
+	unsigned int type;
+	u32 reg_state, reg_cmd;
+
+	type = FIELD_GET(RK3576CAN_REG_ERROR_CODE_TYPE, reg_ec);
+	reg_cmd = rkcanfd_read(priv, RK3576CAN_REG_CMD);
+	reg_state = rkcanfd_read(priv, RK3576CAN_REG_STATE);
+
+	netdev_dbg(priv->ndev, "%s Error in %s %s Phase: %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s(0x%08x) CMD=%u RX=%u TX=%u Error-Warning=%u Bus-Off=%u\n",
+		   rkcanfd_get_error_type_str(type),
+		   reg_ec & RK3576CAN_REG_ERROR_CODE_DIRECTION_RX ? "RX" : "TX",
+		   reg_ec & RK3576CAN_REG_ERROR_CODE_PHASE ? "Data" : "Arbitration",
+		   RK3576CAN_ERROR_CODE(reg_ec, TX_ACK_EOF),
+		   RK3576CAN_ERROR_CODE(reg_ec, TX_CRC),
+		   RK3576CAN_ERROR_CODE(reg_ec, TX_STUFF_COUNT),
+		   RK3576CAN_ERROR_CODE(reg_ec, TX_DATA),
+		   RK3576CAN_ERROR_CODE(reg_ec, TX_SOF_DLC),
+		   RK3576CAN_ERROR_CODE(reg_ec, TX_IDLE),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_ERROR),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_OVERLOAD),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_SPACE),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_EOF),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_ACK_LIM),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_ACK),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_CRC_LIM),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_CRC),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_STUFF_COUNT),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_DATA),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_DLC),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_BRS_ESI),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_RES),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_FDF),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_ID2_RTR),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_SOF_IDE),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_BUS_IDLE),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_BUS_INT),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_STOP),
+		   reg_ec, reg_cmd,
+		   !!(reg_state & RK3576CAN_REG_STATE_RX_PERIOD),
+		   !!(reg_state & RK3576CAN_REG_STATE_TX_PERIOD),
+		   !!(reg_state & RK3576CAN_REG_STATE_ERROR_WARNING_STATE),
+		   !!(reg_state & RK3576CAN_REG_STATE_BUS_OFF_STATE));
+
+	priv->can.can_stats.bus_error++;
+
+	if (reg_ec & RK3576CAN_REG_ERROR_CODE_DIRECTION_RX)
+		stats->rx_errors++;
+	else
+		stats->tx_errors++;
+
+	if (!cf)
+		return;
+
+	if (reg_ec & RK3576CAN_REG_ERROR_CODE_DIRECTION_RX) {
+		if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_SOF_IDE)
+			cf->data[3] = CAN_ERR_PROT_LOC_SOF;
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_ID2_RTR)
+			cf->data[3] = CAN_ERR_PROT_LOC_RTR;
+		/* RKCANFD_REG_ERROR_CODE_RX_FDF */
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_RES)
+			cf->data[3] = CAN_ERR_PROT_LOC_RES0;
+		/* RKCANFD_REG_ERROR_CODE_RX_BRS_ESI */
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_DLC)
+			cf->data[3] = CAN_ERR_PROT_LOC_DLC;
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_DATA)
+			cf->data[3] = CAN_ERR_PROT_LOC_DATA;
+		/* RKCANFD_REG_ERROR_CODE_RX_STUFF_COUNT */
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_CRC)
+			cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_CRC_LIM)
+			cf->data[3] = CAN_ERR_PROT_LOC_ACK_DEL;
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_ACK)
+			cf->data[3] = CAN_ERR_PROT_LOC_ACK;
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_ACK_LIM)
+			cf->data[3] = CAN_ERR_PROT_LOC_ACK_DEL;
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_EOF)
+			cf->data[3] = CAN_ERR_PROT_LOC_EOF;
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_SPACE)
+			cf->data[3] = CAN_ERR_PROT_LOC_EOF;
+	} else {
+		cf->data[2] |= CAN_ERR_PROT_TX;
+
+		if (reg_ec & RK3576CAN_REG_ERROR_CODE_TX_SOF_DLC)
+			cf->data[3] = CAN_ERR_PROT_LOC_SOF;
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_TX_DATA)
+			cf->data[3] = CAN_ERR_PROT_LOC_DATA;
+		/* RKCANFD_REG_ERROR_CODE_TX_STUFF_COUNT */
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_TX_CRC)
+			cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_TX_ACK_EOF)
+			cf->data[3] = CAN_ERR_PROT_LOC_ACK_DEL;
+	}
+
+	switch (reg_ec & RK3576CAN_REG_ERROR_CODE_TYPE) {
+	case FIELD_PREP_CONST(RK3576CAN_REG_ERROR_CODE_TYPE,
+			      RK3576CAN_REG_ERROR_CODE_TYPE_BIT):
+
+		cf->data[2] |= CAN_ERR_PROT_BIT;
+		break;
+	case FIELD_PREP_CONST(RK3576CAN_REG_ERROR_CODE_TYPE,
+			      RK3576CAN_REG_ERROR_CODE_TYPE_STUFF):
+		cf->data[2] |= CAN_ERR_PROT_STUFF;
+		break;
+	case FIELD_PREP_CONST(RK3576CAN_REG_ERROR_CODE_TYPE,
+			      RK3576CAN_REG_ERROR_CODE_TYPE_FORM):
+		cf->data[2] |= CAN_ERR_PROT_FORM;
+		break;
+	case FIELD_PREP_CONST(RK3576CAN_REG_ERROR_CODE_TYPE,
+			      RK3576CAN_REG_ERROR_CODE_TYPE_ACK):
+		cf->can_id |= CAN_ERR_ACK;
+		break;
+	case FIELD_PREP_CONST(RK3576CAN_REG_ERROR_CODE_TYPE,
+			      RK3576CAN_REG_ERROR_CODE_TYPE_CRC):
+		cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
+		break;
+	}
+}
+
 static int rkcanfd_handle_error_int(struct rkcanfd_priv *priv)
 {
 	struct net_device_stats *stats = &priv->ndev->stats;
@@ -530,6 +794,41 @@ static int rkcanfd_handle_error_int(struct rkcanfd_priv *priv)
 	return 0;
 }
 
+static int rkcanfd_handle_rk3576_error_int(struct rkcanfd_priv *priv)
+{
+	struct net_device_stats *stats = &priv->ndev->stats;
+	struct can_frame *cf = NULL;
+	u32 reg_ec;
+	struct sk_buff *skb;
+	int err;
+
+	reg_ec = rkcanfd_read(priv, RK3576CAN_REG_ERROR_CODE);
+	if (!reg_ec)
+		return 0;
+
+	if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) {
+		skb = alloc_can_err_skb(priv->ndev, &cf);
+		if (cf) {
+			struct can_berr_counter bec;
+
+			priv->devtype_data.get_berr_counter(priv, &bec);
+			cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR | CAN_ERR_CNT;
+			cf->data[6] = bec.txerr;
+			cf->data[7] = bec.rxerr;
+		}
+	}
+
+	rk3576can_handle_error_int_reg_ec(priv, cf, reg_ec);
+	if (!cf)
+		return 0;
+
+	err = can_rx_offload_queue_tail(&priv->offload, skb);
+	if (err)
+		stats->rx_fifo_errors++;
+
+	return 0;
+}
+
 static int rkcanfd_handle_state_error_int(struct rkcanfd_priv *priv)
 {
 	struct net_device_stats *stats = &priv->ndev->stats;
@@ -575,6 +874,50 @@ static int rkcanfd_handle_state_error_int(struct rkcanfd_priv *priv)
 	return 0;
 }
 
+static int rkcanfd_handle_rk3576_state_error_int(struct rkcanfd_priv *priv)
+{
+	struct net_device_stats *stats = &priv->ndev->stats;
+	enum can_state new_state, rx_state, tx_state;
+	struct net_device *ndev = priv->ndev;
+	struct can_berr_counter bec;
+	struct can_frame *cf = NULL;
+	struct sk_buff *skb;
+	int err;
+
+	priv->devtype_data.get_berr_counter(priv, &bec);
+	can_state_get_by_berr_counter(ndev, &bec, &tx_state, &rx_state);
+
+	new_state = max(tx_state, rx_state);
+	if (new_state == priv->can.state)
+		return 0;
+
+	/* The skb allocation might fail, but can_change_state()
+	 * handles cf == NULL.
+	 */
+	skb = alloc_can_err_skb(priv->ndev, &cf);
+	can_change_state(ndev, cf, tx_state, rx_state);
+
+	if (new_state == CAN_STATE_BUS_OFF) {
+		priv->devtype_data.chip_stop(priv, CAN_STATE_BUS_OFF);
+		can_bus_off(ndev);
+	}
+
+	if (!skb)
+		return 0;
+
+	if (new_state != CAN_STATE_BUS_OFF) {
+		cf->can_id |= CAN_ERR_CNT;
+		cf->data[6] = bec.txerr;
+		cf->data[7] = bec.rxerr;
+	}
+
+	err = can_rx_offload_queue_tail(&priv->offload, skb);
+	if (err)
+		stats->rx_fifo_errors++;
+
+	return 0;
+}
+
 static int
 rkcanfd_handle_rx_fifo_overflow_int(struct rkcanfd_priv *priv)
 {
@@ -621,6 +964,55 @@ rkcanfd_handle_rx_fifo_overflow_int(struct rkcanfd_priv *priv)
 	err; \
 })
 
+static irqreturn_t rk3576can_irq(int irq, void *dev_id)
+{
+	struct rkcanfd_priv *priv = dev_id;
+	u32 reg_int_unmasked, reg_int;
+
+	reg_int_unmasked = rkcanfd_read(priv, RK3576CAN_REG_INT);
+	reg_int = reg_int_unmasked & ~priv->reg_int_mask_default;
+
+	if (!reg_int)
+		return IRQ_NONE;
+
+	rkcanfd_write(priv, RK3576CAN_REG_INT, reg_int);
+
+	if (reg_int & (RK3576CAN_REG_INT_RXSTR_TIMEOUT_INT |
+		       RK3576CAN_REG_INT_ISM_WTM_INT |
+		       RK3576CAN_REG_INT_RX_FIFO_FULL_INT)) {
+		rkcanfd_write(priv, RK3576CAN_REG_INT_MASK,
+			      priv->reg_int_mask_default | RK3576CAN_REG_INT_ISM_WTM_INT |
+			      RK3576CAN_REG_INT_RXSTR_TIMEOUT_INT |
+			      RK3576CAN_REG_INT_RX_FINISH_INT);
+		rkcanfd_handle(priv, rk3576_rx_int);
+	}
+
+	if (reg_int & RK3576CAN_REG_INT_TX_FINISH_INT)
+		rkcanfd_handle(priv, rk3576_tx_int);
+
+	if (reg_int & RK3576CAN_REG_INT_ERROR_INT)
+		rkcanfd_handle(priv, rk3576_error_int);
+
+	if (reg_int & (RK3576CAN_REG_INT_BUS_OFF_INT |
+		       RK3576CAN_REG_INT_PASSIVE_ERROR_INT |
+		       RK3576CAN_REG_INT_ERROR_WARNING_INT) ||
+	    priv->can.state > CAN_STATE_ERROR_ACTIVE)
+		rkcanfd_handle(priv, rk3576_state_error_int);
+
+	if (reg_int & RK3576CAN_REG_INT_WAKEUP_INT)
+		netdev_info(priv->ndev, "%s: WAKEUP_INT\n", __func__);
+
+	if (reg_int & RK3576CAN_REG_INT_BUS_OFF_RECOVERY_INT)
+		netdev_info(priv->ndev, "%s: BUS_OFF_RECOVERY_INT\n", __func__);
+
+	if (reg_int & RK3576CAN_REG_INT_OVERLOAD_INT)
+		netdev_info(priv->ndev, "%s: OVERLOAD_INT\n", __func__);
+
+	can_rx_offload_irq_finish(&priv->offload);
+
+	return IRQ_HANDLED;
+}
+
 static irqreturn_t rkcanfd_irq(int irq, void *dev_id)
 {
 	struct rkcanfd_priv *priv = dev_id;
@@ -775,6 +1167,16 @@ static void rkcanfd_register_done(const struct rkcanfd_priv *priv)
 			    RKCANFD_ERRATUM_5_SYSCLOCK_HZ_MIN / MEGA);
 }
 
+static void rk3576can_register_done(const struct rkcanfd_priv *priv)
+{
+	u32 dev_id;
+
+	dev_id = rkcanfd_read(priv, RK3576CAN_REG_RTL_VERSION);
+	netdev_info(priv->ndev,
+		    "Rockchip-CANFD %s rev%u.\n",
+		    rkcanfd_get_model_str(priv), dev_id);
+}
+
 static int rkcanfd_register(struct rkcanfd_priv *priv)
 {
 	struct net_device *ndev = priv->ndev;
@@ -856,6 +1258,20 @@ static const struct rkcanfd_devtype_data rkcanfd_devtype_data_rk3568v3 = {
 	.register_done = rkcanfd_register_done,
 };
 
+/* The rk3576 CAN-FD */
+static const struct rkcanfd_devtype_data rkcan_devtype_data_rk3576 = {
+	.model = RKCAN_MODEL_RK3576,
+	.quirks = RKCANFD_QUIRK_CANFD_BROKEN,
+	.get_berr_counter = rk3576can_get_berr_counter_corrected,
+	.interrupts_enable = rkcanfd_chip_interrupts_enable,
+	.interrupts_disable = rk3576can_chip_interrupts_disable,
+	.chip_start = rk3576can_chip_start,
+	.chip_stop = rk3576can_chip_stop,
+	.chip_stop_sync = rk3576can_chip_stop_sync,
+	.irq = rk3576can_irq,
+	.register_done = rk3576can_register_done,
+};
+
 static const struct of_device_id rkcanfd_of_match[] = {
 	{
 		.compatible = "rockchip,rk3568v2-canfd",
@@ -863,6 +1279,9 @@ static const struct of_device_id rkcanfd_of_match[] = {
 	}, {
 		.compatible = "rockchip,rk3568v3-canfd",
 		.data = &rkcanfd_devtype_data_rk3568v3,
+	},  {
+		.compatible = "rockchip,rk3576-can",
+		.data = &rkcan_devtype_data_rk3576,
 	}, {
 		/* sentinel */
 	},
diff --git a/drivers/net/can/rockchip/rockchip_canfd-rx.c b/drivers/net/can/rockchip/rockchip_canfd-rx.c
index 475c0409e215..6bc4b0185502 100644
--- a/drivers/net/can/rockchip/rockchip_canfd-rx.c
+++ b/drivers/net/can/rockchip/rockchip_canfd-rx.c
@@ -91,6 +91,47 @@ rkcanfd_fifo_header_to_cfd_header(const struct rkcanfd_priv *priv,
 	return len + cfd->len;
 }
 
+static unsigned int
+rk3576can_fifo_header_to_cfd_header(const struct rkcanfd_priv *priv,
+				    const struct rk3576can_fifo_header *header,
+				    struct canfd_frame *cfd)
+{
+	unsigned int len = sizeof(*cfd) - sizeof(cfd->data);
+	u8 dlc;
+
+	if (header->frameinfo & RK3576CAN_REG_RXFRD_FRAMEINFO_FRAME_FORMAT)
+		cfd->can_id = FIELD_GET(RKCANFD_REG_FD_ID_EFF, header->id) |
+			CAN_EFF_FLAG;
+	else
+		cfd->can_id = FIELD_GET(RKCANFD_REG_FD_ID_SFF, header->id);
+
+	dlc = FIELD_GET(RK3576CAN_REG_RXFRD_FRAMEINFO_DATA_LENGTH,
+			header->frameinfo);
+
+	/* CAN-FD */
+	if (header->frameinfo & RK3576CAN_REG_RXFRD_FRAMEINFO_FDF) {
+		cfd->len = can_fd_dlc2len(dlc);
+
+		/* The cfd is not allocated by alloc_canfd_skb(), so
+		 * set CANFD_FDF here.
+		 */
+		cfd->flags |= CANFD_FDF;
+
+		if (header->frameinfo & RK3576CAN_REG_RXFRD_FRAMEINFO_BRS)
+			cfd->flags |= CANFD_BRS;
+	} else {
+		cfd->len = can_cc_dlc2len(dlc);
+
+		if (header->frameinfo & RK3576CAN_REG_RXFRD_FRAMEINFO_RTR) {
+			cfd->can_id |= CAN_RTR_FLAG;
+
+			return len;
+		}
+	}
+
+	return len + cfd->len;
+}
+
 static int rkcanfd_rxstx_filter(struct rkcanfd_priv *priv,
 				const struct canfd_frame *cfd_rx, const u32 ts,
 				bool *tx_done)
@@ -198,6 +239,44 @@ rkcanfd_fifo_header_empty(const struct rkcanfd_fifo_header *header)
 		header->frameinfo == header->ts;
 }
 
+static int rk3576can_handle_rx_int_one(struct rkcanfd_priv *priv)
+{
+	struct net_device_stats *stats = &priv->ndev->stats;
+	struct canfd_frame cfd[1] = { }, *skb_cfd;
+	struct rk3576can_fifo_header header[1] = { };
+	struct sk_buff *skb;
+	unsigned int len;
+	int err;
+
+	/* read header into separate struct and convert it later */
+	rkcanfd_read_rep(priv, RKCANFD_REG_RX_FIFO_RDATA,
+			 header, sizeof(*header));
+	/* read data directly into cfd */
+	rkcanfd_read_rep(priv, RKCANFD_REG_RX_FIFO_RDATA,
+			 cfd->data, sizeof(cfd->data));
+
+	len = rk3576can_fifo_header_to_cfd_header(priv, header, cfd);
+
+	if (header->frameinfo & RK3576CAN_REG_RXFRD_FRAMEINFO_FDF)
+		skb = alloc_canfd_skb(priv->ndev, &skb_cfd);
+	else
+		skb = alloc_can_skb(priv->ndev, (struct can_frame **)&skb_cfd);
+
+	if (!skb) {
+		stats->rx_dropped++;
+
+		return 0;
+	}
+
+	memcpy(skb_cfd, cfd, len);
+
+	err = can_rx_offload_queue_tail(&priv->offload, skb);
+	if (err)
+		stats->rx_fifo_errors++;
+
+	return 0;
+}
+
 static int rkcanfd_handle_rx_int_one(struct rkcanfd_priv *priv)
 {
 	struct net_device_stats *stats = &priv->ndev->stats;
@@ -284,6 +363,15 @@ rkcanfd_rx_fifo_get_len(const struct rkcanfd_priv *priv)
 	return FIELD_GET(RKCANFD_REG_RX_FIFO_CTRL_RX_FIFO_CNT, reg);
 }
 
+static inline unsigned int
+rk3576can_rx_fifo_get_len(const struct rkcanfd_priv *priv)
+{
+	const u32 reg = rkcanfd_read(priv, RK3576CAN_REG_STR_STATE);
+	int val = FIELD_GET(RK3576CAN_REG_STR_STATE_INTM_LEFT_CNT, reg);
+
+	return DIV_ROUND_UP(val, RK3576CAN_REG_STR_STATE_INTM_LEFT_CNT_UNIT);
+}
+
 int rkcanfd_handle_rx_int(struct rkcanfd_priv *priv)
 {
 	unsigned int len;
@@ -297,3 +385,18 @@ int rkcanfd_handle_rx_int(struct rkcanfd_priv *priv)
 
 	return 0;
 }
+
+int rkcanfd_handle_rk3576_rx_int(struct rkcanfd_priv *priv)
+{
+	unsigned int len;
+	int err;
+
+	while ((len = rk3576can_rx_fifo_get_len(priv))) {
+		err = rk3576can_handle_rx_int_one(priv);
+		if (err)
+			return err;
+	}
+	rkcanfd_write(priv, RK3576CAN_REG_INT_MASK, priv->reg_int_mask_default);
+	return 0;
+}
+
diff --git a/drivers/net/can/rockchip/rockchip_canfd-tx.c b/drivers/net/can/rockchip/rockchip_canfd-tx.c
index 12200dcfd338..de2f673c31ed 100644
--- a/drivers/net/can/rockchip/rockchip_canfd-tx.c
+++ b/drivers/net/can/rockchip/rockchip_canfd-tx.c
@@ -165,3 +165,23 @@ void rkcanfd_handle_tx_done_one(struct rkcanfd_priv *priv, const u32 ts,
 							    frame_len_p);
 	stats->tx_packets++;
 }
+
+int rkcanfd_handle_rk3576_tx_int(struct rkcanfd_priv *priv)
+{
+	struct net_device_stats *stats = &priv->ndev->stats;
+	unsigned int tx_tail;
+	unsigned int frame_len = 0;
+
+	tx_tail = rkcanfd_get_tx_tail(priv);
+
+	stats->tx_bytes +=
+		can_rx_offload_get_echo_skb_queue_tail(&priv->offload,
+						       tx_tail, &frame_len);
+	stats->tx_packets++;
+	WRITE_ONCE(priv->tx_tail, priv->tx_tail + 1);
+	netif_subqueue_completed_wake(priv->ndev, 0, 1, frame_len,
+				      rkcanfd_get_effective_tx_free(priv),
+				      RKCANFD_TX_START_THRESHOLD);
+	return 0;
+}
+
diff --git a/drivers/net/can/rockchip/rockchip_canfd.h b/drivers/net/can/rockchip/rockchip_canfd.h
index 72f26b96add0..77c673cfea3b 100644
--- a/drivers/net/can/rockchip/rockchip_canfd.h
+++ b/drivers/net/can/rockchip/rockchip_canfd.h
@@ -287,6 +287,256 @@
 #define RKCANFD_REG_RX_FIFO_RDATA 0x400
 #define RKCANFD_REG_TXE_FIFO_RDATA 0x500
 
+#define RK3576CAN_REG_MODE 0x000
+#define RK3576CAN_REG_CMD 0x004
+
+#define RK3576CAN_REG_STATE 0x008
+#define RK3576CAN_REG_STATE_SLEEP_STATE BIT(5)
+#define RK3576CAN_REG_STATE_BUS_OFF_STATE BIT(4)
+#define RK3576CAN_REG_STATE_ERROR_WARNING_STATE BIT(3)
+#define RK3576CAN_REG_STATE_TX_PERIOD BIT(2)
+#define RK3576CAN_REG_STATE_RX_PERIOD BIT(1)
+#define RK3576CAN_REG_STATE_TX_BUFFER_FULL BIT(0)
+
+#define RK3576CAN_REG_INT 0x00c
+#define RK3576CAN_REG_INT_BUSOFF_RCY_INT BIT(19)
+#define RK3576CAN_REG_INT_ESM_WTM_INT BIT(18)
+#define RK3576CAN_REG_INT_ISM_WTM_INT BIT(17)
+#define RK3576CAN_REG_INT_BUSINT_INT BIT(16)
+#define RK3576CAN_REG_INT_RXSTR_TIMEOUT_INT BIT(15)
+#define RK3576CAN_REG_INT_MFI_TIMEOUT_INT BIT(14)
+#define RK3576CAN_REG_INT_MFI_INT BIT(13)
+#define RK3576CAN_REG_INT_AUTO_RETX_FAIL_INT BIT(12)
+#define RK3576CAN_REG_INT_WAKEUP_INT BIT(11)
+#define RK3576CAN_REG_INT_BUS_OFF_RECOVERY_INT BIT(10)
+#define RK3576CAN_REG_INT_BUS_OFF_INT BIT(9)
+#define RK3576CAN_REG_INT_RX_FIFO_OVERFLOW_INT BIT(8)
+#define RK3576CAN_REG_INT_RX_FIFO_FULL_INT BIT(7)
+#define RK3576CAN_REG_INT_ERROR_INT BIT(6)
+#define RK3576CAN_REG_INT_TX_ARBIT_FAIL_INT BIT(5)
+#define RK3576CAN_REG_INT_PASSIVE_ERROR_INT BIT(4)
+#define RK3576CAN_REG_INT_OVERLOAD_INT BIT(3)
+#define RK3576CAN_REG_INT_ERROR_WARNING_INT BIT(2)
+#define RK3576CAN_REG_INT_TX_FINISH_INT BIT(1)
+#define RK3576CAN_REG_INT_RX_FINISH_INT BIT(0)
+
+#define RK3576CAN_REG_INT_ALL \
+	(RK3576CAN_REG_INT_BUSOFF_RCY_INT | \
+	 RK3576CAN_REG_INT_ESM_WTM_INT | \
+	 RK3576CAN_REG_INT_ISM_WTM_INT | \
+	 RK3576CAN_REG_INT_BUSINT_INT | \
+	 RK3576CAN_REG_INT_RXSTR_TIMEOUT_INT | \
+	 RK3576CAN_REG_INT_MFI_TIMEOUT_INT | \
+	 RK3576CAN_REG_INT_MFI_INT | \
+	 RK3576CAN_REG_INT_AUTO_RETX_FAIL_INT | \
+	 RK3576CAN_REG_INT_WAKEUP_INT | \
+	 RK3576CAN_REG_INT_BUS_OFF_RECOVERY_INT | \
+	 RK3576CAN_REG_INT_BUS_OFF_INT | \
+	 RK3576CAN_REG_INT_RX_FIFO_OVERFLOW_INT | \
+	 RK3576CAN_REG_INT_RX_FIFO_FULL_INT | \
+	 RK3576CAN_REG_INT_ERROR_INT | \
+	 RK3576CAN_REG_INT_TX_ARBIT_FAIL_INT | \
+	 RK3576CAN_REG_INT_PASSIVE_ERROR_INT | \
+	 RK3576CAN_REG_INT_OVERLOAD_INT | \
+	 RK3576CAN_REG_INT_ERROR_WARNING_INT | \
+	 RK3576CAN_REG_INT_TX_FINISH_INT | \
+	 RK3576CAN_REG_INT_RX_FINISH_INT)
+
+#define RK3576CAN_REG_INT_ALL_ERROR \
+	(RK3576CAN_REG_INT_BUS_OFF_INT | \
+	 RK3576CAN_REG_INT_ERROR_INT | \
+	 RK3576CAN_REG_INT_PASSIVE_ERROR_INT | \
+	 RK3576CAN_REG_INT_ERROR_WARNING_INT)
+
+#define RK3576CAN_REG_INT_MASK 0x010
+
+#define RK3576CAN_REG_FD_NOMINAL_BITTIMING 0x100
+#define RK3576CAN_REG_FD_NOMINAL_BITTIMING_SAMPLE_MODE BIT(31)
+#define RK3576CAN_REG_FD_NOMINAL_BITTIMING_SJW GENMASK(30, 24)
+#define RK3576CAN_REG_FD_NOMINAL_BITTIMING_BRP GENMASK(23, 16)
+#define RK3576CAN_REG_FD_NOMINAL_BITTIMING_TSEG2 GENMASK(14, 8)
+#define RK3576CAN_REG_FD_NOMINAL_BITTIMING_TSEG1 GENMASK(7, 0)
+
+#define RK3576CAN_REG_FD_DATA_BITTIMING 0x104
+#define RK3576CAN_REG_FD_DATA_BITTIMING_BRS_TSEG1 GENMASK(31, 24)
+#define RK3576CAN_REG_FD_DATA_BITTIMING_BRS_MODE BIT(23)
+#define RK3576CAN_REG_FD_DATA_BITTIMING_ACKSLOT_SYNC_DIS BIT(22)
+#define RK3576CAN_REG_FD_DATA_BITTIMING_SJW GENMASK(20, 17)
+#define RK3576CAN_REG_FD_DATA_BITTIMING_BRP GENMASK(16, 9)
+#define RK3576CAN_REG_FD_DATA_BITTIMING_TSEG2 GENMASK(8, 5)
+#define RK3576CAN_REG_FD_DATA_BITTIMING_TSEG1 GENMASK(4, 0)
+
+#define RK3576CAN_REG_TRANSMIT_DELAY_COMPENSATION 0x108
+#define RK3576CAN_REG_TRANSMIT_DELAY_COMPENSATION_TDC_OFFSET GENMASK(6, 1)
+#define RK3576CAN_REG_TRANSMIT_DELAY_COMPENSATION_TDC_ENABLE BIT(0)
+
+#define RK3576CAN_REG_BRS_CFG 0x10c
+#define RK3576CAN_REG_BRS_CFG_TRIPLE_SYNC_MODE BIT(31)
+#define RK3576CAN_REG_BRS_CFG_SP2_DTSEG1 GENMASK(30, 26)
+#define RK3576CAN_REG_BRS_CFG_SP2_NTSEG1 GENMASK(25, 18)
+#define RK3576CAN_REG_BRS_CFG_SP1_DTSEG1 GENMASK(17, 13)
+#define RK3576CAN_REG_BRS_CFG_SP1_NTSEG1 GENMASK(12, 5)
+#define RK3576CAN_REG_BRS_CFG_RESYNC_MODE BIT(3)
+#define RK3576CAN_REG_BRS_CFG_BRS_POSSYNC_EN BIT(1)
+#define RK3576CAN_REG_BRS_CFG_BRS_NEGSYNC_EN BIT(0)
+
+#define RK3576CAN_REG_LOOP_CNT 0x110
+
+#define RK3576CAN_REG_DMA_CTRL 0x11c
+#define RK3576CAN_REG_DMA_CTRL_DMA_RX_EN BIT(9)
+#define RK3576CAN_REG_DMA_CTRL_DMA_THR GENMASK(8, 0)
+
+#define RK3576CAN_REG_FD_TXFRAMEINFO 0x200
+
+#define RK3576CAN_REG_FD_TXID 0x204
+#define RK3576CAN_REG_FD_ID_EFF GENMASK(28, 0)
+#define RK3576CAN_REG_FD_ID_SFF GENMASK(11, 0)
+
+#define RK3576CAN_REG_FD_TXDATA0 0x208
+#define RK3576CAN_REG_FD_TXDATA1 0x20c
+#define RK3576CAN_REG_FD_TXDATA2 0x210
+#define RK3576CAN_REG_FD_TXDATA3 0x214
+#define RK3576CAN_REG_FD_TXDATA4 0x218
+#define RK3576CAN_REG_FD_TXDATA5 0x21c
+#define RK3576CAN_REG_FD_TXDATA6 0x220
+#define RK3576CAN_REG_FD_TXDATA7 0x224
+#define RK3576CAN_REG_FD_TXDATA8 0x228
+#define RK3576CAN_REG_FD_TXDATA9 0x22c
+#define RK3576CAN_REG_FD_TXDATA10 0x230
+#define RK3576CAN_REG_FD_TXDATA11 0x234
+#define RK3576CAN_REG_FD_TXDATA12 0x238
+#define RK3576CAN_REG_FD_TXDATA13 0x23c
+#define RK3576CAN_REG_FD_TXDATA14 0x240
+#define RK3576CAN_REG_FD_TXDATA15 0x244
+
+#define RK3576CAN_REG_RXFRD 0x400
+#define RK3576CAN_REG_RXFRD_FRAMEINFO_FRAME_FORMAT BIT(23)
+#define RK3576CAN_REG_RXFRD_FRAMEINFO_RTR BIT(22)
+#define RK3576CAN_REG_RXFRD_FRAMEINFO_FDF BIT(21)
+#define RK3576CAN_REG_RXFRD_FRAMEINFO_BRS BIT(20)
+#define RK3576CAN_REG_RXFRD_FRAMEINFO_DATA_LENGTH GENMASK(27, 24)
+
+#define RK3576CAN_REG_STR_CTL 0x600
+#define RK3576CAN_REG_STR_CTL_STORAGE_TIMEOUT_MODE BIT(8)
+#define RK3576CAN_REG_STR_CTL_ESM_SEL_MASK GENMASK(7, 6)
+#define RK3576CAN_REG_STR_CTL_RX_STORAGE_RESET BIT(4)
+#define RK3576CAN_REG_STR_CTL_ISM_SEL GENMASK(3, 2)
+#define RK3576CAN_REG_STR_CTL_ISM_SEL_FLEXIBLE 0x0
+#define RK3576CAN_REG_STR_CTL_ISM_SEL_CAN_FIXED 0x1
+#define RK3576CAN_REG_STR_CTL_ISM_SEL_CANFD_FIXED 0x2
+#define RK3576CAN_REG_STR_CTL_EXT_STORAGE_MODE BIT(1)
+#define RK3576CAN_REG_STR_CTL_BUFFER_MODE_ENABLE BIT(0)
+
+#define RK3576CAN_REG_STR_STATE 0x604
+#define RK3576CAN_REG_STR_STATE_INTM_FRAME_CNT GENMASK(25, 17)
+#define RK3576CAN_REG_STR_STATE_INTM_LEFT_CNT GENMASK(16, 8)
+#define RK3576CAN_REG_STR_STATE_INTM_LEFT_CNT_UNIT 18
+#define RK3576CAN_REG_STR_STATE_EXTM_FULL BIT(3)
+#define RK3576CAN_REG_STR_STATE_EXTM_EMPTY BIT(2)
+#define RK3576CAN_REG_STR_STATE_INTM_FULL BIT(1)
+#define RK3576CAN_REG_STR_STATE_INTM_EMPTY BIT(0)
+
+#define RK3576CAN_REG_STR_TIMEOUT 0x608
+
+#define RK3576CAN_REG_STR_WTM 0x60c
+#define RK3576CAN_REG_ATF(n) (0x700 + ((n) << 2))
+#define RK3576CAN_REG_ATFM(n) (0x714 + ((n) << 2))
+#define RK3576CAN_REG_ATFM_MASK_SEL BIT(31)
+#define RK3576CAN_REG_ATFM_RTR_EN BIT(30)
+#define RK3576CAN_REG_ATFM_RTR BIT(29)
+#define RK3576CAN_REG_ATFM_MASK_SEL_MASK_MODE 0x0
+#define RK3576CAN_REG_ATFM_MASK_SEL_LIST_MODE 0x1
+#define RK3576CAN_REG_ATFM_ID GENMASK(28, 0)
+
+#define RK3576CAN_REG_ATF_DLC 0x728
+#define RK3576CAN_REG_ATF_DLC_ATF_DLC_MODE BIT(5)
+#define RK3576CAN_REG_ATF_DLC_ATF_DLC_EN BIT(4)
+#define RK3576CAN_REG_ATF_DLC_ATF_DLC GENMASK(3, 0)
+
+#define RK3576CAN_REG_ATF_CTL 0x72c
+#define RK3576CAN_REG_ATF_CTL_ATF_DIS(n) BIT(n)
+#define RK3576CAN_REG_ATF_CTL_ATF_DIS_ALL GENMASK(15, 0)
+
+#define RK3576CAN_REG_SPACE_CTRL 0x800
+
+#define RK3576CAN_REG_AUTO_RETX_CFG 0x808
+#define RK3576CAN_REG_AUTO_RETX_CFG_RETX_TIME_LIMIT GENMASK(18, 3)
+#define RK3576CAN_REG_AUTO_RETX_CFG_RETX_LIMIT_EN BIT(1)
+#define RK3576CAN_REG_AUTO_RETX_CFG_AUTO_RETX_EN BIT(0)
+
+#define RK3576CAN_REG_AUTO_RETX_STATE0 0x80c
+#define RK3576CAN_REG_AUTO_RETX_STATE0_AUTO_RETX_CNT GENMASK(15, 0)
+
+#define RK3576CAN_REG_AUTO_RETX_STATE1 0x810
+#define RK3576CAN_REG_OLF_CFG 0x814
+#define RK3576CAN_REG_RXINT_CTRL 0x818
+#define RK3576CAN_REG_RXINT_TIMEOUT 0x81c
+#define RK3576CAN_REG_OTHER_CFG 0x820
+#define RK3576CAN_REG_WAVE_FILTER_CFG 0x824
+#define RK3576CAN_REG_RBC_CFG 0x828
+#define RK3576CAN_REG_TXCRC_CFG 0x82c
+
+#define RK3576CAN_REG_BUSOFFRCY_CFG 0x830
+#define RK3576CAN_REG_BUSOFF_RCY_THR 0x834
+
+#define RK3576CAN_REG_ERROR_CODE 0x900
+#define RK3576CAN_REG_ERROR_MASK 0x904
+#define RK3576CAN_REG_ERROR_MASK_ACK_ERROR BIT(4)
+#define RK3576CAN_REG_ERROR_MASK_FORM_ERROR BIT(3)
+#define RK3576CAN_REG_ERROR_MASK_CRC_ERROR BIT(2)
+#define RK3576CAN_REG_ERROR_MASK_STUFF_ERROR BIT(1)
+#define RK3576CAN_REG_ERROR_MASK_BIT_ERROR BIT(0)
+
+#define RK3576CAN_REG_RXERRORCNT 0x910
+#define RK3576CAN_REG_TXERRORCNT 0x914
+#define RK3576CAN_REG_RX_RXSRAM_RDATA 0xc00
+#define RK3576CAN_REG_RTL_VERSION 0xf0c
+
+#define RK3576CAN_REG_ERROR_CODE_PHASE BIT(29)
+#define RK3576CAN_REG_ERROR_CODE_TYPE GENMASK(28, 26)
+#define RK3576CAN_REG_ERROR_CODE_TYPE_BIT 0x0
+#define RK3576CAN_REG_ERROR_CODE_TYPE_STUFF 0x1
+#define RK3576CAN_REG_ERROR_CODE_TYPE_FORM 0x2
+#define RK3576CAN_REG_ERROR_CODE_TYPE_ACK 0x3
+#define RK3576CAN_REG_ERROR_CODE_TYPE_CRC 0x4
+#define RK3576CAN_REG_ERROR_CODE_DIRECTION_RX BIT(25)
+#define RK3576CAN_REG_ERROR_CODE_TX GENMASK(24, 19)
+#define RK3576CAN_REG_ERROR_CODE_TX_ACK_EOF BIT(24)
+#define RK3576CAN_REG_ERROR_CODE_TX_CRC BIT(23)
+#define RK3576CAN_REG_ERROR_CODE_TX_STUFF_COUNT BIT(22)
+#define RK3576CAN_REG_ERROR_CODE_TX_DATA BIT(21)
+#define RK3576CAN_REG_ERROR_CODE_TX_SOF_DLC BIT(20)
+#define RK3576CAN_REG_ERROR_CODE_TX_IDLE BIT(19)
+#define RK3576CAN_REG_ERROR_CODE_RX GENMASK(18, 0)
+#define RK3576CAN_REG_ERROR_CODE_RX_ERROR BIT(18)
+#define RK3576CAN_REG_ERROR_CODE_RX_OVERLOAD BIT(17)
+#define RK3576CAN_REG_ERROR_CODE_RX_SPACE BIT(16)
+#define RK3576CAN_REG_ERROR_CODE_RX_EOF BIT(15)
+#define RK3576CAN_REG_ERROR_CODE_RX_ACK_LIM BIT(14)
+#define RK3576CAN_REG_ERROR_CODE_RX_ACK BIT(13)
+#define RK3576CAN_REG_ERROR_CODE_RX_CRC_LIM BIT(12)
+#define RK3576CAN_REG_ERROR_CODE_RX_CRC BIT(11)
+#define RK3576CAN_REG_ERROR_CODE_RX_STUFF_COUNT BIT(10)
+#define RK3576CAN_REG_ERROR_CODE_RX_DATA BIT(9)
+#define RK3576CAN_REG_ERROR_CODE_RX_DLC BIT(8)
+#define RK3576CAN_REG_ERROR_CODE_RX_BRS_ESI BIT(7)
+#define RK3576CAN_REG_ERROR_CODE_RX_RES BIT(6)
+#define RK3576CAN_REG_ERROR_CODE_RX_FDF BIT(5)
+#define RK3576CAN_REG_ERROR_CODE_RX_ID2_RTR BIT(4)
+#define RK3576CAN_REG_ERROR_CODE_RX_SOF_IDE BIT(3)
+#define RK3576CAN_REG_ERROR_CODE_RX_BUS_IDLE BIT(2)
+#define RK3576CAN_REG_ERROR_CODE_RX_BUS_INT BIT(1)
+#define RK3576CAN_REG_ERROR_CODE_RX_STOP BIT(0)
+
+#define RK3576CAN_ISM_WATERMASK_CAN 0x6c /* word */
+#define RK3576CAN_ISM_WATERMASK_CANFD 0x6c /* word */
+
+#define RK3576CAN_SRAM_MAX_DEPTH 256 /* word */
+
+#define RK3576CAN_CANFD_FILTER GENMASK(28, 0)
+
+#define RK3576CAN_CANFD_FIFO_CNT GENMASK(7, 0)
+
 #define DEVICE_NAME "rockchip_canfd"
 #define RKCANFD_NAPI_WEIGHT 32
 #define RKCANFD_TXFIFO_DEPTH 2
@@ -434,6 +684,7 @@
 enum rkcanfd_model {
 	RKCANFD_MODEL_RK3568V2 = 0x35682,
 	RKCANFD_MODEL_RK3568V3 = 0x35683,
+	RKCAN_MODEL_RK3576 = 0x3576,
 };
 
 struct rkcanfd_priv;
@@ -457,6 +708,11 @@ struct rkcanfd_fifo_header {
 	u32 ts;
 };
 
+struct rk3576can_fifo_header {
+	u32 frameinfo;
+	u32 id;
+};
+
 struct rkcanfd_stats {
 	struct u64_stats_sync syncp;
 
@@ -546,6 +802,8 @@ rkcanfd_get_tx_free(const struct rkcanfd_priv *priv)
 void rkcanfd_ethtool_init(struct rkcanfd_priv *priv);
 
 int rkcanfd_handle_rx_int(struct rkcanfd_priv *priv);
+int rkcanfd_handle_rk3576_tx_int(struct rkcanfd_priv *priv);
+int rkcanfd_handle_rk3576_rx_int(struct rkcanfd_priv *priv);
 
 void rkcanfd_skb_set_timestamp(const struct rkcanfd_priv *priv,
 			       struct sk_buff *skb, const u32 timestamp);
-- 
2.34.1



From antoine.bouyer at nxp.com  Thu Nov 13 00:19:10 2025
From: antoine.bouyer at nxp.com (Antoine Bouyer)
Date: Thu, 13 Nov 2025 09:19:10 +0100
Subject: [PATCH v8 5/8] media: v4l2-core: Introduce v4l2-isp.c
In-Reply-To: <20251020-extensible-parameters-validation-v8-5-afba4ba7b42d@ideasonboard.com>
References: <20251020-extensible-parameters-validation-v8-0-afba4ba7b42d@ideasonboard.com>
 <20251020-extensible-parameters-validation-v8-5-afba4ba7b42d@ideasonboard.com>
Message-ID: <90267077-c74c-4e05-809d-94694d162e18@nxp.com>


Hi Jacopo

On 10/20/25 10:24 AM, Jacopo Mondi wrote:
> 
> Add to the V4L2 framework helper functions to support drivers when
> validating a buffer of V4L2 ISP parameters.
> 
> Driver shall use v4l2_isp_params_validate_buffer_size() to verify the
> size correctness of the data received from userspace, and after having
> copied the data to a kernel-only memory location, complete the
> validation by calling v4l2_isp_params_validate_buffer().
> 
> Reviewed-by: Daniel Scally <dan.scally at ideasonboard.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas at ideasonboard.com>
> Reviewed-by: Michael Riesch <michael.riesch at collabora.com>
> Acked-by: Sakari Ailus <sakari.ailus at linux.intel.com>
> Signed-off-by: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
> ---
>   MAINTAINERS                        |   2 +
>   drivers/media/v4l2-core/Kconfig    |   4 ++
>   drivers/media/v4l2-core/Makefile   |   1 +
>   drivers/media/v4l2-core/v4l2-isp.c | 128 +++++++++++++++++++++++++++++++++++++
>   include/media/v4l2-isp.h           |  91 ++++++++++++++++++++++++++
>   5 files changed, 226 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index f52237d57710cadff78b297d2b4610b508f55092..5833f82caa7f2f734bb0e1be144ade2109b23988 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -26857,6 +26857,8 @@ M:      Jacopo Mondi <jacopo.mondi at ideasonboard.com>
>   L:     linux-media at vger.kernel.org
>   S:     Maintained
>   F:     Documentation/userspace-api/media/v4l/v4l2-isp.rst
> +F:     drivers/media/v4l2-core/v4l2-isp.c
> +F:     include/media/v4l2-isp.h
>   F:     include/uapi/linux/media/v4l2-isp.h
> 
>   VF610 NAND DRIVER
> diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig
> index 331b8e535e5bbf33f22638b2ae8bc764ad5fc407..d50ccac9733cc39a43426ae7e7996dd0b5b45186 100644
> --- a/drivers/media/v4l2-core/Kconfig
> +++ b/drivers/media/v4l2-core/Kconfig
> @@ -82,3 +82,7 @@ config V4L2_CCI_I2C
>          depends on I2C
>          select REGMAP_I2C
>          select V4L2_CCI
> +
> +config V4L2_ISP
> +       tristate

When configured as module, there's build error:

ERROR: modpost: missing MODULE_LICENSE() in 
drivers/media/v4l2-core/v4l2-isp.o
WARNING: modpost: missing MODULE_DESCRIPTION() in 
drivers/media/v4l2-core/v4l2-isp.o

It happens when selected from an ISP driver, and ISP driver is a module. 
Then module is applied to v4l2-isp too.

> +       depends on VIDEOBUF2_CORE
> diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile
> index 2177b9d63a8ffc1127c5a70118249a2ff63cd759..329f0eadce994cc1c8580beb435f68fa7e2a7aeb 100644
> --- a/drivers/media/v4l2-core/Makefile
> +++ b/drivers/media/v4l2-core/Makefile
> @@ -29,6 +29,7 @@ obj-$(CONFIG_V4L2_CCI) += v4l2-cci.o
>   obj-$(CONFIG_V4L2_FLASH_LED_CLASS) += v4l2-flash-led-class.o
>   obj-$(CONFIG_V4L2_FWNODE) += v4l2-fwnode.o
>   obj-$(CONFIG_V4L2_H264) += v4l2-h264.o
> +obj-$(CONFIG_V4L2_ISP) += v4l2-isp.o
>   obj-$(CONFIG_V4L2_JPEG_HELPER) += v4l2-jpeg.o
>   obj-$(CONFIG_V4L2_MEM2MEM_DEV) += v4l2-mem2mem.o
>   obj-$(CONFIG_V4L2_VP9) += v4l2-vp9.o
> diff --git a/drivers/media/v4l2-core/v4l2-isp.c b/drivers/media/v4l2-core/v4l2-isp.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..35f0b701f1729c3c0ccc34b1c89189b179e0b684
> --- /dev/null
> +++ b/drivers/media/v4l2-core/v4l2-isp.c
> @@ -0,0 +1,128 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Video4Linux2 generic ISP parameters and statistics support
> + *
> + * Copyright (C) 2025 Ideas On Board Oy
> + * Author: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
> + */
> +
> +#include <media/v4l2-isp.h>
> +
> +#include <linux/bitops.h>
> +#include <linux/device.h>
> +
> +#include <media/videobuf2-core.h>
> +
> +int v4l2_isp_params_validate_buffer_size(struct device *dev,
> +                                        struct vb2_buffer *vb,
> +                                        size_t max_size)
> +{
> +       size_t header_size = offsetof(struct v4l2_isp_params_buffer, data);
> +       size_t payload_size = vb2_get_plane_payload(vb, 0);
> +
> +       /* Payload size can't be greater than the destination buffer size */
> +       if (payload_size > max_size) {
> +               dev_dbg(dev, "Payload size is too large: %zu\n", payload_size);
> +               return -EINVAL;
> +       }
> +
> +       /* Payload size can't be smaller than the header size */
> +       if (payload_size < header_size) {
> +               dev_dbg(dev, "Payload size is too small: %zu\n", payload_size);
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +EXPORT_SYMBOL_GPL(v4l2_isp_params_validate_buffer_size);
> +
> +int v4l2_isp_params_validate_buffer(struct device *dev, struct vb2_buffer *vb,
> +                                   const struct v4l2_isp_params_buffer *buffer,
> +                                   const struct v4l2_isp_params_block_info *info,
> +                                   size_t num_blocks)
> +{
> +       size_t header_size = offsetof(struct v4l2_isp_params_buffer, data);
> +       size_t payload_size = vb2_get_plane_payload(vb, 0);
> +       size_t block_offset = 0;
> +       size_t buffer_size;
> +
> +       /*
> +        * Currently only the first version of the V4L2 ISP parameters format is
> +        * supported. We accept both V0 and V1 to support existing drivers
> +        * compatible with V4L2 ISP that use either 0 or 1 as their "first
> +        * version" identifiers.
> +        */
> +       if (buffer->version != V4L2_ISP_PARAMS_VERSION_V0 &&
> +           buffer->version != V4L2_ISP_PARAMS_VERSION_V1) {
> +               dev_dbg(dev,
> +                       "Unsupported V4L2 ISP parameters format version: %u\n",
> +                       buffer->version);
> +               return -EINVAL;
> +       }
> +
> +       /* Validate the size reported in the header */
> +       buffer_size = header_size + buffer->data_size;
> +       if (buffer_size != payload_size) {
> +               dev_dbg(dev, "Data size %zu and payload size %zu are different\n",
> +                       buffer_size, payload_size);
> +               return -EINVAL;
> +       }
> +
> +       /* Walk the list of ISP configuration blocks and validate them. */
> +       buffer_size = buffer->data_size;
> +       while (buffer_size >= sizeof(struct v4l2_isp_params_block_header)) {
> +               const struct v4l2_isp_params_block_info *block_info;
> +               const struct v4l2_isp_params_block_header *block;
> +
> +               block = (const struct v4l2_isp_params_block_header *)
> +                       (buffer->data + block_offset);
> +
> +               if (block->type >= num_blocks) {
> +                       dev_dbg(dev,
> +                               "Invalid block type %u at offset %zu\n",
> +                               block->type, block_offset);
> +                       return -EINVAL;
> +               }
> +
> +               if (block->size > buffer_size) {
> +                       dev_dbg(dev, "Premature end of parameters data\n");
> +                       return -EINVAL;
> +               }
> +
> +               /* It's invalid to specify both ENABLE and DISABLE. */
> +               if ((block->flags & (V4L2_ISP_PARAMS_FL_BLOCK_ENABLE |
> +                                    V4L2_ISP_PARAMS_FL_BLOCK_DISABLE)) ==
> +                    (V4L2_ISP_PARAMS_FL_BLOCK_ENABLE |
> +                    V4L2_ISP_PARAMS_FL_BLOCK_DISABLE)) {
> +                       dev_dbg(dev, "Invalid block flags %x at offset %zu\n",
> +                               block->flags, block_offset);
> +                       return -EINVAL;
> +               }
> +
> +               /*
> +                * Match the block reported size against the info provided
> +                * one, but allow the block to only contain the header in
> +                * case it is going to be disabled.
> +                */
> +               block_info = &info[block->type];
> +               if (block->size != block_info->size &&
> +                   (!(block->flags & V4L2_ISP_PARAMS_FL_BLOCK_DISABLE) ||
> +                   block->size != sizeof(*block))) {
> +                       dev_dbg(dev,
> +                               "Invalid block size %u (expected %zu) at offset %zu\n",
> +                               block->size, block_info->size, block_offset);
> +                       return -EINVAL;
> +               }
> +
> +               block_offset += block->size;
> +               buffer_size -= block->size;
> +       }
> +
> +       if (buffer_size) {
> +               dev_dbg(dev, "Unexpected data after the parameters buffer end\n");
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +EXPORT_SYMBOL_GPL(v4l2_isp_params_validate_buffer);
> diff --git a/include/media/v4l2-isp.h b/include/media/v4l2-isp.h
> new file mode 100644
> index 0000000000000000000000000000000000000000..8b4695663699e7f176384739cf54ed7fa2c578f8
> --- /dev/null
> +++ b/include/media/v4l2-isp.h
> @@ -0,0 +1,91 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Video4Linux2 generic ISP parameters and statistics support
> + *
> + * Copyright (C) 2025 Ideas On Board Oy
> + * Author: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
> + */
> +
> +#ifndef _V4L2_ISP_H_
> +#define _V4L2_ISP_H_
> +
> +#include <linux/media/v4l2-isp.h>
> +
> +struct device;
> +struct vb2_buffer;
> +
> +/**
> + * v4l2_isp_params_buffer_size - Calculate size of v4l2_isp_params_buffer
> + * @max_params_size: The total size of the ISP configuration blocks
> + *
> + * Users of the v4l2 extensible parameters will have differing sized data arrays
> + * depending on their specific parameter buffers. Drivers and userspace will
> + * need to be able to calculate the appropriate size of the struct to
> + * accommodate all ISP configuration blocks provided by the platform.
> + * This macro provides a convenient tool for the calculation.
> + */
> +#define v4l2_isp_params_buffer_size(max_params_size) \
> +       (offsetof(struct v4l2_isp_params_buffer, data) + (max_params_size))
> +
> +/**
> + * v4l2_isp_params_validate_buffer_size - Validate a V4L2 ISP buffer sizes
> + * @dev: the driver's device pointer
> + * @vb: the videobuf2 buffer
> + * @max_size: the maximum allowed buffer size
> + *
> + * This function performs validation of the size of a V4L2 ISP parameters buffer
> + * before the driver can access the actual data buffer content.
> + *
> + * After the sizes validation, drivers should copy the buffer content to a
> + * kernel-only memory area to prevent userspace from modifying it,
> + * before completing validation using v4l2_isp_params_validate_buffer().
> + *
> + * The @vb buffer as received from the vb2 .buf_prepare() operation is checked
> + * against @max_size and it's validated to be large enough to accommodate at
> + * least one ISP configuration block.
> + */
> +int v4l2_isp_params_validate_buffer_size(struct device *dev,
> +                                        struct vb2_buffer *vb,
> +                                        size_t max_size);
> +
> +/**
> + * struct v4l2_isp_params_block_info - V4L2 ISP per-block info
> + * @size: the block expected size
> + *
> + * The v4l2_isp_params_block_info collects information of the ISP configuration
> + * blocks for validation purposes. It currently only contains the expected
> + * block size.
> + *
> + * Drivers shall prepare a list of block info, indexed by block type, one for
> + * each supported ISP block and correctly populate them with the expected block
> + * size.
> + */
> +struct v4l2_isp_params_block_info {
> +       size_t size;
> +};
> +
> +/**
> + * v4l2_isp_params_validate_buffer - Validate a V4L2 ISP parameters buffer
> + * @dev: the driver's device pointer
> + * @vb: the videobuf2 buffer
> + * @buffer: the V4L2 ISP parameters buffer
> + * @info: the list of per-block validation info
> + * @num_blocks: the number of blocks
> + *
> + * This function completes the validation of a V4L2 ISP parameters buffer,
> + * verifying each configuration block correctness before the driver can use
> + * them to program the hardware.
> + *
> + * Drivers should use this function after having validated the correctness of
> + * the vb2 buffer sizes by using the v4l2_isp_params_validate_buffer_size()
> + * helper first. Once the buffer size has been validated, drivers should
> + * perform a copy of the user provided buffer into a kernel-only memory buffer
> + * to prevent userspace from modifying its content after it has been submitted
> + * to the driver, and then call this function to complete validation.
> + */
> +int v4l2_isp_params_validate_buffer(struct device *dev, struct vb2_buffer *vb,
> +                                   const struct v4l2_isp_params_buffer *buffer,
> +                                   const struct v4l2_isp_params_block_info *info,
> +                                   size_t num_blocks);
> +
> +#endif /* _V4L2_ISP_H_ */
> 
> --
> 2.51.0
> 



From krzk at kernel.org  Thu Nov 13 00:35:19 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 13 Nov 2025 09:35:19 +0100
Subject: [PATCH 1/2] dt-bindings: arm: rockchip: Asus Tinkerboard 3 and 3S
In-Reply-To: <20251111172003.2324525-2-michael.opdenacker@rootcommit.com>
References: <20251111172003.2324525-1-michael.opdenacker@rootcommit.com>
 <20251111172003.2324525-2-michael.opdenacker@rootcommit.com>
Message-ID: <20251113-berserk-hairy-alligator-2eee0c@kuoka>

On Tue, Nov 11, 2025 at 05:20:22PM +0000, michael.opdenacker at rootcommit.com wrote:
> From: Michael Opdenacker <michael.opdenacker at rootcommit.com>
> 
> Document the compatible strings for Asus Tinkerboard 3 [1] and 3S [2],
> which are SBCs based on the Rockchip 3566 SoC.
> 
> The "3S" version ("S" for "storage") just adds a 16 GB eMMC
> and a "mask ROM" DIP switch to the "3" version.
> 
> Link: https://tinker-board.asus.com/series/tinker-board-3.html [1]
> Link: https://tinker-board.asus.com/series/tinker-board-3s.html [2]
> Signed-off-by: Michael Opdenacker <michael.opdenacker at rootcommit.com>
> ---
>  Documentation/devicetree/bindings/arm/rockchip.yaml | 11 +++++++++++
>  1 file changed, 11 insertions(+)

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Best regards,
Krzysztof



From jacopo.mondi at ideasonboard.com  Thu Nov 13 00:49:49 2025
From: jacopo.mondi at ideasonboard.com (Jacopo Mondi)
Date: Thu, 13 Nov 2025 09:49:49 +0100
Subject: [PATCH v8 5/8] media: v4l2-core: Introduce v4l2-isp.c
In-Reply-To: <90267077-c74c-4e05-809d-94694d162e18@nxp.com>
References: <20251020-extensible-parameters-validation-v8-0-afba4ba7b42d@ideasonboard.com>
 <20251020-extensible-parameters-validation-v8-5-afba4ba7b42d@ideasonboard.com>
 <90267077-c74c-4e05-809d-94694d162e18@nxp.com>
Message-ID: <mowumvzl6rk2st2lwdhqfuepwm6txxrmr7praxn43tski52xox@vvgr2hyllxgz>

HI Antoine

On Thu, Nov 13, 2025 at 09:19:10AM +0100, Antoine Bouyer wrote:
>
> Hi Jacopo
>
> On 10/20/25 10:24 AM, Jacopo Mondi wrote:
> >
> > Add to the V4L2 framework helper functions to support drivers when
> > validating a buffer of V4L2 ISP parameters.
> >
> > Driver shall use v4l2_isp_params_validate_buffer_size() to verify the
> > size correctness of the data received from userspace, and after having
> > copied the data to a kernel-only memory location, complete the
> > validation by calling v4l2_isp_params_validate_buffer().
> >
> > Reviewed-by: Daniel Scally <dan.scally at ideasonboard.com>
> > Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas at ideasonboard.com>
> > Reviewed-by: Michael Riesch <michael.riesch at collabora.com>
> > Acked-by: Sakari Ailus <sakari.ailus at linux.intel.com>
> > Signed-off-by: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
> > ---
> >   MAINTAINERS                        |   2 +
> >   drivers/media/v4l2-core/Kconfig    |   4 ++
> >   drivers/media/v4l2-core/Makefile   |   1 +
> >   drivers/media/v4l2-core/v4l2-isp.c | 128 +++++++++++++++++++++++++++++++++++++
> >   include/media/v4l2-isp.h           |  91 ++++++++++++++++++++++++++
> >   5 files changed, 226 insertions(+)
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index f52237d57710cadff78b297d2b4610b508f55092..5833f82caa7f2f734bb0e1be144ade2109b23988 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -26857,6 +26857,8 @@ M:      Jacopo Mondi <jacopo.mondi at ideasonboard.com>
> >   L:     linux-media at vger.kernel.org
> >   S:     Maintained
> >   F:     Documentation/userspace-api/media/v4l/v4l2-isp.rst
> > +F:     drivers/media/v4l2-core/v4l2-isp.c
> > +F:     include/media/v4l2-isp.h
> >   F:     include/uapi/linux/media/v4l2-isp.h
> >
> >   VF610 NAND DRIVER
> > diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig
> > index 331b8e535e5bbf33f22638b2ae8bc764ad5fc407..d50ccac9733cc39a43426ae7e7996dd0b5b45186 100644
> > --- a/drivers/media/v4l2-core/Kconfig
> > +++ b/drivers/media/v4l2-core/Kconfig
> > @@ -82,3 +82,7 @@ config V4L2_CCI_I2C
> >          depends on I2C
> >          select REGMAP_I2C
> >          select V4L2_CCI
> > +
> > +config V4L2_ISP
> > +       tristate
>
> When configured as module, there's build error:
>
> ERROR: modpost: missing MODULE_LICENSE() in
> drivers/media/v4l2-core/v4l2-isp.o
> WARNING: modpost: missing MODULE_DESCRIPTION() in
> drivers/media/v4l2-core/v4l2-isp.o
>
> It happens when selected from an ISP driver, and ISP driver is a module.
> Then module is applied to v4l2-isp too.

Thanks for reporting it! I was about to send a pull request -.-'

I can reproduce locally

ERROR: modpost: missing MODULE_LICENSE() in drivers/media/v4l2-core/v4l2-isp.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/media/v4l2-core/v4l2-isp.o
make[3]: *** [../scripts/Makefile.modpost:147: Module.symvers] Error 1

And I've fixed it by adding:

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jacopo Mondi <jacopo.mondi at ideasonboard.com");
MODULE_DESCRIPTION("V4L2 generic ISP parameters and statistics helpers");

Thank you!


>
> > +       depends on VIDEOBUF2_CORE
> > diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile
> > index 2177b9d63a8ffc1127c5a70118249a2ff63cd759..329f0eadce994cc1c8580beb435f68fa7e2a7aeb 100644
> > --- a/drivers/media/v4l2-core/Makefile
> > +++ b/drivers/media/v4l2-core/Makefile
> > @@ -29,6 +29,7 @@ obj-$(CONFIG_V4L2_CCI) += v4l2-cci.o
> >   obj-$(CONFIG_V4L2_FLASH_LED_CLASS) += v4l2-flash-led-class.o
> >   obj-$(CONFIG_V4L2_FWNODE) += v4l2-fwnode.o
> >   obj-$(CONFIG_V4L2_H264) += v4l2-h264.o
> > +obj-$(CONFIG_V4L2_ISP) += v4l2-isp.o
> >   obj-$(CONFIG_V4L2_JPEG_HELPER) += v4l2-jpeg.o
> >   obj-$(CONFIG_V4L2_MEM2MEM_DEV) += v4l2-mem2mem.o
> >   obj-$(CONFIG_V4L2_VP9) += v4l2-vp9.o
> > diff --git a/drivers/media/v4l2-core/v4l2-isp.c b/drivers/media/v4l2-core/v4l2-isp.c
> > new file mode 100644
> > index 0000000000000000000000000000000000000000..35f0b701f1729c3c0ccc34b1c89189b179e0b684
> > --- /dev/null
> > +++ b/drivers/media/v4l2-core/v4l2-isp.c
> > @@ -0,0 +1,128 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +/*
> > + * Video4Linux2 generic ISP parameters and statistics support
> > + *
> > + * Copyright (C) 2025 Ideas On Board Oy
> > + * Author: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
> > + */
> > +
> > +#include <media/v4l2-isp.h>
> > +
> > +#include <linux/bitops.h>
> > +#include <linux/device.h>
> > +
> > +#include <media/videobuf2-core.h>
> > +
> > +int v4l2_isp_params_validate_buffer_size(struct device *dev,
> > +                                        struct vb2_buffer *vb,
> > +                                        size_t max_size)
> > +{
> > +       size_t header_size = offsetof(struct v4l2_isp_params_buffer, data);
> > +       size_t payload_size = vb2_get_plane_payload(vb, 0);
> > +
> > +       /* Payload size can't be greater than the destination buffer size */
> > +       if (payload_size > max_size) {
> > +               dev_dbg(dev, "Payload size is too large: %zu\n", payload_size);
> > +               return -EINVAL;
> > +       }
> > +
> > +       /* Payload size can't be smaller than the header size */
> > +       if (payload_size < header_size) {
> > +               dev_dbg(dev, "Payload size is too small: %zu\n", payload_size);
> > +               return -EINVAL;
> > +       }
> > +
> > +       return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(v4l2_isp_params_validate_buffer_size);
> > +
> > +int v4l2_isp_params_validate_buffer(struct device *dev, struct vb2_buffer *vb,
> > +                                   const struct v4l2_isp_params_buffer *buffer,
> > +                                   const struct v4l2_isp_params_block_info *info,
> > +                                   size_t num_blocks)
> > +{
> > +       size_t header_size = offsetof(struct v4l2_isp_params_buffer, data);
> > +       size_t payload_size = vb2_get_plane_payload(vb, 0);
> > +       size_t block_offset = 0;
> > +       size_t buffer_size;
> > +
> > +       /*
> > +        * Currently only the first version of the V4L2 ISP parameters format is
> > +        * supported. We accept both V0 and V1 to support existing drivers
> > +        * compatible with V4L2 ISP that use either 0 or 1 as their "first
> > +        * version" identifiers.
> > +        */
> > +       if (buffer->version != V4L2_ISP_PARAMS_VERSION_V0 &&
> > +           buffer->version != V4L2_ISP_PARAMS_VERSION_V1) {
> > +               dev_dbg(dev,
> > +                       "Unsupported V4L2 ISP parameters format version: %u\n",
> > +                       buffer->version);
> > +               return -EINVAL;
> > +       }
> > +
> > +       /* Validate the size reported in the header */
> > +       buffer_size = header_size + buffer->data_size;
> > +       if (buffer_size != payload_size) {
> > +               dev_dbg(dev, "Data size %zu and payload size %zu are different\n",
> > +                       buffer_size, payload_size);
> > +               return -EINVAL;
> > +       }
> > +
> > +       /* Walk the list of ISP configuration blocks and validate them. */
> > +       buffer_size = buffer->data_size;
> > +       while (buffer_size >= sizeof(struct v4l2_isp_params_block_header)) {
> > +               const struct v4l2_isp_params_block_info *block_info;
> > +               const struct v4l2_isp_params_block_header *block;
> > +
> > +               block = (const struct v4l2_isp_params_block_header *)
> > +                       (buffer->data + block_offset);
> > +
> > +               if (block->type >= num_blocks) {
> > +                       dev_dbg(dev,
> > +                               "Invalid block type %u at offset %zu\n",
> > +                               block->type, block_offset);
> > +                       return -EINVAL;
> > +               }
> > +
> > +               if (block->size > buffer_size) {
> > +                       dev_dbg(dev, "Premature end of parameters data\n");
> > +                       return -EINVAL;
> > +               }
> > +
> > +               /* It's invalid to specify both ENABLE and DISABLE. */
> > +               if ((block->flags & (V4L2_ISP_PARAMS_FL_BLOCK_ENABLE |
> > +                                    V4L2_ISP_PARAMS_FL_BLOCK_DISABLE)) ==
> > +                    (V4L2_ISP_PARAMS_FL_BLOCK_ENABLE |
> > +                    V4L2_ISP_PARAMS_FL_BLOCK_DISABLE)) {
> > +                       dev_dbg(dev, "Invalid block flags %x at offset %zu\n",
> > +                               block->flags, block_offset);
> > +                       return -EINVAL;
> > +               }
> > +
> > +               /*
> > +                * Match the block reported size against the info provided
> > +                * one, but allow the block to only contain the header in
> > +                * case it is going to be disabled.
> > +                */
> > +               block_info = &info[block->type];
> > +               if (block->size != block_info->size &&
> > +                   (!(block->flags & V4L2_ISP_PARAMS_FL_BLOCK_DISABLE) ||
> > +                   block->size != sizeof(*block))) {
> > +                       dev_dbg(dev,
> > +                               "Invalid block size %u (expected %zu) at offset %zu\n",
> > +                               block->size, block_info->size, block_offset);
> > +                       return -EINVAL;
> > +               }
> > +
> > +               block_offset += block->size;
> > +               buffer_size -= block->size;
> > +       }
> > +
> > +       if (buffer_size) {
> > +               dev_dbg(dev, "Unexpected data after the parameters buffer end\n");
> > +               return -EINVAL;
> > +       }
> > +
> > +       return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(v4l2_isp_params_validate_buffer);
> > diff --git a/include/media/v4l2-isp.h b/include/media/v4l2-isp.h
> > new file mode 100644
> > index 0000000000000000000000000000000000000000..8b4695663699e7f176384739cf54ed7fa2c578f8
> > --- /dev/null
> > +++ b/include/media/v4l2-isp.h
> > @@ -0,0 +1,91 @@
> > +/* SPDX-License-Identifier: GPL-2.0-or-later */
> > +/*
> > + * Video4Linux2 generic ISP parameters and statistics support
> > + *
> > + * Copyright (C) 2025 Ideas On Board Oy
> > + * Author: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
> > + */
> > +
> > +#ifndef _V4L2_ISP_H_
> > +#define _V4L2_ISP_H_
> > +
> > +#include <linux/media/v4l2-isp.h>
> > +
> > +struct device;
> > +struct vb2_buffer;
> > +
> > +/**
> > + * v4l2_isp_params_buffer_size - Calculate size of v4l2_isp_params_buffer
> > + * @max_params_size: The total size of the ISP configuration blocks
> > + *
> > + * Users of the v4l2 extensible parameters will have differing sized data arrays
> > + * depending on their specific parameter buffers. Drivers and userspace will
> > + * need to be able to calculate the appropriate size of the struct to
> > + * accommodate all ISP configuration blocks provided by the platform.
> > + * This macro provides a convenient tool for the calculation.
> > + */
> > +#define v4l2_isp_params_buffer_size(max_params_size) \
> > +       (offsetof(struct v4l2_isp_params_buffer, data) + (max_params_size))
> > +
> > +/**
> > + * v4l2_isp_params_validate_buffer_size - Validate a V4L2 ISP buffer sizes
> > + * @dev: the driver's device pointer
> > + * @vb: the videobuf2 buffer
> > + * @max_size: the maximum allowed buffer size
> > + *
> > + * This function performs validation of the size of a V4L2 ISP parameters buffer
> > + * before the driver can access the actual data buffer content.
> > + *
> > + * After the sizes validation, drivers should copy the buffer content to a
> > + * kernel-only memory area to prevent userspace from modifying it,
> > + * before completing validation using v4l2_isp_params_validate_buffer().
> > + *
> > + * The @vb buffer as received from the vb2 .buf_prepare() operation is checked
> > + * against @max_size and it's validated to be large enough to accommodate at
> > + * least one ISP configuration block.
> > + */
> > +int v4l2_isp_params_validate_buffer_size(struct device *dev,
> > +                                        struct vb2_buffer *vb,
> > +                                        size_t max_size);
> > +
> > +/**
> > + * struct v4l2_isp_params_block_info - V4L2 ISP per-block info
> > + * @size: the block expected size
> > + *
> > + * The v4l2_isp_params_block_info collects information of the ISP configuration
> > + * blocks for validation purposes. It currently only contains the expected
> > + * block size.
> > + *
> > + * Drivers shall prepare a list of block info, indexed by block type, one for
> > + * each supported ISP block and correctly populate them with the expected block
> > + * size.
> > + */
> > +struct v4l2_isp_params_block_info {
> > +       size_t size;
> > +};
> > +
> > +/**
> > + * v4l2_isp_params_validate_buffer - Validate a V4L2 ISP parameters buffer
> > + * @dev: the driver's device pointer
> > + * @vb: the videobuf2 buffer
> > + * @buffer: the V4L2 ISP parameters buffer
> > + * @info: the list of per-block validation info
> > + * @num_blocks: the number of blocks
> > + *
> > + * This function completes the validation of a V4L2 ISP parameters buffer,
> > + * verifying each configuration block correctness before the driver can use
> > + * them to program the hardware.
> > + *
> > + * Drivers should use this function after having validated the correctness of
> > + * the vb2 buffer sizes by using the v4l2_isp_params_validate_buffer_size()
> > + * helper first. Once the buffer size has been validated, drivers should
> > + * perform a copy of the user provided buffer into a kernel-only memory buffer
> > + * to prevent userspace from modifying its content after it has been submitted
> > + * to the driver, and then call this function to complete validation.
> > + */
> > +int v4l2_isp_params_validate_buffer(struct device *dev, struct vb2_buffer *vb,
> > +                                   const struct v4l2_isp_params_buffer *buffer,
> > +                                   const struct v4l2_isp_params_block_info *info,
> > +                                   size_t num_blocks);
> > +
> > +#endif /* _V4L2_ISP_H_ */
> >
> > --
> > 2.51.0
> >
>


From quentin.schulz at cherry.de  Thu Nov 13 01:57:16 2025
From: quentin.schulz at cherry.de (Quentin Schulz)
Date: Thu, 13 Nov 2025 10:57:16 +0100
Subject: [PATCH] arm64: dts: rockchip: disable HS400 on RK3588 Tiger
In-Reply-To: <20251112-tiger-hs200-v1-1-b50adac107c0@cherry.de>
References: <20251112-tiger-hs200-v1-1-b50adac107c0@cherry.de>
Message-ID: <575fd825-5ee8-4a46-b9ef-2a16d9ce61b1@cherry.de>

Hi all,

On 11/12/25 4:01 PM, Quentin Schulz wrote:
> From: Quentin Schulz <quentin.schulz at cherry.de>
> 
> We've had reports from the field that some RK3588 Tiger have random
> issues with eMMC errors.
> 
> Applying commit a28352cf2d2f ("mmc: sdhci-of-dwcmshc: Change
> DLL_STRBIN_TAPNUM_DEFAULT to 0x4") didn't help and seemed to have made
> things worse for our board.
> 
> Our HW department checked the eMMC lines and reported that they are too
> long and don't look great so signal integrity is probably not the best.
> 
> Note that not all Tigers with the same eMMC chip have errors, so the
> suspicion is that we're really on the edge in terms of signal integrity
> and only a handful devices are failing. Additionally, we have RK3588
> Jaguars with the same eMMC chip but the layout is different and we also
> haven't received reports about those so far.
> 
> Lowering the max-frequency to 150MHz from 200MHz instead of simply
> disabling HS400 was briefly tested and seem to work as well. We've
> disabled HS400 downstream and haven't received reports since so we'll go
> with that instead of lowering the max-frequency.
> 
> Signed-off-by: Quentin Schulz <quentin.schulz at cherry.de>

Went too fast and forgot:

Fixes: 6173ef24b35b ("arm64: dts: rockchip: add RK3588-Q7 (Tiger) SoM")
Cc: stable at vger.kernel.org

Will give a few days for reviews and then send a v2 next week.

Cheers,
Quentin


From diederik at cknow-tech.com  Thu Nov 13 03:18:17 2025
From: diederik at cknow-tech.com (Diederik de Haas)
Date: Thu, 13 Nov 2025 12:18:17 +0100
Subject: [PATCH] drm/rockchip: vop2: Use OVL_LAYER_SEL configuration
 instead of use win_mask calculate used layers
In-Reply-To: <hrg6geclph37olvqr3o5v4d4mifvl25kaemh7f2z3hwega7h2b@muf2gkfqzvvz>
References: <20251112085024.2480111-1-andyshrk@163.com>
 <hrg6geclph37olvqr3o5v4d4mifvl25kaemh7f2z3hwega7h2b@muf2gkfqzvvz>
Message-ID: <DE7IXK6SWV7J.3B9AOCCGWT4EH@cknow-tech.com>

On Thu Nov 13, 2025 at 9:11 AM CET, Dang Huynh wrote:
> Hi Andy,
>
> This fix works on my device. No more black box around the cursor.
>
> Tested-by: Dang Huynh <dang.huynh at mainlining.org>

Thanks for testing and your Tested-by tag :-D

FYI: Apparently something went wrong with delivery it as it only arrived
at LKML, but not dri-devel, linux-arm-kernel or linux-rockchip MLs.
No idea if that's problematic (for b4 f.e.) though.

'lore' has it here:
https://lore.kernel.org/all/hrg6geclph37olvqr3o5v4d4mifvl25kaemh7f2z3hwega7h2b at muf2gkfqzvvz/

Cheers,
 Diederik

> On Wed, Nov 12, 2025 at 04:50:23PM +0800, Andy Yan wrote:
>> From: Andy Yan <andy.yan at rock-chips.com>
>> 
>> When there are multiple Video Ports, and only one of them is working
>> (for example, VP1 is working while VP0 is not), in this case, the
>> win_mask of VP0 is 0. However, we have already set the port mux for VP0
>> according to vp0->nlayers, and at the same time, in the OVL_LAYER_SEL
>> register, there are windows will also be assigned to layers which will
>> map to the inactive VPs. In this situation, vp0->win_mask is zero as it
>> now working, it is more reliable to calculate the used layers based on
>> the configuration of the OVL_LAYER_SEL register.
>> 
>> Note: as the configuration of OVL_LAYER_SEL is take effect when the
>> vsync is come, so we use the value backup in vop2->old_layer_sel instead
>> of read OVL_LAYER_SEL directly.
>> 
>> Fixes: 3e89a8c68354 ("drm/rockchip: vop2: Fix the update of LAYER/PORT select registers when there are multi display output on rk3588/rk3568")
>> Reported-by: Diederik de Haas <diederik at cknow-tech.com>
>> Closes: https://bugs.kde.org/show_bug.cgi?id=511274
>> Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
>> ---
>> 
>>  drivers/gpu/drm/rockchip/rockchip_vop2_reg.c | 49 +++++++++++++++++---
>>  1 file changed, 42 insertions(+), 7 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
>> index d22ce11a4235..f3950e8476a7 100644
>> --- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
>> +++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
>> @@ -1369,6 +1369,25 @@ static const struct vop2_regs_dump rk3588_regs_dump[] = {
>>  	},
>>  };
>>  
>> +/*
>> + * phys_id is used to identify a main window(Cluster Win/Smart Win, not
>> + * include the sub win of a cluster or the multi area) that can do overlay
>> + * in main overlay stage.
>> + */
>> +static struct vop2_win *vop2_find_win_by_phys_id(struct vop2 *vop2, uint8_t phys_id)
>> +{
>> +	struct vop2_win *win;
>> +	int i;
>> +
>> +	for (i = 0; i < vop2->data->win_size; i++) {
>> +		win = &vop2->win[i];
>> +		if (win->data->phys_id == phys_id)
>> +			return win;
>> +	}
>> +
>> +	return NULL;
>> +}
>> +
>>  static unsigned long rk3568_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags)
>>  {
>>  	struct vop2 *vop2 = vp->vop2;
>> @@ -1842,15 +1861,31 @@ static void vop2_parse_alpha(struct vop2_alpha_config *alpha_config,
>>  	alpha->dst_alpha_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE;
>>  }
>>  
>> -static int vop2_find_start_mixer_id_for_vp(struct vop2 *vop2, u8 port_id)
>> +static int vop2_find_start_mixer_id_for_vp(struct vop2_video_port *vp)
>>  {
>> -	struct vop2_video_port *vp;
>> -	int used_layer = 0;
>> +	struct vop2 *vop2 = vp->vop2;
>> +	struct vop2_win *win;
>> +	u32 layer_sel = vop2->old_layer_sel;
>> +	u32 used_layer = 0;
>> +	unsigned long win_mask = vp->win_mask;
>> +	unsigned long phys_id;
>> +	bool match;
>>  	int i;
>>  
>> -	for (i = 0; i < port_id; i++) {
>> -		vp = &vop2->vps[i];
>> -		used_layer += hweight32(vp->win_mask);
>> +	for (i = 0; i < 31; i += 4) {
>> +		match = false;
>> +		for_each_set_bit(phys_id, &win_mask, ROCKCHIP_VOP2_ESMART3) {
>> +			win = vop2_find_win_by_phys_id(vop2, phys_id);
>> +			if (win->data->layer_sel_id[vp->id] == ((layer_sel >> i) & 0xf)) {
>> +				match = true;
>> +				break;
>> +			}
>> +		}
>> +
>> +		if (!match)
>> +			used_layer += 1;
>> +		else
>> +			break;
>>  	}
>>  
>>  	return used_layer;
>> @@ -1935,7 +1970,7 @@ static void vop2_setup_alpha(struct vop2_video_port *vp)
>>  	u32 dst_global_alpha = DRM_BLEND_ALPHA_OPAQUE;
>>  
>>  	if (vop2->version <= VOP_VERSION_RK3588)
>> -		mixer_id = vop2_find_start_mixer_id_for_vp(vop2, vp->id);
>> +		mixer_id = vop2_find_start_mixer_id_for_vp(vp);
>>  	else
>>  		mixer_id = 0;
>>  
>> -- 
>> 2.43.0
>> 
>> base-commit: ded94ec6167e84195507237100f6278941e36fdd
>> branch: drm-misc-next-2025-1016
>> 
>> 
>> _______________________________________________
>> Linux-rockchip mailing list
>> Linux-rockchip at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-rockchip



From naoki at radxa.com  Thu Nov 13 04:42:20 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Thu, 13 Nov 2025 12:42:20 +0000
Subject: [PATCH v3 1/3] arm64: dts: rockchip: Use default-state for power LED for Radxa boards
In-Reply-To: <20251113124222.4691-1-naoki@radxa.com>
References: <20251113124222.4691-1-naoki@radxa.com>
Message-ID: <20251113124222.4691-2-naoki@radxa.com>

Currently, on Radxa boards, the power LED is turned on immediately
after power-up, independent of software control. The heartbeat LED and
other available LEDs are subsequently turned on by the initial
software, such as U-Boot, to indicate software is running.

However, the device tree description for this behavior is inconsistent
and fragmented, with definitions split between the main Linux DTS
files and separate U-Boot files (u-boot/arch/arm/dts/*-u-boot.dtsi).

This patch addresses the inconsistency for the power LED by using
default-state = "on" instead of linux,default-trigger = "default-on".

Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
 arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts    | 1 -
 arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts | 2 +-
 arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts      | 1 -
 arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts      | 2 +-
 arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts   | 2 +-
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts     | 2 +-
 6 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
index 7a32972bc2496..c1e3098b9a7bc 100644
--- a/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
@@ -35,7 +35,6 @@ green-led {
 			function = LED_FUNCTION_POWER;
 			gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
 			label = "rockpis:green:power";
-			linux,default-trigger = "default-on";
 		};
 
 		blue-led {
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts
index 962b8b231c960..74160cf891885 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts
@@ -39,8 +39,8 @@ leds {
 		led-0 {
 			function = LED_FUNCTION_POWER;
 			color = <LED_COLOR_ID_GREEN>;
+			default-state = "on";
 			gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_LOW>;
-			linux,default-trigger = "default-on";
 		};
 
 		/* USER_LED2 */
diff --git a/arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts b/arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts
index c03ae1dd34560..0b696d49b71fa 100644
--- a/arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts
@@ -45,7 +45,6 @@ led-1 {
 		default-state = "on";
 		function = LED_FUNCTION_STATUS;
 		gpios = <&gpio3 RK_PC1 GPIO_ACTIVE_LOW>;
-		linux,default-trigger = "default-on";
 	};
 };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts b/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts
index 9bc33422ced50..7023dc326d0e8 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts
@@ -52,9 +52,9 @@ leds: leds {
 
 		power-led {
 			color = <LED_COLOR_ID_GREEN>;
+			default-state = "on";
 			function = LED_FUNCTION_STATUS;
 			gpios = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>;
-			linux,default-trigger = "default-on";
 		};
 
 		user-led {
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
index bc8140883de47..e360446368ae6 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
@@ -88,8 +88,8 @@ gpio-leds {
 		pinctrl-0 = <&led_pins>;
 
 		power-led1 {
+			default-state = "on";
 			gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
-			linux,default-trigger = "default-on";
 		};
 
 		hdd-led2 {
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
index 19a08f7794e67..217538ed12df8 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
@@ -61,9 +61,9 @@ io-led {
 
 		power-led {
 			color = <LED_COLOR_ID_GREEN>;
+			default-state = "on";
 			function = LED_FUNCTION_POWER;
 			gpios = <&gpio3 RK_PC4 GPIO_ACTIVE_HIGH>;
-			linux,default-trigger = "default-on";
 		};
 	};
 
-- 
2.43.0



From naoki at radxa.com  Thu Nov 13 04:42:21 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Thu, 13 Nov 2025 12:42:21 +0000
Subject: [PATCH v3 2/3] arm64: dts: rockchip: Turn on heartbeat LED at boot for Radxa boards
In-Reply-To: <20251113124222.4691-1-naoki@radxa.com>
References: <20251113124222.4691-1-naoki@radxa.com>
Message-ID: <20251113124222.4691-3-naoki@radxa.com>

Currently, on Radxa boards, the power LED is turned on immediately
after power-up, independent of software control. The heartbeat LED and
other available LEDs are subsequently turned on by the initial
software, such as U-Boot, to indicate software is running.

However, the device tree description for this behavior is inconsistent
and fragmented, with definitions split between the main Linux DTS
files and separate U-Boot files (u-boot/arch/arm/dts/*-u-boot.dtsi).

This patch addresses the description fragmentation for the heartbeat
LED by consolidating its default-state = "on" definition from the
U-Boot files into the main Linux DTS.

- Radxa CM3 IO board
  https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3566-radxa-cm3-io-u-boot.dtsi#L10-12

- Radxa CM3I
  https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3568-radxa-e25-u-boot.dtsi#L7-24

- Radxa ROCK 3A
  https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3568-rock-3a-u-boot.dtsi#L11-13

- Radxa ROCK 3C
  https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3566-rock-3c-u-boot.dtsi#L14-16

- Radxa ROCK 4C+
  https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3399-rock-4c-plus-u-boot.dtsi#L11-17

- Radxa ROCK 4D
  (New)

- Radxa ROCK 4SE
  Radxa ROCK Pi 4A/A+/B/B+/C
  https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3399-rock-pi-4-u-boot.dtsi#L11-13

- Radxa ROCK 5A
  https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3588s-rock-5a-u-boot.dtsi#L10-12

- Radxa ROCK 5B
  https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3588-rock-5b-u-boot.dtsi#L11-13

- Radxa ROCK 5B+/5T
  (New)

- Radxa ROCK Pi E
  https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3328-rock-pi-e-base-u-boot.dtsi#L10-12

Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
 arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts    | 1 +
 arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts | 1 +
 arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi   | 1 +
 arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts | 1 +
 arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts      | 1 +
 arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi  | 1 +
 arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts      | 1 +
 arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts      | 1 +
 arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi     | 1 +
 arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts      | 1 +
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts     | 1 +
 11 files changed, 11 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
index a4bdd87d0729f..d3d6f34b66fb0 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
@@ -59,6 +59,7 @@ leds {
 
 		led-0 {
 			color = <LED_COLOR_ID_BLUE>;
+			default-state = "on";
 			gpios = <&gpio3 RK_PA5 GPIO_ACTIVE_LOW>;
 			linux,default-trigger = "heartbeat";
 		};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts
index 74160cf891885..a83ffbef22a7b 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts
@@ -47,6 +47,7 @@ led-0 {
 		led-1 {
 			function = LED_FUNCTION_STATUS;
 			color = <LED_COLOR_ID_BLUE>;
+			default-state = "on";
 			gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "heartbeat";
 		};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
index 046dbe3290178..ef434c23fe85c 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
@@ -35,6 +35,7 @@ leds {
 		led-0 {
 			function = LED_FUNCTION_STATUS;
 			color = <LED_COLOR_ID_BLUE>;
+			default-state = "on";
 			gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "heartbeat";
 		};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts b/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
index b5b253f04cdf5..9e7212b70e3f1 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts
@@ -46,6 +46,7 @@ leds {
 		led-1 {
 			gpios = <&gpio4 RK_PA4 GPIO_ACTIVE_LOW>;
 			color = <LED_COLOR_ID_GREEN>;
+			default-state = "on";
 			function = LED_FUNCTION_ACTIVITY;
 			linux,default-trigger = "heartbeat";
 			pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
index 6224d72813e59..3ec108bcf89a1 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
@@ -47,6 +47,7 @@ led-0 {
 			gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
 			function = LED_FUNCTION_HEARTBEAT;
 			color = <LED_COLOR_ID_BLUE>;
+			default-state = "on";
 			linux,default-trigger = "heartbeat";
 			pinctrl-names = "default";
 			pinctrl-0 = <&user_led2>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi b/arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi
index 729e38b9f620e..140582f8e1034 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi
@@ -23,6 +23,7 @@ led_user: led-0 {
 			gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
 			function = LED_FUNCTION_HEARTBEAT;
 			color = <LED_COLOR_ID_GREEN>;
+			default-state = "on";
 			linux,default-trigger = "heartbeat";
 			pinctrl-names = "default";
 			pinctrl-0 = <&led_user_en>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
index 44cfdfeed6681..e6c18df0fa582 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
@@ -47,6 +47,7 @@ led_user: led-0 {
 			gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
 			function = LED_FUNCTION_HEARTBEAT;
 			color = <LED_COLOR_ID_BLUE>;
+			default-state = "on";
 			linux,default-trigger = "heartbeat";
 			pinctrl-names = "default";
 			pinctrl-0 = <&led_user_en>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts b/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts
index 7023dc326d0e8..99d3a8be8f18c 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts
@@ -59,6 +59,7 @@ power-led {
 
 		user-led {
 			color = <LED_COLOR_ID_BLUE>;
+			default-state = "on";
 			function = LED_FUNCTION_HEARTBEAT;
 			gpios = <&gpio0 RK_PC4 GPIO_ACTIVE_LOW>;
 			linux,default-trigger = "heartbeat";
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi
index e5c474e4d02a6..8c4a4270f9f93 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi
@@ -30,6 +30,7 @@ leds {
 		led_rgb_b {
 			function = LED_FUNCTION_STATUS;
 			color = <LED_COLOR_ID_BLUE>;
+			default-state = "on";
 			gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "heartbeat";
 		};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts
index 0dd90c744380b..87e9d4b86dad4 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts
@@ -33,6 +33,7 @@ leds {
 		led_rgb_b {
 			function = LED_FUNCTION_STATUS;
 			color = <LED_COLOR_ID_BLUE>;
+			default-state = "on";
 			gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "heartbeat";
 		};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
index 217538ed12df8..46c81e796b100 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
@@ -54,6 +54,7 @@ leds {
 
 		io-led {
 			color = <LED_COLOR_ID_BLUE>;
+			default-state = "on";
 			function = LED_FUNCTION_STATUS;
 			gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "heartbeat";
-- 
2.43.0



From naoki at radxa.com  Thu Nov 13 04:42:22 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Thu, 13 Nov 2025 12:42:22 +0000
Subject: [PATCH v3 3/3] arm64: dts: rockchip: Remove default-state = "off" from LEDs for Radxa boards
In-Reply-To: <20251113124222.4691-1-naoki@radxa.com>
References: <20251113124222.4691-1-naoki@radxa.com>
Message-ID: <20251113124222.4691-4-naoki@radxa.com>

Currently, on Radxa boards, the power LED is turned on immediately
after power-up, independent of software control. The heartbeat LED and
other available LEDs are subsequently turned on by the initial
software, such as U-Boot, to indicate software is running.

However, the device tree description for this behavior is inconsistent
and fragmented, with definitions split between the main Linux DTS
files and separate U-Boot files (u-boot/arch/arm/dts/*-u-boot.dtsi).

This patch addresses inconsistency by removing redundant default-state
= "off" definitions, as this is already the default configuration.

Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
---
 arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts | 2 --
 arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts | 2 --
 2 files changed, 4 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts b/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts
index b324527561558..79d316a1d8495 100644
--- a/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts
@@ -62,7 +62,6 @@ leds {
 
 		led-lan {
 			color = <LED_COLOR_ID_GREEN>;
-			default-state = "off";
 			function = LED_FUNCTION_LAN;
 			gpios = <&gpio4 RK_PB5 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "netdev";
@@ -78,7 +77,6 @@ led-sys {
 
 		led-wan {
 			color = <LED_COLOR_ID_GREEN>;
-			default-state = "off";
 			function = LED_FUNCTION_WAN;
 			gpios = <&gpio4 RK_PC0 GPIO_ACTIVE_HIGH>;
 			linux,default-trigger = "netdev";
diff --git a/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts b/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts
index 854c118418eb8..f737769d4a007 100644
--- a/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts
@@ -71,7 +71,6 @@ leds-1 {
 
 		led-1 {
 			color = <LED_COLOR_ID_GREEN>;
-			default-state = "off";
 			function = LED_FUNCTION_LAN;
 			linux,default-trigger = "netdev";
 			pwms = <&pwm14 0 1000000 PWM_POLARITY_INVERTED>;
@@ -80,7 +79,6 @@ led-1 {
 
 		led-2 {
 			color = <LED_COLOR_ID_GREEN>;
-			default-state = "off";
 			function = LED_FUNCTION_WAN;
 			linux,default-trigger = "netdev";
 			pwms = <&pwm11 0 1000000 PWM_POLARITY_INVERTED>;
-- 
2.43.0



From naoki at radxa.com  Thu Nov 13 04:42:19 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Thu, 13 Nov 2025 12:42:19 +0000
Subject: [PATCH v3 0/3] Consolidate and clarify LED device tree descriptions on Radxa boards
Message-ID: <20251113124222.4691-1-naoki@radxa.com>

Currently, on Radxa boards, the power LED is turned on immediately
after power-up, independent of software control. The heartbeat LED and
other available LEDs are subsequently turned on by the initial
software, such as U-Boot, to indicate software is running.

However, the device tree description for this behavior is inconsistent
and fragmented, with definitions split between the main Linux DTS
files and separate U-Boot files (u-boot/arch/arm/dts/*-u-boot.dtsi).

This patch series addresses this inconsistency and fragmentation by
consolidating the description within the upstream device tree, thereby
improving overall clarity.

Patch 1 addresses the inconsistency for the power LED by using
default-state = "on" instead of linux,default-trigger = "default-on".

Patch 2 addresses the description fragmentation for the heartbeat LED
by consolidating its default-state = "on" definition from the U-Boot
files into the main Linux DTS.

Patch 3 addresses inconsistency by removing redundant default-state =
"off" definitions, as this is already the default configuration.


This patch series does not address some LEDs that are (implicitly)
default-state = "off" at kernel but should be "on" at bootloader.
These will be addressed separately.

FUKAUMI Naoki (3):
  arm64: dts: rockchip: Use default-state for power LED for Radxa boards
  arm64: dts: rockchip: Turn on heartbeat LED at boot for Radxa boards
  arm64: dts: rockchip: Remove default-state = "off" from LEDs for Radxa
    boards
---
Changes in v3:
- Split into three patches
- Reword commit message
Changes in v2:
- Add more URLs for reference
- Reword commit message
---
 arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts    | 1 -
 arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts    | 1 +
 arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts | 3 ++-
 arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi   | 1 +
 arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts   | 2 --
 arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts      | 1 -
 arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts | 1 +
 arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts      | 1 +
 arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi  | 1 +
 arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts      | 1 +
 arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts      | 3 ++-
 arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts   | 2 --
 arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts   | 2 +-
 arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi     | 1 +
 arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts      | 1 +
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts     | 3 ++-
 16 files changed, 15 insertions(+), 10 deletions(-)

-- 
2.43.0



From amadeus at jmu.edu.cn  Thu Nov 13 05:00:21 2025
From: amadeus at jmu.edu.cn (Chukun Pan)
Date: Thu, 13 Nov 2025 21:00:21 +0800
Subject: [PATCH v5 3/3] arm64: dts: rockchip: Add devicetree for the 9Tripod X3568 v4
In-Reply-To: <6F2972A5-047F-48A5-B409-C3F3E71643AD@gmail.com>
References: <6F2972A5-047F-48A5-B409-C3F3E71643AD@gmail.com>
Message-ID: <20251113130021.822765-1-amadeus@jmu.edu.cn>

Hi,

> PCIe and MIC picked from OEM source codes.

I know it comes from BSP code, but it's not correct.
A PCIe 3.3V power supply will not have a 0.1V situation.
Rockchip fixed this in their kernel a long time ago:
https://github.com/rockchip-linux/kernel/commit/17e9559f67d26f3c602e38a24feb5194e51ac782

> Since parts of the OEM source code are not available in mainline,
> I refer to other boards (e.g. RK3568-EVB or RK3568-ROC-PC), but
> I don't have a camera or screen to test, so I mark them as demo.

These things may have been brought by rk3568-evbxxx.dtsi, and may
not actually exist.


From amadeus at jmu.edu.cn  Thu Nov 13 06:00:20 2025
From: amadeus at jmu.edu.cn (Chukun Pan)
Date: Thu, 13 Nov 2025 22:00:20 +0800
Subject: [PATCH v2 4/4] arm64: dts: rockchip: Make eeprom read-only for Radxa ROCK 3C/5A/5C
In-Reply-To: <20251112035133.28753-5-naoki@radxa.com>
References: <20251112035133.28753-5-naoki@radxa.com>
Message-ID: <20251113140020.919159-1-amadeus@jmu.edu.cn>

Hi,

> Make the BL24C16 EEPROM chips found on Radxa ROCK 3C, 5A and 5C SBCs
> read-only, [1] [2] [3] because they contain factory-programmed data
> that isn't supposed to be modified by the end users. [4]

Is this true? I confirmed that the EEPROM was empty when I submitted
the ROCK 3C support. Based on the Radxa boards I purchased, it seems
that only the "Network Computer" series SBC (E20C, E24C, E52C, E54C)
have production information in their EEPROM.

Thanks,
Chukun


From mkl at pengutronix.de  Thu Nov 13 06:14:56 2025
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Thu, 13 Nov 2025 15:14:56 +0100
Subject: [PATCH v9 3/3] net: can: rockchip: add can for RK3576 Soc
In-Reply-To: <20251113075419.482940-4-zhangqing@rock-chips.com>
References: <20251113075419.482940-1-zhangqing@rock-chips.com>
 <20251113075419.482940-4-zhangqing@rock-chips.com>
Message-ID: <20251113-slim-foamy-gecko-2dc389-mkl@pengutronix.de>

On 13.11.2025 15:54:19, Elaine Zhang wrote:
> Is new controller, new register layout and Bit position definition:

Let's improve the patch description a bit. What about:

The CAN FD cores in the rk3576 SoC are a newer revision than those in
the rk3568. The main differences are:

- changed register layout
- different bit position
- ...

I remember:
- time stamp register removed

Please go through this list and remove everything that was unchanged and
add it to the list I started above.

> Support CAN protocol, ISO 11898-1
> Support transmit or receive error count
> Support acceptance filter, more functional
> Support interrupt and all interrupt can be masked
> Support error code check
> Support self test\silent\loop-back mode
> Support auto retransmission mode
> Support auto bus on after bus-off state
> Support 2 transmit buffers
> Support Internal Storage Mode
>
> Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
> ---
>  .../net/can/rockchip/rockchip_canfd-core.c    | 419 ++++++++++++++++++
>  drivers/net/can/rockchip/rockchip_canfd-rx.c  | 103 +++++
>  drivers/net/can/rockchip/rockchip_canfd-tx.c  |  20 +
>  drivers/net/can/rockchip/rockchip_canfd.h     | 258 +++++++++++
>  4 files changed, 800 insertions(+)
>
> diff --git a/drivers/net/can/rockchip/rockchip_canfd-core.c b/drivers/net/can/rockchip/rockchip_canfd-core.c
> index 761cb36148ff..58fffcf97b20 100644
> --- a/drivers/net/can/rockchip/rockchip_canfd-core.c
> +++ b/drivers/net/can/rockchip/rockchip_canfd-core.c
> @@ -31,6 +31,8 @@ static const char *__rkcanfd_get_model_str(enum rkcanfd_model model)
>  		return "rk3568v2";
>  	case RKCANFD_MODEL_RK3568V3:
>  		return "rk3568v3";
> +	case RKCAN_MODEL_RK3576:
> +		return "rk3576";
>  	}
>
>  	return "<unknown>";
> @@ -176,6 +178,27 @@ static void rkcanfd_get_berr_counter_corrected(struct rkcanfd_priv *priv,
>  		    !!(reg_state & RKCANFD_REG_STATE_ERROR_WARNING_STATE));
>  }
>
> +static void rk3576can_get_berr_counter_corrected(struct rkcanfd_priv *priv,
> +						 struct can_berr_counter *bec)
> +{
> +	struct can_berr_counter bec_raw;

You've removed the workaround handling for the berr_counter. This means
your SoC is not affected by it. So the bec_raw and taking care of
priv->bec is not needed.

> +	u32 reg_state;
> +
> +	bec->rxerr = rkcanfd_read(priv, RK3576CAN_REG_RXERRORCNT);
> +	bec->txerr = rkcanfd_read(priv, RK3576CAN_REG_TXERRORCNT);

> +	bec_raw = *bec;
remove, see above

> +
> +	priv->bec = *bec;

remove, see above

> +
> +	reg_state = rkcanfd_read(priv, RKCANFD_REG_STATE);
> +	netdev_vdbg(priv->ndev,
> +		    "%s: Raw/Cor: txerr=%3u/%3u rxerr=%3u/%3u Bus Off=%u Warning=%u\n",
> +		    __func__,
> +		    bec_raw.txerr, bec->txerr, bec_raw.rxerr, bec->rxerr,
> +		    !!(reg_state & RK3576CAN_REG_STATE_BUS_OFF_STATE),
> +		    !!(reg_state & RK3576CAN_REG_STATE_ERROR_WARNING_STATE));

I think the vdbg can be removed, if the IP core is not affected by the
problem.

> +}
> +
>  static int rkcanfd_get_berr_counter(const struct net_device *ndev,
>  				    struct can_berr_counter *bec)
>  {
> @@ -206,6 +229,11 @@ static void rkcanfd_chip_interrupts_disable(const struct rkcanfd_priv *priv)
>  	rkcanfd_write(priv, RKCANFD_REG_INT_MASK, RKCANFD_REG_INT_ALL);
>  }
>
> +static void rk3576can_chip_interrupts_disable(const struct rkcanfd_priv *priv)
> +{
> +	rkcanfd_write(priv, RK3576CAN_REG_INT_MASK, RK3576CAN_REG_INT_ALL);
> +}
> +
>  static void rkcanfd_chip_fifo_setup(struct rkcanfd_priv *priv)
>  {
>  	u32 reg;
> @@ -220,6 +248,48 @@ static void rkcanfd_chip_fifo_setup(struct rkcanfd_priv *priv)
>  	netdev_reset_queue(priv->ndev);
>  }
>
> +static void rk3576can_chip_fifo_setup(struct rkcanfd_priv *priv)
> +{
> +	u32 reg_ism, reg_water;
> +
> +	reg_ism = FIELD_PREP(RK3576CAN_REG_STR_CTL_ISM_SEL,
> +			     RK3576CAN_REG_STR_CTL_ISM_SEL_CANFD_FIXED) |
> +		  RK3576CAN_REG_STR_CTL_STORAGE_TIMEOUT_MODE;
> +	reg_water = RK3576CAN_ISM_WATERMASK_CANFD;
> +
> +	/* internal sram mode */
> +	rkcanfd_write(priv, RK3576CAN_REG_STR_CTL, reg_ism);
> +	rkcanfd_write(priv, RK3576CAN_REG_STR_WTM, reg_water);
> +	WRITE_ONCE(priv->tx_head, 0);
> +	WRITE_ONCE(priv->tx_tail, 0);
> +	netdev_reset_queue(priv->ndev);
> +}
> +
> +static void rk3576can_atf_config(struct rkcanfd_priv *priv, int mode)
> +{
> +	int i;
> +
> +	switch (mode) {
> +	case RK3576CAN_REG_ATFM_MASK_SEL_MASK_MODE:
> +		for (i = 0; i < 5; i++) {
> +			rkcanfd_write(priv, RK3576CAN_REG_ATF(i), 0);
> +			rkcanfd_write(priv, RK3576CAN_REG_ATFM(i), RK3576CAN_REG_ATFM_ID);
> +		}
> +		break;
> +	case RK3576CAN_REG_ATFM_MASK_SEL_LIST_MODE:
> +		for (i = 0; i < 5; i++) {
> +			rkcanfd_write(priv, RK3576CAN_REG_ATF(i), 0);
> +			rkcanfd_write(priv, RK3576CAN_REG_ATFM(i), RK3576CAN_REG_ATFM_MASK_SEL);
> +		}
> +		break;
> +	default:
> +		rkcanfd_write(priv, RK3576CAN_REG_ATF_CTL, RK3576CAN_REG_ATF_CTL_ATF_DIS_ALL);
> +		return;
> +	}
> +
> +	rkcanfd_write(priv, RK3576CAN_REG_ATF_CTL, 0);
> +}
> +
>  static void rkcanfd_chip_start(struct rkcanfd_priv *priv)
>  {
>  	u32 reg;
> @@ -285,6 +355,61 @@ static void rkcanfd_chip_start(struct rkcanfd_priv *priv)
>  		   rkcanfd_read(priv, RKCANFD_REG_MODE));
>  }
>
> +static void rk3576can_chip_start(struct rkcanfd_priv *priv)
> +
> +{
> +	u32 reg;
> +
> +	rkcanfd_chip_set_reset_mode(priv);
> +
> +	/* Receiving Filter: accept all */
> +	rk3576can_atf_config(priv, RK3576CAN_REG_ATFM_MASK_SEL_MASK_MODE);
> +
> +	/* enable:
> +	 * - WORK_MODE: transition from reset to working mode
> +	 */
> +	reg = rkcanfd_read(priv, RKCANFD_REG_MODE);
> +	priv->reg_mode_default = reg | RKCANFD_REG_MODE_WORK_MODE;
> +
> +	if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
> +		priv->reg_mode_default |= RKCANFD_REG_MODE_LBACK_MODE;
> +		rkcanfd_write(priv, RK3576CAN_REG_ERROR_MASK,
> +			      RK3576CAN_REG_ERROR_MASK_ACK_ERROR);
> +	}
> +
> +	/* mask, i.e. ignore:
> +	 * - RX_FINISH_INT - Rx finish interrupt
> +	 */
> +	priv->reg_int_mask_default = RK3576CAN_REG_INT_RX_FINISH_INT;
> +
> +	/* Do not mask the bus error interrupt if the bus error
> +	 * reporting is requested.
> +	 */
> +	if (!(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING))
> +		priv->reg_int_mask_default |= RKCANFD_REG_INT_ERROR_INT;
> +
> +	memset(&priv->bec, 0x0, sizeof(priv->bec));
> +
> +	rk3576can_chip_fifo_setup(priv);
> +
> +	rkcanfd_write(priv, RK3576CAN_REG_AUTO_RETX_CFG,
> +		      RK3576CAN_REG_AUTO_RETX_CFG_AUTO_RETX_EN);
> +
> +	rkcanfd_write(priv, RK3576CAN_REG_BRS_CFG,
> +		      RK3576CAN_REG_BRS_CFG_BRS_NEGSYNC_EN |
> +		      RK3576CAN_REG_BRS_CFG_BRS_POSSYNC_EN);
> +
> +	rkcanfd_set_bittiming(priv);
> +
> +	priv->devtype_data.interrupts_disable(priv);
> +	rkcanfd_chip_set_work_mode(priv);
> +
> +	priv->can.state = CAN_STATE_ERROR_ACTIVE;
> +
> +	netdev_dbg(priv->ndev, "%s: reg_mode=0x%08x\n", __func__,
> +		   rkcanfd_read(priv, RKCANFD_REG_MODE));
> +}
> +
>  static void __rkcanfd_chip_stop(struct rkcanfd_priv *priv, const enum can_state state)
>  {
>  	priv->can.state = state;
> @@ -301,6 +426,13 @@ static void rkcanfd_chip_stop(struct rkcanfd_priv *priv, const enum can_state st
>  	__rkcanfd_chip_stop(priv, state);
>  }
>
> +static void rk3576can_chip_stop(struct rkcanfd_priv *priv, const enum can_state state)
> +{
> +	priv->can.state = state;
> +
> +	__rkcanfd_chip_stop(priv, state);
> +}
> +
>  static void rkcanfd_chip_stop_sync(struct rkcanfd_priv *priv, const enum can_state state)
>  {
>  	priv->can.state = state;
> @@ -309,6 +441,13 @@ static void rkcanfd_chip_stop_sync(struct rkcanfd_priv *priv, const enum can_sta
>  	__rkcanfd_chip_stop(priv, state);
>  }
>
> +static void rk3576can_chip_stop_sync(struct rkcanfd_priv *priv, const enum can_state state)
> +{
> +	priv->can.state = state;
> +
> +	__rkcanfd_chip_stop(priv, state);
> +}
> +
>  static int rkcanfd_set_mode(struct net_device *ndev,
>  			    enum can_mode mode)
>  {
> @@ -364,6 +503,9 @@ static const char *rkcanfd_get_error_type_str(unsigned int type)
>  #define RKCAN_ERROR_CODE(reg_ec, code) \
>  	((reg_ec) & RKCANFD_REG_ERROR_CODE_##code ? __stringify(code) " " : "")
>
> +#define RK3576CAN_ERROR_CODE(reg_ec, code) \
> +	((reg_ec) & RK3576CAN_REG_ERROR_CODE_##code ? __stringify(code) " " : "")
> +
>  static void
>  rkcanfd_handle_error_int_reg_ec(struct rkcanfd_priv *priv, struct can_frame *cf,
>  				const u32 reg_ec)
> @@ -493,6 +635,128 @@ rkcanfd_handle_error_int_reg_ec(struct rkcanfd_priv *priv, struct can_frame *cf,
>  	}
>  }
>
> +static void
> +rk3576can_handle_error_int_reg_ec(struct rkcanfd_priv *priv, struct can_frame *cf,
> +				  const u32 reg_ec)
> +{
> +	struct net_device_stats *stats = &priv->ndev->stats;
> +	unsigned int type;
> +	u32 reg_state, reg_cmd;
> +
> +	type = FIELD_GET(RK3576CAN_REG_ERROR_CODE_TYPE, reg_ec);
> +	reg_cmd = rkcanfd_read(priv, RK3576CAN_REG_CMD);
> +	reg_state = rkcanfd_read(priv, RK3576CAN_REG_STATE);
> +
> +	netdev_dbg(priv->ndev, "%s Error in %s %s Phase: %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s(0x%08x) CMD=%u RX=%u TX=%u Error-Warning=%u Bus-Off=%u\n",
> +		   rkcanfd_get_error_type_str(type),
> +		   reg_ec & RK3576CAN_REG_ERROR_CODE_DIRECTION_RX ? "RX" : "TX",
> +		   reg_ec & RK3576CAN_REG_ERROR_CODE_PHASE ? "Data" : "Arbitration",
> +		   RK3576CAN_ERROR_CODE(reg_ec, TX_ACK_EOF),
> +		   RK3576CAN_ERROR_CODE(reg_ec, TX_CRC),
> +		   RK3576CAN_ERROR_CODE(reg_ec, TX_STUFF_COUNT),
> +		   RK3576CAN_ERROR_CODE(reg_ec, TX_DATA),
> +		   RK3576CAN_ERROR_CODE(reg_ec, TX_SOF_DLC),
> +		   RK3576CAN_ERROR_CODE(reg_ec, TX_IDLE),
> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_ERROR),
> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_OVERLOAD),
> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_SPACE),
> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_EOF),
> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_ACK_LIM),
> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_ACK),
> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_CRC_LIM),
> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_CRC),
> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_STUFF_COUNT),
> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_DATA),
> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_DLC),
> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_BRS_ESI),
> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_RES),
> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_FDF),
> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_ID2_RTR),
> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_SOF_IDE),
> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_BUS_IDLE),
> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_BUS_INT),
> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_STOP),
> +		   reg_ec, reg_cmd,
> +		   !!(reg_state & RK3576CAN_REG_STATE_RX_PERIOD),
> +		   !!(reg_state & RK3576CAN_REG_STATE_TX_PERIOD),
> +		   !!(reg_state & RK3576CAN_REG_STATE_ERROR_WARNING_STATE),
> +		   !!(reg_state & RK3576CAN_REG_STATE_BUS_OFF_STATE));
> +
> +	priv->can.can_stats.bus_error++;
> +
> +	if (reg_ec & RK3576CAN_REG_ERROR_CODE_DIRECTION_RX)
> +		stats->rx_errors++;
> +	else
> +		stats->tx_errors++;
> +
> +	if (!cf)
> +		return;
> +
> +	if (reg_ec & RK3576CAN_REG_ERROR_CODE_DIRECTION_RX) {
> +		if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_SOF_IDE)
> +			cf->data[3] = CAN_ERR_PROT_LOC_SOF;
> +		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_ID2_RTR)
> +			cf->data[3] = CAN_ERR_PROT_LOC_RTR;
> +		/* RKCANFD_REG_ERROR_CODE_RX_FDF */
> +		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_RES)
> +			cf->data[3] = CAN_ERR_PROT_LOC_RES0;
> +		/* RKCANFD_REG_ERROR_CODE_RX_BRS_ESI */
> +		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_DLC)
> +			cf->data[3] = CAN_ERR_PROT_LOC_DLC;
> +		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_DATA)
> +			cf->data[3] = CAN_ERR_PROT_LOC_DATA;
> +		/* RKCANFD_REG_ERROR_CODE_RX_STUFF_COUNT */
> +		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_CRC)
> +			cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
> +		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_CRC_LIM)
> +			cf->data[3] = CAN_ERR_PROT_LOC_ACK_DEL;
> +		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_ACK)
> +			cf->data[3] = CAN_ERR_PROT_LOC_ACK;
> +		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_ACK_LIM)
> +			cf->data[3] = CAN_ERR_PROT_LOC_ACK_DEL;
> +		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_EOF)
> +			cf->data[3] = CAN_ERR_PROT_LOC_EOF;
> +		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_SPACE)
> +			cf->data[3] = CAN_ERR_PROT_LOC_EOF;
> +	} else {
> +		cf->data[2] |= CAN_ERR_PROT_TX;
> +
> +		if (reg_ec & RK3576CAN_REG_ERROR_CODE_TX_SOF_DLC)
> +			cf->data[3] = CAN_ERR_PROT_LOC_SOF;
> +		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_TX_DATA)
> +			cf->data[3] = CAN_ERR_PROT_LOC_DATA;
> +		/* RKCANFD_REG_ERROR_CODE_TX_STUFF_COUNT */
> +		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_TX_CRC)
> +			cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
> +		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_TX_ACK_EOF)
> +			cf->data[3] = CAN_ERR_PROT_LOC_ACK_DEL;
> +	}
> +
> +	switch (reg_ec & RK3576CAN_REG_ERROR_CODE_TYPE) {
> +	case FIELD_PREP_CONST(RK3576CAN_REG_ERROR_CODE_TYPE,
> +			      RK3576CAN_REG_ERROR_CODE_TYPE_BIT):
> +
> +		cf->data[2] |= CAN_ERR_PROT_BIT;
> +		break;
> +	case FIELD_PREP_CONST(RK3576CAN_REG_ERROR_CODE_TYPE,
> +			      RK3576CAN_REG_ERROR_CODE_TYPE_STUFF):
> +		cf->data[2] |= CAN_ERR_PROT_STUFF;
> +		break;
> +	case FIELD_PREP_CONST(RK3576CAN_REG_ERROR_CODE_TYPE,
> +			      RK3576CAN_REG_ERROR_CODE_TYPE_FORM):
> +		cf->data[2] |= CAN_ERR_PROT_FORM;
> +		break;
> +	case FIELD_PREP_CONST(RK3576CAN_REG_ERROR_CODE_TYPE,
> +			      RK3576CAN_REG_ERROR_CODE_TYPE_ACK):
> +		cf->can_id |= CAN_ERR_ACK;
> +		break;
> +	case FIELD_PREP_CONST(RK3576CAN_REG_ERROR_CODE_TYPE,
> +			      RK3576CAN_REG_ERROR_CODE_TYPE_CRC):
> +		cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
> +		break;
> +	}
> +}
> +
>  static int rkcanfd_handle_error_int(struct rkcanfd_priv *priv)
>  {
>  	struct net_device_stats *stats = &priv->ndev->stats;
> @@ -530,6 +794,41 @@ static int rkcanfd_handle_error_int(struct rkcanfd_priv *priv)
>  	return 0;
>  }
>
> +static int rkcanfd_handle_rk3576_error_int(struct rkcanfd_priv *priv)
> +{
> +	struct net_device_stats *stats = &priv->ndev->stats;
> +	struct can_frame *cf = NULL;
> +	u32 reg_ec;
> +	struct sk_buff *skb;
> +	int err;
> +
> +	reg_ec = rkcanfd_read(priv, RK3576CAN_REG_ERROR_CODE);
> +	if (!reg_ec)
> +		return 0;
> +
> +	if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) {
> +		skb = alloc_can_err_skb(priv->ndev, &cf);
> +		if (cf) {
> +			struct can_berr_counter bec;
> +
> +			priv->devtype_data.get_berr_counter(priv, &bec);
> +			cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR | CAN_ERR_CNT;
> +			cf->data[6] = bec.txerr;
> +			cf->data[7] = bec.rxerr;
> +		}
> +	}
> +
> +	rk3576can_handle_error_int_reg_ec(priv, cf, reg_ec);
> +	if (!cf)
> +		return 0;
> +
> +	err = can_rx_offload_queue_tail(&priv->offload, skb);
> +	if (err)
> +		stats->rx_fifo_errors++;
> +
> +	return 0;
> +}
> +
>  static int rkcanfd_handle_state_error_int(struct rkcanfd_priv *priv)
>  {
>  	struct net_device_stats *stats = &priv->ndev->stats;
> @@ -575,6 +874,50 @@ static int rkcanfd_handle_state_error_int(struct rkcanfd_priv *priv)
>  	return 0;
>  }
>
> +static int rkcanfd_handle_rk3576_state_error_int(struct rkcanfd_priv *priv)
> +{
> +	struct net_device_stats *stats = &priv->ndev->stats;
> +	enum can_state new_state, rx_state, tx_state;
> +	struct net_device *ndev = priv->ndev;
> +	struct can_berr_counter bec;
> +	struct can_frame *cf = NULL;
> +	struct sk_buff *skb;
> +	int err;
> +
> +	priv->devtype_data.get_berr_counter(priv, &bec);

You're already in the rk3576 specific code.

> +	can_state_get_by_berr_counter(ndev, &bec, &tx_state, &rx_state);
> +
> +	new_state = max(tx_state, rx_state);
> +	if (new_state == priv->can.state)
> +		return 0;
> +
> +	/* The skb allocation might fail, but can_change_state()
> +	 * handles cf == NULL.
> +	 */
> +	skb = alloc_can_err_skb(priv->ndev, &cf);
> +	can_change_state(ndev, cf, tx_state, rx_state);
> +
> +	if (new_state == CAN_STATE_BUS_OFF) {
> +		priv->devtype_data.chip_stop(priv, CAN_STATE_BUS_OFF);
> +		can_bus_off(ndev);
> +	}
> +
> +	if (!skb)
> +		return 0;
> +
> +	if (new_state != CAN_STATE_BUS_OFF) {
> +		cf->can_id |= CAN_ERR_CNT;
> +		cf->data[6] = bec.txerr;
> +		cf->data[7] = bec.rxerr;
> +	}
> +
> +	err = can_rx_offload_queue_tail(&priv->offload, skb);
> +	if (err)
> +		stats->rx_fifo_errors++;
> +
> +	return 0;
> +}
> +
>  static int
>  rkcanfd_handle_rx_fifo_overflow_int(struct rkcanfd_priv *priv)
>  {
> @@ -621,6 +964,55 @@ rkcanfd_handle_rx_fifo_overflow_int(struct rkcanfd_priv *priv)
>  	err; \
>  })
>
> +static irqreturn_t rk3576can_irq(int irq, void *dev_id)
> +{
> +	struct rkcanfd_priv *priv = dev_id;
> +	u32 reg_int_unmasked, reg_int;
> +
> +	reg_int_unmasked = rkcanfd_read(priv, RK3576CAN_REG_INT);
> +	reg_int = reg_int_unmasked & ~priv->reg_int_mask_default;
> +
> +	if (!reg_int)
> +		return IRQ_NONE;
> +
> +	rkcanfd_write(priv, RK3576CAN_REG_INT, reg_int);
> +
> +	if (reg_int & (RK3576CAN_REG_INT_RXSTR_TIMEOUT_INT |
> +		       RK3576CAN_REG_INT_ISM_WTM_INT |
> +		       RK3576CAN_REG_INT_RX_FIFO_FULL_INT)) {
> +		rkcanfd_write(priv, RK3576CAN_REG_INT_MASK,
> +			      priv->reg_int_mask_default | RK3576CAN_REG_INT_ISM_WTM_INT |
> +			      RK3576CAN_REG_INT_RXSTR_TIMEOUT_INT |
> +			      RK3576CAN_REG_INT_RX_FINISH_INT);
> +		rkcanfd_handle(priv, rk3576_rx_int);
> +	}
> +
> +	if (reg_int & RK3576CAN_REG_INT_TX_FINISH_INT)
> +		rkcanfd_handle(priv, rk3576_tx_int);
> +
> +	if (reg_int & RK3576CAN_REG_INT_ERROR_INT)
> +		rkcanfd_handle(priv, rk3576_error_int);
> +
> +	if (reg_int & (RK3576CAN_REG_INT_BUS_OFF_INT |
> +		       RK3576CAN_REG_INT_PASSIVE_ERROR_INT |
> +		       RK3576CAN_REG_INT_ERROR_WARNING_INT) ||
> +	    priv->can.state > CAN_STATE_ERROR_ACTIVE)
> +		rkcanfd_handle(priv, rk3576_state_error_int);
> +
> +	if (reg_int & RK3576CAN_REG_INT_WAKEUP_INT)
> +		netdev_info(priv->ndev, "%s: WAKEUP_INT\n", __func__);
> +
> +	if (reg_int & RK3576CAN_REG_INT_BUS_OFF_RECOVERY_INT)
> +		netdev_info(priv->ndev, "%s: BUS_OFF_RECOVERY_INT\n", __func__);
> +
> +	if (reg_int & RK3576CAN_REG_INT_OVERLOAD_INT)
> +		netdev_info(priv->ndev, "%s: OVERLOAD_INT\n", __func__);
> +
> +	can_rx_offload_irq_finish(&priv->offload);
> +
> +	return IRQ_HANDLED;
> +}
> +
>  static irqreturn_t rkcanfd_irq(int irq, void *dev_id)
>  {
>  	struct rkcanfd_priv *priv = dev_id;
> @@ -775,6 +1167,16 @@ static void rkcanfd_register_done(const struct rkcanfd_priv *priv)
>  			    RKCANFD_ERRATUM_5_SYSCLOCK_HZ_MIN / MEGA);
>  }
>
> +static void rk3576can_register_done(const struct rkcanfd_priv *priv)
> +{
> +	u32 dev_id;
> +
> +	dev_id = rkcanfd_read(priv, RK3576CAN_REG_RTL_VERSION);
> +	netdev_info(priv->ndev,
> +		    "Rockchip-CANFD %s rev%u.\n",
> +		    rkcanfd_get_model_str(priv), dev_id);

Please also print the activated errata.

> +}
> +
>  static int rkcanfd_register(struct rkcanfd_priv *priv)
>  {
>  	struct net_device *ndev = priv->ndev;
> @@ -856,6 +1258,20 @@ static const struct rkcanfd_devtype_data rkcanfd_devtype_data_rk3568v3 = {
>  	.register_done = rkcanfd_register_done,
>  };
>
> +/* The rk3576 CAN-FD */
> +static const struct rkcanfd_devtype_data rkcan_devtype_data_rk3576 = {
> +	.model = RKCAN_MODEL_RK3576,
> +	.quirks = RKCANFD_QUIRK_CANFD_BROKEN,

Is CAN-FD mode broken on the rk3576?

Please test CAN-FD and please do the tests documented near the
definition of RKCANFD_QUIRK_CANFD_BROKEN:

| Tests on the rk3568v2 and rk3568v3 show that receiving certain
| CAN-FD frames trigger an Error Interrupt.
|
| - Form Error in RX Arbitration Phase: TX_IDLE RX_STUFF_COUNT (0x0a010100) CMD=0 RX=0 TX=0
|   Error-Warning=1 Bus-Off=0
|   To reproduce:
|   host:
|     cansend can0 002##01f
|   DUT:
|     candump any,0:0,#FFFFFFFF -cexdHtA
|
| - Form Error in RX Arbitration Phase: TX_IDLE RX_CRC (0x0a010200) CMD=0 RX=0 TX=0
|   Error-Warning=1 Bus-Off=0
|   To reproduce:
|   host:
|     cansend can0 002##07217010000000000
|   DUT:
|     candump any,0:0,#FFFFFFFF -cexdHtA

regards,
Marc

--
Pengutronix e.K.                 | Marc Kleine-Budde          |
Embedded Linux                   | https://www.pengutronix.de |
Vertretung N?rnberg              | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-9   |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251113/da975929/attachment-0001.sig>

From bvanassche at acm.org  Thu Nov 13 08:28:57 2025
From: bvanassche at acm.org (Bart Van Assche)
Date: Thu, 13 Nov 2025 08:28:57 -0800
Subject: [PATCH] scsi: ufs: rockchip: Fix compile error without
 CONFIG_GPIOLIB
In-Reply-To: <1763011091-243727-1-git-send-email-shawn.lin@rock-chips.com>
References: <1763011091-243727-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <faf2e938-5bb2-448b-8e34-a8422611f54f@acm.org>

On 11/12/25 9:18 PM, Shawn Lin wrote:
> drivers/ufs/host/ufs-rockchip.c:168:19: error: implicit declaration of function
> 'devm_gpiod_get'; did you mean 'em_pd_get'? [-Werror=implicit-function-declaration]
Reviewed-by: Bart Van Assche <bvanassche at acm.org>



From linux at armlinux.org.uk  Thu Nov 13 09:46:16 2025
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 13 Nov 2025 17:46:16 +0000
Subject: [PATCH net-next 0/4] net: stmmac: rk: use PHY_INTF_SEL_x
Message-ID: <aRYZaKTIvfYoV3wE@shell.armlinux.org.uk>

This series is a minimal conversion of the dwmac-rk huge driver to use
PHY_INTF_SEL_x constants.

Patch 2 appears to reorder the output functions making diffing the
generated code impossible.

 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 245 +++++++++++--------------
 1 file changed, 109 insertions(+), 136 deletions(-)
-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!


From rmk+kernel at armlinux.org.uk  Thu Nov 13 09:46:35 2025
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 13 Nov 2025 17:46:35 +0000
Subject: [PATCH net-next 1/4] net: stmmac: rk: replace HIWORD_UPDATE() with
 GRF_FIELD()
In-Reply-To: <aRYZaKTIvfYoV3wE@shell.armlinux.org.uk>
References: <aRYZaKTIvfYoV3wE@shell.armlinux.org.uk>
Message-ID: <E1vJbP1-0000000EBqJ-1AjR@rmk-PC.armlinux.org.uk>

Provide GRF_FIELD() which takes the high/low bit numbers of the field
and field value, generates the mask and passes it to FIELD_PREP_WM16.
Replace all HIWORD_UPDATE() instances with this.

No change to produced code on aarch64.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 .../net/ethernet/stmicro/stmmac/dwmac-rk.c    | 64 +++++++++----------
 1 file changed, 32 insertions(+), 32 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index a5c7e03ebc63..794a7ed71451 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -149,11 +149,11 @@ static int rk_set_clk_mac_speed(struct rk_priv_data *bsp_priv,
 	return clk_set_rate(clk_mac_speed, rate);
 }
 
-#define HIWORD_UPDATE(val, mask, shift) \
-		(FIELD_PREP_WM16((mask) << (shift), (val)))
+#define GRF_FIELD(hi, lo, val)		\
+	FIELD_PREP_WM16(GENMASK_U16(hi, lo), val)
 
-#define GRF_BIT(nr)	(BIT(nr) | BIT(nr+16))
-#define GRF_CLR_BIT(nr)	(BIT(nr+16))
+#define GRF_BIT(nr)			(BIT(nr) | BIT(nr+16))
+#define GRF_CLR_BIT(nr)			(BIT(nr+16))
 
 #define DELAY_ENABLE(soc, tx, rx) \
 	(((tx) ? soc##_GMAC_TXCLK_DLY_ENABLE : soc##_GMAC_TXCLK_DLY_DISABLE) | \
@@ -168,8 +168,8 @@ static int rk_set_clk_mac_speed(struct rk_priv_data *bsp_priv,
 #define RK_MACPHY_DISABLE		GRF_CLR_BIT(0)
 #define RK_MACPHY_CFG_CLK_50M		GRF_BIT(14)
 #define RK_GMAC2PHY_RMII_MODE		(GRF_BIT(6) | GRF_CLR_BIT(7))
-#define RK_GRF_CON2_MACPHY_ID		HIWORD_UPDATE(0x1234, 0xffff, 0)
-#define RK_GRF_CON3_MACPHY_ID		HIWORD_UPDATE(0x35, 0x3f, 0)
+#define RK_GRF_CON2_MACPHY_ID		GRF_FIELD(15, 0, 0x1234)
+#define RK_GRF_CON3_MACPHY_ID		GRF_FIELD(5, 0, 0x35)
 
 static void rk_gmac_integrated_ephy_powerup(struct rk_priv_data *priv)
 {
@@ -285,8 +285,8 @@ static const struct rk_gmac_ops px30_ops = {
 #define RK3128_GMAC_TXCLK_DLY_DISABLE  GRF_CLR_BIT(14)
 #define RK3128_GMAC_RXCLK_DLY_ENABLE   GRF_BIT(15)
 #define RK3128_GMAC_RXCLK_DLY_DISABLE  GRF_CLR_BIT(15)
-#define RK3128_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7)
-#define RK3128_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
+#define RK3128_GMAC_CLK_RX_DL_CFG(val) GRF_FIELD(13, 7, val)
+#define RK3128_GMAC_CLK_TX_DL_CFG(val) GRF_FIELD(6, 0, val)
 
 /* RK3128_GRF_MAC_CON1 */
 #define RK3128_GMAC_PHY_INTF_SEL_RGMII	\
@@ -350,8 +350,8 @@ static const struct rk_gmac_ops rk3128_ops = {
 #define RK3228_GRF_CON_MUX	0x50
 
 /* RK3228_GRF_MAC_CON0 */
-#define RK3228_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 7)
-#define RK3228_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
+#define RK3228_GMAC_CLK_RX_DL_CFG(val)	GRF_FIELD(13, 7, val)
+#define RK3228_GMAC_CLK_TX_DL_CFG(val)	GRF_FIELD(6, 0, val)
 
 /* RK3228_GRF_MAC_CON1 */
 #define RK3228_GMAC_PHY_INTF_SEL_RGMII	\
@@ -456,8 +456,8 @@ static const struct rk_gmac_ops rk3228_ops = {
 #define RK3288_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(14)
 #define RK3288_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
 #define RK3288_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
-#define RK3288_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 7)
-#define RK3288_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
+#define RK3288_GMAC_CLK_RX_DL_CFG(val)	GRF_FIELD(13, 7, val)
+#define RK3288_GMAC_CLK_TX_DL_CFG(val)	GRF_FIELD(6, 0, val)
 
 static void rk3288_set_to_rgmii(struct rk_priv_data *bsp_priv,
 				int tx_delay, int rx_delay)
@@ -537,8 +537,8 @@ static const struct rk_gmac_ops rk3308_ops = {
 #define RK3328_GRF_MACPHY_CON1	0xb04
 
 /* RK3328_GRF_MAC_CON0 */
-#define RK3328_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 7)
-#define RK3328_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
+#define RK3328_GMAC_CLK_RX_DL_CFG(val)	GRF_FIELD(13, 7, val)
+#define RK3328_GMAC_CLK_TX_DL_CFG(val)	GRF_FIELD(6, 0, val)
 
 /* RK3328_GRF_MAC_CON1 */
 #define RK3328_GMAC_PHY_INTF_SEL_RGMII	\
@@ -651,8 +651,8 @@ static const struct rk_gmac_ops rk3328_ops = {
 #define RK3366_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(7)
 #define RK3366_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
 #define RK3366_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
-#define RK3366_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
-#define RK3366_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
+#define RK3366_GMAC_CLK_RX_DL_CFG(val)	GRF_FIELD(14, 8, val)
+#define RK3366_GMAC_CLK_TX_DL_CFG(val)	GRF_FIELD(6, 0, val)
 
 static void rk3366_set_to_rgmii(struct rk_priv_data *bsp_priv,
 				int tx_delay, int rx_delay)
@@ -718,8 +718,8 @@ static const struct rk_gmac_ops rk3366_ops = {
 #define RK3368_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(7)
 #define RK3368_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
 #define RK3368_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
-#define RK3368_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
-#define RK3368_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
+#define RK3368_GMAC_CLK_RX_DL_CFG(val)	GRF_FIELD(14, 8, val)
+#define RK3368_GMAC_CLK_TX_DL_CFG(val)	GRF_FIELD(6, 0, val)
 
 static void rk3368_set_to_rgmii(struct rk_priv_data *bsp_priv,
 				int tx_delay, int rx_delay)
@@ -785,8 +785,8 @@ static const struct rk_gmac_ops rk3368_ops = {
 #define RK3399_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(7)
 #define RK3399_GMAC_RXCLK_DLY_ENABLE	GRF_BIT(15)
 #define RK3399_GMAC_RXCLK_DLY_DISABLE	GRF_CLR_BIT(15)
-#define RK3399_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
-#define RK3399_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
+#define RK3399_GMAC_CLK_RX_DL_CFG(val)	GRF_FIELD(14, 8, val)
+#define RK3399_GMAC_CLK_TX_DL_CFG(val)	GRF_FIELD(6, 0, val)
 
 static void rk3399_set_to_rgmii(struct rk_priv_data *bsp_priv,
 				int tx_delay, int rx_delay)
@@ -901,8 +901,8 @@ static const struct rk_gmac_ops rk3506_ops = {
 #define RK3528_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(14)
 #define RK3528_GMAC_TXCLK_DLY_DISABLE	GRF_CLR_BIT(14)
 
-#define RK3528_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0xFF, 8)
-#define RK3528_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0xFF, 0)
+#define RK3528_GMAC_CLK_RX_DL_CFG(val)	GRF_FIELD(15, 8, val)
+#define RK3528_GMAC_CLK_TX_DL_CFG(val)	GRF_FIELD(7, 0, val)
 
 #define RK3528_GMAC0_PHY_INTF_SEL_RMII	GRF_BIT(1)
 #define RK3528_GMAC1_PHY_INTF_SEL_RGMII	GRF_CLR_BIT(8)
@@ -1041,8 +1041,8 @@ static const struct rk_gmac_ops rk3528_ops = {
 #define RK3568_GMAC_TXCLK_DLY_DISABLE		GRF_CLR_BIT(0)
 
 /* RK3568_GRF_GMAC0_CON0 && RK3568_GRF_GMAC1_CON0 */
-#define RK3568_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
-#define RK3568_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
+#define RK3568_GMAC_CLK_RX_DL_CFG(val)	GRF_FIELD(14, 8, val)
+#define RK3568_GMAC_CLK_TX_DL_CFG(val)	GRF_FIELD(6, 0, val)
 
 static void rk3568_set_to_rgmii(struct rk_priv_data *bsp_priv,
 				int tx_delay, int rx_delay)
@@ -1096,8 +1096,8 @@ static const struct rk_gmac_ops rk3568_ops = {
 #define RK3576_GMAC_TXCLK_DLY_ENABLE		GRF_BIT(7)
 #define RK3576_GMAC_TXCLK_DLY_DISABLE		GRF_CLR_BIT(7)
 
-#define RK3576_GMAC_CLK_RX_DL_CFG(val)		HIWORD_UPDATE(val, 0x7F, 8)
-#define RK3576_GMAC_CLK_TX_DL_CFG(val)		HIWORD_UPDATE(val, 0x7F, 0)
+#define RK3576_GMAC_CLK_RX_DL_CFG(val)		GRF_FIELD(14, 8, val)
+#define RK3576_GMAC_CLK_TX_DL_CFG(val)		GRF_FIELD(6, 0, val)
 
 /* SDGMAC_GRF */
 #define RK3576_GRF_GMAC_CON0			0X0020
@@ -1220,8 +1220,8 @@ static const struct rk_gmac_ops rk3576_ops = {
 #define RK3588_GMAC_TXCLK_DLY_ENABLE(id)	GRF_BIT(2 * (id) + 2)
 #define RK3588_GMAC_TXCLK_DLY_DISABLE(id)	GRF_CLR_BIT(2 * (id) + 2)
 
-#define RK3588_GMAC_CLK_RX_DL_CFG(val)		HIWORD_UPDATE(val, 0xFF, 8)
-#define RK3588_GMAC_CLK_TX_DL_CFG(val)		HIWORD_UPDATE(val, 0xFF, 0)
+#define RK3588_GMAC_CLK_RX_DL_CFG(val)		GRF_FIELD(15, 8, val)
+#define RK3588_GMAC_CLK_TX_DL_CFG(val)		GRF_FIELD(7, 0, val)
 
 /* php_grf */
 #define RK3588_GRF_GMAC_CON0			0X0008
@@ -1400,11 +1400,11 @@ static const struct rk_gmac_ops rv1108_ops = {
 #define RV1126_GMAC_M1_TXCLK_DLY_DISABLE	GRF_CLR_BIT(2)
 
 /* RV1126_GRF_GMAC_CON1 */
-#define RV1126_GMAC_M0_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
-#define RV1126_GMAC_M0_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
+#define RV1126_GMAC_M0_CLK_RX_DL_CFG(val)	GRF_FIELD(14, 8, val)
+#define RV1126_GMAC_M0_CLK_TX_DL_CFG(val)	GRF_FIELD(6, 0, val)
 /* RV1126_GRF_GMAC_CON2 */
-#define RV1126_GMAC_M1_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
-#define RV1126_GMAC_M1_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
+#define RV1126_GMAC_M1_CLK_RX_DL_CFG(val)	GRF_FIELD(14, 8, val)
+#define RV1126_GMAC_M1_CLK_TX_DL_CFG(val)	GRF_FIELD(6, 0, val)
 
 static void rv1126_set_to_rgmii(struct rk_priv_data *bsp_priv,
 				int tx_delay, int rx_delay)
-- 
2.47.3



From rmk+kernel at armlinux.org.uk  Thu Nov 13 09:46:40 2025
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 13 Nov 2025 17:46:40 +0000
Subject: [PATCH net-next 2/4] net: stmmac: rk: convert all bitfields to
 GRF_FIELD*()
In-Reply-To: <aRYZaKTIvfYoV3wE@shell.armlinux.org.uk>
References: <aRYZaKTIvfYoV3wE@shell.armlinux.org.uk>
Message-ID: <E1vJbP6-0000000EBqP-1cmm@rmk-PC.armlinux.org.uk>

Convert all bitfields to GRF_FIELD() or GRF_FIELD_CONST(), which makes
the bitfield values more readable, and also allows the aarch64 compiler
to produce better code.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 .../net/ethernet/stmicro/stmmac/dwmac-rk.c    | 136 ++++++++----------
 1 file changed, 57 insertions(+), 79 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 794a7ed71451..4257cc1f66e9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -151,6 +151,8 @@ static int rk_set_clk_mac_speed(struct rk_priv_data *bsp_priv,
 
 #define GRF_FIELD(hi, lo, val)		\
 	FIELD_PREP_WM16(GENMASK_U16(hi, lo), val)
+#define GRF_FIELD_CONST(hi, lo, val)	\
+	FIELD_PREP_WM16_CONST(GENMASK_U16(hi, lo), val)
 
 #define GRF_BIT(nr)			(BIT(nr) | BIT(nr+16))
 #define GRF_CLR_BIT(nr)			(BIT(nr+16))
@@ -167,7 +169,7 @@ static int rk_set_clk_mac_speed(struct rk_priv_data *bsp_priv,
 #define RK_MACPHY_ENABLE		GRF_BIT(0)
 #define RK_MACPHY_DISABLE		GRF_CLR_BIT(0)
 #define RK_MACPHY_CFG_CLK_50M		GRF_BIT(14)
-#define RK_GMAC2PHY_RMII_MODE		(GRF_BIT(6) | GRF_CLR_BIT(7))
+#define RK_GMAC2PHY_RMII_MODE		GRF_FIELD(7, 6, 1)
 #define RK_GRF_CON2_MACPHY_ID		GRF_FIELD(15, 0, 0x1234)
 #define RK_GRF_CON3_MACPHY_ID		GRF_FIELD(5, 0, 0x35)
 
@@ -203,7 +205,7 @@ static void rk_gmac_integrated_ephy_powerdown(struct rk_priv_data *priv)
 #define RK_FEPHY_SHUTDOWN		GRF_BIT(1)
 #define RK_FEPHY_POWERUP		GRF_CLR_BIT(1)
 #define RK_FEPHY_INTERNAL_RMII_SEL	GRF_BIT(6)
-#define RK_FEPHY_24M_CLK_SEL		(GRF_BIT(8) | GRF_BIT(9))
+#define RK_FEPHY_24M_CLK_SEL		GRF_FIELD(9, 8, 3)
 #define RK_FEPHY_PHY_ID			GRF_BIT(11)
 
 static void rk_gmac_integrated_fephy_powerup(struct rk_priv_data *priv,
@@ -232,8 +234,7 @@ static void rk_gmac_integrated_fephy_powerdown(struct rk_priv_data *priv,
 #define PX30_GRF_GMAC_CON1		0x0904
 
 /* PX30_GRF_GMAC_CON1 */
-#define PX30_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \
-					 GRF_BIT(6))
+#define PX30_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, 4)
 #define PX30_GMAC_SPEED_10M		GRF_CLR_BIT(2)
 #define PX30_GMAC_SPEED_100M		GRF_BIT(2)
 
@@ -289,19 +290,17 @@ static const struct rk_gmac_ops px30_ops = {
 #define RK3128_GMAC_CLK_TX_DL_CFG(val) GRF_FIELD(6, 0, val)
 
 /* RK3128_GRF_MAC_CON1 */
-#define RK3128_GMAC_PHY_INTF_SEL_RGMII	\
-		(GRF_BIT(6) | GRF_CLR_BIT(7) | GRF_CLR_BIT(8))
-#define RK3128_GMAC_PHY_INTF_SEL_RMII	\
-		(GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | GRF_BIT(8))
+#define RK3128_GMAC_PHY_INTF_SEL_RGMII GRF_FIELD(8, 6, 1)
+#define RK3128_GMAC_PHY_INTF_SEL_RMII  GRF_FIELD(8, 6, 4)
 #define RK3128_GMAC_FLOW_CTRL          GRF_BIT(9)
 #define RK3128_GMAC_FLOW_CTRL_CLR      GRF_CLR_BIT(9)
 #define RK3128_GMAC_SPEED_10M          GRF_CLR_BIT(10)
 #define RK3128_GMAC_SPEED_100M         GRF_BIT(10)
 #define RK3128_GMAC_RMII_CLK_25M       GRF_BIT(11)
 #define RK3128_GMAC_RMII_CLK_2_5M      GRF_CLR_BIT(11)
-#define RK3128_GMAC_CLK_125M           (GRF_CLR_BIT(12) | GRF_CLR_BIT(13))
-#define RK3128_GMAC_CLK_25M            (GRF_BIT(12) | GRF_BIT(13))
-#define RK3128_GMAC_CLK_2_5M           (GRF_CLR_BIT(12) | GRF_BIT(13))
+#define RK3128_GMAC_CLK_125M           GRF_FIELD_CONST(13, 12, 0)
+#define RK3128_GMAC_CLK_25M            GRF_FIELD_CONST(13, 12, 3)
+#define RK3128_GMAC_CLK_2_5M           GRF_FIELD_CONST(13, 12, 2)
 #define RK3128_GMAC_RMII_MODE          GRF_BIT(14)
 #define RK3128_GMAC_RMII_MODE_CLR      GRF_CLR_BIT(14)
 
@@ -354,19 +353,17 @@ static const struct rk_gmac_ops rk3128_ops = {
 #define RK3228_GMAC_CLK_TX_DL_CFG(val)	GRF_FIELD(6, 0, val)
 
 /* RK3228_GRF_MAC_CON1 */
-#define RK3228_GMAC_PHY_INTF_SEL_RGMII	\
-		(GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
-#define RK3228_GMAC_PHY_INTF_SEL_RMII	\
-		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
+#define RK3228_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(6, 4, 1)
+#define RK3228_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, 4)
 #define RK3228_GMAC_FLOW_CTRL		GRF_BIT(3)
 #define RK3228_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
 #define RK3228_GMAC_SPEED_10M		GRF_CLR_BIT(2)
 #define RK3228_GMAC_SPEED_100M		GRF_BIT(2)
 #define RK3228_GMAC_RMII_CLK_25M	GRF_BIT(7)
 #define RK3228_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(7)
-#define RK3228_GMAC_CLK_125M		(GRF_CLR_BIT(8) | GRF_CLR_BIT(9))
-#define RK3228_GMAC_CLK_25M		(GRF_BIT(8) | GRF_BIT(9))
-#define RK3228_GMAC_CLK_2_5M		(GRF_CLR_BIT(8) | GRF_BIT(9))
+#define RK3228_GMAC_CLK_125M		GRF_FIELD_CONST(9, 8, 0)
+#define RK3228_GMAC_CLK_25M		GRF_FIELD_CONST(9, 8, 3)
+#define RK3228_GMAC_CLK_2_5M		GRF_FIELD_CONST(9, 8, 2)
 #define RK3228_GMAC_RMII_MODE		GRF_BIT(10)
 #define RK3228_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(10)
 #define RK3228_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(0)
@@ -435,19 +432,17 @@ static const struct rk_gmac_ops rk3228_ops = {
 #define RK3288_GRF_SOC_CON3	0x0250
 
 /*RK3288_GRF_SOC_CON1*/
-#define RK3288_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(6) | GRF_CLR_BIT(7) | \
-					 GRF_CLR_BIT(8))
-#define RK3288_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | \
-					 GRF_BIT(8))
+#define RK3288_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(8, 6, 1)
+#define RK3288_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(8, 6, 4)
 #define RK3288_GMAC_FLOW_CTRL		GRF_BIT(9)
 #define RK3288_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(9)
 #define RK3288_GMAC_SPEED_10M		GRF_CLR_BIT(10)
 #define RK3288_GMAC_SPEED_100M		GRF_BIT(10)
 #define RK3288_GMAC_RMII_CLK_25M	GRF_BIT(11)
 #define RK3288_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(11)
-#define RK3288_GMAC_CLK_125M		(GRF_CLR_BIT(12) | GRF_CLR_BIT(13))
-#define RK3288_GMAC_CLK_25M		(GRF_BIT(12) | GRF_BIT(13))
-#define RK3288_GMAC_CLK_2_5M		(GRF_CLR_BIT(12) | GRF_BIT(13))
+#define RK3288_GMAC_CLK_125M		GRF_FIELD_CONST(13, 12, 0)
+#define RK3288_GMAC_CLK_25M		GRF_FIELD_CONST(13, 12, 3)
+#define RK3288_GMAC_CLK_2_5M		GRF_FIELD_CONST(13, 12, 2)
 #define RK3288_GMAC_RMII_MODE		GRF_BIT(14)
 #define RK3288_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(14)
 
@@ -501,8 +496,7 @@ static const struct rk_gmac_ops rk3288_ops = {
 #define RK3308_GRF_MAC_CON0		0x04a0
 
 /* RK3308_GRF_MAC_CON0 */
-#define RK3308_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(2) | GRF_CLR_BIT(3) | \
-					GRF_BIT(4))
+#define RK3308_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(4, 2, 4)
 #define RK3308_GMAC_FLOW_CTRL		GRF_BIT(3)
 #define RK3308_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
 #define RK3308_GMAC_SPEED_10M		GRF_CLR_BIT(0)
@@ -541,19 +535,17 @@ static const struct rk_gmac_ops rk3308_ops = {
 #define RK3328_GMAC_CLK_TX_DL_CFG(val)	GRF_FIELD(6, 0, val)
 
 /* RK3328_GRF_MAC_CON1 */
-#define RK3328_GMAC_PHY_INTF_SEL_RGMII	\
-		(GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
-#define RK3328_GMAC_PHY_INTF_SEL_RMII	\
-		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
+#define RK3328_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(6, 4, 1)
+#define RK3328_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, 4)
 #define RK3328_GMAC_FLOW_CTRL		GRF_BIT(3)
 #define RK3328_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
 #define RK3328_GMAC_SPEED_10M		GRF_CLR_BIT(2)
 #define RK3328_GMAC_SPEED_100M		GRF_BIT(2)
 #define RK3328_GMAC_RMII_CLK_25M	GRF_BIT(7)
 #define RK3328_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(7)
-#define RK3328_GMAC_CLK_125M		(GRF_CLR_BIT(11) | GRF_CLR_BIT(12))
-#define RK3328_GMAC_CLK_25M		(GRF_BIT(11) | GRF_BIT(12))
-#define RK3328_GMAC_CLK_2_5M		(GRF_CLR_BIT(11) | GRF_BIT(12))
+#define RK3328_GMAC_CLK_125M		GRF_FIELD_CONST(12, 11, 0)
+#define RK3328_GMAC_CLK_25M		GRF_FIELD_CONST(12, 11, 3)
+#define RK3328_GMAC_CLK_2_5M		GRF_FIELD_CONST(12, 11, 2)
 #define RK3328_GMAC_RMII_MODE		GRF_BIT(9)
 #define RK3328_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(9)
 #define RK3328_GMAC_TXCLK_DLY_ENABLE	GRF_BIT(0)
@@ -630,19 +622,17 @@ static const struct rk_gmac_ops rk3328_ops = {
 #define RK3366_GRF_SOC_CON7	0x041c
 
 /* RK3366_GRF_SOC_CON6 */
-#define RK3366_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(9) | GRF_CLR_BIT(10) | \
-					 GRF_CLR_BIT(11))
-#define RK3366_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \
-					 GRF_BIT(11))
+#define RK3366_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(11, 9, 1)
+#define RK3366_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(11, 9, 4)
 #define RK3366_GMAC_FLOW_CTRL		GRF_BIT(8)
 #define RK3366_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
 #define RK3366_GMAC_SPEED_10M		GRF_CLR_BIT(7)
 #define RK3366_GMAC_SPEED_100M		GRF_BIT(7)
 #define RK3366_GMAC_RMII_CLK_25M	GRF_BIT(3)
 #define RK3366_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(3)
-#define RK3366_GMAC_CLK_125M		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5))
-#define RK3366_GMAC_CLK_25M		(GRF_BIT(4) | GRF_BIT(5))
-#define RK3366_GMAC_CLK_2_5M		(GRF_CLR_BIT(4) | GRF_BIT(5))
+#define RK3366_GMAC_CLK_125M		GRF_FIELD_CONST(5, 4, 0)
+#define RK3366_GMAC_CLK_25M		GRF_FIELD_CONST(5, 4, 3)
+#define RK3366_GMAC_CLK_2_5M		GRF_FIELD_CONST(5, 4, 2)
 #define RK3366_GMAC_RMII_MODE		GRF_BIT(6)
 #define RK3366_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(6)
 
@@ -697,19 +687,17 @@ static const struct rk_gmac_ops rk3366_ops = {
 #define RK3368_GRF_SOC_CON16	0x0440
 
 /* RK3368_GRF_SOC_CON15 */
-#define RK3368_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(9) | GRF_CLR_BIT(10) | \
-					 GRF_CLR_BIT(11))
-#define RK3368_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \
-					 GRF_BIT(11))
+#define RK3368_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(11, 9, 1)
+#define RK3368_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(11, 9, 4)
 #define RK3368_GMAC_FLOW_CTRL		GRF_BIT(8)
 #define RK3368_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
 #define RK3368_GMAC_SPEED_10M		GRF_CLR_BIT(7)
 #define RK3368_GMAC_SPEED_100M		GRF_BIT(7)
 #define RK3368_GMAC_RMII_CLK_25M	GRF_BIT(3)
 #define RK3368_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(3)
-#define RK3368_GMAC_CLK_125M		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5))
-#define RK3368_GMAC_CLK_25M		(GRF_BIT(4) | GRF_BIT(5))
-#define RK3368_GMAC_CLK_2_5M		(GRF_CLR_BIT(4) | GRF_BIT(5))
+#define RK3368_GMAC_CLK_125M		GRF_FIELD_CONST(5, 4, 0)
+#define RK3368_GMAC_CLK_25M		GRF_FIELD_CONST(5, 4, 3)
+#define RK3368_GMAC_CLK_2_5M		GRF_FIELD_CONST(5, 4, 2)
 #define RK3368_GMAC_RMII_MODE		GRF_BIT(6)
 #define RK3368_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(6)
 
@@ -764,19 +752,17 @@ static const struct rk_gmac_ops rk3368_ops = {
 #define RK3399_GRF_SOC_CON6	0xc218
 
 /* RK3399_GRF_SOC_CON5 */
-#define RK3399_GMAC_PHY_INTF_SEL_RGMII	(GRF_BIT(9) | GRF_CLR_BIT(10) | \
-					 GRF_CLR_BIT(11))
-#define RK3399_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \
-					 GRF_BIT(11))
+#define RK3399_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(11, 9, 1)
+#define RK3399_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(11, 9, 4)
 #define RK3399_GMAC_FLOW_CTRL		GRF_BIT(8)
 #define RK3399_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
 #define RK3399_GMAC_SPEED_10M		GRF_CLR_BIT(7)
 #define RK3399_GMAC_SPEED_100M		GRF_BIT(7)
 #define RK3399_GMAC_RMII_CLK_25M	GRF_BIT(3)
 #define RK3399_GMAC_RMII_CLK_2_5M	GRF_CLR_BIT(3)
-#define RK3399_GMAC_CLK_125M		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5))
-#define RK3399_GMAC_CLK_25M		(GRF_BIT(4) | GRF_BIT(5))
-#define RK3399_GMAC_CLK_2_5M		(GRF_CLR_BIT(4) | GRF_BIT(5))
+#define RK3399_GMAC_CLK_125M		GRF_FIELD_CONST(5, 4, 0)
+#define RK3399_GMAC_CLK_25M		GRF_FIELD_CONST(5, 4, 3)
+#define RK3399_GMAC_CLK_2_5M		GRF_FIELD_CONST(5, 4, 2)
 #define RK3399_GMAC_RMII_MODE		GRF_BIT(6)
 #define RK3399_GMAC_RMII_MODE_CLR	GRF_CLR_BIT(6)
 
@@ -916,9 +902,9 @@ static const struct rk_gmac_ops rk3506_ops = {
 #define RK3528_GMAC1_CLK_RMII_DIV2	GRF_BIT(10)
 #define RK3528_GMAC1_CLK_RMII_DIV20	GRF_CLR_BIT(10)
 
-#define RK3528_GMAC1_CLK_RGMII_DIV1	(GRF_CLR_BIT(11) | GRF_CLR_BIT(10))
-#define RK3528_GMAC1_CLK_RGMII_DIV5	(GRF_BIT(11) | GRF_BIT(10))
-#define RK3528_GMAC1_CLK_RGMII_DIV50	(GRF_BIT(11) | GRF_CLR_BIT(10))
+#define RK3528_GMAC1_CLK_RGMII_DIV1	GRF_FIELD_CONST(11, 10, 0)
+#define RK3528_GMAC1_CLK_RGMII_DIV5	GRF_FIELD_CONST(11, 10, 3)
+#define RK3528_GMAC1_CLK_RGMII_DIV50	GRF_FIELD_CONST(11, 10, 2)
 
 #define RK3528_GMAC0_CLK_RMII_GATE	GRF_BIT(2)
 #define RK3528_GMAC0_CLK_RMII_NOGATE	GRF_CLR_BIT(2)
@@ -1029,10 +1015,8 @@ static const struct rk_gmac_ops rk3528_ops = {
 #define RK3568_GRF_GMAC1_CON1		0x038c
 
 /* RK3568_GRF_GMAC0_CON1 && RK3568_GRF_GMAC1_CON1 */
-#define RK3568_GMAC_PHY_INTF_SEL_RGMII	\
-		(GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
-#define RK3568_GMAC_PHY_INTF_SEL_RMII	\
-		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
+#define RK3568_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(6, 4, 1)
+#define RK3568_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, 4)
 #define RK3568_GMAC_FLOW_CTRL			GRF_BIT(3)
 #define RK3568_GMAC_FLOW_CTRL_CLR		GRF_CLR_BIT(3)
 #define RK3568_GMAC_RXCLK_DLY_ENABLE		GRF_BIT(1)
@@ -1112,12 +1096,9 @@ static const struct rk_gmac_ops rk3568_ops = {
 #define RK3576_GMAC_CLK_RMII_DIV2		GRF_BIT(5)
 #define RK3576_GMAC_CLK_RMII_DIV20		GRF_CLR_BIT(5)
 
-#define RK3576_GMAC_CLK_RGMII_DIV1		\
-			(GRF_CLR_BIT(6) | GRF_CLR_BIT(5))
-#define RK3576_GMAC_CLK_RGMII_DIV5		\
-			(GRF_BIT(6) | GRF_BIT(5))
-#define RK3576_GMAC_CLK_RGMII_DIV50		\
-			(GRF_BIT(6) | GRF_CLR_BIT(5))
+#define RK3576_GMAC_CLK_RGMII_DIV1		GRF_FIELD_CONST(6, 5, 0)
+#define RK3576_GMAC_CLK_RGMII_DIV5		GRF_FIELD_CONST(6, 5, 3)
+#define RK3576_GMAC_CLK_RGMII_DIV50		GRF_FIELD_CONST(6, 5, 2)
 
 #define RK3576_GMAC_CLK_RMII_GATE		GRF_BIT(4)
 #define RK3576_GMAC_CLK_RMII_NOGATE		GRF_CLR_BIT(4)
@@ -1228,9 +1209,9 @@ static const struct rk_gmac_ops rk3576_ops = {
 #define RK3588_GRF_CLK_CON1			0X0070
 
 #define RK3588_GMAC_PHY_INTF_SEL_RGMII(id)	\
-	(GRF_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_CLR_BIT(5 + (id) * 6))
+	(GRF_FIELD(5, 3, 1) << ((id) * 6))
 #define RK3588_GMAC_PHY_INTF_SEL_RMII(id)	\
-	(GRF_CLR_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_BIT(5 + (id) * 6))
+	(GRF_FIELD(5, 3, 4) << ((id) * 6))
 
 #define RK3588_GMAC_CLK_RMII_MODE(id)		GRF_BIT(5 * (id))
 #define RK3588_GMAC_CLK_RGMII_MODE(id)		GRF_CLR_BIT(5 * (id))
@@ -1242,11 +1223,11 @@ static const struct rk_gmac_ops rk3576_ops = {
 #define RK3588_GMA_CLK_RMII_DIV20(id)		GRF_CLR_BIT(5 * (id) + 2)
 
 #define RK3588_GMAC_CLK_RGMII_DIV1(id)		\
-			(GRF_CLR_BIT(5 * (id) + 2) | GRF_CLR_BIT(5 * (id) + 3))
+	(GRF_FIELD_CONST(3, 2, 0) << ((id) * 5))
 #define RK3588_GMAC_CLK_RGMII_DIV5(id)		\
-			(GRF_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3))
+	(GRF_FIELD_CONST(3, 2, 3) << ((id) * 5))
 #define RK3588_GMAC_CLK_RGMII_DIV50(id)		\
-			(GRF_CLR_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3))
+	(GRF_FIELD_CONST(3, 2, 2) << ((id) * 5))
 
 #define RK3588_GMAC_CLK_RMII_GATE(id)		GRF_BIT(5 * (id) + 1)
 #define RK3588_GMAC_CLK_RMII_NOGATE(id)		GRF_CLR_BIT(5 * (id) + 1)
@@ -1347,8 +1328,7 @@ static const struct rk_gmac_ops rk3588_ops = {
 #define RV1108_GRF_GMAC_CON0		0X0900
 
 /* RV1108_GRF_GMAC_CON0 */
-#define RV1108_GMAC_PHY_INTF_SEL_RMII	(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \
-					GRF_BIT(6))
+#define RV1108_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, 4)
 #define RV1108_GMAC_FLOW_CTRL		GRF_BIT(3)
 #define RV1108_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
 #define RV1108_GMAC_SPEED_10M		GRF_CLR_BIT(2)
@@ -1384,10 +1364,8 @@ static const struct rk_gmac_ops rv1108_ops = {
 #define RV1126_GRF_GMAC_CON2		0X0078
 
 /* RV1126_GRF_GMAC_CON0 */
-#define RV1126_GMAC_PHY_INTF_SEL_RGMII	\
-		(GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
-#define RV1126_GMAC_PHY_INTF_SEL_RMII	\
-		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
+#define RV1126_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(6, 4, 1)
+#define RV1126_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, 4)
 #define RV1126_GMAC_FLOW_CTRL			GRF_BIT(7)
 #define RV1126_GMAC_FLOW_CTRL_CLR		GRF_CLR_BIT(7)
 #define RV1126_GMAC_M0_RXCLK_DLY_ENABLE		GRF_BIT(1)
-- 
2.47.3



From rmk+kernel at armlinux.org.uk  Thu Nov 13 09:46:45 2025
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 13 Nov 2025 17:46:45 +0000
Subject: [PATCH net-next 3/4] net: stmmac: rk: use PHY_INTF_SEL_x constants
In-Reply-To: <aRYZaKTIvfYoV3wE@shell.armlinux.org.uk>
References: <aRYZaKTIvfYoV3wE@shell.armlinux.org.uk>
Message-ID: <E1vJbPB-0000000EBqV-27GS@rmk-PC.armlinux.org.uk>

The values used in the xxx_GMAC_PHY_INTF_SEL_xxx() macros are the
phy_intf_sel values used for the dwmac core. Use these to define these
constants.

No change to produced code on aarch64.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 .../net/ethernet/stmicro/stmmac/dwmac-rk.c    | 46 +++++++++----------
 1 file changed, 23 insertions(+), 23 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 4257cc1f66e9..49076ee00877 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -234,7 +234,7 @@ static void rk_gmac_integrated_fephy_powerdown(struct rk_priv_data *priv,
 #define PX30_GRF_GMAC_CON1		0x0904
 
 /* PX30_GRF_GMAC_CON1 */
-#define PX30_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, 4)
+#define PX30_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RMII)
 #define PX30_GMAC_SPEED_10M		GRF_CLR_BIT(2)
 #define PX30_GMAC_SPEED_100M		GRF_BIT(2)
 
@@ -290,8 +290,8 @@ static const struct rk_gmac_ops px30_ops = {
 #define RK3128_GMAC_CLK_TX_DL_CFG(val) GRF_FIELD(6, 0, val)
 
 /* RK3128_GRF_MAC_CON1 */
-#define RK3128_GMAC_PHY_INTF_SEL_RGMII GRF_FIELD(8, 6, 1)
-#define RK3128_GMAC_PHY_INTF_SEL_RMII  GRF_FIELD(8, 6, 4)
+#define RK3128_GMAC_PHY_INTF_SEL_RGMII GRF_FIELD(8, 6, PHY_INTF_SEL_RGMII)
+#define RK3128_GMAC_PHY_INTF_SEL_RMII  GRF_FIELD(8, 6, PHY_INTF_SEL_RMII)
 #define RK3128_GMAC_FLOW_CTRL          GRF_BIT(9)
 #define RK3128_GMAC_FLOW_CTRL_CLR      GRF_CLR_BIT(9)
 #define RK3128_GMAC_SPEED_10M          GRF_CLR_BIT(10)
@@ -353,8 +353,8 @@ static const struct rk_gmac_ops rk3128_ops = {
 #define RK3228_GMAC_CLK_TX_DL_CFG(val)	GRF_FIELD(6, 0, val)
 
 /* RK3228_GRF_MAC_CON1 */
-#define RK3228_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(6, 4, 1)
-#define RK3228_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, 4)
+#define RK3228_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RGMII)
+#define RK3228_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RMII)
 #define RK3228_GMAC_FLOW_CTRL		GRF_BIT(3)
 #define RK3228_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
 #define RK3228_GMAC_SPEED_10M		GRF_CLR_BIT(2)
@@ -432,8 +432,8 @@ static const struct rk_gmac_ops rk3228_ops = {
 #define RK3288_GRF_SOC_CON3	0x0250
 
 /*RK3288_GRF_SOC_CON1*/
-#define RK3288_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(8, 6, 1)
-#define RK3288_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(8, 6, 4)
+#define RK3288_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(8, 6, PHY_INTF_SEL_RGMII)
+#define RK3288_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(8, 6, PHY_INTF_SEL_RMII)
 #define RK3288_GMAC_FLOW_CTRL		GRF_BIT(9)
 #define RK3288_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(9)
 #define RK3288_GMAC_SPEED_10M		GRF_CLR_BIT(10)
@@ -496,7 +496,7 @@ static const struct rk_gmac_ops rk3288_ops = {
 #define RK3308_GRF_MAC_CON0		0x04a0
 
 /* RK3308_GRF_MAC_CON0 */
-#define RK3308_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(4, 2, 4)
+#define RK3308_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(4, 2, PHY_INTF_SEL_RMII)
 #define RK3308_GMAC_FLOW_CTRL		GRF_BIT(3)
 #define RK3308_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
 #define RK3308_GMAC_SPEED_10M		GRF_CLR_BIT(0)
@@ -535,8 +535,8 @@ static const struct rk_gmac_ops rk3308_ops = {
 #define RK3328_GMAC_CLK_TX_DL_CFG(val)	GRF_FIELD(6, 0, val)
 
 /* RK3328_GRF_MAC_CON1 */
-#define RK3328_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(6, 4, 1)
-#define RK3328_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, 4)
+#define RK3328_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RGMII)
+#define RK3328_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RMII)
 #define RK3328_GMAC_FLOW_CTRL		GRF_BIT(3)
 #define RK3328_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
 #define RK3328_GMAC_SPEED_10M		GRF_CLR_BIT(2)
@@ -622,8 +622,8 @@ static const struct rk_gmac_ops rk3328_ops = {
 #define RK3366_GRF_SOC_CON7	0x041c
 
 /* RK3366_GRF_SOC_CON6 */
-#define RK3366_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(11, 9, 1)
-#define RK3366_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(11, 9, 4)
+#define RK3366_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(11, 9, PHY_INTF_SEL_RGMII)
+#define RK3366_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(11, 9, PHY_INTF_SEL_RMII)
 #define RK3366_GMAC_FLOW_CTRL		GRF_BIT(8)
 #define RK3366_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
 #define RK3366_GMAC_SPEED_10M		GRF_CLR_BIT(7)
@@ -687,8 +687,8 @@ static const struct rk_gmac_ops rk3366_ops = {
 #define RK3368_GRF_SOC_CON16	0x0440
 
 /* RK3368_GRF_SOC_CON15 */
-#define RK3368_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(11, 9, 1)
-#define RK3368_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(11, 9, 4)
+#define RK3368_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(11, 9, PHY_INTF_SEL_RGMII)
+#define RK3368_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(11, 9, PHY_INTF_SEL_RMII)
 #define RK3368_GMAC_FLOW_CTRL		GRF_BIT(8)
 #define RK3368_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
 #define RK3368_GMAC_SPEED_10M		GRF_CLR_BIT(7)
@@ -752,8 +752,8 @@ static const struct rk_gmac_ops rk3368_ops = {
 #define RK3399_GRF_SOC_CON6	0xc218
 
 /* RK3399_GRF_SOC_CON5 */
-#define RK3399_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(11, 9, 1)
-#define RK3399_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(11, 9, 4)
+#define RK3399_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(11, 9, PHY_INTF_SEL_RGMII)
+#define RK3399_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(11, 9, PHY_INTF_SEL_RMII)
 #define RK3399_GMAC_FLOW_CTRL		GRF_BIT(8)
 #define RK3399_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
 #define RK3399_GMAC_SPEED_10M		GRF_CLR_BIT(7)
@@ -1015,8 +1015,8 @@ static const struct rk_gmac_ops rk3528_ops = {
 #define RK3568_GRF_GMAC1_CON1		0x038c
 
 /* RK3568_GRF_GMAC0_CON1 && RK3568_GRF_GMAC1_CON1 */
-#define RK3568_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(6, 4, 1)
-#define RK3568_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, 4)
+#define RK3568_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RGMII)
+#define RK3568_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RMII)
 #define RK3568_GMAC_FLOW_CTRL			GRF_BIT(3)
 #define RK3568_GMAC_FLOW_CTRL_CLR		GRF_CLR_BIT(3)
 #define RK3568_GMAC_RXCLK_DLY_ENABLE		GRF_BIT(1)
@@ -1209,9 +1209,9 @@ static const struct rk_gmac_ops rk3576_ops = {
 #define RK3588_GRF_CLK_CON1			0X0070
 
 #define RK3588_GMAC_PHY_INTF_SEL_RGMII(id)	\
-	(GRF_FIELD(5, 3, 1) << ((id) * 6))
+	(GRF_FIELD(5, 3, PHY_INTF_SEL_RGMII) << ((id) * 6))
 #define RK3588_GMAC_PHY_INTF_SEL_RMII(id)	\
-	(GRF_FIELD(5, 3, 4) << ((id) * 6))
+	(GRF_FIELD(5, 3, PHY_INTF_SEL_RMII) << ((id) * 6))
 
 #define RK3588_GMAC_CLK_RMII_MODE(id)		GRF_BIT(5 * (id))
 #define RK3588_GMAC_CLK_RGMII_MODE(id)		GRF_CLR_BIT(5 * (id))
@@ -1328,7 +1328,7 @@ static const struct rk_gmac_ops rk3588_ops = {
 #define RV1108_GRF_GMAC_CON0		0X0900
 
 /* RV1108_GRF_GMAC_CON0 */
-#define RV1108_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, 4)
+#define RV1108_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RMII)
 #define RV1108_GMAC_FLOW_CTRL		GRF_BIT(3)
 #define RV1108_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
 #define RV1108_GMAC_SPEED_10M		GRF_CLR_BIT(2)
@@ -1364,8 +1364,8 @@ static const struct rk_gmac_ops rv1108_ops = {
 #define RV1126_GRF_GMAC_CON2		0X0078
 
 /* RV1126_GRF_GMAC_CON0 */
-#define RV1126_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(6, 4, 1)
-#define RV1126_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, 4)
+#define RV1126_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RGMII)
+#define RV1126_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RMII)
 #define RV1126_GMAC_FLOW_CTRL			GRF_BIT(7)
 #define RV1126_GMAC_FLOW_CTRL_CLR		GRF_CLR_BIT(7)
 #define RV1126_GMAC_M0_RXCLK_DLY_ENABLE		GRF_BIT(1)
-- 
2.47.3



From rmk+kernel at armlinux.org.uk  Thu Nov 13 09:46:50 2025
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 13 Nov 2025 17:46:50 +0000
Subject: [PATCH net-next 4/4] net: stmmac: rk: use PHY_INTF_SEL_x in functions
In-Reply-To: <aRYZaKTIvfYoV3wE@shell.armlinux.org.uk>
References: <aRYZaKTIvfYoV3wE@shell.armlinux.org.uk>
Message-ID: <E1vJbPG-0000000EBqb-2cF2@rmk-PC.armlinux.org.uk>

Rather than defining one xxx_GMAC_PHY_INTF_SEL_xxx() for each mode,
define xxx_GMAC_PHY_INTF_SEL() which takes the phy_intf_sel value.
Pass the appropriate value into these new macros in the set_to_xxx()
methods.

No change to produced code on aarch64.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 .../net/ethernet/stmicro/stmmac/dwmac-rk.c    | 91 +++++++++----------
 1 file changed, 43 insertions(+), 48 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 49076ee00877..6e75da577af5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -234,14 +234,14 @@ static void rk_gmac_integrated_fephy_powerdown(struct rk_priv_data *priv,
 #define PX30_GRF_GMAC_CON1		0x0904
 
 /* PX30_GRF_GMAC_CON1 */
-#define PX30_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RMII)
+#define PX30_GMAC_PHY_INTF_SEL(val)	GRF_FIELD(6, 4, val)
 #define PX30_GMAC_SPEED_10M		GRF_CLR_BIT(2)
 #define PX30_GMAC_SPEED_100M		GRF_BIT(2)
 
 static void px30_set_to_rmii(struct rk_priv_data *bsp_priv)
 {
 	regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
-		     PX30_GMAC_PHY_INTF_SEL_RMII);
+		     PX30_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RMII));
 }
 
 static int px30_set_speed(struct rk_priv_data *bsp_priv,
@@ -290,8 +290,7 @@ static const struct rk_gmac_ops px30_ops = {
 #define RK3128_GMAC_CLK_TX_DL_CFG(val) GRF_FIELD(6, 0, val)
 
 /* RK3128_GRF_MAC_CON1 */
-#define RK3128_GMAC_PHY_INTF_SEL_RGMII GRF_FIELD(8, 6, PHY_INTF_SEL_RGMII)
-#define RK3128_GMAC_PHY_INTF_SEL_RMII  GRF_FIELD(8, 6, PHY_INTF_SEL_RMII)
+#define RK3128_GMAC_PHY_INTF_SEL(val)  GRF_FIELD(8, 6, val)
 #define RK3128_GMAC_FLOW_CTRL          GRF_BIT(9)
 #define RK3128_GMAC_FLOW_CTRL_CLR      GRF_CLR_BIT(9)
 #define RK3128_GMAC_SPEED_10M          GRF_CLR_BIT(10)
@@ -308,7 +307,7 @@ static void rk3128_set_to_rgmii(struct rk_priv_data *bsp_priv,
 				int tx_delay, int rx_delay)
 {
 	regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
-		     RK3128_GMAC_PHY_INTF_SEL_RGMII |
+		     RK3128_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RGMII) |
 		     RK3128_GMAC_RMII_MODE_CLR);
 	regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON0,
 		     DELAY_ENABLE(RK3128, tx_delay, rx_delay) |
@@ -319,7 +318,8 @@ static void rk3128_set_to_rgmii(struct rk_priv_data *bsp_priv,
 static void rk3128_set_to_rmii(struct rk_priv_data *bsp_priv)
 {
 	regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
-		     RK3128_GMAC_PHY_INTF_SEL_RMII | RK3128_GMAC_RMII_MODE);
+		     RK3128_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RMII) |
+		     RK3128_GMAC_RMII_MODE);
 }
 
 static const struct rk_reg_speed_data rk3128_reg_speed_data = {
@@ -353,8 +353,7 @@ static const struct rk_gmac_ops rk3128_ops = {
 #define RK3228_GMAC_CLK_TX_DL_CFG(val)	GRF_FIELD(6, 0, val)
 
 /* RK3228_GRF_MAC_CON1 */
-#define RK3228_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RGMII)
-#define RK3228_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RMII)
+#define RK3228_GMAC_PHY_INTF_SEL(val)	GRF_FIELD(6, 4, val)
 #define RK3228_GMAC_FLOW_CTRL		GRF_BIT(3)
 #define RK3228_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
 #define RK3228_GMAC_SPEED_10M		GRF_CLR_BIT(2)
@@ -378,7 +377,7 @@ static void rk3228_set_to_rgmii(struct rk_priv_data *bsp_priv,
 				int tx_delay, int rx_delay)
 {
 	regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
-		     RK3228_GMAC_PHY_INTF_SEL_RGMII |
+		     RK3228_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RGMII) |
 		     RK3228_GMAC_RMII_MODE_CLR |
 		     DELAY_ENABLE(RK3228, tx_delay, rx_delay));
 
@@ -390,7 +389,7 @@ static void rk3228_set_to_rgmii(struct rk_priv_data *bsp_priv,
 static void rk3228_set_to_rmii(struct rk_priv_data *bsp_priv)
 {
 	regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
-		     RK3228_GMAC_PHY_INTF_SEL_RMII |
+		     RK3228_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RMII) |
 		     RK3228_GMAC_RMII_MODE);
 
 	/* set MAC to RMII mode */
@@ -432,8 +431,7 @@ static const struct rk_gmac_ops rk3228_ops = {
 #define RK3288_GRF_SOC_CON3	0x0250
 
 /*RK3288_GRF_SOC_CON1*/
-#define RK3288_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(8, 6, PHY_INTF_SEL_RGMII)
-#define RK3288_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(8, 6, PHY_INTF_SEL_RMII)
+#define RK3288_GMAC_PHY_INTF_SEL(val)	GRF_FIELD(8, 6, val)
 #define RK3288_GMAC_FLOW_CTRL		GRF_BIT(9)
 #define RK3288_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(9)
 #define RK3288_GMAC_SPEED_10M		GRF_CLR_BIT(10)
@@ -458,7 +456,7 @@ static void rk3288_set_to_rgmii(struct rk_priv_data *bsp_priv,
 				int tx_delay, int rx_delay)
 {
 	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
-		     RK3288_GMAC_PHY_INTF_SEL_RGMII |
+		     RK3288_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RGMII) |
 		     RK3288_GMAC_RMII_MODE_CLR);
 	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON3,
 		     DELAY_ENABLE(RK3288, tx_delay, rx_delay) |
@@ -469,7 +467,8 @@ static void rk3288_set_to_rgmii(struct rk_priv_data *bsp_priv,
 static void rk3288_set_to_rmii(struct rk_priv_data *bsp_priv)
 {
 	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
-		     RK3288_GMAC_PHY_INTF_SEL_RMII | RK3288_GMAC_RMII_MODE);
+		     RK3288_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RMII) |
+		     RK3288_GMAC_RMII_MODE);
 }
 
 static const struct rk_reg_speed_data rk3288_reg_speed_data = {
@@ -496,7 +495,7 @@ static const struct rk_gmac_ops rk3288_ops = {
 #define RK3308_GRF_MAC_CON0		0x04a0
 
 /* RK3308_GRF_MAC_CON0 */
-#define RK3308_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(4, 2, PHY_INTF_SEL_RMII)
+#define RK3308_GMAC_PHY_INTF_SEL(val)	GRF_FIELD(4, 2, val)
 #define RK3308_GMAC_FLOW_CTRL		GRF_BIT(3)
 #define RK3308_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
 #define RK3308_GMAC_SPEED_10M		GRF_CLR_BIT(0)
@@ -505,7 +504,7 @@ static const struct rk_gmac_ops rk3288_ops = {
 static void rk3308_set_to_rmii(struct rk_priv_data *bsp_priv)
 {
 	regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0,
-		     RK3308_GMAC_PHY_INTF_SEL_RMII);
+		     RK3308_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RMII));
 }
 
 static const struct rk_reg_speed_data rk3308_reg_speed_data = {
@@ -535,8 +534,7 @@ static const struct rk_gmac_ops rk3308_ops = {
 #define RK3328_GMAC_CLK_TX_DL_CFG(val)	GRF_FIELD(6, 0, val)
 
 /* RK3328_GRF_MAC_CON1 */
-#define RK3328_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RGMII)
-#define RK3328_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RMII)
+#define RK3328_GMAC_PHY_INTF_SEL(val)	GRF_FIELD(6, 4, val)
 #define RK3328_GMAC_FLOW_CTRL		GRF_BIT(3)
 #define RK3328_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
 #define RK3328_GMAC_SPEED_10M		GRF_CLR_BIT(2)
@@ -558,7 +556,7 @@ static void rk3328_set_to_rgmii(struct rk_priv_data *bsp_priv,
 				int tx_delay, int rx_delay)
 {
 	regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
-		     RK3328_GMAC_PHY_INTF_SEL_RGMII |
+		     RK3328_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RGMII) |
 		     RK3328_GMAC_RMII_MODE_CLR |
 		     RK3328_GMAC_RXCLK_DLY_ENABLE |
 		     RK3328_GMAC_TXCLK_DLY_ENABLE);
@@ -576,7 +574,7 @@ static void rk3328_set_to_rmii(struct rk_priv_data *bsp_priv)
 		  RK3328_GRF_MAC_CON1;
 
 	regmap_write(bsp_priv->grf, reg,
-		     RK3328_GMAC_PHY_INTF_SEL_RMII |
+		     RK3328_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RMII) |
 		     RK3328_GMAC_RMII_MODE);
 }
 
@@ -622,8 +620,7 @@ static const struct rk_gmac_ops rk3328_ops = {
 #define RK3366_GRF_SOC_CON7	0x041c
 
 /* RK3366_GRF_SOC_CON6 */
-#define RK3366_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(11, 9, PHY_INTF_SEL_RGMII)
-#define RK3366_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(11, 9, PHY_INTF_SEL_RMII)
+#define RK3366_GMAC_PHY_INTF_SEL(val)	GRF_FIELD(11, 9, val)
 #define RK3366_GMAC_FLOW_CTRL		GRF_BIT(8)
 #define RK3366_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
 #define RK3366_GMAC_SPEED_10M		GRF_CLR_BIT(7)
@@ -648,7 +645,7 @@ static void rk3366_set_to_rgmii(struct rk_priv_data *bsp_priv,
 				int tx_delay, int rx_delay)
 {
 	regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
-		     RK3366_GMAC_PHY_INTF_SEL_RGMII |
+		     RK3366_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RGMII) |
 		     RK3366_GMAC_RMII_MODE_CLR);
 	regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON7,
 		     DELAY_ENABLE(RK3366, tx_delay, rx_delay) |
@@ -659,7 +656,8 @@ static void rk3366_set_to_rgmii(struct rk_priv_data *bsp_priv,
 static void rk3366_set_to_rmii(struct rk_priv_data *bsp_priv)
 {
 	regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
-		     RK3366_GMAC_PHY_INTF_SEL_RMII | RK3366_GMAC_RMII_MODE);
+		     RK3366_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RMII) |
+		     RK3366_GMAC_RMII_MODE);
 }
 
 static const struct rk_reg_speed_data rk3366_reg_speed_data = {
@@ -687,8 +685,7 @@ static const struct rk_gmac_ops rk3366_ops = {
 #define RK3368_GRF_SOC_CON16	0x0440
 
 /* RK3368_GRF_SOC_CON15 */
-#define RK3368_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(11, 9, PHY_INTF_SEL_RGMII)
-#define RK3368_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(11, 9, PHY_INTF_SEL_RMII)
+#define RK3368_GMAC_PHY_INTF_SEL(val)	GRF_FIELD(11, 9, val)
 #define RK3368_GMAC_FLOW_CTRL		GRF_BIT(8)
 #define RK3368_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
 #define RK3368_GMAC_SPEED_10M		GRF_CLR_BIT(7)
@@ -713,7 +710,7 @@ static void rk3368_set_to_rgmii(struct rk_priv_data *bsp_priv,
 				int tx_delay, int rx_delay)
 {
 	regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
-		     RK3368_GMAC_PHY_INTF_SEL_RGMII |
+		     RK3368_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RGMII) |
 		     RK3368_GMAC_RMII_MODE_CLR);
 	regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON16,
 		     DELAY_ENABLE(RK3368, tx_delay, rx_delay) |
@@ -724,7 +721,8 @@ static void rk3368_set_to_rgmii(struct rk_priv_data *bsp_priv,
 static void rk3368_set_to_rmii(struct rk_priv_data *bsp_priv)
 {
 	regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
-		     RK3368_GMAC_PHY_INTF_SEL_RMII | RK3368_GMAC_RMII_MODE);
+		     RK3368_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RMII) |
+		     RK3368_GMAC_RMII_MODE);
 }
 
 static const struct rk_reg_speed_data rk3368_reg_speed_data = {
@@ -752,8 +750,7 @@ static const struct rk_gmac_ops rk3368_ops = {
 #define RK3399_GRF_SOC_CON6	0xc218
 
 /* RK3399_GRF_SOC_CON5 */
-#define RK3399_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(11, 9, PHY_INTF_SEL_RGMII)
-#define RK3399_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(11, 9, PHY_INTF_SEL_RMII)
+#define RK3399_GMAC_PHY_INTF_SEL(val)	GRF_FIELD(11, 9, val)
 #define RK3399_GMAC_FLOW_CTRL		GRF_BIT(8)
 #define RK3399_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
 #define RK3399_GMAC_SPEED_10M		GRF_CLR_BIT(7)
@@ -778,7 +775,7 @@ static void rk3399_set_to_rgmii(struct rk_priv_data *bsp_priv,
 				int tx_delay, int rx_delay)
 {
 	regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
-		     RK3399_GMAC_PHY_INTF_SEL_RGMII |
+		     RK3399_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RGMII) |
 		     RK3399_GMAC_RMII_MODE_CLR);
 	regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON6,
 		     DELAY_ENABLE(RK3399, tx_delay, rx_delay) |
@@ -789,7 +786,8 @@ static void rk3399_set_to_rgmii(struct rk_priv_data *bsp_priv,
 static void rk3399_set_to_rmii(struct rk_priv_data *bsp_priv)
 {
 	regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
-		     RK3399_GMAC_PHY_INTF_SEL_RMII | RK3399_GMAC_RMII_MODE);
+		     RK3399_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RMII) |
+		     RK3399_GMAC_RMII_MODE);
 }
 
 static const struct rk_reg_speed_data rk3399_reg_speed_data = {
@@ -1015,8 +1013,7 @@ static const struct rk_gmac_ops rk3528_ops = {
 #define RK3568_GRF_GMAC1_CON1		0x038c
 
 /* RK3568_GRF_GMAC0_CON1 && RK3568_GRF_GMAC1_CON1 */
-#define RK3568_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RGMII)
-#define RK3568_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RMII)
+#define RK3568_GMAC_PHY_INTF_SEL(val)	GRF_FIELD(6, 4, val)
 #define RK3568_GMAC_FLOW_CTRL			GRF_BIT(3)
 #define RK3568_GMAC_FLOW_CTRL_CLR		GRF_CLR_BIT(3)
 #define RK3568_GMAC_RXCLK_DLY_ENABLE		GRF_BIT(1)
@@ -1043,7 +1040,7 @@ static void rk3568_set_to_rgmii(struct rk_priv_data *bsp_priv,
 		     RK3568_GMAC_CLK_TX_DL_CFG(tx_delay));
 
 	regmap_write(bsp_priv->grf, con1,
-		     RK3568_GMAC_PHY_INTF_SEL_RGMII |
+		     RK3568_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RGMII) |
 		     RK3568_GMAC_RXCLK_DLY_ENABLE |
 		     RK3568_GMAC_TXCLK_DLY_ENABLE);
 }
@@ -1054,7 +1051,8 @@ static void rk3568_set_to_rmii(struct rk_priv_data *bsp_priv)
 
 	con1 = (bsp_priv->id == 1) ? RK3568_GRF_GMAC1_CON1 :
 				     RK3568_GRF_GMAC0_CON1;
-	regmap_write(bsp_priv->grf, con1, RK3568_GMAC_PHY_INTF_SEL_RMII);
+	regmap_write(bsp_priv->grf, con1,
+		     RK3568_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RMII));
 }
 
 static const struct rk_gmac_ops rk3568_ops = {
@@ -1208,10 +1206,8 @@ static const struct rk_gmac_ops rk3576_ops = {
 #define RK3588_GRF_GMAC_CON0			0X0008
 #define RK3588_GRF_CLK_CON1			0X0070
 
-#define RK3588_GMAC_PHY_INTF_SEL_RGMII(id)	\
-	(GRF_FIELD(5, 3, PHY_INTF_SEL_RGMII) << ((id) * 6))
-#define RK3588_GMAC_PHY_INTF_SEL_RMII(id)	\
-	(GRF_FIELD(5, 3, PHY_INTF_SEL_RMII) << ((id) * 6))
+#define RK3588_GMAC_PHY_INTF_SEL(id, val)	\
+	(GRF_FIELD(5, 3, val) << ((id) * 6))
 
 #define RK3588_GMAC_CLK_RMII_MODE(id)		GRF_BIT(5 * (id))
 #define RK3588_GMAC_CLK_RGMII_MODE(id)		GRF_CLR_BIT(5 * (id))
@@ -1241,7 +1237,7 @@ static void rk3588_set_to_rgmii(struct rk_priv_data *bsp_priv,
 					 RK3588_GRF_GMAC_CON8;
 
 	regmap_write(bsp_priv->php_grf, RK3588_GRF_GMAC_CON0,
-		     RK3588_GMAC_PHY_INTF_SEL_RGMII(id));
+		     RK3588_GMAC_PHY_INTF_SEL(id, PHY_INTF_SEL_RGMII));
 
 	regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1,
 		     RK3588_GMAC_CLK_RGMII_MODE(id));
@@ -1258,7 +1254,7 @@ static void rk3588_set_to_rgmii(struct rk_priv_data *bsp_priv,
 static void rk3588_set_to_rmii(struct rk_priv_data *bsp_priv)
 {
 	regmap_write(bsp_priv->php_grf, RK3588_GRF_GMAC_CON0,
-		     RK3588_GMAC_PHY_INTF_SEL_RMII(bsp_priv->id));
+		     RK3588_GMAC_PHY_INTF_SEL(bsp_priv->id, PHY_INTF_SEL_RMII));
 
 	regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1,
 		     RK3588_GMAC_CLK_RMII_MODE(bsp_priv->id));
@@ -1328,7 +1324,7 @@ static const struct rk_gmac_ops rk3588_ops = {
 #define RV1108_GRF_GMAC_CON0		0X0900
 
 /* RV1108_GRF_GMAC_CON0 */
-#define RV1108_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RMII)
+#define RV1108_GMAC_PHY_INTF_SEL(val)	GRF_FIELD(6, 4, val)
 #define RV1108_GMAC_FLOW_CTRL		GRF_BIT(3)
 #define RV1108_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
 #define RV1108_GMAC_SPEED_10M		GRF_CLR_BIT(2)
@@ -1339,7 +1335,7 @@ static const struct rk_gmac_ops rk3588_ops = {
 static void rv1108_set_to_rmii(struct rk_priv_data *bsp_priv)
 {
 	regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
-		     RV1108_GMAC_PHY_INTF_SEL_RMII);
+		     RV1108_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RMII));
 }
 
 static const struct rk_reg_speed_data rv1108_reg_speed_data = {
@@ -1364,8 +1360,7 @@ static const struct rk_gmac_ops rv1108_ops = {
 #define RV1126_GRF_GMAC_CON2		0X0078
 
 /* RV1126_GRF_GMAC_CON0 */
-#define RV1126_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RGMII)
-#define RV1126_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RMII)
+#define RV1126_GMAC_PHY_INTF_SEL(val)	GRF_FIELD(6, 4, val)
 #define RV1126_GMAC_FLOW_CTRL			GRF_BIT(7)
 #define RV1126_GMAC_FLOW_CTRL_CLR		GRF_CLR_BIT(7)
 #define RV1126_GMAC_M0_RXCLK_DLY_ENABLE		GRF_BIT(1)
@@ -1388,7 +1383,7 @@ static void rv1126_set_to_rgmii(struct rk_priv_data *bsp_priv,
 				int tx_delay, int rx_delay)
 {
 	regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON0,
-		     RV1126_GMAC_PHY_INTF_SEL_RGMII |
+		     RV1126_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RGMII) |
 		     RV1126_GMAC_M0_RXCLK_DLY_ENABLE |
 		     RV1126_GMAC_M0_TXCLK_DLY_ENABLE |
 		     RV1126_GMAC_M1_RXCLK_DLY_ENABLE |
@@ -1406,7 +1401,7 @@ static void rv1126_set_to_rgmii(struct rk_priv_data *bsp_priv,
 static void rv1126_set_to_rmii(struct rk_priv_data *bsp_priv)
 {
 	regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON0,
-		     RV1126_GMAC_PHY_INTF_SEL_RMII);
+		     RV1126_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RMII));
 }
 
 static const struct rk_gmac_ops rv1126_ops = {
-- 
2.47.3



From macroalpha82 at gmail.com  Thu Nov 13 11:29:36 2025
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Thu, 13 Nov 2025 13:29:36 -0600
Subject: [PATCH v2 0/3] Add HDMI for Gameforce Ace
Message-ID: <20251113192939.30031-1-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

Add support for the micro HDMI port for the Gameforce Ace. This port does
not have a HPD pin so it requires making changes to the HDMI controller
to support this configuration.

Changes since v1:
 - Simplified checking of no-hpd parameter and changed to
   device_property_read_bool() function.

Chris Morgan (3):
  dt-bindings: display: rockchip: Add no-hpd for dw-hdmi-qp controller
  drm/bridge: dw-hdmi-qp: Add support for missing HPD
  arm64: dts: rockchip: Add HDMI to Gameforce Ace

 .../rockchip/rockchip,rk3588-dw-hdmi-qp.yaml  |  6 ++
 .../dts/rockchip/rk3588s-gameforce-ace.dts    | 63 +++++++++++++++++++
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c  | 32 ++++++++--
 3 files changed, 97 insertions(+), 4 deletions(-)

-- 
2.43.0



From macroalpha82 at gmail.com  Thu Nov 13 11:29:37 2025
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Thu, 13 Nov 2025 13:29:37 -0600
Subject: [PATCH v2 1/3] dt-bindings: display: rockchip: Add no-hpd for dw-hdmi-qp controller
In-Reply-To: <20251113192939.30031-1-macroalpha82@gmail.com>
References: <20251113192939.30031-1-macroalpha82@gmail.com>
Message-ID: <20251113192939.30031-2-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

Add an attribute of "no-hpd" for the Rockchip dw-hdmi-qp controller.
This is used to describe implementations where the HPD pin is not
connected or used for other purposes, such as in the RK3588S based
Gameforce Ace which repurposed the GPIO for an additional face
button.

The "no-hpd" option was chosen to be consistent with other devices
which already define this parameter for broken or missing hpd
functionality.

Acked-by: Conor Dooley <conor.dooley at microchip.com>
Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
---
 .../display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml        | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml
index 96b4b088eebe..07342838cd52 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml
@@ -69,6 +69,12 @@ properties:
       - const: main
       - const: hpd
 
+  no-hpd:
+    type: boolean
+    description:
+      The HPD pin is not present or used for another purpose, and the EDID
+      must be polled instead to determine if a device is attached.
+
   phys:
     maxItems: 1
     description: The HDMI/eDP PHY
-- 
2.43.0



From macroalpha82 at gmail.com  Thu Nov 13 11:29:38 2025
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Thu, 13 Nov 2025 13:29:38 -0600
Subject: [PATCH v2 2/3] drm/bridge: dw-hdmi-qp: Add support for missing HPD
In-Reply-To: <20251113192939.30031-1-macroalpha82@gmail.com>
References: <20251113192939.30031-1-macroalpha82@gmail.com>
Message-ID: <20251113192939.30031-3-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

Add support for the dw-hdmi-qp driver to handle devices with missing
HPD pins.

Since in this situation we are now polling for the EDID data via i2c
change the error message to a debug message when we are unable to
complete an i2c read, as a disconnected device would otherwise fill
dmesg with i2c read errors.

Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 32 +++++++++++++++++---
 1 file changed, 28 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
index 39332c57f2c5..a2b1a4821714 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
@@ -145,6 +145,7 @@ struct dw_hdmi_qp {
 	struct regmap *regm;
 
 	unsigned long tmds_char_rate;
+	bool no_hpd;
 };
 
 static void dw_hdmi_qp_write(struct dw_hdmi_qp *hdmi, unsigned int val,
@@ -520,6 +521,11 @@ static int dw_hdmi_qp_i2c_read(struct dw_hdmi_qp *hdmi,
 		i2c->is_regaddr = true;
 	}
 
+	/*
+	 * Mark errors as debug messages when using no_hpd so no device
+	 * attached does not fill up dmesg.
+	 */
+
 	while (length--) {
 		reinit_completion(&i2c->cmp);
 
@@ -535,14 +541,20 @@ static int dw_hdmi_qp_i2c_read(struct dw_hdmi_qp *hdmi,
 
 		stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10);
 		if (!stat) {
-			dev_err(hdmi->dev, "i2c read timed out\n");
+			if (hdmi->no_hpd)
+				dev_dbg(hdmi->dev, "i2c read timed out\n");
+			else
+				dev_err(hdmi->dev, "i2c read timed out\n");
 			dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0);
 			return -EAGAIN;
 		}
 
 		/* Check for error condition on the bus */
 		if (i2c->stat & I2CM_NACK_RCVD_IRQ) {
-			dev_err(hdmi->dev, "i2c read error\n");
+			if (hdmi->no_hpd)
+				dev_dbg(hdmi->dev, "i2c read error\n");
+			else
+				dev_err(hdmi->dev, "i2c read error\n");
 			dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0);
 			return -EIO;
 		}
@@ -879,6 +891,15 @@ static enum drm_connector_status
 dw_hdmi_qp_bridge_detect(struct drm_bridge *bridge, struct drm_connector *connector)
 {
 	struct dw_hdmi_qp *hdmi = bridge->driver_private;
+	const struct drm_edid *drm_edid;
+
+	if (hdmi->no_hpd) {
+		drm_edid = drm_edid_read_ddc(connector, bridge->ddc);
+		if (drm_edid)
+			return connector_status_connected;
+		else
+			return connector_status_disconnected;
+	}
 
 	return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
 }
@@ -1074,12 +1095,15 @@ struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev,
 	if (ret)
 		return ERR_PTR(ret);
 
+	hdmi->no_hpd = device_property_read_bool(dev, "no-hpd");
+
 	hdmi->bridge.driver_private = hdmi;
 	hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT |
 			   DRM_BRIDGE_OP_EDID |
 			   DRM_BRIDGE_OP_HDMI |
-			   DRM_BRIDGE_OP_HDMI_AUDIO |
-			   DRM_BRIDGE_OP_HPD;
+			   DRM_BRIDGE_OP_HDMI_AUDIO;
+	if (!hdmi->no_hpd)
+		hdmi->bridge.ops |= DRM_BRIDGE_OP_HPD;
 	hdmi->bridge.of_node = pdev->dev.of_node;
 	hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
 	hdmi->bridge.vendor = "Synopsys";
-- 
2.43.0



From macroalpha82 at gmail.com  Thu Nov 13 11:29:39 2025
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Thu, 13 Nov 2025 13:29:39 -0600
Subject: [PATCH v2 3/3] arm64: dts: rockchip: Add HDMI to Gameforce Ace
In-Reply-To: <20251113192939.30031-1-macroalpha82@gmail.com>
References: <20251113192939.30031-1-macroalpha82@gmail.com>
Message-ID: <20251113192939.30031-4-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

Add support for the HDMI port for the Gameforce Ace. The HDMI port
has no HPD pin present (the manufacturer's devicetree states the pin
is reused for an additional face button) so add the attribute of
no-hpd to poll for connected devices.

Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
---
 .../dts/rockchip/rk3588s-gameforce-ace.dts    | 63 +++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts b/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts
index f5894672fcbd..b98e1a3369dc 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts
@@ -300,6 +300,20 @@ amp_headphone: headphone-amplifier {
 		sound-name-prefix = "Headphones Amplifier";
 	};
 
+	hdmi0-con {
+		compatible = "hdmi-connector";
+		ddc-en-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_HIGH>;
+		pinctrl-0 = <&hdmi0_en>;
+		pinctrl-names = "default";
+		type = "d";
+
+		port {
+			hdmi0_con_in: endpoint {
+				remote-endpoint = <&hdmi0_out_con>;
+			};
+		};
+	};
+
 	pwm_fan: pwm-fan {
 		compatible = "pwm-fan";
 		#cooling-cells = <2>;
@@ -498,6 +512,34 @@ &gpu {
 	status = "okay";
 };
 
+&hdmi0 {
+	no-hpd;
+	pinctrl-0 = <&hdmim0_tx0_cec>, <&hdmim0_tx0_scl>,
+		    <&hdmim0_tx0_sda>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&hdmi0_in {
+	hdmi0_in_vp0: endpoint {
+		remote-endpoint = <&vp0_out_hdmi0>;
+	};
+};
+
+&hdmi0_out {
+	hdmi0_out_con: endpoint {
+		remote-endpoint = <&hdmi0_con_in>;
+	};
+};
+
+&hdmi0_sound {
+	status = "okay";
+};
+
+&hdptxphy0 {
+	status = "okay";
+};
+
 &i2c0 {
 	pinctrl-0 = <&i2c0m2_xfer>;
 	pinctrl-names = "default";
@@ -746,6 +788,10 @@ &i2s0_sdi0
 	status = "okay";
 };
 
+&i2s5_8ch {
+	status = "okay";
+};
+
 &mipidcphy0 {
 	status = "okay";
 };
@@ -842,6 +888,13 @@ charger_int_h: charger-int-h {
 		};
 	};
 
+	hdmi {
+		hdmi0_en: hdmi0-en {
+			rockchip,pins =
+				<4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
 	hym8563 {
 		hym8563_int: hym8563-int {
 			rockchip,pins =
@@ -1416,6 +1469,16 @@ &vop_mmu {
 	status = "okay";
 };
 
+&vp0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	vp0_out_hdmi0: endpoint at ROCKCHIP_VOP2_EP_HDMI0 {
+		reg = <ROCKCHIP_VOP2_EP_HDMI0>;
+		remote-endpoint = <&hdmi0_in_vp0>;
+	};
+};
+
 &vp3 {
 	#address-cells = <1>;
 	#size-cells = <0>;
-- 
2.43.0



From conor at kernel.org  Thu Nov 13 11:40:04 2025
From: conor at kernel.org (Conor Dooley)
Date: Thu, 13 Nov 2025 19:40:04 +0000
Subject: [PATCH v9 1/3] dt-bindings: can: rockchip_canfd: add rk3576 CAN
 controller
In-Reply-To: <20251113075419.482940-2-zhangqing@rock-chips.com>
References: <20251113075419.482940-1-zhangqing@rock-chips.com>
 <20251113075419.482940-2-zhangqing@rock-chips.com>
Message-ID: <20251113-bullfrog-destiny-977deea729e1@spud>

On Thu, Nov 13, 2025 at 03:54:17PM +0800, Elaine Zhang wrote:
> Add documentation for the rockchip rk3576 CAN controller.
> 
> Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>

Acked-by: Conor Dooley <conor.dooley at microchip.com>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251113/2584a538/attachment.sig>

From laurent.pinchart at ideasonboard.com  Thu Nov 13 14:09:51 2025
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Fri, 14 Nov 2025 00:09:51 +0200
Subject: [PATCH v3 0/2] drm/rockchip: dw_hdmi_qp: Fixup usage of
 enable_gpio
In-Reply-To: <20251027222641.25066-1-laurent.pinchart@ideasonboard.com>
References: <20251027222641.25066-1-laurent.pinchart@ideasonboard.com>
Message-ID: <20251113220951.GA5912@pendragon.ideasonboard.com>

Andy, Heiko, Sandy, could one of you push this to drm-misc ?

On Tue, Oct 28, 2025 at 12:26:39AM +0200, Laurent Pinchart wrote:
> Hello,
> 
> The dw_hdmi_qp driver supports a "enable-gpios" DT property that is not
> documented in the corresponding DT bindings, and is not used in any
> upstream device tree sources. This patch series renames the property to
> "frl-enable-gpios" to express its purpose more clearly, and documents it
> in the bindings.
> 
> In the previous these two patches were part of "[PATCH v2 0/5] arm64:
> dts: rockchip: Add device tree for the Orange Pi CM5 Base board" ([1]).
> I have split them from the Orange Pi CM5 Base DT and rebased them on top
> of the drm-misc-next branch to ease integration.
> 
> The other main change compared to v2 is the rename of the property from
> "tmds-enable-gpios" to "frl-enable-gpios".
> 
> [1] https://lore.kernel.org/all/20251005235542.1017-1-laurent.pinchart at ideasonboard.com/
> 
> Cristian Ciocaltea (2):
>   dt-bindings: display: rk3588-dw-hdmi-qp: Add frl-enable-gpios property
>   drm/rockchip: dw_hdmi_qp: Fixup usage of enable_gpio member in main
>     struct
> 
>  .../rockchip/rockchip,rk3588-dw-hdmi-qp.yaml       | 11 +++++++++++
>  drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c     | 14 +++++++-------
>  2 files changed, 18 insertions(+), 7 deletions(-)
> 
> 
> base-commit: 18ff1dc462ef6dacba76ea9cb9a4fadb385d6ec4

-- 
Regards,

Laurent Pinchart


From cristian.ciocaltea at collabora.com  Thu Nov 13 14:24:27 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Fri, 14 Nov 2025 00:24:27 +0200
Subject: [PATCH v2 2/3] drm/bridge: dw-hdmi-qp: Add support for missing
 HPD
In-Reply-To: <20251113192939.30031-3-macroalpha82@gmail.com>
References: <20251113192939.30031-1-macroalpha82@gmail.com>
 <20251113192939.30031-3-macroalpha82@gmail.com>
Message-ID: <684723a1-50f4-4645-ab6e-52e69d1fc96a@collabora.com>

On 11/13/25 9:29 PM, Chris Morgan wrote:
> From: Chris Morgan <macromorgan at hotmail.com>
> 
> Add support for the dw-hdmi-qp driver to handle devices with missing
> HPD pins.
> 
> Since in this situation we are now polling for the EDID data via i2c
> change the error message to a debug message when we are unable to
> complete an i2c read, as a disconnected device would otherwise fill
> dmesg with i2c read errors.
> 
> Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 32 +++++++++++++++++---
>  1 file changed, 28 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
> index 39332c57f2c5..a2b1a4821714 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
> @@ -145,6 +145,7 @@ struct dw_hdmi_qp {
>  	struct regmap *regm;
>  
>  	unsigned long tmds_char_rate;
> +	bool no_hpd;
>  };
>  
>  static void dw_hdmi_qp_write(struct dw_hdmi_qp *hdmi, unsigned int val,
> @@ -520,6 +521,11 @@ static int dw_hdmi_qp_i2c_read(struct dw_hdmi_qp *hdmi,
>  		i2c->is_regaddr = true;
>  	}
>  
> +	/*
> +	 * Mark errors as debug messages when using no_hpd so no device
> +	 * attached does not fill up dmesg.
> +	 */
> +

Using the *_ratelimited() variant - see below - would make this comment kind of
redundant.  Moreover, you've already explained the rationale behind the change
in the commit description.  Hence I'd rather drop it.

>  	while (length--) {
>  		reinit_completion(&i2c->cmp);
>  
> @@ -535,14 +541,20 @@ static int dw_hdmi_qp_i2c_read(struct dw_hdmi_qp *hdmi,
>  
>  		stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10);
>  		if (!stat) {
> -			dev_err(hdmi->dev, "i2c read timed out\n");
> +			if (hdmi->no_hpd)
> +				dev_dbg(hdmi->dev, "i2c read timed out\n");

I think it's worth switching to dev_dbg_ratelimited() in this case.

> +			else
> +				dev_err(hdmi->dev, "i2c read timed out\n");
>  			dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0);
>  			return -EAGAIN;
>  		}
>  
>  		/* Check for error condition on the bus */
>  		if (i2c->stat & I2CM_NACK_RCVD_IRQ) {
> -			dev_err(hdmi->dev, "i2c read error\n");
> +			if (hdmi->no_hpd)
> +				dev_dbg(hdmi->dev, "i2c read error\n");

Same here.

> +			else
> +				dev_err(hdmi->dev, "i2c read error\n");
>  			dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0);
>  			return -EIO;
>  		}

[...]

Regardless,

Reviewed-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>



From heiko at sntech.de  Thu Nov 13 14:35:57 2025
From: heiko at sntech.de (Heiko =?UTF-8?B?U3TDvGJuZXI=?=)
Date: Thu, 13 Nov 2025 23:35:57 +0100
Subject: [PATCH 2/2] arm64: dts: rockchip: add Tinkerboard 3 and 3S device tree
In-Reply-To: <20251111172003.2324525-3-michael.opdenacker@rootcommit.com>
References: <20251111172003.2324525-1-michael.opdenacker@rootcommit.com>
 <20251111172003.2324525-3-michael.opdenacker@rootcommit.com>
Message-ID: <3310785.5fSG56mABF@diego>

Hi Michael,

Am Dienstag, 11. November 2025, 18:20:23 Mitteleurop?ische Normalzeit schrieb michael.opdenacker at rootcommit.com:
> From: Michael Opdenacker <michael.opdenacker at rootcommit.com>
> 
> Add initial device tree support for Asus Tinkerboard 3 [1] and 3S [2],
> which are SBCs based on the Rockchip 3566 SoC.
> 
> The "3S" version ("S" for "storage") just adds a 16 GB eMMC
> and a "mask ROM" DIP switch (to mask the eMMC and enter "Mask ROM"
> mode for recovery) to the "3" version.
> 
> This adds support for:
> - Debug UART (/dev/ttyS2)
> - SD card (/dev/mmcblk1)
> - eMMC (/dev/mmcblk0, only on Tinkerboard 3S)
> - I2C:
>   - i2c0 (internal bus with a PMIC and regulators)
>   - i2c2 (internal bus with an at24 eeprom and an RTC device)
> - USB 2.0 ports
> - 2 GPIO LEDS
> 
> Link: https://tinker-board.asus.com/series/tinker-board-3.html [1]
> Link: https://tinker-board.asus.com/series/tinker-board-3s.html [2]
> Signed-off-by: Michael Opdenacker <michael.opdenacker at rootcommit.com>
> ---

please follow the DTS coding style
https://docs.kernel.org/devicetree/bindings/dts-coding-style.html


> +/ {
> +	aliases {
> +		serial2 = &uart2;
> +		mmc1 = &sdmmc0;
> +		i2c0 = &i2c0;
> +		i2c2 = &i2c2;

alphabetical property order


> +	};
> +
> +	chosen {
> +		stdout-path = "serial2:1500000n8";
> +	};
> +
> +	vcc3v3_sys: regulator-3v3-vcc-sys {
> +		compatible = "regulator-fixed";
> +		regulator-name = "vcc3v3_sys";
> +		regulator-always-on;
> +		regulator-boot-on;
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		vin-supply = <&vcc5v0_sys>;
> +	};
> +
> +	vcc5v0_sys: regulator-5v0-vcc-sys {
> +		compatible = "regulator-fixed";
> +		regulator-name = "vcc5v0_sys";
> +		regulator-always-on;
> +		regulator-boot-on;
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +	};
> +
> +	vcc5v0_usb_host: regulator-5v0-vcc-usb-host {
> +		compatible = "regulator-fixed";
> +		enable-active-high;
> +		gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&usb_host_pwren_h>;
> +		regulator-name = "vcc5v0_usb_host";
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +		vin-supply = <&vcc5v0_sys>;
> +	};
> +
> +	gpio_leds: gpio-leds {

gpio-foo before regulator-bar

> +		compatible = "gpio-leds";
> +
> +		act-led {
> +			gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>;
> +			linux,default-trigger="mmc1";
> +};

missing indentation

> +
> +		rsv-led {
> +			gpios = <&gpio0 RK_PD6 GPIO_ACTIVE_HIGH>;
> +			linux,default-trigger="none";
> +		};
> +	};
> +};
> +
> +&uart2 {

alphabetical ordering of phandles please (uart2 definitly somewhere after i2c0)

> +	status = "okay";
> +};
> +
> +&i2c0 {
> +	status = "okay";
> +
> +	rk809: pmic at 20 {
> +		compatible = "rockchip,rk809";
> +		reg = <0x20>;
> +		assigned-clocks = <&cru I2S1_MCLKOUT_TX>;
> +		assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>;
> +		#clock-cells = <1>;
> +		clocks = <&cru I2S1_MCLKOUT_TX>;
> +		clock-names = "mclk";
> +		clock-output-names = "rk809-clkout1", "rk809-clkout2";
> +		interrupt-parent = <&gpio0>;
> +		interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pmic_int_l>, <&i2s1m0_mclk>;
> +		#sound-dai-cells = <0>;
> +		system-power-controller;
> +		wakeup-source;
> +
> +		vcc1-supply = <&vcc3v3_sys>;
> +		vcc2-supply = <&vcc3v3_sys>;
> +		vcc3-supply = <&vcc3v3_sys>;
> +		vcc4-supply = <&vcc3v3_sys>;
> +		vcc5-supply = <&vcc3v3_sys>;
> +		vcc6-supply = <&vcc3v3_sys>;
> +		vcc7-supply = <&vcc3v3_sys>;
> +		vcc8-supply = <&vcc3v3_sys>;
> +		vcc9-supply = <&vcc3v3_sys>;
> +
> +		regulators {
> +			vcc_1v8: DCDC_REG5 {
> +				regulator-name = "vcc_1v8";
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			vcc3v3_sd: SWITCH_REG2 {
> +				regulator-name = "vcc3v3_sd";
> +				regulator-always-on;
> +				regulator-boot-on;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			vccio_sd: LDO_REG5 {
> +				regulator-name = "vccio_sd";
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <3300000>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			vcc_3v3: SWITCH_REG1 {
> +				regulator-name = "vcc_3v3";
> +				regulator-always-on;
> +				regulator-boot-on;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +		};
> +	};
> +
> +	vdd_cpu: regulator at 40 {

you probably need &cpu0 phandles to set this regulator-supply?

> +		compatible = "silergy,syr827";
> +		reg = <0x40>;
> +		fcs,suspend-voltage-selector = <1>;
> +		regulator-name = "vdd_cpu";
> +		regulator-always-on;
> +		regulator-boot-on;
> +		regulator-min-microvolt = <830000>;
> +		regulator-max-microvolt = <1200000>;
> +		regulator-ramp-delay = <2300>;
> +		vin-supply = <&vcc3v3_sys>;
> +
> +		regulator-state-mem {
> +			regulator-off-in-suspend;
> +		};
> +	};
> +};
> +
> +&i2c2 {
> +	status = "okay";
> +
> +	m24c08 at 50 {

I guess eeprom at 50 ?

Heiko




From heiko at sntech.de  Thu Nov 13 15:00:19 2025
From: heiko at sntech.de (Heiko =?UTF-8?B?U3TDvGJuZXI=?=)
Date: Fri, 14 Nov 2025 00:00:19 +0100
Subject: [PATCH 1/6] arm64: dts: rockchip: add mmc aliases for 100ASK DshanPi A1
In-Reply-To: <20251101120010.41729-1-amadeus@jmu.edu.cn>
References: <20251101120010.41729-1-amadeus@jmu.edu.cn>
Message-ID: <1841407.VLH7GnMWUR@diego>

Hi,

Am Samstag, 1. November 2025, 13:00:05 Mitteleurop?ische Normalzeit schrieb Chukun Pan:
> Add missing MMC aliases. Remove the max-frequency property
> from the MMC node, which is already defined in rk3576.dtsi.

please split this into 2 patches, one for the aliases, one for the
max-frequency removal.

Thanks
Heiko

> 
> Signed-off-by: Chukun Pan <amadeus at jmu.edu.cn>
> ---
>  arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts b/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
> index 59c172573cf8..9cbd3fae16ab 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
> @@ -19,6 +19,8 @@ / {
>  	aliases {
>  		ethernet0 = &gmac0;
>  		ethernet1 = &gmac1;
> +		mmc0 = &sdhci;
> +		mmc1 = &sdmmc;
>  	};
>  
>  	chosen {
> @@ -735,7 +737,6 @@ &sai6 {
>  &sdhci {
>  	bus-width = <8>;
>  	full-pwr-cycle-in-suspend;
> -	max-frequency = <200000000>;
>  	mmc-hs400-1_8v;
>  	mmc-hs400-enhanced-strobe;
>  	no-sdio;
> @@ -749,7 +750,6 @@ &sdmmc {
>  	cap-mmc-highspeed;
>  	cap-sd-highspeed;
>  	disable-wp;
> -	max-frequency = <200000000>;
>  	sd-uhs-sdr104;
>  	vmmc-supply = <&vcc_3v3_s3>;
>  	vqmmc-supply = <&vccio_sd_s0>;
> 






From heiko at sntech.de  Thu Nov 13 15:04:22 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 14 Nov 2025 00:04:22 +0100
Subject: [PATCH] arm64: dts: rockchip: clean up devicetree for 9Tripod X3568 v4
In-Reply-To: <20251107133839.300252-1-coiaprant@gmail.com>
References: <20251107133839.300252-1-coiaprant@gmail.com>
Message-ID: <176307502903.495066.16827160196571620255.b4-ty@sntech.de>


On Fri, 07 Nov 2025 21:38:38 +0800, Coia Prant wrote:
> Fix indentation, remove unused SDIO properties, and drop the GMAC clock
> that was used for input direction. The board uses the clock as
> output, so the input clock is not needed.
> 
> 

Applied, thanks!

[1/1] arm64: dts: rockchip: clean up devicetree for 9Tripod X3568 v4
      commit: c1ffe499306b26a61f390b7d83c5703aa8e2af55

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Thu Nov 13 15:04:25 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 14 Nov 2025 00:04:25 +0100
Subject: [PATCH v1] arm64: dts: rockchip: correct assigned-clock-rates spelling
In-Reply-To: <92714b6c-6c0d-4a10-afe4-73ed313c87c0@gmail.com>
References: <92714b6c-6c0d-4a10-afe4-73ed313c87c0@gmail.com>
Message-ID: <176307502904.495066.10732097835351829050.b4-ty@sntech.de>


On Sat, 01 Nov 2025 16:35:26 +0100, Johan Jonker wrote:
> Due to some copy and paste from the manufacturer tree the property
> assigned-clock-rate is missing a letter "s". Correct spelling to
> reduce dtbs_check output.
> 
> 

Applied, thanks!

[1/1] arm64: dts: rockchip: correct assigned-clock-rates spelling
      commit: 76f4f7e04c213eff794ef6dcb1f216a57c6f2a16

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Thu Nov 13 15:04:26 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 14 Nov 2025 00:04:26 +0100
Subject: [PATCH v1] ARM: dts: rockchip: rk3288: move edp assigned-clocks to edp node
In-Reply-To: <7d6fa223-ab90-4c44-9180-54df78467ea5@gmail.com>
References: <7d6fa223-ab90-4c44-9180-54df78467ea5@gmail.com>
Message-ID: <176307502903.495066.8544378087012934104.b4-ty@sntech.de>


On Sun, 02 Nov 2025 00:18:13 +0100, Johan Jonker wrote:
> The rk3288 power-controller node contains an assigned-clocks property
> that conflicts with the bindings. From the git history it shows that they
> wanted to assign the rk3288 EDP_24M clock input centrally before an edp
> node was available. Move the edp assigned-clocks property to the edp node
> to reduce dtbs_check output.
> 
> 
> [...]

Applied, thanks!

[1/1] ARM: dts: rockchip: rk3288: move edp assigned-clocks to edp node
      commit: 10712ce694a67304a99dbba20f8cb146ca5f4fd6

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Thu Nov 13 15:04:27 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 14 Nov 2025 00:04:27 +0100
Subject: [PATCH] arm64: dts: rockchip: Enable USB-C DP Alt for Indiedroid Nova
In-Reply-To: <20251107214724.878955-1-macroalpha82@gmail.com>
References: <20251107214724.878955-1-macroalpha82@gmail.com>
Message-ID: <176307502902.495066.1512477613240846697.b4-ty@sntech.de>


On Fri, 07 Nov 2025 15:47:24 -0600, Chris Morgan wrote:
> Enable the Display Port alt-mode for the USB-C port on the Indiedroid
> Nova.
> 
> Note that while ROCKCHIP_VOP2_EP_DP0 is defined as 10 we need to
> set the address to "a" or else we receive a dtc warning.
> 
> 
> [...]

Applied, thanks!

[1/1] arm64: dts: rockchip: Enable USB-C DP Alt for Indiedroid Nova
      commit: 7230cdc1fc3cd1b6721df1dbf46c1e2403042203

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Thu Nov 13 15:04:21 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 14 Nov 2025 00:04:21 +0100
Subject: (subset) [PATCH 1/6] arm64: dts: rockchip: add mmc aliases for 100ASK DshanPi A1
In-Reply-To: <20251101120010.41729-1-amadeus@jmu.edu.cn>
References: <20251101120010.41729-1-amadeus@jmu.edu.cn>
Message-ID: <176307502906.495066.9339764118786240746.b4-ty@sntech.de>


On Sat, 01 Nov 2025 20:00:05 +0800, Chukun Pan wrote:
> Add missing MMC aliases. Remove the max-frequency property
> from the MMC node, which is already defined in rk3576.dtsi.
> 
> 

Applied, thanks!

[2/6] arm64: dts: rockchip: fixes regulator for 100ASK DshanPi A1
      commit: 0b822c59c826f47dc63d9470b4710bd251266cae
[3/6] arm64: dts: rockchip: fixes ethernet for 100ASK DshanPi A1
      commit: 9c79c9e03547068404cca5139dfea281d655ff90
[4/6] arm64: dts: rockchip: fixes supply for 100ASK DshanPi A1
      commit: 621bb09a76fa12a9e61c9d745ae524db86abf781
[5/6] arm64: dts: rockchip: fixes audio for 100ASK DshanPi A1
      commit: e99d922d37351ddcd6e1d3f4623340db547c8398

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Thu Nov 13 15:04:24 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 14 Nov 2025 00:04:24 +0100
Subject: [PATCH] arm64: dts: rockchip: use SCMI clock id for gpu clock on rk356x
In-Reply-To: <20251105235408.163282-1-heiko@sntech.de>
References: <20251105235408.163282-1-heiko@sntech.de>
Message-ID: <176307502896.495066.1180507445671783497.b4-ty@sntech.de>


On Thu, 06 Nov 2025 00:54:08 +0100, Heiko Stuebner wrote:
> Instead of hard-coding 1, use the more descriptive ID from the binding
> to reference the SCMI clock for the gpu on rk356x.
> 
> 

Applied, thanks!

[1/1] arm64: dts: rockchip: use SCMI clock id for gpu clock on rk356x
      commit: 4c609425988969e46a6d562329f4061c82017945

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Thu Nov 13 15:04:29 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 14 Nov 2025 00:04:29 +0100
Subject: (subset) [PATCH v2 0/4] Fix and improve EEPROM chip descriptions for Radxa ROCK 3C, 5A and 5C
In-Reply-To: <20251112035133.28753-1-naoki@radxa.com>
References: <20251112035133.28753-1-naoki@radxa.com>
Message-ID: <176307502897.495066.5667820718032411897.b4-ty@sntech.de>


On Wed, 12 Nov 2025 03:51:28 +0000, FUKAUMI Naoki wrote:
> This patch series fixes incorrect or missing entries related to the
> eeprom on the Radxa ROCK 3C, 5A, and 5C.
> 
> FUKAUMI Naoki (4):
>   arm64: dts: rockchip: Move the EEPROM to correct I2C bus on Radxa ROCK
>     5A
>   arm64: dts: rockchip: Add eeprom vcc-supply for Radxa ROCK 5A
>   arm64: dts: rockchip: Add eeprom vcc-supply for Radxa ROCK 3C
>   arm64: dts: rockchip: Make eeprom read-only for Radxa ROCK 3C/5A/5C
> 
> [...]

Applied, thanks!

[1/4] arm64: dts: rockchip: Move the EEPROM to correct I2C bus on Radxa ROCK 5A
      commit: 92e6e0b0e595afdda6296c760551ad3ffe9d5231
[2/4] arm64: dts: rockchip: Add eeprom vcc-supply for Radxa ROCK 5A
      commit: 3069ff1930aa71e125874c780ffaa6caeda5800a
[3/4] arm64: dts: rockchip: Add eeprom vcc-supply for Radxa ROCK 3C
      commit: 260316d35cf8f8606c5ed7a349cc92e1e71d8150

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Thu Nov 13 15:04:28 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 14 Nov 2025 00:04:28 +0100
Subject: [PATCH v2 0/3] Fixes and improvements to sdmmc descriptions for Radxa ROCK 5 ITX/5B/5B+/5T/5A/5C
In-Reply-To: <20251111071730.126238-1-naoki@radxa.com>
References: <20251111071730.126238-1-naoki@radxa.com>
Message-ID: <176307502893.495066.1213119327156938500.b4-ty@sntech.de>


On Tue, 11 Nov 2025 07:17:27 +0000, FUKAUMI Naoki wrote:
> This patch series fixes microSD card detection for ROCK 5 ITX/5C and
> improves sdmmc properties for ROCK 5 ITX/5B/5B+/5T/5A/5C.
> 
> FUKAUMI Naoki (3):
>   arm64: dts: rockchip: Fix microSD card detect for Radxa ROCK 5 ITX/5C
>   arm64: dts: rockchip: Add sdmmc pinctrl for Radxa ROCK 5
>     ITX/5B/5B+/5T/5C
>   arm64: dts: rockchip: Remove sdmmc max-frequency for Radxa ROCK 5
>     ITX/5B/5B+/5T
> 
> [...]

Applied, thanks!

[1/3] arm64: dts: rockchip: Fix microSD card detect for Radxa ROCK 5 ITX/5C
      commit: c7a9549ce46e7422e96e2b677ab578b32b3eef25
[2/3] arm64: dts: rockchip: Add sdmmc pinctrl for Radxa ROCK 5 ITX/5B/5B+/5T/5C
      --> merged into patch1 ... property and pinctrl should be in the same patch

[3/3] arm64: dts: rockchip: Remove sdmmc max-frequency for Radxa ROCK 5 ITX/5B/5B+/5T
      commit: 57bd160290f39ee90bc51b4daa224b481d726480

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Thu Nov 13 15:04:23 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 14 Nov 2025 00:04:23 +0100
Subject: [PATCH] devicetree rk3588: enable HDMI audio on Rock 5 ITX
In-Reply-To: <20251110181153.CC62B6732A@verein.lst.de>
References: <20251110181153.CC62B6732A@verein.lst.de>
Message-ID: <176307502898.495066.6660023173872091863.b4-ty@sntech.de>


On Mon, 10 Nov 2025 19:11:53 +0100, Torsten Duwe wrote:
> The Rock 5 ITX only needs enablement for 2 nodes in order to send audio
> on HDMI1, the connector closer to the 12V barrel jack and farther from
> S/PDIF.  It is sufficient to declare the audio injection as okay, and
> to activate I2S6.
> 
> Note that for the other HDMI output it is not that trivial, as the video
> data there originates from the SoC's DisplayPort output DP1 and is only
> converted to HDMI in U7 (an RA620).
> 
> [...]

Applied, thanks!

[1/1] devicetree rk3588: enable HDMI audio on Rock 5 ITX
      commit: 3906f8558838841dad2bb96fc6ca10fe54a99f09

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Thu Nov 13 15:04:20 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 14 Nov 2025 00:04:20 +0100
Subject: [PATCH 1/1] arm64: dts: rockchip: drop reset from rk3576 i2c9 node
In-Reply-To: <20251101140101.302229-1-amadeus@jmu.edu.cn>
References: <20251101140101.302229-1-amadeus@jmu.edu.cn>
Message-ID: <176307502905.495066.14409715879346224898.b4-ty@sntech.de>


On Sat, 01 Nov 2025 22:01:01 +0800, Chukun Pan wrote:
> The reset property is not part of the binding, so drop it.
> It is also not used by the driver, so it was likely copied
> from some vendor-kernel node.
> 
> 

Applied, thanks!

[1/1] arm64: dts: rockchip: drop reset from rk3576 i2c9 node
      commit: 264152a97edf9f1b7ed5372e4033e46108e41422

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Thu Nov 13 15:05:53 2025
From: heiko at sntech.de (Heiko =?UTF-8?B?U3TDvGJuZXI=?=)
Date: Fri, 14 Nov 2025 00:05:53 +0100
Subject: [PATCH 6/6] arm64: dts: rockchip: update 100ASK DshanPi A1 support
In-Reply-To: <20251101120010.41729-6-amadeus@jmu.edu.cn>
References: <20251101120010.41729-1-amadeus@jmu.edu.cn>
 <20251101120010.41729-6-amadeus@jmu.edu.cn>
Message-ID: <2041193.usQuhbGJ8B@diego>

Am Samstag, 1. November 2025, 13:00:10 Mitteleurop?ische Normalzeit schrieb Chukun Pan:
> Enable button, RTC and USB support for the 100ASK DshanPi A1 board.

please split this into 3 patches :-) .

The list above already describes the points to split on.

Thanks
Heiko






From heiko at sntech.de  Thu Nov 13 15:18:15 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 14 Nov 2025 00:18:15 +0100
Subject: [PATCH] arm64: dts: rockchip: disable HS400 on RK3588 Tiger
In-Reply-To: <20251112-tiger-hs200-v1-1-b50adac107c0@cherry.de>
References: <20251112-tiger-hs200-v1-1-b50adac107c0@cherry.de>
Message-ID: <176307584244.496508.13187740741138486595.b4-ty@sntech.de>


On Wed, 12 Nov 2025 16:01:53 +0100, Quentin Schulz wrote:
> We've had reports from the field that some RK3588 Tiger have random
> issues with eMMC errors.
> 
> Applying commit a28352cf2d2f ("mmc: sdhci-of-dwcmshc: Change
> DLL_STRBIN_TAPNUM_DEFAULT to 0x4") didn't help and seemed to have made
> things worse for our board.
> 
> [...]

Applied, thanks!

[1/1] arm64: dts: rockchip: disable HS400 on RK3588 Tiger
      commit: baa18d577cd445145039e731d3de0fa49ca57204

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Thu Nov 13 15:18:16 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 14 Nov 2025 00:18:16 +0100
Subject: [PATCH v3] arm64: dts: rockchip: orangepi-5: fix PCIe 3.3V regulator voltage
In-Reply-To: <cf6e08dfdfbf1c540685d12388baab1326f95d2c.1762165324.git.xakep.amatop@gmail.com>
References: <cf6e08dfdfbf1c540685d12388baab1326f95d2c.1762165324.git.xakep.amatop@gmail.com>
Message-ID: <176307584246.496508.12079514999315183214.b4-ty@sntech.de>


On Mon, 03 Nov 2025 12:27:40 +0200, Mykola Kvach wrote:
> The vcc3v3_pcie20 fixed regulator powers the PCIe device-side 3.3V rail
> for pcie2x1l2 via vpcie3v3-supply. The DTS mistakenly set its
> regulator-min/max-microvolt to 1800000 (1.8 V). Correct both to 3300000
> (3.3 V) to match the rail name, the PCIe/M.2 power requirement, and the
> actual hardware wiring on Orange Pi 5.
> 
> 
> [...]

Applied, thanks!

[1/1] arm64: dts: rockchip: orangepi-5: fix PCIe 3.3V regulator voltage
      commit: b5414520793e68d266fdd97a84989d9831156aad

Please start new threads when sending version x+1 and don't append
that new patch to the old thread (less confusing for tooling like b4).

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Thu Nov 13 15:21:31 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 14 Nov 2025 00:21:31 +0100
Subject: (subset) [PATCH v2 0/2] mmc: sdhci-of-dwcmshc: Add command queue support for Rockchip SOCs
In-Reply-To: <20251031-rockchip-emmc-cqe-support-v2-0-958171f5edad@collabora.com>
References: <20251031-rockchip-emmc-cqe-support-v2-0-958171f5edad@collabora.com>
Message-ID: <176307608061.496957.2197880320790247592.b4-ty@sntech.de>


On Fri, 31 Oct 2025 16:58:22 +0100, Sebastian Reichel wrote:
> Right now at least the recent Rockchip SoCs do not support system
> suspend with the mainline kernel. I'm currently looking into
> improving support for the RK3576 platform.
> 
> On the Sige5 one of the issues is the eMMC controller, which fails
> to suspend when trying to disable CQE support. While investigating
> I found a missing Rockchip quirk in the Rockchip kernel, which is
> needed for CQE. Since the RK3576 DT has been upstreamed with the
> 'supports-cqe' property (RK3588 does not yet have it), we run into
> this problem for that platform.
> 
> [...]

Applied, thanks!

[2/2] arm64: dts: rockchip: add eMMC CQE support for rk3588
      commit: 9d856aa1c81930a5d8df0e29d6cb0faa3fa87206

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Thu Nov 13 15:04:30 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 14 Nov 2025 00:04:30 +0100
Subject: (subset) [PATCH v2 0/2] mmc: sdhci-of-dwcmshc: Add command queue support for Rockchip SOCs
In-Reply-To: <20251031-rockchip-emmc-cqe-support-v2-0-958171f5edad@collabora.com>
References: <20251031-rockchip-emmc-cqe-support-v2-0-958171f5edad@collabora.com>
Message-ID: <176307502900.495066.12322233848584561595.b4-ty@sntech.de>


On Fri, 31 Oct 2025 16:58:22 +0100, Sebastian Reichel wrote:
> Right now at least the recent Rockchip SoCs do not support system
> suspend with the mainline kernel. I'm currently looking into
> improving support for the RK3576 platform.
> 
> On the Sige5 one of the issues is the eMMC controller, which fails
> to suspend when trying to disable CQE support. While investigating
> I found a missing Rockchip quirk in the Rockchip kernel, which is
> needed for CQE. Since the RK3576 DT has been upstreamed with the
> 'supports-cqe' property (RK3588 does not yet have it), we run into
> this problem for that platform.
> 
> [...]

Applied, thanks!

[2/2] arm64: dts: rockchip: add eMMC CQE support for rk3588
      commit: 9d856aa1c81930a5d8df0e29d6cb0faa3fa87206

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Thu Nov 13 15:04:31 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 14 Nov 2025 00:04:31 +0100
Subject: [PATCH] arm64: dts: rockchip: Remove sdmmc max-frequency on RK3588S EVB1 board
In-Reply-To: <1762844673-123776-1-git-send-email-shawn.lin@rock-chips.com>
References: <1762844673-123776-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <176307502894.495066.3909828296621273696.b4-ty@sntech.de>


On Tue, 11 Nov 2025 15:04:33 +0800, Shawn Lin wrote:
> sdmmc on RK3588S EVB1 could work fine under 200Mhz, no need to limit it
> to 150Mhz.
> 
> 

Applied, thanks!

[1/1] arm64: dts: rockchip: Remove sdmmc max-frequency on RK3588S EVB1 board
      commit: f151b74eadc65b14a60577d3d186385d69c4d79a

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From dsimic at manjaro.org  Thu Nov 13 18:00:54 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Fri, 14 Nov 2025 03:00:54 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH 1/2] =?utf-8?q?dt-bindings=3A?==?utf-8?q?_arm=3A?=
 =?utf-8?q?_rockchip=3A?= Asus Tinkerboard 3 and 3S
In-Reply-To: <20251111172003.2324525-2-michael.opdenacker@rootcommit.com>
References: <20251111172003.2324525-1-michael.opdenacker@rootcommit.com> <20251111172003.2324525-2-michael.opdenacker@rootcommit.com>
Message-ID: <e8235ec5-d857-1a0a-7108-3c2b8a5dbed9@manjaro.org>

Hello Michael,

Thanks for this patch!  Please, see some comments below.

On Tuesday, November 11, 2025 18:20 CET, michael.opdenacker at rootcommit.com wrote:
> From: Michael Opdenacker <michael.opdenacker at rootcommit.com>
> 
> Document the compatible strings for Asus Tinkerboard 3 [1] and 3S [2],
> which are SBCs based on the Rockchip 3566 SoC.

For consistency, this should be s/Tinkerboard/Tinker Board/.

> The "3S" version ("S" for "storage") just adds a 16 GB eMMC
> and a "mask ROM" DIP switch to the "3" version.
> 
> Link: https://tinker-board.asus.com/series/tinker-board-3.html [1]
> Link: https://tinker-board.asus.com/series/tinker-board-3s.html [2]

These two lines should read like this, to serve as references, with
an empty line afterwards, of course:

  [1] https://tinker-board.asus.com/series/tinker-board-3.html
  [2] https://tinker-board.asus.com/series/tinker-board-3s.html

> Signed-off-by: Michael Opdenacker <michael.opdenacker at rootcommit.com>
> ---
>  Documentation/devicetree/bindings/arm/rockchip.yaml | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
> index 6aceaa8acbb2..451597a6cffb 100644
> --- a/Documentation/devicetree/bindings/arm/rockchip.yaml
> +++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
> @@ -86,6 +86,17 @@ properties:
>            - const: asus,rk3288-tinker-s
>            - const: rockchip,rk3288
>  
> +      - description: Asus Tinker board 3

This should be s/Tinker board/Tinker Board/, because it's actually
a proper noun/name.

> +        items:
> +          - const: asus,rk3566-tinker-3
> +          - const: rockchip,rk3566
> +
> +      - description: Asus Tinker board 3S

The same as above.

> +        items:
> +          - const: asus,rk3566-tinker-3s
> +          - const: asus,rk3566-tinker-3
> +          - const: rockchip,rk3566
> +
>        - description: Beelink A1
>          items:
>            - const: azw,beelink-a1



From dsimic at manjaro.org  Thu Nov 13 18:26:47 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Fri, 14 Nov 2025 03:26:47 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH 2/2] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= add Tinkerboard 3 and 3S device tree
In-Reply-To: <20251111172003.2324525-3-michael.opdenacker@rootcommit.com>
References: <20251111172003.2324525-1-michael.opdenacker@rootcommit.com> <20251111172003.2324525-3-michael.opdenacker@rootcommit.com>
Message-ID: <dbacc018-2631-6606-7562-27371cf45d6f@manjaro.org>

Hello Michael,

Thanks for this patch!  Please, see some comments below.

On Tuesday, November 11, 2025 18:20 CET, michael.opdenacker at rootcommit.com wrote:
> From: Michael Opdenacker <michael.opdenacker at rootcommit.com>
> 
> Add initial device tree support for Asus Tinkerboard 3 [1] and 3S [2],
> which are SBCs based on the Rockchip 3566 SoC.

For consistency and because it's a proper noun, this should be
s/Tinkerboard/Tinker Board/.

> The "3S" version ("S" for "storage") just adds a 16 GB eMMC
> and a "mask ROM" DIP switch (to mask the eMMC and enter "Mask ROM"
> mode for recovery) to the "3" version.
> 
> This adds support for:
> - Debug UART (/dev/ttyS2)
> - SD card (/dev/mmcblk1)
> - eMMC (/dev/mmcblk0, only on Tinkerboard 3S)
> - I2C:
>   - i2c0 (internal bus with a PMIC and regulators)
>   - i2c2 (internal bus with an at24 eeprom and an RTC device)
> - USB 2.0 ports
> - 2 GPIO LEDS
> 
> Link: https://tinker-board.asus.com/series/tinker-board-3.html [1]
> Link: https://tinker-board.asus.com/series/tinker-board-3s.html [2]

These two lines should read like this, to serve as references, with
an empty line afterwards, of course:

  [1] https://tinker-board.asus.com/series/tinker-board-3.html
  [2] https://tinker-board.asus.com/series/tinker-board-3s.html

> Signed-off-by: Michael Opdenacker <michael.opdenacker at rootcommit.com>
> ---
>  arch/arm64/boot/dts/rockchip/Makefile         |   2 +
>  .../boot/dts/rockchip/rk3566-tinker-3.dts     |  14 +
>  .../boot/dts/rockchip/rk3566-tinker-3.dtsi    | 264 ++++++++++++++++++
>  .../boot/dts/rockchip/rk3566-tinker-3s.dts    |  30 ++
>  4 files changed, 310 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-tinker-3.dts
>  create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-tinker-3.dtsi
>  create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-tinker-3s.dts
> 
> diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
> index ad684e3831bc..381831cab20c 100644
> --- a/arch/arm64/boot/dts/rockchip/Makefile
> +++ b/arch/arm64/boot/dts/rockchip/Makefile
> @@ -130,6 +130,8 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-lubancat-1.dtb
>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-nanopi-r3s.dtb
>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-bigtreetech-cb2-manta.dtb
>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-bigtreetech-pi2.dtb
> +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-tinker-3.dtb
> +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-tinker-3s.dtb

The board .dts/.dtb files should include "-board", i.e. these should
be "rk3566-tinker-board-3.dtb" and "rk3566-tinker-board-3s.dtb"
instead, because there's no real need for shortening.  These boards
are simply named "Tinker Board", which should be preserved.

>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-bpi-r2-pro.dtb
>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-v10.dtb
>  dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-fastrhino-r66s.dtb
> diff --git a/arch/arm64/boot/dts/rockchip/rk3566-tinker-3.dts b/arch/arm64/boot/dts/rockchip/rk3566-tinker-3.dts
> new file mode 100644
> index 000000000000..938af35b9004
> --- /dev/null
> +++ b/arch/arm64/boot/dts/rockchip/rk3566-tinker-3.dts
> @@ -0,0 +1,14 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +/*
> + * Copyright (C) 2025 Michael Opdenacker <michael.opdenacker at rootcommit.com>
> + */
> +
> +/dts-v1/;
> +
> +#include "rk3566-tinker-3.dtsi"

The same comment from above about the naming applies here (as well
as in other places), so we should have "rk3566-tinker-board-3.dtsi"
here instead.

> +
> +/ {
> +	model = "Rockchip RK3566 Asus Tinker Board 3";

For consistency and to avoid redundancy, the "Rockchip RK3566"
part should be removed.

> +	compatible = "asus,rk3566-tinker-3", "rockchip,rk3566";

Actually, the compatible should be "asus,rk3566-tinker-board-3"
instead, because there's no real need for shortening it.

> +};
> +
> diff --git a/arch/arm64/boot/dts/rockchip/rk3566-tinker-3.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-tinker-3.dtsi
> new file mode 100644
> index 000000000000..45269d33b0cb
> --- /dev/null
> +++ b/arch/arm64/boot/dts/rockchip/rk3566-tinker-3.dtsi

This .dtsi file should be named "rk3566-tinker-board-3.dtsi" instead,
because there's no need for shortening.  Please see also a comment
above, regarding the naming.

[snip]

> diff --git a/arch/arm64/boot/dts/rockchip/rk3566-tinker-3s.dts b/arch/arm64/boot/dts/rockchip/rk3566-tinker-3s.dts
> new file mode 100644
> index 000000000000..ba7efd702050
> --- /dev/null
> +++ b/arch/arm64/boot/dts/rockchip/rk3566-tinker-3s.dts

This .dts file should be named "rk3566-tinker-board-3s.dts" instead,
because there's no need for shortening.

> @@ -0,0 +1,30 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +/*
> + * Copyright (C) 2025 Michael Opdenacker <michael.opdenacker at rootcommit.com>
> + */
> +
> +/dts-v1/;
> +
> +#include "rk3566-tinker-3.dtsi"
> +
> +/ {
> +	model = "Rockchip RK3566 Asus Tinker Board 3S";

For consistency and to avoid redundancy, the "Rockchip RK3566"
part should be removed.

> +	compatible = "asus,rk3566-tinker-3s", "asus,rk3566-tinker-3", "rockchip,rk3566";

The compatibles should be as below instead, for the same reasons
as already explained above.

  "asus,rk3566-tinker-board-3s", "asus,rk3566-tinker-board-3", "rockchip,rk3566"

Though, perhaps it would be better to not include the "asus,rk3566-
tinker-board-3" part, because I think it's pretty much redundant.

[snip]



From vignesh.raman at collabora.com  Thu Nov 13 19:00:49 2025
From: vignesh.raman at collabora.com (Vignesh Raman)
Date: Fri, 14 Nov 2025 08:30:49 +0530
Subject: [PATCH v1 0/2] drm/ci: uprev IGT and enable apq8016, apq8096
Message-ID: <20251114030056.1139570-1-vignesh.raman@collabora.com>

This series includes,
- Adapting to recent changes in Mesa CI, such as:
   - LAVA overlay-based firmware handling
   - Container/job rule separation
   - Removal of the python-artifacts job
   - Use lava-job-submitter for submitting jobs to LAVA
   - Various other CI improvements
- Move bare-metal jobs for apq8016 and apq8096 to LAVA, as these devices
  are migrated to Collabora LAVA farm.

Pipeline: https://gitlab.freedesktop.org/vigneshraman/msm/-/pipelines/1546424
MR: https://gitlab.freedesktop.org/drm/msm/-/merge_requests/200

There will be a follow up series to update expectation files for the
other jobs.

Vignesh Raman (2):
  drm/ci: uprev mesa
  drm/ci: Move qualcomm baremetal jobs to lava

 drivers/gpu/drm/ci/arm64.config               |   1 +
 drivers/gpu/drm/ci/build.yml                  |  22 ++--
 drivers/gpu/drm/ci/container.yml              |  28 +++--
 drivers/gpu/drm/ci/gitlab-ci.yml              |  95 ++++++++++++----
 drivers/gpu/drm/ci/igt_runner.sh              |   4 +-
 drivers/gpu/drm/ci/image-tags.yml             |  22 ++--
 drivers/gpu/drm/ci/lava-submit.sh             | 101 ++++++++----------
 drivers/gpu/drm/ci/static-checks.yml          |   1 +
 drivers/gpu/drm/ci/test.yml                   |  80 ++++++--------
 .../gpu/drm/ci/xfails/msm-apq8016-fails.txt   |   4 +
 .../gpu/drm/ci/xfails/msm-apq8096-fails.txt   |   2 +
 11 files changed, 213 insertions(+), 147 deletions(-)

-- 
2.51.0



From vignesh.raman at collabora.com  Thu Nov 13 19:00:50 2025
From: vignesh.raman at collabora.com (Vignesh Raman)
Date: Fri, 14 Nov 2025 08:30:50 +0530
Subject: [PATCH v1 1/2] drm/ci: uprev mesa
In-Reply-To: <20251114030056.1139570-1-vignesh.raman@collabora.com>
References: <20251114030056.1139570-1-vignesh.raman@collabora.com>
Message-ID: <20251114030056.1139570-2-vignesh.raman@collabora.com>

Uprev mesa to adapt to the latest changes in Mesa CI, including support
for firmware via LAVA overlays, removal of the python-artifacts job,
split container and build rules, use lava-job-submitter container,
and various misc fixes.

Co-developed-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>
Signed-off-by: Vignesh Raman <vignesh.raman at collabora.com>
---
 drivers/gpu/drm/ci/build.yml         |  22 +++---
 drivers/gpu/drm/ci/container.yml     |  28 ++++++--
 drivers/gpu/drm/ci/gitlab-ci.yml     |  95 ++++++++++++++++++++-----
 drivers/gpu/drm/ci/igt_runner.sh     |   4 +-
 drivers/gpu/drm/ci/image-tags.yml    |  22 +++---
 drivers/gpu/drm/ci/lava-submit.sh    | 101 +++++++++++++--------------
 drivers/gpu/drm/ci/static-checks.yml |   1 +
 drivers/gpu/drm/ci/test.yml          |  18 +++--
 8 files changed, 186 insertions(+), 105 deletions(-)

diff --git a/drivers/gpu/drm/ci/build.yml b/drivers/gpu/drm/ci/build.yml
index af27ff5de369..efbcaae49807 100644
--- a/drivers/gpu/drm/ci/build.yml
+++ b/drivers/gpu/drm/ci/build.yml
@@ -1,6 +1,6 @@
 .build:
   extends:
-    - .container+build-rules
+    - .build-rules
   stage: build-only
   artifacts:
     paths:
@@ -133,6 +133,10 @@ debian-arm32-asan:
   rules:
     - when: never
 
+debian-x86_64-msan:
+  rules:
+    - when: never
+
 debian-arm64:
   rules:
     - when: never
@@ -153,7 +157,7 @@ debian-arm64-ubsan:
   rules:
     - when: never
 
-debian-build-testing:
+debian-build-x86_64:
   rules:
     - when: never
 
@@ -177,31 +181,31 @@ debian-release:
   rules:
     - when: never
 
-debian-s390x:
+debian-riscv64:
   rules:
     - when: never
 
-debian-testing:
+debian-s390x:
   rules:
     - when: never
 
-debian-testing-asan:
+debian-vulkan:
   rules:
     - when: never
 
-debian-testing-msan:
+debian-x86_32:
   rules:
     - when: never
 
-debian-testing-ubsan:
+debian-x86_64:
   rules:
     - when: never
 
-debian-vulkan:
+debian-x86_64-asan:
   rules:
     - when: never
 
-debian-x86_32:
+debian-x86_64-ubsan:
   rules:
     - when: never
 
diff --git a/drivers/gpu/drm/ci/container.yml b/drivers/gpu/drm/ci/container.yml
index 5f90508578a3..ce6007a45a07 100644
--- a/drivers/gpu/drm/ci/container.yml
+++ b/drivers/gpu/drm/ci/container.yml
@@ -5,21 +5,29 @@
 
 debian/x86_64_build-base:
   variables:
-    EXTRA_LOCAL_PACKAGES: "libcairo-dev libdw-dev libjson-c-dev libkmod2 libkmod-dev libpciaccess-dev libproc2-dev libudev-dev libunwind-dev python3-docutils bc python3-ply libssl-dev bc"
+    EXTRA_LOCAL_PACKAGES: "libcairo-dev libdw-dev libjson-c-dev libkmod-dev libpciaccess-dev libproc2-dev libudev-dev libunwind-dev python3-docutils bc python3-ply libssl-dev bc"
+
+debian/arm64_build:
+  variables:
+    EXTRA_LOCAL_PACKAGES: "libcairo-dev libdw-dev libjson-c-dev libproc2-dev libkmod-dev libpciaccess-dev libudev-dev libunwind-dev python3-docutils libssl-dev crossbuild-essential-armhf libkmod-dev:armhf libproc2-dev:armhf libunwind-dev:armhf libdw-dev:armhf libpixman-1-dev:armhf libcairo-dev:armhf libudev-dev:armhf libjson-c-dev:armhf"
 
 debian/x86_64_test-gl:
   variables:
-    EXTRA_LOCAL_PACKAGES: "jq libasound2 libcairo2 libdw1 libglib2.0-0 libjson-c5 libkmod-dev libkmod2 libgles2 libproc2-dev"
+    EXTRA_LOCAL_PACKAGES: "jq libasound2t64 libcairo2 libdw1t64 libglib2.0-0t64 libjson-c5 libkmod2 libgles2 libdrm-nouveau2 libdrm-amdgpu1"
 
-debian/arm64_build:
+debian/arm64_test-gl:
   variables:
-    EXTRA_LOCAL_PACKAGES: "libcairo-dev libdw-dev libjson-c-dev libproc2-dev libkmod2 libkmod-dev libpciaccess-dev libudev-dev libunwind-dev python3-docutils libssl-dev crossbuild-essential-armhf libkmod-dev:armhf libproc2-dev:armhf libunwind-dev:armhf libdw-dev:armhf libpixman-1-dev:armhf libcairo-dev:armhf libudev-dev:armhf libjson-c-dev:armhf"
+    EXTRA_LOCAL_PACKAGES: "jq libasound2t64 libcairo2 libdw1t64 libglib2.0-0t64 libjson-c5 libkmod2 libgles2 libdrm-nouveau2 libdrm-amdgpu1"
 
-.kernel+rootfs:
+debian/arm32_test-gl:
   variables:
-    EXTRA_LOCAL_PACKAGES: "jq libasound2 libcairo2 libdw1 libglib2.0-0 libjson-c5"
+    EXTRA_LOCAL_PACKAGES: "jq libasound2t64 libcairo2 libdw1t64 libglib2.0-0t64 libjson-c5 libkmod2 libgles2 libdrm-nouveau2 libdrm-amdgpu1 libunwind8"
 
 # Disable container jobs that we won't use
+alpine/x86_64_build:
+  rules:
+    - when: never
+
 debian/arm64_test-vk:
   rules:
     - when: never
@@ -28,6 +36,10 @@ debian/baremetal_arm32_test-gl:
   rules:
     - when: never
 
+debian/baremetal_arm64_test-gl:
+  rules:
+    - when: never
+
 debian/baremetal_arm64_test-vk:
   rules:
     - when: never
@@ -36,6 +48,10 @@ debian/ppc64el_build:
   rules:
     - when: never
 
+debian/riscv64_build:
+  rules:
+    - when: never
+
 debian/s390x_build:
   rules:
     - when: never
diff --git a/drivers/gpu/drm/ci/gitlab-ci.yml b/drivers/gpu/drm/ci/gitlab-ci.yml
index 56638814bb28..e23a9110008c 100644
--- a/drivers/gpu/drm/ci/gitlab-ci.yml
+++ b/drivers/gpu/drm/ci/gitlab-ci.yml
@@ -1,6 +1,6 @@
 variables:
   DRM_CI_PROJECT_PATH: &drm-ci-project-path mesa/mesa
-  DRM_CI_COMMIT_SHA: &drm-ci-commit-sha 02337aec715c25dae7ff2479d986f831c77fe536
+  DRM_CI_COMMIT_SHA: &drm-ci-commit-sha f07dab189928ee65865ef9cefcaa4eff05da99b5
 
   UPSTREAM_REPO: https://gitlab.freedesktop.org/drm/kernel.git
   TARGET_BRANCH: drm-next
@@ -11,7 +11,7 @@ variables:
   DEQP_RUNNER_GIT_TAG: v0.20.0
 
   FDO_UPSTREAM_REPO: helen.fornazier/linux   # The repo where the git-archive daily runs
-  MESA_TEMPLATES_COMMIT: &ci-templates-commit c6aeb16f86e32525fa630fb99c66c4f3e62fc3cb
+  MESA_TEMPLATES_COMMIT: &ci-templates-commit aec7a6ce7bb38902c70641526f6611e27141784a
   DRM_CI_PROJECT_URL: https://gitlab.freedesktop.org/${DRM_CI_PROJECT_PATH}
   CI_PRE_CLONE_SCRIPT: |-
           set -o xtrace
@@ -30,6 +30,8 @@ variables:
   S3_GITCACHE_BUCKET: git-cache
   # Bucket for the pipeline artifacts pushed to S3
   S3_ARTIFACTS_BUCKET: artifacts
+  # Base path used for various artifacts
+  S3_BASE_PATH: "${S3_HOST}/${S3_KERNEL_BUCKET}"
   # per-pipeline artifact storage on MinIO
   PIPELINE_ARTIFACTS_BASE: ${S3_HOST}/${S3_ARTIFACTS_BUCKET}/${CI_PROJECT_PATH}/${CI_PIPELINE_ID}
   # per-job artifact storage on MinIO
@@ -44,6 +46,8 @@ variables:
   ARTIFACTS_BASE_URL: https://${CI_PROJECT_ROOT_NAMESPACE}.${CI_PAGES_DOMAIN}/-/${CI_PROJECT_NAME}/-/jobs/${CI_JOB_ID}/artifacts
   # Python scripts for structured logger
   PYTHONPATH: "$PYTHONPATH:$CI_PROJECT_DIR/install"
+  # Mesa-specific variables that shouldn't be forwarded to DUTs and crosvm
+  CI_EXCLUDE_ENV_VAR_REGEX: 'SCRIPTS_DIR|RESULTS_DIR'
 
 
 default:
@@ -84,10 +88,11 @@ include:
   - project: *drm-ci-project-path
     ref: *drm-ci-commit-sha
     file:
+      - '/.gitlab-ci/bare-metal/gitlab-ci.yml'
       - '/.gitlab-ci/build/gitlab-ci.yml'
       - '/.gitlab-ci/container/gitlab-ci.yml'
       - '/.gitlab-ci/farm-rules.yml'
-      - '/.gitlab-ci/lava/lava-gitlab-ci.yml'
+      - '/.gitlab-ci/lava/gitlab-ci.yml'
       - '/.gitlab-ci/test-source-dep.yml'
       - '/.gitlab-ci/test/gitlab-ci.yml'
       - '/src/amd/ci/gitlab-ci-inc.yml'
@@ -147,10 +152,10 @@ stages:
     - if: &is-merge-attempt $GITLAB_USER_LOGIN == "marge-bot" && $CI_PIPELINE_SOURCE == "merge_request_event"
     # post-merge pipeline
     - if: &is-post-merge $GITLAB_USER_LOGIN == "marge-bot" && $CI_PIPELINE_SOURCE == "push"
-    # Pre-merge pipeline
-    - if: &is-pre-merge $CI_PIPELINE_SOURCE == "merge_request_event"
+    # Pre-merge pipeline (because merge pipelines are already caught above)
+    - if: &is-merge-request $CI_PIPELINE_SOURCE == "merge_request_event"
     # Push to a branch on a fork
-    - if: &is-fork-push $CI_PIPELINE_SOURCE == "push"
+    - if: &is-push-to-fork $CI_PIPELINE_SOURCE == "push"
     # nightly pipeline
     - if: &is-scheduled-pipeline $CI_PIPELINE_SOURCE == "schedule"
     # pipeline for direct pushes that bypassed the CI
@@ -160,17 +165,59 @@ stages:
 # Rules applied to every job in the pipeline
 .common-rules:
   rules:
-    - if: *is-fork-push
+    - if: *is-push-to-fork
       when: manual
 
-
 .never-post-merge-rules:
   rules:
     - if: *is-post-merge
       when: never
 
 
-.container+build-rules:
+# Note: make sure the branches in this list are the same as in
+# `.build-only-delayed-rules` below.
+.container-rules:
+  rules:
+    - !reference [.common-rules, rules]
+    # Run when re-enabling a disabled farm, but not when disabling it
+    - !reference [.disable-farm-mr-rules, rules]
+    # Never run immediately after merging, as we just ran everything
+    - !reference [.never-post-merge-rules, rules]
+    # Only rebuild containers in merge pipelines if any tags have been
+    # changed, else we'll just use the already-built containers
+    - if: *is-merge-attempt
+      changes: &image_tags_path
+        - drivers/gpu/drm/ci/image-tags.yml
+      when: on_success
+    # Skip everything for pre-merge and merge pipelines which don't change
+    # anything in the build; we only do this for marge-bot and not user
+    # pipelines in a MR, because we might still need to run it to copy the
+    # container into the user's namespace.
+    - if: *is-merge-attempt
+      when: never
+    # Any MR pipeline which changes image-tags.yml needs to be able to
+    # rebuild the containers
+    - if: *is-merge-request
+      changes: *image_tags_path
+      when: manual
+    # ... however for MRs running inside the user namespace, we may need to
+    # run these jobs to copy the container images from upstream
+    - if: *is-merge-request
+      when: manual
+    # Build everything after someone bypassed the CI
+    - if: *is-direct-push
+      when: manual
+    # Scheduled pipelines reuse already-built containers
+    - if: *is-scheduled-pipeline
+      when: never
+    # Allow building everything in fork pipelines, but build nothing unless
+    # manually triggered
+    - when: manual
+
+
+# Note: make sure the branches in this list are the same as in
+# `.build-only-delayed-rules` below.
+.build-rules:
   rules:
     - !reference [.common-rules, rules]
     # Run when re-enabling a disabled farm, but not when disabling it
@@ -181,7 +228,7 @@ stages:
     - if: *is-merge-attempt
       when: on_success
     # Same as above, but for pre-merge pipelines
-    - if: *is-pre-merge
+    - if: *is-merge-request
       when: manual
     # Build everything after someone bypassed the CI
     - if: *is-direct-push
@@ -197,7 +244,7 @@ stages:
 # Repeat of the above but with `when: on_success` replaced with
 # `when: delayed` + `start_in:`, for build-only jobs.
 # Note: make sure the branches in this list are the same as in
-# `.container+build-rules` above.
+# `.build-rules` above.
 .build-only-delayed-rules:
   rules:
     - !reference [.common-rules, rules]
@@ -210,7 +257,7 @@ stages:
       when: delayed
       start_in: &build-delay 5 minutes
     # Same as above, but for pre-merge pipelines
-    - if: *is-pre-merge
+    - if: *is-merge-request
       when: manual
     # Build everything after someone bypassed the CI
     - if: *is-direct-push
@@ -237,11 +284,6 @@ stages:
       - _build/meson-logs/strace
 
 
-python-artifacts:
-  variables:
-    GIT_DEPTH: 10
-
-
 # Git archive
 make-git-archive:
   extends:
@@ -273,7 +315,7 @@ sanity:
   tags:
     - $FDO_RUNNER_JOB_PRIORITY_TAG_X86_64
   rules:
-    - if: *is-pre-merge
+    - if: *is-merge-request
       when: on_success
     - when: never
   variables:
@@ -284,7 +326,6 @@ sanity:
     - |
       set -eu
       image_tags=(
-        ALPINE_X86_64_LAVA_SSH_TAG
         CONTAINER_TAG
         DEBIAN_BASE_TAG
         DEBIAN_BUILD_TAG
@@ -347,3 +388,19 @@ linkcheck-docs:
 test-docs:
    rules:
     - when: never
+
+.ci-tron-x86_64-test-vk:
+   rules:
+    - when: never
+
+.ci-tron-x86_64-test-gl-manual:
+   rules:
+    - when: never
+
+.ci-tron-arm64-test-gl:
+   rules:
+    - when: never
+
+.ci-tron-x86_64-test-gl:
+   rules:
+    - when: never
diff --git a/drivers/gpu/drm/ci/igt_runner.sh b/drivers/gpu/drm/ci/igt_runner.sh
index b24d4bc53cda..1c01bda52237 100755
--- a/drivers/gpu/drm/ci/igt_runner.sh
+++ b/drivers/gpu/drm/ci/igt_runner.sh
@@ -1,6 +1,8 @@
-#!/bin/sh
+#!/usr/bin/env bash
 # SPDX-License-Identifier: MIT
 
+. "${SCRIPTS_DIR}/setup-test-env.sh"
+
 set -ex
 
 export IGT_FORCE_DRIVER=${DRIVER_NAME}
diff --git a/drivers/gpu/drm/ci/image-tags.yml b/drivers/gpu/drm/ci/image-tags.yml
index 7acc2e2a8eaa..1e6bcb166790 100644
--- a/drivers/gpu/drm/ci/image-tags.yml
+++ b/drivers/gpu/drm/ci/image-tags.yml
@@ -1,18 +1,22 @@
 variables:
-   CONTAINER_TAG: "20250502-mesa-uprev"
-   DEBIAN_BASE_TAG: "${CONTAINER_TAG}"
+   CONTAINER_TAG: "20251113-mesa-uprev"
+
+   DEBIAN_BUILD_BASE_TAG: "${CONTAINER_TAG}"
    DEBIAN_BUILD_TAG: "${CONTAINER_TAG}"
+   DEBIAN_TEST_BASE_TAG: "${CONTAINER_TAG}"
 
    DEBIAN_TEST_GL_TAG: "${CONTAINER_TAG}"
    # default kernel for rootfs before injecting the current kernel tree
-   KERNEL_TAG: "v6.14-mesa-0bdd"
+   KERNEL_TAG: "v6.16-mesa-9d85"
    KERNEL_REPO: "gfx-ci/linux"
-   PKG_REPO_REV: "95bf62c"
-
-   DEBIAN_PYUTILS_TAG: "${CONTAINER_TAG}"
+   PKG_REPO_REV: "0d2527f6"
+   FIRMWARE_TAG: "36f9bbfa"
+   FIRMWARE_REPO: "gfx-ci/firmware"
 
    ALPINE_X86_64_BUILD_TAG: "${CONTAINER_TAG}"
-   ALPINE_X86_64_LAVA_SSH_TAG: "${CONTAINER_TAG}"
 
-   CONDITIONAL_BUILD_ANGLE_TAG: 384145a4023315dae658259bee07c43a
-   CONDITIONAL_BUILD_PIGLIT_TAG: a19e424b8a3f020dbf1b9dd29f220a4f
+   CONDITIONAL_BUILD_ANGLE_TAG: 2388089f6225e4b5542d395cdf23de2f
+   CONDITIONAL_BUILD_CROSVM_TAG: 4079babd375b09761d59eacb25a0598a
+   CONDITIONAL_BUILD_PIGLIT_TAG: 21ab2c66f54777163dd038dc4cfcfde6
+
+   CROSVM_TAG: ${CONDITIONAL_BUILD_CROSVM_TAG}
diff --git a/drivers/gpu/drm/ci/lava-submit.sh b/drivers/gpu/drm/ci/lava-submit.sh
index a295102c3468..405055aa9cc4 100755
--- a/drivers/gpu/drm/ci/lava-submit.sh
+++ b/drivers/gpu/drm/ci/lava-submit.sh
@@ -3,27 +3,18 @@
 # shellcheck disable=SC2086 # we want word splitting
 # shellcheck disable=SC1091 # paths only become valid at runtime
 
-# If we run in the fork (not from mesa or Marge-bot), reuse mainline kernel and rootfs, if exist.
-_check_artifact_path() {
-	_url="https://${1}/${2}"
-	if curl -s -o /dev/null -I -L -f --retry 4 --retry-delay 15 "${_url}"; then
-		echo -n "${_url}"
-	fi
-}
+# shellcheck disable=SC1090
+source "${FDO_CI_BASH_HELPERS}"
 
-get_path_to_artifact() {
-	_mainline_artifact="$(_check_artifact_path ${BASE_SYSTEM_MAINLINE_HOST_PATH} ${1})"
-	if [ -n "${_mainline_artifact}" ]; then
-		echo -n "${_mainline_artifact}"
-		return
-	fi
-	_fork_artifact="$(_check_artifact_path ${BASE_SYSTEM_FORK_HOST_PATH} ${1})"
-	if [ -n "${_fork_artifact}" ]; then
-		echo -n "${_fork_artifact}"
-		return
-	fi
+fdo_log_section_start_collapsed prepare_rootfs "Preparing root filesystem"
+
+set -ex
+
+# If we run in the fork (not from mesa or Marge-bot), reuse mainline kernel and rootfs, if exist.
+ROOTFS_URL="$(fdo_find_s3_path "$LAVA_ROOTFS_PATH")" ||
+{
 	set +x
-	error "Sorry, I couldn't find a viable built path for ${1} in either mainline or a fork." >&2
+	fdo_log_section_error "Sorry, I couldn't find a viable built path for ${LAVA_ROOTFS_PATH} in either mainline or a fork." >&2
 	echo "" >&2
 	echo "If you're working on CI, this probably means that you're missing a dependency:" >&2
 	echo "this job ran ahead of the job which was supposed to upload that artifact." >&2
@@ -35,38 +26,51 @@ get_path_to_artifact() {
 	exit 1
 }
 
-. "${SCRIPTS_DIR}/setup-test-env.sh"
-
-section_start prepare_rootfs "Preparing root filesystem"
-
-set -ex
-
-ROOTFS_URL="$(get_path_to_artifact lava-rootfs.tar.zst)"
-[ $? != 1 ] || exit 1
-
 rm -rf results
-mkdir -p results/job-rootfs-overlay/
+mkdir results
 
-artifacts/ci-common/export-gitlab-job-env-for-dut.sh \
-    > results/job-rootfs-overlay/set-job-env-vars.sh
-cp artifacts/ci-common/init-*.sh results/job-rootfs-overlay/
-cp "$SCRIPTS_DIR"/setup-test-env.sh results/job-rootfs-overlay/
+fdo_filter_env_vars > dut-env-vars.sh
+# Set SCRIPTS_DIR to point to the Mesa install we download for the DUT
+echo "export SCRIPTS_DIR='$CI_PROJECT_DIR/install'" >> dut-env-vars.sh
 
-tar zcf job-rootfs-overlay.tar.gz -C results/job-rootfs-overlay/ .
-ci-fairy s3cp --token-file "${S3_JWT_FILE}" job-rootfs-overlay.tar.gz "https://${JOB_ROOTFS_OVERLAY_PATH}"
+fdo_log_section_end prepare_rootfs
 
 # Prepare env vars for upload.
-section_switch variables "Environment variables passed through to device:"
-cat results/job-rootfs-overlay/set-job-env-vars.sh
+fdo_log_section_start_collapsed variables "Environment variables passed through to device:"
+cat dut-env-vars.sh
+fdo_log_section_end variables
 
-section_switch lava_submit "Submitting job for scheduling"
+fdo_log_section_start_collapsed lava_submit "Submitting job for scheduling"
 
 touch results/lava.log
 tail -f results/lava.log &
 # Ensure that we are printing the commands that are being executed,
 # making it easier to debug the job in case it fails.
 set -x
-PYTHONPATH=artifacts/ artifacts/lava/lava_job_submitter.py \
+
+# List of optional overlays
+LAVA_EXTRA_OVERLAYS=()
+if [ -n "${LAVA_FIRMWARE:-}" ]; then
+    for fw in $LAVA_FIRMWARE; do
+        LAVA_EXTRA_OVERLAYS+=(
+            - append-overlay
+              --name=linux-firmware
+              --url="https://${S3_BASE_PATH}/${FIRMWARE_REPO}/${fw}-${FIRMWARE_TAG}.tar"
+              --path="/"
+              --format=tar
+        )
+    done
+fi
+LAVA_EXTRA_OVERLAYS+=(
+    - append-overlay \
+      --name=kernel-build \
+      --url="${FDO_HTTP_CACHE_URI:-}https://${PIPELINE_ARTIFACTS_BASE}/${DEBIAN_ARCH}/kernel-files.tar.zst" \
+      --compression=zstd \
+      --path="${CI_PROJECT_DIR}" \
+      --format=tar \
+)
+
+lava-job-submitter \
 	--farm "${FARM}" \
 	--device-type "${DEVICE_TYPE}" \
 	--boot-method "${BOOT_METHOD}" \
@@ -75,9 +79,8 @@ PYTHONPATH=artifacts/ artifacts/lava/lava_job_submitter.py \
 	--pipeline-info "$CI_JOB_NAME: $CI_PIPELINE_URL on $CI_COMMIT_REF_NAME ${CI_NODE_INDEX}/${CI_NODE_TOTAL}" \
 	--rootfs-url "${ROOTFS_URL}" \
 	--kernel-url-prefix "https://${PIPELINE_ARTIFACTS_BASE}/${DEBIAN_ARCH}" \
-	--kernel-external "${EXTERNAL_KERNEL_TAG}" \
-	--first-stage-init artifacts/ci-common/init-stage1.sh \
 	--dtb-filename "${DTB}" \
+	--env-file dut-env-vars.sh \
 	--jwt-file "${S3_JWT_FILE}" \
 	--kernel-image-name "${KERNEL_IMAGE_NAME}" \
 	--kernel-image-type "${KERNEL_IMAGE_TYPE}" \
@@ -86,20 +89,10 @@ PYTHONPATH=artifacts/ artifacts/lava/lava_job_submitter.py \
 	--mesa-job-name "$CI_JOB_NAME" \
 	--structured-log-file "results/lava_job_detail.json" \
 	--ssh-client-image "${LAVA_SSH_CLIENT_IMAGE}" \
+	--project-dir "${CI_PROJECT_DIR}" \
 	--project-name "${CI_PROJECT_NAME}" \
-	--starting-section "${CURRENT_SECTION}" \
+	--starting-section lava_submit \
 	--job-submitted-at "${CI_JOB_STARTED_AT}" \
-	- append-overlay \
-		--name=kernel-build \
-		--url="${FDO_HTTP_CACHE_URI:-}https://${PIPELINE_ARTIFACTS_BASE}/${DEBIAN_ARCH}/kernel-files.tar.zst" \
-		--compression=zstd \
-		--path="${CI_PROJECT_DIR}" \
-		--format=tar \
-	- append-overlay \
-		--name=job-overlay \
-		--url="https://${JOB_ROOTFS_OVERLAY_PATH}" \
-		--compression=gz \
-		--path="/" \
-		--format=tar \
+	"${LAVA_EXTRA_OVERLAYS[@]}" \
 	- submit \
 	>> results/lava.log
diff --git a/drivers/gpu/drm/ci/static-checks.yml b/drivers/gpu/drm/ci/static-checks.yml
index 13ffa827b7fa..712d3efe99c6 100644
--- a/drivers/gpu/drm/ci/static-checks.yml
+++ b/drivers/gpu/drm/ci/static-checks.yml
@@ -1,4 +1,5 @@
 check-patch:
+  stage: static-checks
   extends:
     - .build
     - .use-debian/x86_64_build
diff --git a/drivers/gpu/drm/ci/test.yml b/drivers/gpu/drm/ci/test.yml
index 81147e86bfd0..e56895626500 100644
--- a/drivers/gpu/drm/ci/test.yml
+++ b/drivers/gpu/drm/ci/test.yml
@@ -7,13 +7,16 @@
 
 .lava-test:
   extends:
-    - .container+build-rules
+    - .build-rules
     - .allow_failure_lockdep
   timeout: "1h30m"
   rules:
     - !reference [.scheduled_pipeline-rules, rules]
     - !reference [.collabora-farm-rules, rules]
     - when: on_success
+  before_script:
+    #  lava-submit.sh is a part of the archive, unlike Mesa CI
+    - eval "$S3_JWT_FILE_SCRIPT"
   script:
     # Note: Build dir (and thus install) may be dirty due to GIT_STRATEGY
     - rm -rf install
@@ -32,9 +35,7 @@
   dependencies:
     - testing:arm32
   needs:
-    - alpine/x86_64_lava_ssh_client
     - debian/arm32_test-gl
-    - python-artifacts
     - testing:arm32
     - igt:arm32
 
@@ -48,9 +49,7 @@
   dependencies:
     - testing:arm64
   needs:
-    - alpine/x86_64_lava_ssh_client
     - debian/arm64_test-gl
-    - python-artifacts
     - testing:arm64
     - igt:arm64
 
@@ -64,9 +63,7 @@
   dependencies:
     - testing:x86_64
   needs:
-    - alpine/x86_64_lava_ssh_client
     - debian/x86_64_test-gl
-    - python-artifacts
     - testing:x86_64
     - igt:x86_64
 
@@ -110,6 +107,7 @@
     - !reference [default, before_script]
     - rm -rf install
     - tar -xf artifacts/install.tar
+    - mkdir -p /kernel
   script:
     - ln -sf $CI_PROJECT_DIR/install /install
     - mv install/bzImage /kernel/bzImage
@@ -127,6 +125,7 @@
     DRIVER_NAME: msm
     BOOT_METHOD: depthcharge
     KERNEL_IMAGE_TYPE: ""
+    LAVA_FIRMWARE: qcom-lava
 
 msm:sc7180-trogdor-lazor-limozeen:
   extends:
@@ -194,11 +193,13 @@ msm:sm8350-hdk:
     KERNEL_IMAGE_NAME: "Image.gz"
     KERNEL_IMAGE_TYPE: ""
     RUNNER_TAG: mesa-ci-x86-64-lava-sm8350-hdk
+    LAVA_FIRMWARE: qcom-lava
 
 .rockchip-device:
   variables:
     DTB: ${DEVICE_TYPE}
     BOOT_METHOD: depthcharge
+    LAVA_FIRMWARE: arm-lava
 
 .rockchip-display:
   stage: rockchip
@@ -255,6 +256,7 @@ panfrost:rk3399:
     DTB: ""
     BOOT_METHOD: depthcharge
     KERNEL_IMAGE_TYPE: ""
+    LAVA_FIRMWARE: i915
 
 i915:apl:
   extends:
@@ -337,6 +339,7 @@ i915:jsl:
     DTB: ""
     BOOT_METHOD: depthcharge
     KERNEL_IMAGE_TYPE: ""
+    LAVA_FIRMWARE: amdgpu-lava
 
 amdgpu:stoney:
   extends:
@@ -355,6 +358,7 @@ amdgpu:stoney:
     DTB: ${DEVICE_TYPE}
     BOOT_METHOD: depthcharge
     KERNEL_IMAGE_TYPE: ""
+    LAVA_FIRMWARE: arm-lava
 
 .mediatek-display:
   stage: mediatek
-- 
2.51.0



From vignesh.raman at collabora.com  Thu Nov 13 19:00:51 2025
From: vignesh.raman at collabora.com (Vignesh Raman)
Date: Fri, 14 Nov 2025 08:30:51 +0530
Subject: [PATCH v1 2/2] drm/ci: Move qualcomm baremetal jobs to lava
In-Reply-To: <20251114030056.1139570-1-vignesh.raman@collabora.com>
References: <20251114030056.1139570-1-vignesh.raman@collabora.com>
Message-ID: <20251114030056.1139570-3-vignesh.raman@collabora.com>

Qualcomm apq8016 and apq8096 DUTS are moved to Collabora lava
farm. So enable these jobs to use lava and update expectation
files.

Co-developed-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>
Signed-off-by: Vignesh Raman <vignesh.raman at collabora.com>
---
 drivers/gpu/drm/ci/arm64.config               |  1 +
 drivers/gpu/drm/ci/test.yml                   | 62 ++++++-------------
 .../gpu/drm/ci/xfails/msm-apq8016-fails.txt   |  4 ++
 .../gpu/drm/ci/xfails/msm-apq8096-fails.txt   |  2 +
 4 files changed, 27 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/ci/arm64.config b/drivers/gpu/drm/ci/arm64.config
index fddfbd4d2493..b850b88787ad 100644
--- a/drivers/gpu/drm/ci/arm64.config
+++ b/drivers/gpu/drm/ci/arm64.config
@@ -83,6 +83,7 @@ CONFIG_SC_DISPCC_7180=y
 CONFIG_SC_GPUCC_7180=y
 CONFIG_SM_GPUCC_8350=y
 CONFIG_QCOM_SPMI_ADC5=y
+CONFIG_QCOM_SPMI_VADC=y
 CONFIG_DRM_PARADE_PS8640=y
 CONFIG_DRM_LONTIUM_LT9611UXC=y
 CONFIG_PHY_QCOM_USB_HS=y
diff --git a/drivers/gpu/drm/ci/test.yml b/drivers/gpu/drm/ci/test.yml
index e56895626500..42f75993e190 100644
--- a/drivers/gpu/drm/ci/test.yml
+++ b/drivers/gpu/drm/ci/test.yml
@@ -67,31 +67,6 @@
     - testing:x86_64
     - igt:x86_64
 
-.baremetal-igt-arm64:
-  extends:
-    - .baremetal-test-arm64-gl
-    - .use-debian/baremetal_arm64_test-gl
-    - .allow_failure_lockdep
-  timeout: "1h30m"
-  rules:
-    - !reference [.scheduled_pipeline-rules, rules]
-    - !reference [.google-freedreno-farm-rules, rules]
-    - when: on_success
-  variables:
-    FDO_CI_CONCURRENT: 10
-    HWCI_TEST_SCRIPT: "/install/igt_runner.sh"
-    S3_ARTIFACT_NAME: "arm64/kernel-files"
-    BM_KERNEL: https://${PIPELINE_ARTIFACTS_BASE}/arm64/Image.gz
-    BM_CMDLINE: "ip=dhcp console=ttyMSM0,115200n8 $BM_KERNEL_EXTRA_ARGS root=/dev/nfs rw nfsrootdebug nfsroot=,tcp,nfsvers=4.2 init=/init $BM_KERNELARGS"
-    FARM: google
-  needs:
-    - debian/baremetal_arm64_test-gl
-    - job: testing:arm64
-      artifacts: false
-    - igt:arm64
-  tags:
-    - $RUNNER_TAG
-
 .software-driver:
   stage: software-driver
   extends:
@@ -149,34 +124,37 @@ msm:sc7180-trogdor-kingoftown:
 
 msm:apq8016:
   extends:
-    - .baremetal-igt-arm64
+    - .lava-igt:arm64
   stage: msm
+  parallel: 3
   variables:
-    DEVICE_TYPE: apq8016-sbc-usb-host
+    BOOT_METHOD: fastboot
+    DEVICE_TYPE: dragonboard-410c
     DRIVER_NAME: msm
-    BM_DTB: https://${PIPELINE_ARTIFACTS_BASE}/arm64/${DEVICE_TYPE}.dtb
+    DTB: apq8016-sbc-usb-host
+    FARM: collabora
     GPU_VERSION: apq8016
-    # disabling unused clocks congests with the MDSS runtime PM trying to
-    # disable those clocks and causes boot to fail.
-    # Reproducer: DRM_MSM=y, DRM_I2C_ADV7511=m
-    BM_KERNEL_EXTRA_ARGS: clk_ignore_unused
-    RUNNER_TAG: google-freedreno-db410c
-  script:
-    - ./install/bare-metal/fastboot.sh || exit $?
+    KERNEL_IMAGE_NAME: "Image.gz"
+    KERNEL_IMAGE_TYPE: ""
+    RUNNER_TAG: mesa-ci-x86-64-lava-dragonboard-410c
+    LAVA_FIRMWARE: qcom-lava
 
 msm:apq8096:
   extends:
-    - .baremetal-igt-arm64
+    - .lava-igt:arm64
   stage: msm
+  parallel: 3
   variables:
-    DEVICE_TYPE: apq8096-db820c
+    BOOT_METHOD: fastboot
+    DEVICE_TYPE: dragonboard-820c
     DRIVER_NAME: msm
-    BM_KERNEL_EXTRA_ARGS: maxcpus=2
-    BM_DTB: https://${PIPELINE_ARTIFACTS_BASE}/arm64/${DEVICE_TYPE}.dtb
+    DTB: apq8096-db820c
+    FARM: collabora
     GPU_VERSION: apq8096
-    RUNNER_TAG: google-freedreno-db820c
-  script:
-    - ./install/bare-metal/fastboot.sh || exit $?
+    KERNEL_IMAGE_NAME: "Image.gz"
+    KERNEL_IMAGE_TYPE: ""
+    RUNNER_TAG: mesa-ci-x86-64-lava-dragonboard-820c
+    LAVA_FIRMWARE: qcom-lava
 
 msm:sm8350-hdk:
   extends:
diff --git a/drivers/gpu/drm/ci/xfails/msm-apq8016-fails.txt b/drivers/gpu/drm/ci/xfails/msm-apq8016-fails.txt
index 72c469021b66..4546363447ff 100644
--- a/drivers/gpu/drm/ci/xfails/msm-apq8016-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/msm-apq8016-fails.txt
@@ -1,5 +1,9 @@
+core_setmaster at master-drop-set-user,Fail
 kms_3d,Fail
+kms_cursor_legacy at forked-move,Fail
+kms_cursor_legacy at single-bo,Fail
 kms_force_connector_basic at force-edid,Fail
 kms_hdmi_inject at inject-4k,Fail
 kms_lease at lease-uevent,Fail
+msm/msm_mapping at memptrs,Fail
 msm/msm_mapping at ring,Fail
diff --git a/drivers/gpu/drm/ci/xfails/msm-apq8096-fails.txt b/drivers/gpu/drm/ci/xfails/msm-apq8096-fails.txt
index 2893f98a6b97..0d5cb2a87e67 100644
--- a/drivers/gpu/drm/ci/xfails/msm-apq8096-fails.txt
+++ b/drivers/gpu/drm/ci/xfails/msm-apq8096-fails.txt
@@ -1,2 +1,4 @@
+core_setmaster at master-drop-set-user,Fail
 kms_3d,Fail
 kms_lease at lease-uevent,Fail
+msm/msm_mapping at memptrs,Fail
-- 
2.51.0



From dsimic at manjaro.org  Thu Nov 13 20:00:07 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Fri, 14 Nov 2025 05:00:07 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v3 1/3] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= Use default-state for power LED for Radxa boards
In-Reply-To: <20251113124222.4691-2-naoki@radxa.com>
References: <20251113124222.4691-1-naoki@radxa.com> <20251113124222.4691-2-naoki@radxa.com>
Message-ID: <b394e1a7-a53f-9303-495f-776da0ad3118@manjaro.org>

Hello Naoki,

On Thursday, November 13, 2025 13:42 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> Currently, on Radxa boards, the power LED is turned on immediately
> after power-up, independent of software control. The heartbeat LED and
> other available LEDs are subsequently turned on by the initial
> software, such as U-Boot, to indicate software is running.
> 
> However, the device tree description for this behavior is inconsistent
> and fragmented, with definitions split between the main Linux DTS
> files and separate U-Boot files (u-boot/arch/arm/dts/*-u-boot.dtsi).
> 
> This patch addresses the inconsistency for the power LED by using
> default-state = "on" instead of linux,default-trigger = "default-on".
> 
> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> ---
>  arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts    | 1 -
>  arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts | 2 +-
>  arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts      | 1 -
>  arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts      | 2 +-
>  arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts   | 2 +-
>  arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts     | 2 +-
>  6 files changed, 4 insertions(+), 6 deletions(-)

[snip]

Thanks for this patch.  The introduces changes look consistent
to me, so please feel free to include

Reviewed-by: Dragan Simic <dsimic at manjaro.org>



From dsimic at manjaro.org  Thu Nov 13 20:10:32 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Fri, 14 Nov 2025 05:10:32 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v3 2/3] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= Turn on heartbeat LED at boot for Radxa boards
In-Reply-To: <20251113124222.4691-3-naoki@radxa.com>
References: <20251113124222.4691-1-naoki@radxa.com> <20251113124222.4691-3-naoki@radxa.com>
Message-ID: <7d200139-3da1-9d0d-6a30-5791e56b429b@manjaro.org>

Hello Naoki,

(+ Quentin)

On Thursday, November 13, 2025 13:42 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> Currently, on Radxa boards, the power LED is turned on immediately
> after power-up, independent of software control. The heartbeat LED and
> other available LEDs are subsequently turned on by the initial
> software, such as U-Boot, to indicate software is running.
> 
> However, the device tree description for this behavior is inconsistent
> and fragmented, with definitions split between the main Linux DTS
> files and separate U-Boot files (u-boot/arch/arm/dts/*-u-boot.dtsi).
> 
> This patch addresses the description fragmentation for the heartbeat
> LED by consolidating its default-state = "on" definition from the
> U-Boot files into the main Linux DTS.
> 
> - Radxa CM3 IO board
>   https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3566-radxa-cm3-io-u-boot.dtsi#L10-12
> 
> - Radxa CM3I
>   https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3568-radxa-e25-u-boot.dtsi#L7-24
> 
> - Radxa ROCK 3A
>   https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3568-rock-3a-u-boot.dtsi#L11-13
> 
> - Radxa ROCK 3C
>   https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3566-rock-3c-u-boot.dtsi#L14-16
> 
> - Radxa ROCK 4C+
>   https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3399-rock-4c-plus-u-boot.dtsi#L11-17
> 
> - Radxa ROCK 4D
>   (New)
> 
> - Radxa ROCK 4SE
>   Radxa ROCK Pi 4A/A+/B/B+/C
>   https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3399-rock-pi-4-u-boot.dtsi#L11-13
> 
> - Radxa ROCK 5A
>   https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3588s-rock-5a-u-boot.dtsi#L10-12
> 
> - Radxa ROCK 5B
>   https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3588-rock-5b-u-boot.dtsi#L11-13
> 
> - Radxa ROCK 5B+/5T
>   (New)
> 
> - Radxa ROCK Pi E
>   https://source.denx.de/u-boot/u-boot/-/blob/v2025.10/arch/arm/dts/rk3328-rock-pi-e-base-u-boot.dtsi#L10-12
> 
> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> ---
>  arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts    | 1 +
>  arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts | 1 +
>  arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi   | 1 +
>  arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3-io.dts | 1 +
>  arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts      | 1 +
>  arch/arm64/boot/dts/rockchip/rk3568-radxa-cm3i.dtsi  | 1 +
>  arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts      | 1 +
>  arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts      | 1 +
>  arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dtsi     | 1 +
>  arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts      | 1 +
>  arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts     | 1 +
>  11 files changed, 11 insertions(+)

[snip]

I'm sorry, but I disagree with the employed approach.  As already
discussed at length in the v2 of this series, the right and more
useful approach would be to use the LED_BOOT feature in U-Boot and
to move the associated DT definitions from the U-Boot-specific DTs
to the Linux kernel's DTs.

IIUC, there are still some issues with the way U-Boot handles the
LEDs on some Radxa boards that way, [2] but the right approach would
be to get the DT changes implemented now, and resolve the issues
at the U-Boot side afterwards.  It will take a while anyway until
the kernel's DT changes reach U-Boot, so there should be plenty of
time to resolve the observed U-Boot issues.

[1] https://lore.kernel.org/linux-rockchip/20251111054112.55505-1-naoki at radxa.com/T/#u
[2] https://libera.catirclogs.org/linux-rockchip/2025-11-13#1763038074-1763038779;



From dsimic at manjaro.org  Thu Nov 13 20:20:50 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Fri, 14 Nov 2025 05:20:50 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v3 3/3] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= Remove default-state =?utf-8?q?=3D?=
 =?utf-8?q?_=22off=22?= from LEDs for Radxa boards
In-Reply-To: <20251113124222.4691-4-naoki@radxa.com>
References: <20251113124222.4691-1-naoki@radxa.com> <20251113124222.4691-4-naoki@radxa.com>
Message-ID: <7b668c0b-f685-d909-4b05-02778a688839@manjaro.org>

Hello Naoki,

On Thursday, November 13, 2025 13:42 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> Currently, on Radxa boards, the power LED is turned on immediately
> after power-up, independent of software control. The heartbeat LED and
> other available LEDs are subsequently turned on by the initial
> software, such as U-Boot, to indicate software is running.
> 
> However, the device tree description for this behavior is inconsistent
> and fragmented, with definitions split between the main Linux DTS
> files and separate U-Boot files (u-boot/arch/arm/dts/*-u-boot.dtsi).

I'm sorry, but the two paragraphs above seem to be redundant and
should be deleted, because they actually don't help with describing
what this patch attempts to achieve.

> This patch addresses inconsistency by removing redundant default-state
> = "off" definitions, as this is already the default configuration.

Mentioning inconsistency here also seems redundant.

> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> ---
>  arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts | 2 --
>  arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts | 2 --
>  2 files changed, 4 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts b/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts
> index b324527561558..79d316a1d8495 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts
> @@ -62,7 +62,6 @@ leds {
>  
>  		led-lan {
>  			color = <LED_COLOR_ID_GREEN>;
> -			default-state = "off";
>  			function = LED_FUNCTION_LAN;
>  			gpios = <&gpio4 RK_PB5 GPIO_ACTIVE_HIGH>;
>  			linux,default-trigger = "netdev";
> @@ -78,7 +77,6 @@ led-sys {
>  
>  		led-wan {
>  			color = <LED_COLOR_ID_GREEN>;
> -			default-state = "off";
>  			function = LED_FUNCTION_WAN;
>  			gpios = <&gpio4 RK_PC0 GPIO_ACTIVE_HIGH>;
>  			linux,default-trigger = "netdev";
> diff --git a/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts b/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts
> index 854c118418eb8..f737769d4a007 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts
> @@ -71,7 +71,6 @@ leds-1 {
>  
>  		led-1 {
>  			color = <LED_COLOR_ID_GREEN>;
> -			default-state = "off";
>  			function = LED_FUNCTION_LAN;
>  			linux,default-trigger = "netdev";
>  			pwms = <&pwm14 0 1000000 PWM_POLARITY_INVERTED>;
> @@ -80,7 +79,6 @@ led-1 {
>  
>  		led-2 {
>  			color = <LED_COLOR_ID_GREEN>;
> -			default-state = "off";
>  			function = LED_FUNCTION_WAN;
>  			linux,default-trigger = "netdev";
>  			pwms = <&pwm11 0 1000000 PWM_POLARITY_INVERTED>;

Removing the properties that introduce the default values is fine,
so with the remarks above addressed, please feel free to include

Reviewed-by: Dragan Simic <dsimic at manjaro.org>



From dsimic at manjaro.org  Thu Nov 13 20:28:59 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Fri, 14 Nov 2025 05:28:59 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v3 3/3] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= Remove default-state =?utf-8?q?=3D?=
 =?utf-8?q?_=22off=22?= from LEDs for Radxa boards
In-Reply-To: <7b668c0b-f685-d909-4b05-02778a688839@manjaro.org>
References: <20251113124222.4691-1-naoki@radxa.com> <20251113124222.4691-4-naoki@radxa.com> <7b668c0b-f685-d909-4b05-02778a688839@manjaro.org>
Message-ID: <4d94f91f-b399-2808-6ffb-719e688cd9e3@manjaro.org>

On Friday, November 14, 2025 05:20 CET, "Dragan Simic" <dsimic at manjaro.org> wrote:
> Removing the properties that introduce the default values is fine,
> so with the remarks above addressed, please feel free to include
> 
> Reviewed-by: Dragan Simic <dsimic at manjaro.org>

Though, applying this patch might mess up the current behavior
of U-Boot, which doesn't auto-probe and configure the LEDs that
have no "default-state" defined, so perhaps addressing this patch
should be left for after the patch 2/3 is resolved.



From geraldogabriel at gmail.com  Thu Nov 13 20:41:46 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Fri, 14 Nov 2025 01:41:46 -0300
Subject: [PATCH] arm64: dts: rockchip: align bindings to PCIe spec
In-Reply-To: <aRUvr0UggTYkkCZ_@geday>
References: <4b5ffcccfef2a61838aa563521672a171acb27b2.1762321976.git.geraldogabriel@gmail.com>
 <ba120577-42da-424d-8102-9d085c1494c8@rock-chips.com>
 <aQsIXcQzeYop6a0B@geday>
 <67b605b0-7046-448a-bc9b-d3ac56333809@rock-chips.com>
 <aQ1c7ZDycxiOIy8Y@geday>
 <d9e257bd-806c-48b4-bb22-f1342e9fc15a@rock-chips.com>
 <aRLEbfsmXnGwyigS@geday>
 <AGsAmwCFJj0ZQ4vKzrqC84rs.3.1762847224180.Hmail.ye.zhang@rock-chips.com>
 <aRQ_R90S8T82th45@geday>
 <aRUvr0UggTYkkCZ_@geday>
Message-ID: <aRazCssWVdAOmy7D@geday>

On Wed, Nov 12, 2025 at 10:09:15PM -0300, Geraldo Nascimento wrote:
> Hi Ye, Shawn,
> 
> Here's more contained workaround without resorting to clearing DDR to
> INPUT for every GPIO:
> 
> diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c
> index ee1822ca01db..1d89131ec6ac 100644
> --- a/drivers/pci/controller/pcie-rockchip-host.c
> +++ b/drivers/pci/controller/pcie-rockchip-host.c
> @@ -315,7 +315,8 @@ static int rockchip_pcie_host_init_port(struct rockchip_pcie *rockchip)
>  			    PCIE_CLIENT_CONFIG);
>  
>  	msleep(PCIE_T_PVPERL_MS);
> -	gpiod_set_value_cansleep(rockchip->perst_gpio, 1);
> +	gpiod_direction_input(rockchip->perst_gpio);
> +	gpiod_direction_output(rockchip->perst_gpio, 1);
>  
>  	msleep(PCIE_RESET_CONFIG_WAIT_MS);
>  
> This results in working PCIe for me, pass initial link training.

Sorry for the inconvenience of more mail, but I'm providing as much
detail as I can.

This hack has been confirmed to work in U-boot also.

diff --git a/drivers/pci/pcie_rockchip.c b/drivers/pci/pcie_rockchip.c
index 19f9e58a640..5702b607ee6 100644
--- a/drivers/pci/pcie_rockchip.c
+++ b/drivers/pci/pcie_rockchip.c
@@ -329,8 +329,10 @@ static int rockchip_pcie_init_port(struct udevice *dev)
 	writel(PCIE_CLIENT_LINK_TRAIN_ENABLE,
 	       priv->apb_base + PCIE_CLIENT_CONFIG);
 
-	if (dm_gpio_is_valid(&priv->ep_gpio))
-		dm_gpio_set_value(&priv->ep_gpio, 1);
+	if (dm_gpio_is_valid(&priv->ep_gpio)) {
+		dm_gpio_set_dir_flags(&priv->ep_gpio, (priv->ep_gpio.flags & ~GPIOD_IS_OUT) | GPIOD_IS_IN);
+		dm_gpio_set_dir_flags(&priv->ep_gpio, (priv->ep_gpio.flags & ~GPIOD_IS_IN) | GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
+	}
 
 	ret = readl_poll_sleep_timeout
 			(priv->apb_base + PCIE_CLIENT_BASIC_STATUS1,

So my report suggests this is not specific to Linux and because same
workaround works in U-boot simplified driver model I suggest you check
from your side.

Previously PCIe link training timeout, not working. Now I'm very happy
with working PCIe in Linux and U-boot.

Thanks,
Geraldo Nascimento


From naoki at radxa.com  Thu Nov 13 21:03:20 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Fri, 14 Nov 2025 14:03:20 +0900
Subject: [PATCH v6 0/3] Add Radxa CM5 and IO Board
In-Reply-To: <19ce0a41-563c-6202-6b94-b2c644a0b827@manjaro.org>
References: <20251105051335.17652-1-naoki@radxa.com>
 <199E172C8E20ED38+71169242-5525-4d60-9e37-a03ad172d639@radxa.com>
 <CAMWSM7gezjVSoF+-7ivboTeB=5gQAE-QVrbAbKu3M=obmb3Axg@mail.gmail.com>
 <617FDAB231C501DC+3f9809df-87df-4a02-bd5f-ebc6299b3aa7@radxa.com>
 <a10340af-1d0a-bb0b-4835-7b2c9e67d664@manjaro.org>
 <2892FE50237CD58E+0f15924c-a915-4446-954c-d81a782d23e9@radxa.com>
 <19ce0a41-563c-6202-6b94-b2c644a0b827@manjaro.org>
Message-ID: <F02BA2E6B1111826+2445b38d-b5e0-499c-83e7-4521c57b2210@radxa.com>

Hi Dragan, Joseph,

On 11/12/25 09:46, Dragan Simic wrote:
> Hello Naoki,
> 
> On Wednesday, November 12, 2025 00:26 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
>> On 11/11/25 23:33, Dragan Simic wrote:
>>> On Tuesday, November 11, 2025 12:52 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
>>>> On 11/6/25 02:48, Joseph Kogut wrote:
>>>>> On Wed, Nov 5, 2025 at 4:15?AM FUKAUMI Naoki <naoki at radxa.com> wrote:
>>>>>> I'd like to clarify the situation regarding the v6 patch series I submitted.
>>>>>>
>>>>>> The original device tree work for the Radxa CM5 and IO Board was
>>>>>> authored by Joseph Kogut. I took over the responsibility of getting it
>>>>>> upstreamed with his agreement.
>>>>>
>>>>> I'll confirm this. I've been in communication with Naoki. They made a
>>>>> large number of revisions to my original patch series, which I think
>>>>> have technical merit. I suggested they submit the patches themselves,
>>>>> and gave them explicit permission to add my Signed-off-by and CC me.
>>>>>
>>>>> I assume this was the correct way for them to continue the work I
>>>>> started, but if not, please let us know the best way to proceed.
>>>>
>>>> Can anyone help us?
>>>
>>> I'm not exactly sure how to resolve the current situation, but for
>>> Signed-off-by tags to be present, in this case you'd need to have
>>> Co-developed-by tags as well, because the final patch versions,
>>> which would be submitted by Naoki, would differ significantly from
>>> the versions that Joseph actively worked on, if I understood
>>> everything correctly.  Though, for Joseph's Signed-off-by tags to
>>> be included there, he would also need to participate actively in
>>> the development of the final patch versions.
>>
>> https://www.kernel.org/doc/html/latest/process/submitting-patches.html#when-to-use-acked-by-cc-and-co-developed-by
>>
>> If
>> ----
>> From: Joseph Kogut <joseph.kogut at gmail.com>
>>
>> <changelog>
>>
>> Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
>> Co-developed-by: FUKAUMI Naoki <naoki at radxa.com>
>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
>> ----
>> then I can submit my patch series?
> 
> Actually, the Co-developed-by tags would be pointing to Joseph
> in that case, but as I described it above, this approach basically
> cannot be used, because Joseph's original work differs a lot from
> what you'd actually submit to the mailing list(s).
> 
>> Or,
>>
>>> Another option, technically a bit simpler, would be to include just
>>> Originally-by tags for Joseph, which would indicate that Joseph gave
>>> up on the development of the patches and handed them over to Naoki
>>> for future development and submission to the mailing lists. Though,
>>> that would require Joseph to publicly state exactly that.
>>
>> I cannot find any documentation about "Originally-by".
>> Is this correct?
>> ----
>> <changelog>
>>
>> Originally-by: Joseph Kogut <joseph.kogut at gmail.com>
>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
>> ----
> 
> That approach is the only I see applicable in this case.  However,
> let's hear opinions from other people as well.

I see. I want to do this approach.

Joseph, could you give me a statement to do this?

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> By the way, what you called changelogs in the examples above is
> usually called patch descriptions.  When they become merged, they
> become called commit descriptions or, sometimes, commit messages.
> Using the standard lingo usually helps. :)
> 
> 




From krzk at kernel.org  Thu Nov 13 23:10:46 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 14 Nov 2025 08:10:46 +0100
Subject: [PATCH v6 0/3] Add Radxa CM5 and IO Board
In-Reply-To: <F02BA2E6B1111826+2445b38d-b5e0-499c-83e7-4521c57b2210@radxa.com>
References: <20251105051335.17652-1-naoki@radxa.com>
 <199E172C8E20ED38+71169242-5525-4d60-9e37-a03ad172d639@radxa.com>
 <CAMWSM7gezjVSoF+-7ivboTeB=5gQAE-QVrbAbKu3M=obmb3Axg@mail.gmail.com>
 <617FDAB231C501DC+3f9809df-87df-4a02-bd5f-ebc6299b3aa7@radxa.com>
 <a10340af-1d0a-bb0b-4835-7b2c9e67d664@manjaro.org>
 <2892FE50237CD58E+0f15924c-a915-4446-954c-d81a782d23e9@radxa.com>
 <19ce0a41-563c-6202-6b94-b2c644a0b827@manjaro.org>
 <F02BA2E6B1111826+2445b38d-b5e0-499c-83e7-4521c57b2210@radxa.com>
Message-ID: <f2bc30de-119b-4f4a-844a-8a908c9290b6@kernel.org>

On 14/11/2025 06:03, FUKAUMI Naoki wrote:
> Hi Dragan, Joseph,
> 
> On 11/12/25 09:46, Dragan Simic wrote:
>> Hello Naoki,
>>
>> On Wednesday, November 12, 2025 00:26 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
>>> On 11/11/25 23:33, Dragan Simic wrote:
>>>> On Tuesday, November 11, 2025 12:52 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
>>>>> On 11/6/25 02:48, Joseph Kogut wrote:
>>>>>> On Wed, Nov 5, 2025 at 4:15?AM FUKAUMI Naoki <naoki at radxa.com> wrote:
>>>>>>> I'd like to clarify the situation regarding the v6 patch series I submitted.
>>>>>>>
>>>>>>> The original device tree work for the Radxa CM5 and IO Board was
>>>>>>> authored by Joseph Kogut. I took over the responsibility of getting it
>>>>>>> upstreamed with his agreement.
>>>>>>
>>>>>> I'll confirm this. I've been in communication with Naoki. They made a
>>>>>> large number of revisions to my original patch series, which I think
>>>>>> have technical merit. I suggested they submit the patches themselves,
>>>>>> and gave them explicit permission to add my Signed-off-by and CC me.
>>>>>>
>>>>>> I assume this was the correct way for them to continue the work I
>>>>>> started, but if not, please let us know the best way to proceed.
>>>>>
>>>>> Can anyone help us?
>>>>
>>>> I'm not exactly sure how to resolve the current situation, but for
>>>> Signed-off-by tags to be present, in this case you'd need to have
>>>> Co-developed-by tags as well, because the final patch versions,
>>>> which would be submitted by Naoki, would differ significantly from
>>>> the versions that Joseph actively worked on, if I understood
>>>> everything correctly.  Though, for Joseph's Signed-off-by tags to
>>>> be included there, he would also need to participate actively in
>>>> the development of the final patch versions.
>>>
>>> https://www.kernel.org/doc/html/latest/process/submitting-patches.html#when-to-use-acked-by-cc-and-co-developed-by
>>>
>>> If
>>> ----
>>> From: Joseph Kogut <joseph.kogut at gmail.com>
>>>
>>> <changelog>
>>>
>>> Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
>>> Co-developed-by: FUKAUMI Naoki <naoki at radxa.com>
>>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
>>> ----
>>> then I can submit my patch series?
>>
>> Actually, the Co-developed-by tags would be pointing to Joseph
>> in that case, but as I described it above, this approach basically
>> cannot be used, because Joseph's original work differs a lot from
>> what you'd actually submit to the mailing list(s).
>>
>>> Or,
>>>
>>>> Another option, technically a bit simpler, would be to include just
>>>> Originally-by tags for Joseph, which would indicate that Joseph gave
>>>> up on the development of the patches and handed them over to Naoki
>>>> for future development and submission to the mailing lists. Though,
>>>> that would require Joseph to publicly state exactly that.
>>>
>>> I cannot find any documentation about "Originally-by".
>>> Is this correct?
>>> ----
>>> <changelog>
>>>
>>> Originally-by: Joseph Kogut <joseph.kogut at gmail.com>

There is no such tag. Don't invent tags.

>>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
>>> ----
>>
>> That approach is the only I see applicable in this case.  However,
>> let's hear opinions from other people as well.
> 
> I see. I want to do this approach.
> 
> Joseph, could you give me a statement to do this?

Use standard authorship and standard tags, some of which are explained
in Submitting patches.


Best regards,
Krzysztof


From krzk at kernel.org  Thu Nov 13 23:12:06 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 14 Nov 2025 08:12:06 +0100
Subject: [PATCH v6 1/3] dt-bindings: arm: rockchip: Add Radxa CM5 IO Board
In-Reply-To: <93deab54-bd5e-433e-acbc-13f6ead47f43@kernel.org>
References: <20251105051335.17652-1-naoki@radxa.com>
 <20251105051335.17652-2-naoki@radxa.com>
 <ce6e6369-a7e4-4a35-80f8-70ef41c3b877@kernel.org>
 <A6C1199E2A0D3F37+f3fe0fd5-4ca5-4d3d-bc1d-45f46b48f89b@radxa.com>
 <93deab54-bd5e-433e-acbc-13f6ead47f43@kernel.org>
Message-ID: <2177a0f0-68df-495c-b267-18e3d9b6ca80@kernel.org>

On 05/11/2025 08:08, Krzysztof Kozlowski wrote:
> On 05/11/2025 07:57, FUKAUMI Naoki wrote:
>> On 11/5/25 15:43, Krzysztof Kozlowski wrote:
>>> On 05/11/2025 06:13, FUKAUMI Naoki wrote:
>>>> Add device tree binding documentation for the Radxa CM5 IO Board.
>>>>
>>>> Link: https://dl.radxa.com/cm5/radxa_cm5_product_brief.pdf
>>>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
>>>> Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
>>>
>>> Wrong DCO chain.
>>>
>>>> ---
>>>>   Documentation/devicetree/bindings/arm/rockchip.yaml | 7 +++++++
>>>
>>> NAK, you just stolen ownership of an already posted patch.
>>
>> Read "Changes in v6" and patches; my patches are not the same as v5.
>> Your reply is totally inappropriate.
> 
> Inappropriate is taking authorship of someone's patch, because we all
> expect to preserve the original authorship. That's not only basic
> decency but actually a standard.
> 
> Additionally, read Joseph's reply that he wants to continue the work:
> https://lore.kernel.org/all/CAMWSM7iHtAxewW4JkRqRsifVnccqeFviaCgeOyprKDr92FOurg at mail.gmail.com/
> 
> You clearly do not understand how to continue with someone's work.
> 
> It is still a NAK.

And I still wait for justification why you took authorship of this
patch, because to my eye you changed here nothing.

So what did you change HERE that you think you are the author now?

Best regards,
Krzysztof


From dsimic at manjaro.org  Thu Nov 13 23:17:23 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Fri, 14 Nov 2025 08:17:23 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v6 0/3] Add Radxa CM5 and IO Board
In-Reply-To: <f2bc30de-119b-4f4a-844a-8a908c9290b6@kernel.org>
References: <20251105051335.17652-1-naoki@radxa.com>
 <199E172C8E20ED38+71169242-5525-4d60-9e37-a03ad172d639@radxa.com>
 <CAMWSM7gezjVSoF+-7ivboTeB=5gQAE-QVrbAbKu3M=obmb3Axg@mail.gmail.com>
 <617FDAB231C501DC+3f9809df-87df-4a02-bd5f-ebc6299b3aa7@radxa.com>
 <a10340af-1d0a-bb0b-4835-7b2c9e67d664@manjaro.org>
 <2892FE50237CD58E+0f15924c-a915-4446-954c-d81a782d23e9@radxa.com>
 <19ce0a41-563c-6202-6b94-b2c644a0b827@manjaro.org>
 <F02BA2E6B1111826+2445b38d-b5e0-499c-83e7-4521c57b2210@radxa.com> <f2bc30de-119b-4f4a-844a-8a908c9290b6@kernel.org>
Message-ID: <49c39864-3e58-2e0e-7abc-50502f2afb02@manjaro.org>

Hello Krzysztof,

On Friday, November 14, 2025 08:10 CET, Krzysztof Kozlowski <krzk at kernel.org> wrote:
> On 14/11/2025 06:03, FUKAUMI Naoki wrote:
> > On 11/12/25 09:46, Dragan Simic wrote:
> >> On Wednesday, November 12, 2025 00:26 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> >>> On 11/11/25 23:33, Dragan Simic wrote:
> >>>> On Tuesday, November 11, 2025 12:52 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> >>>>> On 11/6/25 02:48, Joseph Kogut wrote:
> >>>>>> On Wed, Nov 5, 2025 at 4:15?AM FUKAUMI Naoki <naoki at radxa.com> wrote:
> >>>>>>> I'd like to clarify the situation regarding the v6 patch series I submitted.
> >>>>>>>
> >>>>>>> The original device tree work for the Radxa CM5 and IO Board was
> >>>>>>> authored by Joseph Kogut. I took over the responsibility of getting it
> >>>>>>> upstreamed with his agreement.
> >>>>>>
> >>>>>> I'll confirm this. I've been in communication with Naoki. They made a
> >>>>>> large number of revisions to my original patch series, which I think
> >>>>>> have technical merit. I suggested they submit the patches themselves,
> >>>>>> and gave them explicit permission to add my Signed-off-by and CC me.
> >>>>>>
> >>>>>> I assume this was the correct way for them to continue the work I
> >>>>>> started, but if not, please let us know the best way to proceed.
> >>>>>
> >>>>> Can anyone help us?
> >>>>
> >>>> I'm not exactly sure how to resolve the current situation, but for
> >>>> Signed-off-by tags to be present, in this case you'd need to have
> >>>> Co-developed-by tags as well, because the final patch versions,
> >>>> which would be submitted by Naoki, would differ significantly from
> >>>> the versions that Joseph actively worked on, if I understood
> >>>> everything correctly.  Though, for Joseph's Signed-off-by tags to
> >>>> be included there, he would also need to participate actively in
> >>>> the development of the final patch versions.
> >>>
> >>> https://www.kernel.org/doc/html/latest/process/submitting-patches.html#when-to-use-acked-by-cc-and-co-developed-by
> >>>
> >>> If
> >>> ----
> >>> From: Joseph Kogut <joseph.kogut at gmail.com>
> >>>
> >>> <changelog>
> >>>
> >>> Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
> >>> Co-developed-by: FUKAUMI Naoki <naoki at radxa.com>
> >>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> >>> ----
> >>> then I can submit my patch series?
> >>
> >> Actually, the Co-developed-by tags would be pointing to Joseph
> >> in that case, but as I described it above, this approach basically
> >> cannot be used, because Joseph's original work differs a lot from
> >> what you'd actually submit to the mailing list(s).
> >>
> >>> Or,
> >>>
> >>>> Another option, technically a bit simpler, would be to include just
> >>>> Originally-by tags for Joseph, which would indicate that Joseph gave
> >>>> up on the development of the patches and handed them over to Naoki
> >>>> for future development and submission to the mailing lists. Though,
> >>>> that would require Joseph to publicly state exactly that.
> >>>
> >>> I cannot find any documentation about "Originally-by".
> >>> Is this correct?
> >>> ----
> >>> <changelog>
> >>>
> >>> Originally-by: Joseph Kogut <joseph.kogut at gmail.com>
> 
> There is no such tag. Don't invent tags.

True, it doesn't exist officially, but it's been used fairly often.

> >>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> >>> ----
> >>
> >> That approach is the only I see applicable in this case.  However,
> >> let's hear opinions from other people as well.
> > 
> > I see. I want to do this approach.
> > 
> > Joseph, could you give me a statement to do this?
> 
> Use standard authorship and standard tags, some of which are explained
> in Submitting patches.

Frankly, your suggestion is useless, because it doesn't explain what 
to do in this particular case.



From krzk at kernel.org  Thu Nov 13 23:22:19 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 14 Nov 2025 08:22:19 +0100
Subject: [PATCH v6 0/3] Add Radxa CM5 and IO Board
In-Reply-To: <49c39864-3e58-2e0e-7abc-50502f2afb02@manjaro.org>
References: <20251105051335.17652-1-naoki@radxa.com>
 <199E172C8E20ED38+71169242-5525-4d60-9e37-a03ad172d639@radxa.com>
 <CAMWSM7gezjVSoF+-7ivboTeB=5gQAE-QVrbAbKu3M=obmb3Axg@mail.gmail.com>
 <617FDAB231C501DC+3f9809df-87df-4a02-bd5f-ebc6299b3aa7@radxa.com>
 <a10340af-1d0a-bb0b-4835-7b2c9e67d664@manjaro.org>
 <2892FE50237CD58E+0f15924c-a915-4446-954c-d81a782d23e9@radxa.com>
 <19ce0a41-563c-6202-6b94-b2c644a0b827@manjaro.org>
 <F02BA2E6B1111826+2445b38d-b5e0-499c-83e7-4521c57b2210@radxa.com>
 <f2bc30de-119b-4f4a-844a-8a908c9290b6@kernel.org>
 <49c39864-3e58-2e0e-7abc-50502f2afb02@manjaro.org>
Message-ID: <7ed7d24a-5395-429f-b999-1374ac910441@kernel.org>

On 14/11/2025 08:17, Dragan Simic wrote:
> Hello Krzysztof,
> 
> On Friday, November 14, 2025 08:10 CET, Krzysztof Kozlowski <krzk at kernel.org> wrote:
>> On 14/11/2025 06:03, FUKAUMI Naoki wrote:
>>> On 11/12/25 09:46, Dragan Simic wrote:
>>>> On Wednesday, November 12, 2025 00:26 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
>>>>> On 11/11/25 23:33, Dragan Simic wrote:
>>>>>> On Tuesday, November 11, 2025 12:52 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
>>>>>>> On 11/6/25 02:48, Joseph Kogut wrote:
>>>>>>>> On Wed, Nov 5, 2025 at 4:15?AM FUKAUMI Naoki <naoki at radxa.com> wrote:
>>>>>>>>> I'd like to clarify the situation regarding the v6 patch series I submitted.
>>>>>>>>>
>>>>>>>>> The original device tree work for the Radxa CM5 and IO Board was
>>>>>>>>> authored by Joseph Kogut. I took over the responsibility of getting it
>>>>>>>>> upstreamed with his agreement.
>>>>>>>>
>>>>>>>> I'll confirm this. I've been in communication with Naoki. They made a
>>>>>>>> large number of revisions to my original patch series, which I think
>>>>>>>> have technical merit. I suggested they submit the patches themselves,
>>>>>>>> and gave them explicit permission to add my Signed-off-by and CC me.
>>>>>>>>
>>>>>>>> I assume this was the correct way for them to continue the work I
>>>>>>>> started, but if not, please let us know the best way to proceed.
>>>>>>>
>>>>>>> Can anyone help us?
>>>>>>
>>>>>> I'm not exactly sure how to resolve the current situation, but for
>>>>>> Signed-off-by tags to be present, in this case you'd need to have
>>>>>> Co-developed-by tags as well, because the final patch versions,
>>>>>> which would be submitted by Naoki, would differ significantly from
>>>>>> the versions that Joseph actively worked on, if I understood
>>>>>> everything correctly.  Though, for Joseph's Signed-off-by tags to
>>>>>> be included there, he would also need to participate actively in
>>>>>> the development of the final patch versions.
>>>>>
>>>>> https://www.kernel.org/doc/html/latest/process/submitting-patches.html#when-to-use-acked-by-cc-and-co-developed-by
>>>>>
>>>>> If
>>>>> ----
>>>>> From: Joseph Kogut <joseph.kogut at gmail.com>
>>>>>
>>>>> <changelog>
>>>>>
>>>>> Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
>>>>> Co-developed-by: FUKAUMI Naoki <naoki at radxa.com>
>>>>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
>>>>> ----
>>>>> then I can submit my patch series?
>>>>
>>>> Actually, the Co-developed-by tags would be pointing to Joseph
>>>> in that case, but as I described it above, this approach basically
>>>> cannot be used, because Joseph's original work differs a lot from
>>>> what you'd actually submit to the mailing list(s).
>>>>
>>>>> Or,
>>>>>
>>>>>> Another option, technically a bit simpler, would be to include just
>>>>>> Originally-by tags for Joseph, which would indicate that Joseph gave
>>>>>> up on the development of the patches and handed them over to Naoki
>>>>>> for future development and submission to the mailing lists. Though,
>>>>>> that would require Joseph to publicly state exactly that.
>>>>>
>>>>> I cannot find any documentation about "Originally-by".
>>>>> Is this correct?
>>>>> ----
>>>>> <changelog>
>>>>>
>>>>> Originally-by: Joseph Kogut <joseph.kogut at gmail.com>
>>
>> There is no such tag. Don't invent tags.
> 
> True, it doesn't exist officially, but it's been used fairly often.
> 
>>>>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
>>>>> ----
>>>>
>>>> That approach is the only I see applicable in this case.  However,
>>>> let's hear opinions from other people as well.
>>>
>>> I see. I want to do this approach.
>>>
>>> Joseph, could you give me a statement to do this?
>>
>> Use standard authorship and standard tags, some of which are explained
>> in Submitting patches.
> 
> Frankly, your suggestion is useless, because it doesn't explain what 
> to do in this particular case.

Maybe because you did not read the doc...


Best regards,
Krzysztof


From dsimic at manjaro.org  Thu Nov 13 23:26:06 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Fri, 14 Nov 2025 08:26:06 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v6 0/3] Add Radxa CM5 and IO Board
In-Reply-To: <7ed7d24a-5395-429f-b999-1374ac910441@kernel.org>
References: <20251105051335.17652-1-naoki@radxa.com>
 <199E172C8E20ED38+71169242-5525-4d60-9e37-a03ad172d639@radxa.com>
 <CAMWSM7gezjVSoF+-7ivboTeB=5gQAE-QVrbAbKu3M=obmb3Axg@mail.gmail.com>
 <617FDAB231C501DC+3f9809df-87df-4a02-bd5f-ebc6299b3aa7@radxa.com>
 <a10340af-1d0a-bb0b-4835-7b2c9e67d664@manjaro.org>
 <2892FE50237CD58E+0f15924c-a915-4446-954c-d81a782d23e9@radxa.com>
 <19ce0a41-563c-6202-6b94-b2c644a0b827@manjaro.org>
 <F02BA2E6B1111826+2445b38d-b5e0-499c-83e7-4521c57b2210@radxa.com>
 <f2bc30de-119b-4f4a-844a-8a908c9290b6@kernel.org>
 <49c39864-3e58-2e0e-7abc-50502f2afb02@manjaro.org> <7ed7d24a-5395-429f-b999-1374ac910441@kernel.org>
Message-ID: <cab16f94-4115-a606-60b4-043b6681f7ab@manjaro.org>

On Friday, November 14, 2025 08:22 CET, Krzysztof Kozlowski <krzk at kernel.org> wrote:
> On 14/11/2025 08:17, Dragan Simic wrote:
> > On Friday, November 14, 2025 08:10 CET, Krzysztof Kozlowski <krzk at kernel.org> wrote:
> >> On 14/11/2025 06:03, FUKAUMI Naoki wrote:
> >>> On 11/12/25 09:46, Dragan Simic wrote:
> >>>> On Wednesday, November 12, 2025 00:26 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> >>>>> On 11/11/25 23:33, Dragan Simic wrote:
> >>>>>> On Tuesday, November 11, 2025 12:52 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> >>>>>>> On 11/6/25 02:48, Joseph Kogut wrote:
> >>>>>>>> On Wed, Nov 5, 2025 at 4:15?AM FUKAUMI Naoki <naoki at radxa.com> wrote:
> >>>>>>>>> I'd like to clarify the situation regarding the v6 patch series I submitted.
> >>>>>>>>>
> >>>>>>>>> The original device tree work for the Radxa CM5 and IO Board was
> >>>>>>>>> authored by Joseph Kogut. I took over the responsibility of getting it
> >>>>>>>>> upstreamed with his agreement.
> >>>>>>>>
> >>>>>>>> I'll confirm this. I've been in communication with Naoki. They made a
> >>>>>>>> large number of revisions to my original patch series, which I think
> >>>>>>>> have technical merit. I suggested they submit the patches themselves,
> >>>>>>>> and gave them explicit permission to add my Signed-off-by and CC me.
> >>>>>>>>
> >>>>>>>> I assume this was the correct way for them to continue the work I
> >>>>>>>> started, but if not, please let us know the best way to proceed.
> >>>>>>>
> >>>>>>> Can anyone help us?
> >>>>>>
> >>>>>> I'm not exactly sure how to resolve the current situation, but for
> >>>>>> Signed-off-by tags to be present, in this case you'd need to have
> >>>>>> Co-developed-by tags as well, because the final patch versions,
> >>>>>> which would be submitted by Naoki, would differ significantly from
> >>>>>> the versions that Joseph actively worked on, if I understood
> >>>>>> everything correctly.  Though, for Joseph's Signed-off-by tags to
> >>>>>> be included there, he would also need to participate actively in
> >>>>>> the development of the final patch versions.
> >>>>>
> >>>>> https://www.kernel.org/doc/html/latest/process/submitting-patches.html#when-to-use-acked-by-cc-and-co-developed-by
> >>>>>
> >>>>> If
> >>>>> ----
> >>>>> From: Joseph Kogut <joseph.kogut at gmail.com>
> >>>>>
> >>>>> <changelog>
> >>>>>
> >>>>> Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
> >>>>> Co-developed-by: FUKAUMI Naoki <naoki at radxa.com>
> >>>>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> >>>>> ----
> >>>>> then I can submit my patch series?
> >>>>
> >>>> Actually, the Co-developed-by tags would be pointing to Joseph
> >>>> in that case, but as I described it above, this approach basically
> >>>> cannot be used, because Joseph's original work differs a lot from
> >>>> what you'd actually submit to the mailing list(s).
> >>>>
> >>>>> Or,
> >>>>>
> >>>>>> Another option, technically a bit simpler, would be to include just
> >>>>>> Originally-by tags for Joseph, which would indicate that Joseph gave
> >>>>>> up on the development of the patches and handed them over to Naoki
> >>>>>> for future development and submission to the mailing lists. Though,
> >>>>>> that would require Joseph to publicly state exactly that.
> >>>>>
> >>>>> I cannot find any documentation about "Originally-by".
> >>>>> Is this correct?
> >>>>> ----
> >>>>> <changelog>
> >>>>>
> >>>>> Originally-by: Joseph Kogut <joseph.kogut at gmail.com>
> >>
> >> There is no such tag. Don't invent tags.
> > 
> > True, it doesn't exist officially, but it's been used fairly often.
> > 
> >>>>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> >>>>> ----
> >>>>
> >>>> That approach is the only I see applicable in this case.  However,
> >>>> let's hear opinions from other people as well.
> >>>
> >>> I see. I want to do this approach.
> >>>
> >>> Joseph, could you give me a statement to do this?
> >>
> >> Use standard authorship and standard tags, some of which are explained
> >> in Submitting patches.
> > 
> > Frankly, your suggestion is useless, because it doesn't explain what 
> > to do in this particular case.
> 
> Maybe because you did not read the doc...

I think you already know the answer: I read it multiple times and 
used it as a reference more than once.



From krzk at kernel.org  Thu Nov 13 23:28:37 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 14 Nov 2025 08:28:37 +0100
Subject: [PATCH v6 0/3] Add Radxa CM5 and IO Board
In-Reply-To: <cab16f94-4115-a606-60b4-043b6681f7ab@manjaro.org>
References: <20251105051335.17652-1-naoki@radxa.com>
 <199E172C8E20ED38+71169242-5525-4d60-9e37-a03ad172d639@radxa.com>
 <CAMWSM7gezjVSoF+-7ivboTeB=5gQAE-QVrbAbKu3M=obmb3Axg@mail.gmail.com>
 <617FDAB231C501DC+3f9809df-87df-4a02-bd5f-ebc6299b3aa7@radxa.com>
 <a10340af-1d0a-bb0b-4835-7b2c9e67d664@manjaro.org>
 <2892FE50237CD58E+0f15924c-a915-4446-954c-d81a782d23e9@radxa.com>
 <19ce0a41-563c-6202-6b94-b2c644a0b827@manjaro.org>
 <F02BA2E6B1111826+2445b38d-b5e0-499c-83e7-4521c57b2210@radxa.com>
 <f2bc30de-119b-4f4a-844a-8a908c9290b6@kernel.org>
 <49c39864-3e58-2e0e-7abc-50502f2afb02@manjaro.org>
 <7ed7d24a-5395-429f-b999-1374ac910441@kernel.org>
 <cab16f94-4115-a606-60b4-043b6681f7ab@manjaro.org>
Message-ID: <67ccca04-b59d-4e22-a0fb-22b19378420d@kernel.org>

On 14/11/2025 08:26, Dragan Simic wrote:
> On Friday, November 14, 2025 08:22 CET, Krzysztof Kozlowski <krzk at kernel.org> wrote:
>> On 14/11/2025 08:17, Dragan Simic wrote:
>>> On Friday, November 14, 2025 08:10 CET, Krzysztof Kozlowski <krzk at kernel.org> wrote:
>>>> On 14/11/2025 06:03, FUKAUMI Naoki wrote:
>>>>> On 11/12/25 09:46, Dragan Simic wrote:
>>>>>> On Wednesday, November 12, 2025 00:26 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
>>>>>>> On 11/11/25 23:33, Dragan Simic wrote:
>>>>>>>> On Tuesday, November 11, 2025 12:52 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
>>>>>>>>> On 11/6/25 02:48, Joseph Kogut wrote:
>>>>>>>>>> On Wed, Nov 5, 2025 at 4:15?AM FUKAUMI Naoki <naoki at radxa.com> wrote:
>>>>>>>>>>> I'd like to clarify the situation regarding the v6 patch series I submitted.
>>>>>>>>>>>
>>>>>>>>>>> The original device tree work for the Radxa CM5 and IO Board was
>>>>>>>>>>> authored by Joseph Kogut. I took over the responsibility of getting it
>>>>>>>>>>> upstreamed with his agreement.
>>>>>>>>>>
>>>>>>>>>> I'll confirm this. I've been in communication with Naoki. They made a
>>>>>>>>>> large number of revisions to my original patch series, which I think
>>>>>>>>>> have technical merit. I suggested they submit the patches themselves,
>>>>>>>>>> and gave them explicit permission to add my Signed-off-by and CC me.
>>>>>>>>>>
>>>>>>>>>> I assume this was the correct way for them to continue the work I
>>>>>>>>>> started, but if not, please let us know the best way to proceed.
>>>>>>>>>
>>>>>>>>> Can anyone help us?
>>>>>>>>
>>>>>>>> I'm not exactly sure how to resolve the current situation, but for
>>>>>>>> Signed-off-by tags to be present, in this case you'd need to have
>>>>>>>> Co-developed-by tags as well, because the final patch versions,
>>>>>>>> which would be submitted by Naoki, would differ significantly from
>>>>>>>> the versions that Joseph actively worked on, if I understood
>>>>>>>> everything correctly.  Though, for Joseph's Signed-off-by tags to
>>>>>>>> be included there, he would also need to participate actively in
>>>>>>>> the development of the final patch versions.
>>>>>>>
>>>>>>> https://www.kernel.org/doc/html/latest/process/submitting-patches.html#when-to-use-acked-by-cc-and-co-developed-by
>>>>>>>
>>>>>>> If
>>>>>>> ----
>>>>>>> From: Joseph Kogut <joseph.kogut at gmail.com>
>>>>>>>
>>>>>>> <changelog>
>>>>>>>
>>>>>>> Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
>>>>>>> Co-developed-by: FUKAUMI Naoki <naoki at radxa.com>
>>>>>>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
>>>>>>> ----
>>>>>>> then I can submit my patch series?
>>>>>>
>>>>>> Actually, the Co-developed-by tags would be pointing to Joseph
>>>>>> in that case, but as I described it above, this approach basically
>>>>>> cannot be used, because Joseph's original work differs a lot from
>>>>>> what you'd actually submit to the mailing list(s).
>>>>>>
>>>>>>> Or,
>>>>>>>
>>>>>>>> Another option, technically a bit simpler, would be to include just
>>>>>>>> Originally-by tags for Joseph, which would indicate that Joseph gave
>>>>>>>> up on the development of the patches and handed them over to Naoki
>>>>>>>> for future development and submission to the mailing lists. Though,
>>>>>>>> that would require Joseph to publicly state exactly that.
>>>>>>>
>>>>>>> I cannot find any documentation about "Originally-by".
>>>>>>> Is this correct?
>>>>>>> ----
>>>>>>> <changelog>
>>>>>>>
>>>>>>> Originally-by: Joseph Kogut <joseph.kogut at gmail.com>
>>>>
>>>> There is no such tag. Don't invent tags.
>>>
>>> True, it doesn't exist officially, but it's been used fairly often.
>>>
>>>>>>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
>>>>>>> ----
>>>>>>
>>>>>> That approach is the only I see applicable in this case.  However,
>>>>>> let's hear opinions from other people as well.
>>>>>
>>>>> I see. I want to do this approach.
>>>>>
>>>>> Joseph, could you give me a statement to do this?
>>>>
>>>> Use standard authorship and standard tags, some of which are explained
>>>> in Submitting patches.
>>>
>>> Frankly, your suggestion is useless, because it doesn't explain what 
>>> to do in this particular case.
>>
>> Maybe because you did not read the doc...
> 
> I think you already know the answer: I read it multiple times and 
> used it as a reference more than once.

Then if you read it and saw my objection to inventing tags, you could
guess that only first solution for patches with changes coming from
multiple authors is allowed. Also you would find from that doc, that
patches which were not changed - like in this patchset - must be
attributed to single author followed by SoB. So both cases nicely
explained. Pretty simple once you remove the invented tag option,
because it is really unnecessary.


Best regards,
Krzysztof


From naoki at radxa.com  Thu Nov 13 23:37:26 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Fri, 14 Nov 2025 16:37:26 +0900
Subject: [PATCH v6 1/3] dt-bindings: arm: rockchip: Add Radxa CM5 IO Board
In-Reply-To: <2177a0f0-68df-495c-b267-18e3d9b6ca80@kernel.org>
References: <20251105051335.17652-1-naoki@radxa.com>
 <20251105051335.17652-2-naoki@radxa.com>
 <ce6e6369-a7e4-4a35-80f8-70ef41c3b877@kernel.org>
 <A6C1199E2A0D3F37+f3fe0fd5-4ca5-4d3d-bc1d-45f46b48f89b@radxa.com>
 <93deab54-bd5e-433e-acbc-13f6ead47f43@kernel.org>
 <2177a0f0-68df-495c-b267-18e3d9b6ca80@kernel.org>
Message-ID: <D88EE9EEB2B37D36+361d448f-d260-4d78-ae6b-abf1caabb94b@radxa.com>

Hi Krzysztof,

On 11/14/25 16:12, Krzysztof Kozlowski wrote:
> On 05/11/2025 08:08, Krzysztof Kozlowski wrote:
>> On 05/11/2025 07:57, FUKAUMI Naoki wrote:
>>> On 11/5/25 15:43, Krzysztof Kozlowski wrote:
>>>> On 05/11/2025 06:13, FUKAUMI Naoki wrote:
>>>>> Add device tree binding documentation for the Radxa CM5 IO Board.
>>>>>
>>>>> Link: https://dl.radxa.com/cm5/radxa_cm5_product_brief.pdf
>>>>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
>>>>> Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
>>>>
>>>> Wrong DCO chain.
>>>>
>>>>> ---
>>>>>    Documentation/devicetree/bindings/arm/rockchip.yaml | 7 +++++++
>>>>
>>>> NAK, you just stolen ownership of an already posted patch.
>>>
>>> Read "Changes in v6" and patches; my patches are not the same as v5.
>>> Your reply is totally inappropriate.
>>
>> Inappropriate is taking authorship of someone's patch, because we all
>> expect to preserve the original authorship. That's not only basic
>> decency but actually a standard.
>>
>> Additionally, read Joseph's reply that he wants to continue the work:
>> https://lore.kernel.org/all/CAMWSM7iHtAxewW4JkRqRsifVnccqeFviaCgeOyprKDr92FOurg at mail.gmail.com/
>>
>> You clearly do not understand how to continue with someone's work.
>>
>> It is still a NAK.
> 
> And I still wait for justification why you took authorship of this
> patch, because to my eye you changed here nothing.
> 
> So what did you change HERE that you think you are the author now?

Changes in v6:
(Patch 1/3)
- Fix description; "Radxa CM5" is the correct name
(Patch 2/3)
- Fix #include(s)
- Include rk3588s.dtsi
- Move alias for gmac1 from io board dts
- Add Maskrom key
- Add pinctrl-* for led-0
- Add vcc_1v1_nldo_s3 regulator for pmic
- Move gmac1 (except status) from io board dts
- Fix phy-supply for gmac1
- Fix compatible for vdd_cpu_big1_s0 regulator
- Add eeprom on i2c0
- Add vdd_npu_s0 regulator for rknn
- Fix compatible for rgmii_phy1
- Add pinctrl-* and reset-* for rgmii_phy1
- Add domain-supply for pd_npu
- Add rknn_*
- Add saradc
- Fix properties in sdhci
- Move pmic from io board dts
- Fix vcc*-supply for pmic
- Add regulators in pmic
- Add tsadc
- Move vop(_mmu) from io board dts
- Trivial changes (labels, names, etc)
(Patch 3/3)
- Fix #include(s)
- Remove #include "rk3588s.dtsi"
- Fix model
- Add fan
- Add Recovery key
- Add pinctrl-* for vcc3v3_wf
- Add vcc_sysin regulator
- Add pinctrl-* for vbus5v0_typec
- Add rfkill-bt and rfkill-wlan for M.2 module
- Add sound for es8316
- Add phy-supply for combphy2_psu
- Fix power-role to "source" for fusb302
- Add rtc for hym8536
- Add audio-codec on i2c8 for es8316
- Add i2s0_8ch for es8316
- Add package_thermal for fan
- Add pinctrl-* for pcie2x1l2
- Add pwm11 for fan
- Fix properties in sdmmmc
- Add phy-supply for u2phy2_host and u2phy3_host
- Remove usb_host0_ohci
- Add pinctrl-* for usbdp_phy0
- Trivial changes (labels, names, etc)

diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml 
b/Documentation/devicetree/bindings/arm/rockchip.yaml
index 4fb6b0e7851f9..f38bbb233bd2a 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.yaml
+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
@@ -880,13 +880,6 @@ properties:
            - const: radxa,cm3
            - const: rockchip,rk3566

-      - description: Radxa Compute Module 5 (CM5)
-        items:
-          - enum:
-              - radxa,cm5-io
-          - const: radxa,cm5
-          - const: rockchip,rk3588s
-
        - description: Radxa CM3 Industrial
          items:
            - enum:
@@ -894,6 +887,13 @@ properties:
            - const: radxa,cm3i
            - const: rockchip,rk3568

+      - description: Radxa CM5
+        items:
+          - enum:
+              - radxa,cm5-io
+          - const: radxa,cm5
+          - const: rockchip,rk3588s
+
        - description: Radxa E20C
          items:
            - const: radxa,e20c
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-radxa-cm5-io.dts 
b/arch/arm64/boot/dts/rockchip/rk3588s-radxa-cm5-io.dts
index 18e11a9c7f037..12fa8ba83212a 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-radxa-cm5-io.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-radxa-cm5-io.dts
@@ -1,23 +1,28 @@
  // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
  /*
+ * Copyright (c) 2025 Radxa Computer (Shenzhen) Co., Ltd.
   * Copyright (c) 2025 Joseph Kogut <joseph.kogut at gmail.com>
   */

  /*
- * CM5 IO board data sheet
- * https://dl.radxa.com/cm5/v2200/radxa_cm5_io_v2200_schematic.pdf
+ * CM5 IO Board schematic
+ * 
https://dl.radxa.com/cm5/io_board_v2200/radxa_cm5_io_board_v2200_schematic.pdf
   */

  /dts-v1/;
-#include "rk3588s.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pwm/pwm.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
+#include <dt-bindings/usb/pd.h>
  #include "rk3588s-radxa-cm5.dtsi"

  / {
-	model = "Radxa Compute Module 5 (CM5) IO Board";
+	model = "Radxa CM5 IO Board";
  	compatible = "radxa,cm5-io", "radxa,cm5", "rockchip,rk3588s";

  	aliases {
-		ethernet0 = &gmac1;
  		mmc1 = &sdmmc;
  	};

@@ -25,18 +30,40 @@ chosen {
  		stdout-path = "serial2:1500000n8";
  	};

-	hdmi-con {
+	fan: fan {
+		compatible = "pwm-fan";
+		#cooling-cells = <2>;
+		cooling-levels = <0 64 128 192 255>;
+		fan-supply = <&vcc5v0_sys>;
+		pwms = <&pwm11 0 60000 0>;
+	};
+
+	hdmi0-con {
  		compatible = "hdmi-connector";
  		type = "a";

  		port {
-			hdmi_con_in: endpoint {
+			hdmi0_con_in: endpoint {
  				remote-endpoint = <&hdmi0_out_con>;
  			};
  		};
  	};

-	vcc12v_dcin: regulator-12v0-vcc-dcin {
+	keys-1 {
+		compatible = "adc-keys";
+		io-channels = <&saradc 1>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <1800000>;
+		poll-interval = <100>;
+
+		button-1 {
+			label = "Recovery";
+			linux,code = <KEY_VENDOR>;
+			press-threshold-microvolt = <0>;
+		};
+	};
+
+	vcc12v_dcin: regulator-12v0 {
  		compatible = "regulator-fixed";
  		regulator-name = "vcc12v_dcin";
  		regulator-always-on;
@@ -45,21 +72,29 @@ vcc12v_dcin: regulator-12v0-vcc-dcin {
  		regulator-max-microvolt = <12000000>;
  	};

-	vcc5v0_host: vcc5v0-host-regulator {
+	vcc3v3_wf: regulator-3v3 {
  		compatible = "regulator-fixed";
-		regulator-name = "vcc5v0_host";
-		regulator-boot-on;
-		regulator-always-on;
-		regulator-min-microvolt = <5000000>;
-		regulator-max-microvolt = <5000000>;
  		enable-active-high;
-		gpio = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>;
+		gpio = <&gpio1 RK_PD3 GPIO_ACTIVE_HIGH>;
  		pinctrl-names = "default";
-		pinctrl-0 = <&vcc5v0_host_en>;
+		pinctrl-0 = <&wifi_pwr_en>;
+		regulator-name = "vcc3v3_wf";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+
+	vcc_sysin: regulator-4v0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_sysin";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <4000000>;
+		regulator-max-microvolt = <4000000>;
  		vin-supply = <&vcc5v0_sys>;
  	};

-	vcc5v0_sys: regulator-5v0-sys {
+	vcc5v0_sys: vcc5v0_usb: regulator-5v0-0 {
  		compatible = "regulator-fixed";
  		regulator-name = "vcc5v0_sys";
  		regulator-always-on;
@@ -69,43 +104,55 @@ vcc5v0_sys: regulator-5v0-sys {
  		vin-supply = <&vcc12v_dcin>;
  	};

-	vbus5v0_typec: vbus5v0-typec {
+	vcc5v0_usb1: regulator-5v0-1 {
  		compatible = "regulator-fixed";
-		regulator-name = "vbus5v0_typec";
-		gpio = <&gpio0 RK_PD5 GPIO_ACTIVE_HIGH>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&vbus5v0_typec_en>;
  		enable-active-high;
+		gpio = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&usb_host_pwren_h>;
+		regulator-name = "vcc5v0_usb1";
  		regulator-min-microvolt = <5000000>;
  		regulator-max-microvolt = <5000000>;
-		vin-supply = <&vcc5v0_sys>;
+		vin-supply = <&vcc5v0_usb>;
  	};

-	vcc3v3_pcie: regulator-3v3-vcc-pcie {
+	vbus5v0_typec: regulator-5v0-2 {
  		compatible = "regulator-fixed";
-		regulator-name = "vcc3v3_pcie2x1l0";
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
  		enable-active-high;
-		regulator-boot-on;
-		regulator-always-on;
-		gpios = <&gpio1 RK_PD3 GPIO_ACTIVE_HIGH>;
-		startup-delay-us = <50000>;
+		gpio = <&gpio0 RK_PD5 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&typec5v_pwren_h>;
+		regulator-name = "vbus5v0_typec";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
  		vin-supply = <&vcc5v0_sys>;
  	};

-	vcc_3v3_s0: pldo-reg4 {
-		compatible = "regulator-fixed";
-		regulator-name = "vcc_3v3_s0";
-		regulator-always-on;
-		regulator-boot-on;
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		regulator-ramp-delay = <12500>;
+	rfkill-bt {
+		compatible = "rfkill-gpio";
+		pinctrl-names = "default";
+		pinctrl-0 = <&host_wake_bt_h>;
+		radio-type = "bluetooth";
+		shutdown-gpios = <&gpio0 RK_PC6 GPIO_ACTIVE_HIGH>;
+	};

-		regulator-state-mem {
-			regulator-off-in-suspend;
-		};
+	rfkill-wlan {
+		compatible = "rfkill-gpio";
+		pinctrl-names = "default";
+		pinctrl-0 = <&bt_reg_on_h>;
+		radio-type = "wlan";
+		shutdown-gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>;
+	};
+
+	sound {
+		compatible = "audio-graph-card";
+		label = "rk3588-es8316";
+		dais = <&i2s0_8ch_p0>;
+		routing = "MIC2", "Mic Jack",
+			  "Headphones", "HPOL",
+			  "Headphones", "HPOR";
+		widgets = "Microphone", "Mic Jack",
+			  "Headphone", "Headphones";
  	};
  };

@@ -114,21 +161,11 @@ &combphy0_ps {
  };

  &combphy2_psu {
+	phy-supply = <&vcc5v0_usb1>;
  	status = "okay";
  };

  &gmac1 {
-	clock_in_out = "output";
-	phy-handle = <&rgmii_phy1>;
-	phy-mode = "rgmii-id";
-	phy-supply = <&vcc_3v3_s0>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&gmac1_miim
-		     &gmac1_tx_bus2
-		     &gmac1_rx_bus2
-		     &gmac1_rgmii_clk
-		     &gmac1_rgmii_bus
-		     &gmac1_clkinout>;
  	status = "okay";
  };

@@ -144,7 +181,7 @@ hdmi0_in_vp0: endpoint {

  &hdmi0_out {
  	hdmi0_out_con: endpoint {
-		remote-endpoint = <&hdmi_con_in>;
+		remote-endpoint = <&hdmi0_con_in>;
  	};
  };

@@ -161,24 +198,24 @@ &i2c6 {
  	pinctrl-0 = <&i2c6m3_xfer>;
  	status = "okay";

-	fusb302: usb-typec at 22 {
+	usb-typec at 22 {
  		compatible = "fcs,fusb302";
  		reg = <0x22>;
  		interrupt-parent = <&gpio0>;
  		interrupts = <RK_PC4 IRQ_TYPE_LEVEL_LOW>;
  		pinctrl-names = "default";
-		pinctrl-0 = <&usbc0_int>;
+		pinctrl-0 = <&cc_int0_l>;
  		vbus-supply = <&vbus5v0_typec>;

  		connector {
  			compatible = "usb-c-connector";
  			data-role = "dual";
  			label = "USB-C";
-			power-role = "dual";
-			try-power-role = "sink";
-			source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
-			sink-pdos = <PDO_FIXED(5000, 1000, PDO_FIXED_USB_COMM)>;
-			op-sink-microwatt = <1000000>;
+			/* fusb302 supports PD Rev 2.0 Ver 1.2 */
+			pd-revision = /bits/ 8 <0x2 0x0 0x1 0x2>;
+			power-role = "source";
+			source-pdos =
+				<PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;

  			ports {
  				#address-cells = <1>;
@@ -186,205 +223,194 @@ ports {

  				port at 0 {
  					reg = <0>;
-					usbc0_orientation_switch: endpoint {
-						remote-endpoint = <&usbdp_phy0_orientation_switch>;
+
+					usbc0_hs: endpoint {
+						remote-endpoint = <&usb_host0_xhci_to_usbc0>;
  					};
  				};

  				port at 1 {
  					reg = <1>;
-					usbc0_role_switch: endpoint {
-						remote-endpoint = <&usb_host0_xhci_role_switch>;
+
+					usbc0_ss: endpoint {
+						remote-endpoint = <&usbdp_phy0_ss>;
  					};
  				};

  				port at 2 {
  					reg = <2>;
-					usbc0_dp_altmode_mux: endpoint {
-						remote-endpoint = <&usbdp_phy0_dp_altmode_mux>;
+
+					usbc0_sbu: endpoint {
+						remote-endpoint = <&usbdp_phy0_sbu>;
  					};
  				};
  			};
  		};
  	};
-};

-&i2s5_8ch {
-	status = "okay";
+	rtc at 51 {
+		compatible = "haoyu,hym8563";
+		reg = <0x51>;
+		#clock-cells = <0>;
+		clock-output-names = "rtc_32k_in";
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&rtc_int_l>;
+		wakeup-source;
+	};
  };

-&pcie2x1l2 {
-	reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
-	vpcie3v3-supply = <&vcc3v3_pcie>;
+&i2c8 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c8m2_xfer>;
  	status = "okay";
-};

-&pinctrl {
-	fusb302 {
-		vbus5v0_typec_en: vbus5v0-typec-en {
-			rockchip,pins = <0 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
-		};
+	audio-codec at 11 {
+		compatible = "everest,es8316";
+		reg = <0x11>;
+		assigned-clocks = <&cru I2S0_8CH_MCLKOUT>;
+		assigned-clock-rates = <12288000>;
+		clocks = <&cru I2S0_8CH_MCLKOUT>;
+		clock-names = "mclk";
+		#sound-dai-cells = <0>;

-		usbc0_int: usbc0-int {
-			rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_up>;
+		port {
+			es8316_p0_0: endpoint {
+				remote-endpoint = <&i2s0_8ch_p0_0>;
+			};
  		};
  	};
+};

-	usb {
-		vcc5v0_host_en: vcc5v0-host-en {
-			rockchip,pins = <1 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
+&i2s0_8ch {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2s0_lrck
+		     &i2s0_mclk
+		     &i2s0_sclk
+		     &i2s0_sdi0
+		     &i2s0_sdo0>;
+	status = "okay";
+
+	i2s0_8ch_p0: port {
+		i2s0_8ch_p0_0: endpoint {
+			dai-format = "i2s";
+			mclk-fs = <256>;
+			remote-endpoint = <&es8316_p0_0>;
  		};
  	};
  };

-&sdmmc {
-	bus-width = <4>;
-	cap-mmc-highspeed;
-	cap-sd-highspeed;
-	disable-wp;
-	max-frequency = <200000000>;
-	no-sdio;
-	no-mmc;
-	sd-uhs-sdr104;
-	pinctrl-names = "default";
-	pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd &sdmmc_det>;
-	vmmc-supply = <&vcc_3v3_s3>;
-	vqmmc-supply = <&vccio_sd_s0>;
+&i2s5_8ch {
  	status = "okay";
  };

-&spi2 {
-	assigned-clocks = <&cru CLK_SPI2>;
-	assigned-clock-rates = <200000000>;
-	num-cs = <1>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
-	status = "okay";
+&package_thermal {
+	polling-delay = <1000>;

-	pmic at 0 {
-		compatible = "rockchip,rk806";
-		reg = <0x0>;
-		interrupt-parent = <&gpio0>;
-		interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
-			    <&rk806_dvs2_null>, <&rk806_dvs3_null>;
-		spi-max-frequency = <1000000>;
-		system-power-controller;
-
-		vcc1-supply = <&vcc5v0_sys>;
-		vcc2-supply = <&vcc5v0_sys>;
-		vcc3-supply = <&vcc5v0_sys>;
-		vcc4-supply = <&vcc5v0_sys>;
-		vcc5-supply = <&vcc5v0_sys>;
-		vcc6-supply = <&vcc5v0_sys>;
-		vcc7-supply = <&vcc5v0_sys>;
-		vcc8-supply = <&vcc5v0_sys>;
-		vcc9-supply = <&vcc5v0_sys>;
-		vcc10-supply = <&vcc5v0_sys>;
-		vcc11-supply = <&vcc_2v0_pldo_s3>;
-		vcc12-supply = <&vcc5v0_sys>;
-		vcc13-supply = <&vdd2_ddr_s3>;
-		vcc14-supply = <&vdd2_ddr_s3>;
-		vcca-supply = <&vcc5v0_sys>;
-
-		gpio-controller;
-		#gpio-cells = <2>;
-
-		rk806_dvs1_null: dvs1-null-pins {
-			pins = "gpio_pwrctrl1";
-			function = "pin_fun0";
+	trips {
+		package_fan0: package-fan0 {
+			hysteresis = <2000>;
+			temperature = <55000>;
+			type = "active";
  		};

-		rk806_dvs2_null: dvs2-null-pins {
-			pins = "gpio_pwrctrl2";
-			function = "pin_fun0";
+		package_fan1: package-fan1 {
+			hysteresis = <2000>;
+			temperature = <65000>;
+			type = "active";
  		};
+	};

-		rk806_dvs3_null: dvs3-null-pins {
-			pins = "gpio_pwrctrl3";
-			function = "pin_fun0";
+	cooling-maps {
+		map0 {
+			cooling-device = <&fan THERMAL_NO_LIMIT 1>;
+			trip = <&package_fan0>;
  		};

-		regulators {
-			vdd_gpu_s0: dcdc-reg1 {
-				regulator-name = "vdd_gpu_s0";
-				regulator-boot-on;
-				regulator-enable-ramp-delay = <400>;
-				regulator-min-microvolt = <550000>;
-				regulator-max-microvolt = <950000>;
-				regulator-ramp-delay = <12500>;
-
-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
+		map1 {
+			cooling-device = <&fan 2 THERMAL_NO_LIMIT>;
+			trip = <&package_fan1>;
+		};
+	};
+};

-			vdd_cpu_lit_s0: dcdc-reg2 {
-				regulator-name = "vdd_cpu_lit_s0";
-				regulator-always-on;
-				regulator-boot-on;
-				regulator-min-microvolt = <550000>;
-				regulator-max-microvolt = <950000>;
-				regulator-ramp-delay = <12500>;
+&pcie2x1l2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie20x1_2_perstn_m0>;
+	reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
+	vpcie3v3-supply = <&vcc3v3_wf>;
+	status = "okay";
+};

-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
+&pinctrl {
+	pcie {
+		pcie20x1_2_perstn_m0: pcie20x1-2-perstn-m0 {
+			rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
+		};

-			vccio_sd_s0: pldo-reg5 {
-				regulator-always-on;
-				regulator-boot-on;
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <3300000>;
-				regulator-name = "vccio_sd_s0";
+		wifi_pwr_en: wifi-pwr-en {
+			rockchip,pins = <1 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};

-				regulator-state-mem {
-					regulator-off-in-suspend;
-				};
-			};
+	rfkill {
+		bt_reg_on_h: bt-reg-on-h {
+			rockchip,pins = <0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_down>;
+		};

-			vdd2_ddr_s3: dcdc-reg6 {
-				regulator-name = "vdd2_ddr_s3";
-				regulator-always-on;
-				regulator-boot-on;
+		host_wake_bt_h: host-wake-bt-h {
+			rockchip,pins = <0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+	};

-				regulator-state-mem {
-					regulator-on-in-suspend;
-				};
-			};
+	rtc {
+		rtc_int_l: rtc-int-l {
+			rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};

-			vcc_2v0_pldo_s3: dcdc-reg7 {
-				regulator-name = "vdd_2v0_pldo_s3";
-				regulator-always-on;
-				regulator-boot-on;
-				regulator-min-microvolt = <2000000>;
-				regulator-max-microvolt = <2000000>;
-				regulator-ramp-delay = <12500>;
-
-				regulator-state-mem {
-					regulator-on-in-suspend;
-					regulator-suspend-microvolt = <2000000>;
-				};
-			};
+	usb {
+		cc_int0_l: cc-int0-l {
+			rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		usb_host_pwren_h: usb-host-pwren-h {
+			rockchip,pins = <1 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
+		};

-			vcc_3v3_s3: dcdc-reg8 {
-				regulator-name = "vcc_3v3_s3";
-				regulator-always-on;
-				regulator-boot-on;
-				regulator-min-microvolt = <3300000>;
-				regulator-max-microvolt = <3300000>;
+		usbc_sbu_dc: usbc-sbu-dc {
+			rockchip,pins = <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>,
+					<3 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};

-				regulator-state-mem {
-					regulator-on-in-suspend;
-					regulator-suspend-microvolt = <3300000>;
-				};
-			};
+		typec5v_pwren_h: typec5v-pwren-h {
+			rockchip,pins = <0 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
  		};
  	};
  };

+&pwm11 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pwm11m3_pins>;
+	status = "okay";
+};
+
+&sdmmc {
+	bus-width = <4>;
+	cap-mmc-highspeed;
+	cap-sd-highspeed;
+	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
+	disable-wp;
+	no-sdio;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd>;
+	sd-uhs-sdr104;
+	vmmc-supply = <&vcc_3v3_s3>;
+	vqmmc-supply = <&vccio_sd_s0>;
+	status = "okay";
+};
+
  &u2phy0 {
  	status = "okay";
  };
@@ -398,6 +424,7 @@ &u2phy2 {
  };

  &u2phy2_host {
+	phy-supply = <&vcc5v0_usb1>;
  	status = "okay";
  };

@@ -406,6 +433,7 @@ &u2phy3 {
  };

  &u2phy3_host {
+	phy-supply = <&vcc5v0_usb1>;
  	status = "okay";
  };

@@ -419,18 +447,13 @@ &usb_host0_ehci {
  	status = "okay";
  };

-&usb_host0_ohci {
-	status = "okay";
-};
-
  &usb_host0_xhci {
-	dr_mode = "otg";
  	usb-role-switch;
  	status = "okay";

  	port {
-		usb_host0_xhci_role_switch: endpoint {
-			remote-endpoint = <&usbc0_role_switch>;
+		usb_host0_xhci_to_usbc0: endpoint {
+			remote-endpoint = <&usbc0_hs>;
  		};
  	};
  };
@@ -450,6 +473,8 @@ &usb_host2_xhci {
  &usbdp_phy0 {
  	mode-switch;
  	orientation-switch;
+	pinctrl-names = "default";
+	pinctrl-0 = <&usbc_sbu_dc>;
  	sbu1-dc-gpios = <&gpio3 RK_PC4 GPIO_ACTIVE_HIGH>;
  	sbu2-dc-gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_HIGH>;
  	status = "okay";
@@ -458,26 +483,18 @@ port {
  		#address-cells = <1>;
  		#size-cells = <0>;

-		usbdp_phy0_orientation_switch: endpoint at 0 {
+		usbdp_phy0_ss: endpoint at 0 {
  			reg = <0>;
-			remote-endpoint = <&usbc0_orientation_switch>;
+			remote-endpoint = <&usbc0_ss>;
  		};

-		usbdp_phy0_dp_altmode_mux: endpoint at 1 {
+		usbdp_phy0_sbu: endpoint at 1 {
  			reg = <1>;
-			remote-endpoint = <&usbc0_dp_altmode_mux>;
+			remote-endpoint = <&usbc0_sbu>;
  		};
  	};
  };

-&vop {
-	status = "okay";
-};
-
-&vop_mmu {
-	status = "okay";
-};
-
  &vp0 {
  	vp0_out_hdmi0: endpoint at ROCKCHIP_VOP2_EP_HDMI0 {
  		reg = <ROCKCHIP_VOP2_EP_HDMI0>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-radxa-cm5.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3588s-radxa-cm5.dtsi
index 6410ea5255dc7..f2da73126c1fe 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-radxa-cm5.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-radxa-cm5.dtsi
@@ -1,36 +1,67 @@
  // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
  /*
+ * Copyright (c) 2025 Radxa Computer (Shenzhen) Co., Ltd.
   * Copyright (c) 2025 Joseph Kogut <joseph.kogut at gmail.com>
   */

  /*
- * CM5 data sheet
+ * CM5 schematic
   * https://dl.radxa.com/cm5/v2210/radxa_cm5_v2210_schematic.pdf
   */

+/dts-v1/;
+
  #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
  #include <dt-bindings/leds/common.h>
-#include <dt-bindings/soc/rockchip,vop2.h>
-#include <dt-bindings/usb/pd.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rk3588s.dtsi"

  / {
  	compatible = "radxa,cm5", "rockchip,rk3588s";

  	aliases {
+		ethernet0 = &gmac1;
  		mmc0 = &sdhci;
  	};

-	leds {
+	keys-0 {
+		compatible = "adc-keys";
+		io-channels = <&saradc 0>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <1800000>;
+		poll-interval = <100>;
+
+		button-0 {
+			label = "Maskrom";
+			linux,code = <KEY_SETUP>;
+			press-threshold-microvolt = <0>;
+		};
+	};
+
+	leds-0 {
  		compatible = "gpio-leds";

-		led_sys: led-0 {
+		led-0 {
  			color = <LED_COLOR_ID_BLUE>;
  			default-state = "on";
-			function = LED_FUNCTION_HEARTBEAT;
+			function = LED_FUNCTION_STATUS;
  			gpios = <&gpio4 RK_PB4 GPIO_ACTIVE_HIGH>;
  			linux,default-trigger = "heartbeat";
+			pinctrl-names = "default";
+			pinctrl-0 = <&gpio4_b4>;
  		};
  	};
+
+	vcc_1v1_nldo_s3: regulator-1v1 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_1v1_nldo_s3";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <1100000>;
+		regulator-max-microvolt = <1100000>;
+		vin-supply = <&vcc_sysin>;
+	};
  };

  &cpu_b0 {
@@ -65,6 +96,20 @@ &cpu_l3 {
  	cpu-supply = <&vdd_cpu_lit_s0>;
  };

+&gmac1 {
+	clock_in_out = "output";
+	phy-handle = <&rgmii_phy1>;
+	phy-mode = "rgmii-id";
+	phy-supply = <&vcc_3v3_s3>;
+	pinctrl-0 = <&gmac1_miim
+		     &gmac1_tx_bus2
+		     &gmac1_rx_bus2
+		     &gmac1_rgmii_clk
+		     &gmac1_rgmii_bus
+		     &gmac1_clkinout>;
+	pinctrl-names = "default";
+};
+
  &gpu {
  	mali-supply = <&vdd_gpu_s0>;
  	status = "okay";
@@ -85,7 +130,7 @@ vdd_cpu_big0_s0: regulator at 42 {
  		regulator-min-microvolt = <550000>;
  		regulator-max-microvolt = <1050000>;
  		regulator-ramp-delay = <2300>;
-		vin-supply = <&vcc5v0_sys>;
+		vin-supply = <&vcc_sysin>;

  		regulator-state-mem {
  			regulator-off-in-suspend;
@@ -93,7 +138,7 @@ regulator-state-mem {
  	};

  	vdd_cpu_big1_s0: regulator at 43 {
-		compatible = "rockchip,rk8602";
+		compatible = "rockchip,rk8603", "rockchip,rk8602";
  		reg = <0x43>;
  		fcs,suspend-voltage-selector = <1>;
  		regulator-name = "vdd_cpu_big1_s0";
@@ -102,7 +147,36 @@ vdd_cpu_big1_s0: regulator at 43 {
  		regulator-min-microvolt = <550000>;
  		regulator-max-microvolt = <1050000>;
  		regulator-ramp-delay = <2300>;
-		vin-supply = <&vcc5v0_sys>;
+		vin-supply = <&vcc_sysin>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+
+	eeprom at 50 {
+		compatible = "belling,bl24c16a", "atmel,24c16";
+		reg = <0x50>;
+		pagesize = <16>;
+		read-only;
+		vcc-supply = <&vcc_3v3_s3>;
+	};
+};
+
+&i2c2 {
+	status = "okay";
+
+	vdd_npu_s0: regulator at 42 {
+		compatible = "rockchip,rk8602";
+		reg = <0x42>;
+		fcs,suspend-voltage-selector = <1>;
+		regulator-name = "vdd_npu_s0";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <550000>;
+		regulator-max-microvolt = <950000>;
+		regulator-ramp-delay = <2300>;
+		vin-supply = <&vcc_sysin>;

  		regulator-state-mem {
  			regulator-off-in-suspend;
@@ -111,9 +185,14 @@ regulator-state-mem {
  };

  &mdio1 {
-	rgmii_phy1: phy at 1 {
-		compatible = "ethernet-phy-ieee802.3-c22";
-		reg = <0x1>;
+	rgmii_phy1: ethernet-phy at 1 {
+		compatible = "ethernet-phy-id001c.c916";
+		reg = <1>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&gmac1_rstn>;
+		reset-assert-us = <20000>;
+		reset-deassert-us = <100000>;
+		reset-gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>;
  	};
  };

@@ -121,15 +200,403 @@ &pd_gpu {
  	domain-supply = <&vdd_gpu_s0>;
  };

+&pd_npu {
+	domain-supply = <&vdd_npu_s0>;
+};
+
+&pinctrl {
+	ethernet {
+		gmac1_rstn: gmac1-rstn {
+			rockchip,pins = <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	leds {
+		gpio4_b4: gpio4-b4 {
+			rockchip,pins = <4 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
+
+&rknn_core_0 {
+	npu-supply = <&vdd_npu_s0>;
+	sram-supply = <&vdd_npu_s0>;
+	status = "okay";
+};
+
+&rknn_core_1 {
+	npu-supply = <&vdd_npu_s0>;
+	sram-supply = <&vdd_npu_s0>;
+	status = "okay";
+};
+
+&rknn_core_2 {
+	npu-supply = <&vdd_npu_s0>;
+	sram-supply = <&vdd_npu_s0>;
+	status = "okay";
+};
+
+&rknn_mmu_0 {
+	status = "okay";
+};
+
+&rknn_mmu_1 {
+	status = "okay";
+};
+
+&rknn_mmu_2 {
+	status = "okay";
+};
+
+&saradc {
+	vref-supply = <&vcca_1v8_s0>;
+	status = "okay";
+};
+
  &sdhci {
  	bus-width = <8>;
-	no-sdio;
-	no-sd;
-	non-removable;
-	max-frequency = <200000000>;
+	cap-mmc-highspeed;
  	mmc-hs400-1_8v;
  	mmc-hs400-enhanced-strobe;
-	mmc-hs200-1_8v;
+	no-sd;
+	no-sdio;
+	non-removable;
+	vmmc-supply = <&vcc_3v3_s3>;
+	vqmmc-supply = <&vcc_1v8_s3>;
+	status = "okay";
+};
+
+&spi2 {
+	assigned-clocks = <&cru CLK_SPI2>;
+	assigned-clock-rates = <200000000>;
+	num-cs = <1>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
+	status = "okay";
+
+	pmic at 0 {
+		compatible = "rockchip,rk806";
+		reg = <0>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
+			    <&rk806_dvs2_null>, <&rk806_dvs3_null>;
+		spi-max-frequency = <1000000>;
+		system-power-controller;
+
+		vcc1-supply = <&vcc_sysin>;
+		vcc2-supply = <&vcc_sysin>;
+		vcc3-supply = <&vcc_sysin>;
+		vcc4-supply = <&vcc_sysin>;
+		vcc5-supply = <&vcc_sysin>;
+		vcc6-supply = <&vcc_sysin>;
+		vcc7-supply = <&vcc_sysin>;
+		vcc8-supply = <&vcc_sysin>;
+		vcc9-supply = <&vcc_sysin>;
+		vcc10-supply = <&vcc_sysin>;
+		vcc11-supply = <&vcc_2v0_pldo_s3>;
+		vcc12-supply = <&vcc_sysin>;
+		vcc13-supply = <&vcc_1v1_nldo_s3>;
+		vcc14-supply = <&vcc_1v1_nldo_s3>;
+		vcca-supply = <&vcc_sysin>;
+
+		rk806_dvs1_null: dvs1-null-pins {
+			pins = "gpio_pwrctrl1";
+			function = "pin_fun0";
+		};
+
+		rk806_dvs2_null: dvs2-null-pins {
+			pins = "gpio_pwrctrl2";
+			function = "pin_fun0";
+		};
+
+		rk806_dvs3_null: dvs3-null-pins {
+			pins = "gpio_pwrctrl3";
+			function = "pin_fun0";
+		};
+
+		regulators {
+			vdd_gpu_s0: dcdc-reg1 {
+				regulator-name = "vdd_gpu_s0";
+				regulator-boot-on;
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <950000>;
+				regulator-ramp-delay = <12500>;
+				regulator-enable-ramp-delay = <400>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_cpu_lit_s0: dcdc-reg2 {
+				regulator-name = "vdd_cpu_lit_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <950000>;
+				regulator-ramp-delay = <12500>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_logic_s0: dcdc-reg3 {
+				regulator-name = "vdd_logic_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <675000>;
+				regulator-max-microvolt = <800000>;
+				regulator-ramp-delay = <12500>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <750000>;
+				};
+			};
+
+			vdd_vdenc_s0: dcdc-reg4 {
+				regulator-name = "vdd_vdenc_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <550000>;
+				regulator-max-microvolt = <950000>;
+				regulator-ramp-delay = <12500>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_ddr_s0: dcdc-reg5 {
+				regulator-name = "vdd_ddr_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <675000>;
+				regulator-max-microvolt = <900000>;
+				regulator-ramp-delay = <12500>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+					regulator-suspend-microvolt = <850000>;
+				};
+			};
+
+			vdd2_ddr_s3: dcdc-reg6 {
+				regulator-name = "vdd2_ddr_s3";
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			vcc_2v0_pldo_s3: dcdc-reg7 {
+				regulator-name = "vcc_2v0_pldo_s3";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <2000000>;
+				regulator-max-microvolt = <2000000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <2000000>;
+				};
+			};
+
+			vcc_3v3_s0: vcc_3v3_s3: dcdc-reg8 {
+				regulator-name = "vcc_3v3_s3";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vddq_ddr_s0: dcdc-reg9 {
+				regulator-name = "vddq_ddr_s0";
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_1v8_s3: dcdc-reg10 {
+				regulator-name = "vcc_1v8_s3";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vcc_1v8_s0: pldo-reg1 {
+				regulator-name = "vcc_1v8_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vcca_1v8_s0: pldo-reg2 {
+				regulator-name = "vcca_1v8_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vdda_1v2_s0: pldo-reg3 {
+				regulator-name = "vdda_1v2_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcca_3v3_s0: pldo-reg4 {
+				regulator-name = "vcca_3v3_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vccio_sd_s0: pldo-reg5 {
+				regulator-name = "vccio_sd_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			pldo-reg6 {
+				regulator-name = "pldo_reg6";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vdd_0v75_s3: nldo-reg1 {
+				regulator-name = "vdd_0v75_s3";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <750000>;
+				regulator-max-microvolt = <750000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <750000>;
+				};
+			};
+
+			vdda_ddr_pll_s0: nldo-reg2 {
+				regulator-name = "vdda_ddr_pll_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <850000>;
+				};
+			};
+
+			vdda_0v75_s0: nldo-reg3 {
+				regulator-name = "vdda_0v75_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <837500>;
+				regulator-max-microvolt = <837500>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <750000>;
+				};
+			};
+
+			vdda_0v85_s0: nldo-reg4 {
+				regulator-name = "vdda_0v85_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <850000>;
+				regulator-max-microvolt = <850000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			hdmi_vdda0v85_s0: nldo-reg5 {
+				regulator-name = "hdmi_vdda0v85_s0";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <837500>;
+				regulator-max-microvolt = <837500>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+		};
+	};
+};
+
+&tsadc {
+	rockchip,hw-tshut-mode = <1>; /* tshut mode 0:CRU 1:GPIO */
+	rockchip,hw-tshut-polarity = <0>; /* tshut polarity 0:LOW 1:HIGH */
+	status = "okay";
+};
+
+&vop {
  	status = "okay";
  };

+&vop_mmu {
+	status = "okay";
+};

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> Best regards,
> Krzysztof
> 



From krzk at kernel.org  Thu Nov 13 23:42:22 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 14 Nov 2025 08:42:22 +0100
Subject: [PATCH v6 1/3] dt-bindings: arm: rockchip: Add Radxa CM5 IO Board
In-Reply-To: <D88EE9EEB2B37D36+361d448f-d260-4d78-ae6b-abf1caabb94b@radxa.com>
References: <20251105051335.17652-1-naoki@radxa.com>
 <20251105051335.17652-2-naoki@radxa.com>
 <ce6e6369-a7e4-4a35-80f8-70ef41c3b877@kernel.org>
 <A6C1199E2A0D3F37+f3fe0fd5-4ca5-4d3d-bc1d-45f46b48f89b@radxa.com>
 <93deab54-bd5e-433e-acbc-13f6ead47f43@kernel.org>
 <2177a0f0-68df-495c-b267-18e3d9b6ca80@kernel.org>
 <D88EE9EEB2B37D36+361d448f-d260-4d78-ae6b-abf1caabb94b@radxa.com>
Message-ID: <b2833988-6319-4426-8a25-c0d34acffa47@kernel.org>

On 14/11/2025 08:37, FUKAUMI Naoki wrote:
> Hi Krzysztof,
> 
> On 11/14/25 16:12, Krzysztof Kozlowski wrote:
>> On 05/11/2025 08:08, Krzysztof Kozlowski wrote:
>>> On 05/11/2025 07:57, FUKAUMI Naoki wrote:
>>>> On 11/5/25 15:43, Krzysztof Kozlowski wrote:
>>>>> On 05/11/2025 06:13, FUKAUMI Naoki wrote:
>>>>>> Add device tree binding documentation for the Radxa CM5 IO Board.
>>>>>>
>>>>>> Link: https://dl.radxa.com/cm5/radxa_cm5_product_brief.pdf
>>>>>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
>>>>>> Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
>>>>>
>>>>> Wrong DCO chain.
>>>>>
>>>>>> ---
>>>>>>    Documentation/devicetree/bindings/arm/rockchip.yaml | 7 +++++++
>>>>>
>>>>> NAK, you just stolen ownership of an already posted patch.
>>>>
>>>> Read "Changes in v6" and patches; my patches are not the same as v5.
>>>> Your reply is totally inappropriate.
>>>
>>> Inappropriate is taking authorship of someone's patch, because we all
>>> expect to preserve the original authorship. That's not only basic
>>> decency but actually a standard.
>>>
>>> Additionally, read Joseph's reply that he wants to continue the work:
>>> https://lore.kernel.org/all/CAMWSM7iHtAxewW4JkRqRsifVnccqeFviaCgeOyprKDr92FOurg at mail.gmail.com/
>>>
>>> You clearly do not understand how to continue with someone's work.
>>>
>>> It is still a NAK.
>>
>> And I still wait for justification why you took authorship of this
>> patch, because to my eye you changed here nothing.
>>
>> So what did you change HERE that you think you are the author now?
> 
> Changes in v6:
> (Patch 1/3)
> - Fix description; "Radxa CM5" is the correct name

HERE, in this patch. Don't paste me hundreds of unrelated code. Write
concise and precise answers/comments.

Best regards,
Krzysztof


From naoki at radxa.com  Thu Nov 13 23:47:03 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Fri, 14 Nov 2025 16:47:03 +0900
Subject: [PATCH v6 1/3] dt-bindings: arm: rockchip: Add Radxa CM5 IO Board
In-Reply-To: <b2833988-6319-4426-8a25-c0d34acffa47@kernel.org>
References: <20251105051335.17652-1-naoki@radxa.com>
 <20251105051335.17652-2-naoki@radxa.com>
 <ce6e6369-a7e4-4a35-80f8-70ef41c3b877@kernel.org>
 <A6C1199E2A0D3F37+f3fe0fd5-4ca5-4d3d-bc1d-45f46b48f89b@radxa.com>
 <93deab54-bd5e-433e-acbc-13f6ead47f43@kernel.org>
 <2177a0f0-68df-495c-b267-18e3d9b6ca80@kernel.org>
 <D88EE9EEB2B37D36+361d448f-d260-4d78-ae6b-abf1caabb94b@radxa.com>
 <b2833988-6319-4426-8a25-c0d34acffa47@kernel.org>
Message-ID: <B6224BD6578686FF+dc81e00c-46f6-4791-af8a-99cf8e880f0c@radxa.com>

On 11/14/25 16:42, Krzysztof Kozlowski wrote:
> On 14/11/2025 08:37, FUKAUMI Naoki wrote:
>> Hi Krzysztof,
>>
>> On 11/14/25 16:12, Krzysztof Kozlowski wrote:
>>> On 05/11/2025 08:08, Krzysztof Kozlowski wrote:
>>>> On 05/11/2025 07:57, FUKAUMI Naoki wrote:
>>>>> On 11/5/25 15:43, Krzysztof Kozlowski wrote:
>>>>>> On 05/11/2025 06:13, FUKAUMI Naoki wrote:
>>>>>>> Add device tree binding documentation for the Radxa CM5 IO Board.
>>>>>>>
>>>>>>> Link: https://dl.radxa.com/cm5/radxa_cm5_product_brief.pdf
>>>>>>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
>>>>>>> Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
>>>>>>
>>>>>> Wrong DCO chain.
>>>>>>
>>>>>>> ---
>>>>>>>     Documentation/devicetree/bindings/arm/rockchip.yaml | 7 +++++++
>>>>>>
>>>>>> NAK, you just stolen ownership of an already posted patch.
>>>>>
>>>>> Read "Changes in v6" and patches; my patches are not the same as v5.
>>>>> Your reply is totally inappropriate.
>>>>
>>>> Inappropriate is taking authorship of someone's patch, because we all
>>>> expect to preserve the original authorship. That's not only basic
>>>> decency but actually a standard.
>>>>
>>>> Additionally, read Joseph's reply that he wants to continue the work:
>>>> https://lore.kernel.org/all/CAMWSM7iHtAxewW4JkRqRsifVnccqeFviaCgeOyprKDr92FOurg at mail.gmail.com/
>>>>
>>>> You clearly do not understand how to continue with someone's work.
>>>>
>>>> It is still a NAK.
>>>
>>> And I still wait for justification why you took authorship of this
>>> patch, because to my eye you changed here nothing.
>>>
>>> So what did you change HERE that you think you are the author now?
>>
>> Changes in v6:
>> (Patch 1/3)
>> - Fix description; "Radxa CM5" is the correct name
> 
> HERE, in this patch. Don't paste me hundreds of unrelated code. Write
> concise and precise answers/comments.

https://lore.kernel.org/linux-rockchip/AE0735A6C797CCFF+10496d73-7c0a-4884-9561-24721305a24f at radxa.com/

| By the way, at some point I switched from "continuing your work" to
| "recreating a new one based on my current work." The results of my
| current work(*3) have changed significantly.

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> Best regards,
> Krzysztof
> 




From krzk at kernel.org  Thu Nov 13 23:51:32 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 14 Nov 2025 08:51:32 +0100
Subject: [PATCH v6 1/3] dt-bindings: arm: rockchip: Add Radxa CM5 IO Board
In-Reply-To: <B6224BD6578686FF+dc81e00c-46f6-4791-af8a-99cf8e880f0c@radxa.com>
References: <20251105051335.17652-1-naoki@radxa.com>
 <20251105051335.17652-2-naoki@radxa.com>
 <ce6e6369-a7e4-4a35-80f8-70ef41c3b877@kernel.org>
 <A6C1199E2A0D3F37+f3fe0fd5-4ca5-4d3d-bc1d-45f46b48f89b@radxa.com>
 <93deab54-bd5e-433e-acbc-13f6ead47f43@kernel.org>
 <2177a0f0-68df-495c-b267-18e3d9b6ca80@kernel.org>
 <D88EE9EEB2B37D36+361d448f-d260-4d78-ae6b-abf1caabb94b@radxa.com>
 <b2833988-6319-4426-8a25-c0d34acffa47@kernel.org>
 <B6224BD6578686FF+dc81e00c-46f6-4791-af8a-99cf8e880f0c@radxa.com>
Message-ID: <f112b806-b204-46b5-90b2-813ad5d0ceee@kernel.org>

On 14/11/2025 08:47, FUKAUMI Naoki wrote:
> On 11/14/25 16:42, Krzysztof Kozlowski wrote:
>> On 14/11/2025 08:37, FUKAUMI Naoki wrote:
>>> Hi Krzysztof,
>>>
>>> On 11/14/25 16:12, Krzysztof Kozlowski wrote:
>>>> On 05/11/2025 08:08, Krzysztof Kozlowski wrote:
>>>>> On 05/11/2025 07:57, FUKAUMI Naoki wrote:
>>>>>> On 11/5/25 15:43, Krzysztof Kozlowski wrote:
>>>>>>> On 05/11/2025 06:13, FUKAUMI Naoki wrote:
>>>>>>>> Add device tree binding documentation for the Radxa CM5 IO Board.
>>>>>>>>
>>>>>>>> Link: https://dl.radxa.com/cm5/radxa_cm5_product_brief.pdf
>>>>>>>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
>>>>>>>> Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
>>>>>>>
>>>>>>> Wrong DCO chain.
>>>>>>>
>>>>>>>> ---
>>>>>>>>     Documentation/devicetree/bindings/arm/rockchip.yaml | 7 +++++++
>>>>>>>
>>>>>>> NAK, you just stolen ownership of an already posted patch.
>>>>>>
>>>>>> Read "Changes in v6" and patches; my patches are not the same as v5.
>>>>>> Your reply is totally inappropriate.
>>>>>
>>>>> Inappropriate is taking authorship of someone's patch, because we all
>>>>> expect to preserve the original authorship. That's not only basic
>>>>> decency but actually a standard.
>>>>>
>>>>> Additionally, read Joseph's reply that he wants to continue the work:
>>>>> https://lore.kernel.org/all/CAMWSM7iHtAxewW4JkRqRsifVnccqeFviaCgeOyprKDr92FOurg at mail.gmail.com/
>>>>>
>>>>> You clearly do not understand how to continue with someone's work.
>>>>>
>>>>> It is still a NAK.
>>>>
>>>> And I still wait for justification why you took authorship of this
>>>> patch, because to my eye you changed here nothing.
>>>>
>>>> So what did you change HERE that you think you are the author now?
>>>
>>> Changes in v6:
>>> (Patch 1/3)
>>> - Fix description; "Radxa CM5" is the correct name
>>
>> HERE, in this patch. Don't paste me hundreds of unrelated code. Write
>> concise and precise answers/comments.
> 
> https://lore.kernel.org/linux-rockchip/AE0735A6C797CCFF+10496d73-7c0a-4884-9561-24721305a24f at radxa.com/
> 
> | By the way, at some point I switched from "continuing your work" to
> | "recreating a new one based on my current work." The results of my
> | current work(*3) have changed significantly.

So next time I will take your patch, your code, say "I recreated it" and
submit under my authorship and for you it is fine?

Please take Joseph's patch instead. Read submitting patches doc to
understand which one more tag has to be added when sending somoene
else's work.

In the future, I sincerely suggest avoiding re-creating people's work
but building on top, because you just duplicate the effort.

Best regards,
Krzysztof


From naoki at radxa.com  Fri Nov 14 00:06:33 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Fri, 14 Nov 2025 17:06:33 +0900
Subject: [PATCH v6 0/3] Add Radxa CM5 and IO Board
In-Reply-To: <199E172C8E20ED38+71169242-5525-4d60-9e37-a03ad172d639@radxa.com>
References: <20251105051335.17652-1-naoki@radxa.com>
 <199E172C8E20ED38+71169242-5525-4d60-9e37-a03ad172d639@radxa.com>
Message-ID: <705A25012553039E+ea9a05c0-ccc5-4d70-930b-e989300e55a1@radxa.com>

Hi Joseph,

On 11/5/25 21:15, FUKAUMI Naoki wrote:
> I'd like to clarify the situation regarding the v6 patch series I 
> submitted.
> 
> The original device tree work for the Radxa CM5 and IO Board was 
> authored by Joseph Kogut. I took over the responsibility of getting it 
> upstreamed with his agreement.
> 
> However, I now understand that I should have preserved the original 
> Signed-off-by chain (and DCO) in the v6 series. This was my oversight.
> 
> To correct this, I would prefer for Joseph to post the patches himself, 
> which will not include my Signed-off-by.

Could you please post the patches?

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> My apologies for the confusion this caused. Thank you for pointing this 
> out.
> 
> Best regards,
> 
> -- 
> FUKAUMI Naoki
> Radxa Computer (Shenzhen) Co., Ltd.
> 
> On 11/5/25 14:13, FUKAUMI Naoki wrote:
>> This patch series add support for the Radxa CM5 SoM and IO Board.
>>
>> Changes in v6:
>> (Patch 1/3)
>> - Fix description; "Radxa CM5" is the correct name
>> (Patch 2/3)
>> - Fix #include(s)
>> - Include rk3588s.dtsi
>> - Move alias for gmac1 from io board dts
>> - Add Maskrom key
>> - Add pinctrl-* for led-0
>> - Add vcc_1v1_nldo_s3 regulator for pmic
>> - Move gmac1 (except status) from io board dts
>> - Fix phy-supply for gmac1
>> - Fix compatible for vdd_cpu_big1_s0 regulator
>> - Add eeprom on i2c0
>> - Add vdd_npu_s0 regulator for rknn
>> - Fix compatible for rgmii_phy1
>> - Add pinctrl-* and reset-* for rgmii_phy1
>> - Add domain-supply for pd_npu
>> - Add rknn_*
>> - Add saradc
>> - Fix properties in sdhci
>> - Move pmic from io board dts
>> - Fix vcc*-supply for pmic
>> - Add regulators in pmic
>> - Add tsadc
>> - Move vop(_mmu) from io board dts
>> - Trivial changes (labels, names, etc)
>> (Patch 3/3)
>> - Fix #include(s)
>> - Remove #include "rk3588s.dtsi"
>> - Fix model
>> - Add fan
>> - Add Recovery key
>> - Add pinctrl-* for vcc3v3_wf
>> - Add vcc_sysin regulator
>> - Add pinctrl-* for vbus5v0_typec
>> - Add rfkill-bt and rfkill-wlan for M.2 module
>> - Add sound for es8316
>> - Add phy-supply for combphy2_psu
>> - Fix power-role to "source" for fusb302
>> - Add rtc for hym8536
>> - Add audio-codec on i2c8 for es8316
>> - Add i2s0_8ch for es8316
>> - Add package_thermal for fan
>> - Add pinctrl-* for pcie2x1l2
>> - Add pwm11 for fan
>> - Fix properties in sdmmmc
>> - Add phy-supply for u2phy2_host and u2phy3_host
>> - Remove usb_host0_ohci
>> - Add pinctrl-* for usbdp_phy0
>> - Trivial changes (labels, names, etc)
>>
>> Changes in v5:
>> (Patch 2/3, per Jimmy)
>> - Alias eMMC to mmc0
>> - Remove unused sdio alias
>> - Move gmac, hdmi0 nodes to carrier board dts
>> (Patch 3/3, per Jimmy)
>> - Enable hdmi0_sound and i2s5_8ch
>> - Remove redundant enablement of sdhci
>> - Enable usb_host2_xhci
>>
>> - Tested HDMI audio
>>
>> Changes in v4:
>> - Fixed XHCI initialization bug by changing try-power-role from source
>> ?? to sink
>>
>> Changes in v3:
>> - Addressed YAML syntax error in dt binding (per Rob)
>> - Fixed whitespace issue in dts reported by checkpatch.pl
>> - Split base SoM and carrier board into separate patches
>> - Added further details about the SoM and carrier to the commit
>> ?? messages
>>
>> Changes in v2:
>> - Added copyright header and data sheet links
>> - Removed non-existent property
>> - Sorted alphabetically
>> - Removed errant whitespace
>> - Moved status to the end of each node
>> - Removed pinctrl-names property from leds (indicated by CHECK_DTBS)
>> - Removed delays from gmac with internal delay
>>
>> Link: https://lore.kernel.org/r/20250617-rk3588s-cm5-io-dts-upstream- 
>> v5-0-8d96854a5bbd at gmail.com
>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
>> Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
>> ---
>> I have communicated with Joseph privately and taken ownership of
>> moving this forward, with his blessing. All bugs belong to me.
>> ---
>> FUKAUMI Naoki (3):
>> ?? dt-bindings: arm: rockchip: Add Radxa CM5 IO Board
>> ?? arm64: dts: rockchip: Add Radxa CM5
>> ?? arm64: dts: rockchip: Add Radxa CM5 IO Board
>>
>> ? .../devicetree/bindings/arm/rockchip.yaml???? |?? 7 +
>> ? arch/arm64/boot/dts/rockchip/Makefile???????? |?? 1 +
>> ? .../dts/rockchip/rk3588s-radxa-cm5-io.dts???? | 503 +++++++++++++++
>> ? .../boot/dts/rockchip/rk3588s-radxa-cm5.dtsi? | 602 ++++++++++++++++++
>> ? 4 files changed, 1113 insertions(+)
>> ? create mode 100644 arch/arm64/boot/dts/rockchip/rk3588s-radxa-cm5- 
>> io.dts
>> ? create mode 100644 arch/arm64/boot/dts/rockchip/rk3588s-radxa-cm5.dtsi
> 
> 



From dsimic at manjaro.org  Fri Nov 14 00:10:13 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Fri, 14 Nov 2025 09:10:13 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v6 0/3] Add Radxa CM5 and IO Board
In-Reply-To: <67ccca04-b59d-4e22-a0fb-22b19378420d@kernel.org>
References: <20251105051335.17652-1-naoki@radxa.com>
 <199E172C8E20ED38+71169242-5525-4d60-9e37-a03ad172d639@radxa.com>
 <CAMWSM7gezjVSoF+-7ivboTeB=5gQAE-QVrbAbKu3M=obmb3Axg@mail.gmail.com>
 <617FDAB231C501DC+3f9809df-87df-4a02-bd5f-ebc6299b3aa7@radxa.com>
 <a10340af-1d0a-bb0b-4835-7b2c9e67d664@manjaro.org>
 <2892FE50237CD58E+0f15924c-a915-4446-954c-d81a782d23e9@radxa.com>
 <19ce0a41-563c-6202-6b94-b2c644a0b827@manjaro.org>
 <F02BA2E6B1111826+2445b38d-b5e0-499c-83e7-4521c57b2210@radxa.com>
 <f2bc30de-119b-4f4a-844a-8a908c9290b6@kernel.org>
 <49c39864-3e58-2e0e-7abc-50502f2afb02@manjaro.org>
 <7ed7d24a-5395-429f-b999-1374ac910441@kernel.org>
 <cab16f94-4115-a606-60b4-043b6681f7ab@manjaro.org> <67ccca04-b59d-4e22-a0fb-22b19378420d@kernel.org>
Message-ID: <c01b756a-73ea-3d0d-44b9-6ce8a535a103@manjaro.org>

On Friday, November 14, 2025 08:28 CET, Krzysztof Kozlowski <krzk at kernel.org> wrote:
> On 14/11/2025 08:26, Dragan Simic wrote:
> > On Friday, November 14, 2025 08:22 CET, Krzysztof Kozlowski <krzk at kernel.org> wrote:
> >> On 14/11/2025 08:17, Dragan Simic wrote:
> >>> On Friday, November 14, 2025 08:10 CET, Krzysztof Kozlowski <krzk at kernel.org> wrote:
> >>>> On 14/11/2025 06:03, FUKAUMI Naoki wrote:
> >>>>> On 11/12/25 09:46, Dragan Simic wrote:
> >>>>>> On Wednesday, November 12, 2025 00:26 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> >>>>>>> On 11/11/25 23:33, Dragan Simic wrote:
> >>>>>>>> On Tuesday, November 11, 2025 12:52 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> >>>>>>>>> On 11/6/25 02:48, Joseph Kogut wrote:
> >>>>>>>>>> On Wed, Nov 5, 2025 at 4:15?AM FUKAUMI Naoki <naoki at radxa.com> wrote:
> >>>>>>>>>>> I'd like to clarify the situation regarding the v6 patch series I submitted.
> >>>>>>>>>>>
> >>>>>>>>>>> The original device tree work for the Radxa CM5 and IO Board was
> >>>>>>>>>>> authored by Joseph Kogut. I took over the responsibility of getting it
> >>>>>>>>>>> upstreamed with his agreement.
> >>>>>>>>>>
> >>>>>>>>>> I'll confirm this. I've been in communication with Naoki. They made a
> >>>>>>>>>> large number of revisions to my original patch series, which I think
> >>>>>>>>>> have technical merit. I suggested they submit the patches themselves,
> >>>>>>>>>> and gave them explicit permission to add my Signed-off-by and CC me.
> >>>>>>>>>>
> >>>>>>>>>> I assume this was the correct way for them to continue the work I
> >>>>>>>>>> started, but if not, please let us know the best way to proceed.
> >>>>>>>>>
> >>>>>>>>> Can anyone help us?
> >>>>>>>>
> >>>>>>>> I'm not exactly sure how to resolve the current situation, but for
> >>>>>>>> Signed-off-by tags to be present, in this case you'd need to have
> >>>>>>>> Co-developed-by tags as well, because the final patch versions,
> >>>>>>>> which would be submitted by Naoki, would differ significantly from
> >>>>>>>> the versions that Joseph actively worked on, if I understood
> >>>>>>>> everything correctly.  Though, for Joseph's Signed-off-by tags to
> >>>>>>>> be included there, he would also need to participate actively in
> >>>>>>>> the development of the final patch versions.
> >>>>>>>
> >>>>>>> https://www.kernel.org/doc/html/latest/process/submitting-patches.html#when-to-use-acked-by-cc-and-co-developed-by
> >>>>>>>
> >>>>>>> If
> >>>>>>> ----
> >>>>>>> From: Joseph Kogut <joseph.kogut at gmail.com>
> >>>>>>>
> >>>>>>> <changelog>
> >>>>>>>
> >>>>>>> Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
> >>>>>>> Co-developed-by: FUKAUMI Naoki <naoki at radxa.com>
> >>>>>>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> >>>>>>> ----
> >>>>>>> then I can submit my patch series?
> >>>>>>
> >>>>>> Actually, the Co-developed-by tags would be pointing to Joseph
> >>>>>> in that case, but as I described it above, this approach basically
> >>>>>> cannot be used, because Joseph's original work differs a lot from
> >>>>>> what you'd actually submit to the mailing list(s).
> >>>>>>
> >>>>>>> Or,
> >>>>>>>
> >>>>>>>> Another option, technically a bit simpler, would be to include just
> >>>>>>>> Originally-by tags for Joseph, which would indicate that Joseph gave
> >>>>>>>> up on the development of the patches and handed them over to Naoki
> >>>>>>>> for future development and submission to the mailing lists. Though,
> >>>>>>>> that would require Joseph to publicly state exactly that.
> >>>>>>>
> >>>>>>> I cannot find any documentation about "Originally-by".
> >>>>>>> Is this correct?
> >>>>>>> ----
> >>>>>>> <changelog>
> >>>>>>>
> >>>>>>> Originally-by: Joseph Kogut <joseph.kogut at gmail.com>
> >>>>
> >>>> There is no such tag. Don't invent tags.
> >>>
> >>> True, it doesn't exist officially, but it's been used fairly often.
> >>>
> >>>>>>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> >>>>>>> ----
> >>>>>>
> >>>>>> That approach is the only I see applicable in this case.  However,
> >>>>>> let's hear opinions from other people as well.
> >>>>>
> >>>>> I see. I want to do this approach.
> >>>>>
> >>>>> Joseph, could you give me a statement to do this?
> >>>>
> >>>> Use standard authorship and standard tags, some of which are explained
> >>>> in Submitting patches.
> >>>
> >>> Frankly, your suggestion is useless, because it doesn't explain what 
> >>> to do in this particular case.
> >>
> >> Maybe because you did not read the doc...
> > 
> > I think you already know the answer: I read it multiple times and 
> > used it as a reference more than once.
> 
> Then if you read it and saw my objection to inventing tags, you could
> guess that only first solution for patches with changes coming from
> multiple authors is allowed. Also you would find from that doc, that
> patches which were not changed - like in this patchset - must be
> attributed to single author followed by SoB. So both cases nicely
> explained. Pretty simple once you remove the invented tag option,
> because it is really unnecessary.

Thanks, I appreciate your detailed response.

Let's have a look at the following excerpt from Documentation/
process/submitting-patches.rst:

 503 Co-developed-by: states that the patch was co-created by multiple developers;
 504 it is used to give attribution to co-authors (in addition to the author
 505 attributed by the From: tag) when several people work on a single patch.  Since
 506 Co-developed-by: denotes authorship, every Co-developed-by: must be immediately
 507 followed by a Signed-off-by: of the associated co-author.  Standard sign-off
 508 procedure applies, i.e. the ordering of Signed-off-by: tags should reflect the
 509 chronological history of the patch insofar as possible, regardless of whether
 510 the author is attributed via From: or Co-developed-by:.  Notably, the last
 511 Signed-off-by: must always be that of the developer submitting the patch.

Following that, you're absolutely right that the above-described
first approach is the way to go.  However, providing a Signed-off-by
actually means that, at least formally, the signer becomes legally
responsible for the code in the patch;  I'm not sure how fair is it
for someone to become responsible for something that happened long
time ago, about which they have no longer a clue about, which may
happen in case someone rescues an old, abandoned patch, and changes
or improves it a lot before submitting it to a mailing list?

Of course, what I described is more of a hypothetical case, but the
documentation should be covering such cases as well.

That's where Originally-by, I think, comes as a possible solution;
it's a bit like Acked-by, i.e. it's a "lighter" version of Signed-
off-by, in the sense of effectively not making someone legally
responsible for the code they originally authored but have had
abandoned and which someone else is now submitting, while still
providing the mandatory attribution.

I hope it makes sense.



From naoki at radxa.com  Fri Nov 14 00:18:36 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Fri, 14 Nov 2025 17:18:36 +0900
Subject: [PATCH v3 1/3] dt-bindings: arm: rockchip: Add Radxa CM5 IO board
In-Reply-To: <E04572034CE4DC35+005c7dd7-cb2f-4f82-9889-ac14733a7647@radxa.com>
References: <174735136138.1544989.11909422896170025756.robh@kernel.org>
 <20250528221823.2974653-1-joseph.kogut@gmail.com>
 <20250528221823.2974653-2-joseph.kogut@gmail.com>
 <20250529-impressive-real-monkey-a7818b@kuoka>
 <6443BD03B4C4F1FE+d20c3903-e2dc-4c2b-8f6e-fac38f242898@radxa.com>
 <2f4e7f94-2921-493c-94fa-45749a060bc0@kernel.org>
 <870075785A1ED2B9+6fb5238e-dc57-406b-acf9-b88b237d8e5b@radxa.com>
 <f12bc562-b5bb-4bdd-b274-23582df8f2d4@kernel.org>
 <E04572034CE4DC35+005c7dd7-cb2f-4f82-9889-ac14733a7647@radxa.com>
Message-ID: <76B8B69932F4AA70+f730dac3-31e2-42b2-88a5-bfebf0ee8e36@radxa.com>

On 11/5/25 10:37, FUKAUMI Naoki wrote:
> Hi Krzysztof
> 
> On 10/28/25 19:41, Krzysztof Kozlowski wrote:
>> On 28/10/2025 10:44, FUKAUMI Naoki wrote:
>>> Hi Joseph
>>>
>>> Your patch seems to be NAKed.
>>> I will submit new patch soon.
>>
>> Sorry, what? Don't hijack other people's work.
> 
> I have Joseph's permission to post my patch.
> 
> Furthermore, this is not the first time, to my knowledge, that someone 
> else has posted another patch for the same board. (See below)
> 
>  ?https://lore.kernel.org/linux-rockchip/20241226005845.46473-1- 
> naoki at radxa.com/T/#u
>  ?https://lore.kernel.org/linux-rockchip/20250324-rock5bp-for-upstream- 
> v1-0-6217edf15b19 at kernel.org/T/#u

Could you please write concise and precise answers/comments for the part 
you previously snipped[1]?

[1] 
https://lore.kernel.org/linux-rockchip/86939056-7617-4730-9464-f7ecbd0e4537 at kernel.org/

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> Best regards,
> 
> -- 
> FUKAUMI Naoki
> Radxa Computer (Shenzhen) Co., Ltd.
> 
>>>
>>> Best regards,
>>>
>>> -- 
>>> FUKAUMI Naoki
>>> Radxa Computer (Shenzhen) Co., Ltd.
>>>
>>> On 10/28/25 18:37, Krzysztof Kozlowski wrote:
>>>> On 28/10/2025 10:33, FUKAUMI Naoki wrote:
>>>>> Hi Krzysztof,
>>>>>
>>>>> https://patchwork.kernel.org/project/linux-rockchip/ 
>>>>> patch/20250528221823.2974653-2-joseph.kogut at gmail.com/
>>>>>
>>>>> On 5/29/25 18:19, Krzysztof Kozlowski wrote:
>>>>>> On Wed, May 28, 2025 at 03:18:21PM GMT, Joseph Kogut wrote:
>>>>>>> Add device tree binding for the Radxa CM5 IO board.
>>>>>>>
>>>>>>> This board is based on the rk3588s.
>>>>>>
>>>>>> Do not attach (thread) your patchsets to some other threads 
>>>>>> (unrelated
>>>>>> or older versions). This buries them deep in the mailbox and might
>>>>>> interfere with applying entire sets.
>>>>>>
>>>>>>
>>>>>> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
>>>>> Please explain the sorting rule used for this file. You must have 
>>>>> known
>>>>> the sorting rule; otherwise, how can you be sure this patch is 
>>>>> correct?
>>>>
>>>> Huh? I don't have a clue about sorting rule but if you mock my review
>>>> let's make it different:
>>>>
>>>> NAK
>>
>>
>> Ah, you were poking around other patch? I should have ignored that :/
>>
>>
>> Best regards,
>> Krzysztof
>>
> 



From maxime.chevallier at bootlin.com  Fri Nov 14 00:19:25 2025
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Fri, 14 Nov 2025 09:19:25 +0100
Subject: [PATCH net-next 1/4] net: stmmac: rk: replace HIWORD_UPDATE()
 with GRF_FIELD()
In-Reply-To: <E1vJbP1-0000000EBqJ-1AjR@rmk-PC.armlinux.org.uk>
References: <aRYZaKTIvfYoV3wE@shell.armlinux.org.uk>
 <E1vJbP1-0000000EBqJ-1AjR@rmk-PC.armlinux.org.uk>
Message-ID: <fbfd62b5-d584-4e00-a666-fad0438709e8@bootlin.com>

Hi,

On 13/11/2025 18:46, Russell King (Oracle) wrote:
> Provide GRF_FIELD() which takes the high/low bit numbers of the field
> and field value, generates the mask and passes it to FIELD_PREP_WM16.
> Replace all HIWORD_UPDATE() instances with this.
> 
> No change to produced code on aarch64.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Reviewed-by: Maxime Chevallier <maxime.chevallier at bootlin.com>

Maxime



From naoki at radxa.com  Fri Nov 14 00:24:38 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Fri, 14 Nov 2025 17:24:38 +0900
Subject: [PATCH v6 1/3] dt-bindings: arm: rockchip: Add Radxa CM5 IO Board
In-Reply-To: <f112b806-b204-46b5-90b2-813ad5d0ceee@kernel.org>
References: <20251105051335.17652-1-naoki@radxa.com>
 <20251105051335.17652-2-naoki@radxa.com>
 <ce6e6369-a7e4-4a35-80f8-70ef41c3b877@kernel.org>
 <A6C1199E2A0D3F37+f3fe0fd5-4ca5-4d3d-bc1d-45f46b48f89b@radxa.com>
 <93deab54-bd5e-433e-acbc-13f6ead47f43@kernel.org>
 <2177a0f0-68df-495c-b267-18e3d9b6ca80@kernel.org>
 <D88EE9EEB2B37D36+361d448f-d260-4d78-ae6b-abf1caabb94b@radxa.com>
 <b2833988-6319-4426-8a25-c0d34acffa47@kernel.org>
 <B6224BD6578686FF+dc81e00c-46f6-4791-af8a-99cf8e880f0c@radxa.com>
 <f112b806-b204-46b5-90b2-813ad5d0ceee@kernel.org>
Message-ID: <A3AD69295D2E2D65+db2dc8bd-054f-4dda-9dd1-3cc0c0feed35@radxa.com>

On 11/14/25 16:51, Krzysztof Kozlowski wrote:
> On 14/11/2025 08:47, FUKAUMI Naoki wrote:
>> On 11/14/25 16:42, Krzysztof Kozlowski wrote:
>>> On 14/11/2025 08:37, FUKAUMI Naoki wrote:
>>>> Hi Krzysztof,
>>>>
>>>> On 11/14/25 16:12, Krzysztof Kozlowski wrote:
>>>>> On 05/11/2025 08:08, Krzysztof Kozlowski wrote:
>>>>>> On 05/11/2025 07:57, FUKAUMI Naoki wrote:
>>>>>>> On 11/5/25 15:43, Krzysztof Kozlowski wrote:
>>>>>>>> On 05/11/2025 06:13, FUKAUMI Naoki wrote:
>>>>>>>>> Add device tree binding documentation for the Radxa CM5 IO Board.
>>>>>>>>>
>>>>>>>>> Link: https://dl.radxa.com/cm5/radxa_cm5_product_brief.pdf
>>>>>>>>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
>>>>>>>>> Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
>>>>>>>>
>>>>>>>> Wrong DCO chain.
>>>>>>>>
>>>>>>>>> ---
>>>>>>>>>      Documentation/devicetree/bindings/arm/rockchip.yaml | 7 +++++++
>>>>>>>>
>>>>>>>> NAK, you just stolen ownership of an already posted patch.
>>>>>>>
>>>>>>> Read "Changes in v6" and patches; my patches are not the same as v5.
>>>>>>> Your reply is totally inappropriate.
>>>>>>
>>>>>> Inappropriate is taking authorship of someone's patch, because we all
>>>>>> expect to preserve the original authorship. That's not only basic
>>>>>> decency but actually a standard.
>>>>>>
>>>>>> Additionally, read Joseph's reply that he wants to continue the work:
>>>>>> https://lore.kernel.org/all/CAMWSM7iHtAxewW4JkRqRsifVnccqeFviaCgeOyprKDr92FOurg at mail.gmail.com/
>>>>>>
>>>>>> You clearly do not understand how to continue with someone's work.
>>>>>>
>>>>>> It is still a NAK.
>>>>>
>>>>> And I still wait for justification why you took authorship of this
>>>>> patch, because to my eye you changed here nothing.
>>>>>
>>>>> So what did you change HERE that you think you are the author now?
>>>>
>>>> Changes in v6:
>>>> (Patch 1/3)
>>>> - Fix description; "Radxa CM5" is the correct name
>>>
>>> HERE, in this patch. Don't paste me hundreds of unrelated code. Write
>>> concise and precise answers/comments.
>>
>> https://lore.kernel.org/linux-rockchip/AE0735A6C797CCFF+10496d73-7c0a-4884-9561-24721305a24f at radxa.com/
>>
>> | By the way, at some point I switched from "continuing your work" to
>> | "recreating a new one based on my current work." The results of my
>> | current work(*3) have changed significantly.
> 
> So next time I will take your patch, your code, say "I recreated it" and
> submit under my authorship and for you it is fine?

Regarding CM5 patches, I'm fine.

> Please take Joseph's patch instead. Read submitting patches doc to
> understand which one more tag has to be added when sending somoene
> else's work.
> 
> In the future, I sincerely suggest avoiding re-creating people's work
> but building on top, because you just duplicate the effort.

I understand that you don't understand how I made efforts to build my 
work on top of Joseph's patches.

Thank you for your attention.

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> Best regards,
> Krzysztof
> 



From maxime.chevallier at bootlin.com  Fri Nov 14 00:29:08 2025
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Fri, 14 Nov 2025 09:29:08 +0100
Subject: [PATCH net-next 3/4] net: stmmac: rk: use PHY_INTF_SEL_x
 constants
In-Reply-To: <E1vJbPB-0000000EBqV-27GS@rmk-PC.armlinux.org.uk>
References: <aRYZaKTIvfYoV3wE@shell.armlinux.org.uk>
 <E1vJbPB-0000000EBqV-27GS@rmk-PC.armlinux.org.uk>
Message-ID: <a9e9b465-9e27-479e-8230-ab4a7f6be5b3@bootlin.com>



On 13/11/2025 18:46, Russell King (Oracle) wrote:
> The values used in the xxx_GMAC_PHY_INTF_SEL_xxx() macros are the
> phy_intf_sel values used for the dwmac core. Use these to define these
> constants.
> 
> No change to produced code on aarch64.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Reviewed-by: Maxime Chevallier <maxime.chevallier at bootlin.com>

Maxime

> ---
>  .../net/ethernet/stmicro/stmmac/dwmac-rk.c    | 46 +++++++++----------
>  1 file changed, 23 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
> index 4257cc1f66e9..49076ee00877 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
> @@ -234,7 +234,7 @@ static void rk_gmac_integrated_fephy_powerdown(struct rk_priv_data *priv,
>  #define PX30_GRF_GMAC_CON1		0x0904
>  
>  /* PX30_GRF_GMAC_CON1 */
> -#define PX30_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, 4)
> +#define PX30_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RMII)
>  #define PX30_GMAC_SPEED_10M		GRF_CLR_BIT(2)
>  #define PX30_GMAC_SPEED_100M		GRF_BIT(2)
>  
> @@ -290,8 +290,8 @@ static const struct rk_gmac_ops px30_ops = {
>  #define RK3128_GMAC_CLK_TX_DL_CFG(val) GRF_FIELD(6, 0, val)
>  
>  /* RK3128_GRF_MAC_CON1 */
> -#define RK3128_GMAC_PHY_INTF_SEL_RGMII GRF_FIELD(8, 6, 1)
> -#define RK3128_GMAC_PHY_INTF_SEL_RMII  GRF_FIELD(8, 6, 4)
> +#define RK3128_GMAC_PHY_INTF_SEL_RGMII GRF_FIELD(8, 6, PHY_INTF_SEL_RGMII)
> +#define RK3128_GMAC_PHY_INTF_SEL_RMII  GRF_FIELD(8, 6, PHY_INTF_SEL_RMII)
>  #define RK3128_GMAC_FLOW_CTRL          GRF_BIT(9)
>  #define RK3128_GMAC_FLOW_CTRL_CLR      GRF_CLR_BIT(9)
>  #define RK3128_GMAC_SPEED_10M          GRF_CLR_BIT(10)
> @@ -353,8 +353,8 @@ static const struct rk_gmac_ops rk3128_ops = {
>  #define RK3228_GMAC_CLK_TX_DL_CFG(val)	GRF_FIELD(6, 0, val)
>  
>  /* RK3228_GRF_MAC_CON1 */
> -#define RK3228_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(6, 4, 1)
> -#define RK3228_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, 4)
> +#define RK3228_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RGMII)
> +#define RK3228_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RMII)
>  #define RK3228_GMAC_FLOW_CTRL		GRF_BIT(3)
>  #define RK3228_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
>  #define RK3228_GMAC_SPEED_10M		GRF_CLR_BIT(2)
> @@ -432,8 +432,8 @@ static const struct rk_gmac_ops rk3228_ops = {
>  #define RK3288_GRF_SOC_CON3	0x0250
>  
>  /*RK3288_GRF_SOC_CON1*/
> -#define RK3288_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(8, 6, 1)
> -#define RK3288_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(8, 6, 4)
> +#define RK3288_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(8, 6, PHY_INTF_SEL_RGMII)
> +#define RK3288_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(8, 6, PHY_INTF_SEL_RMII)
>  #define RK3288_GMAC_FLOW_CTRL		GRF_BIT(9)
>  #define RK3288_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(9)
>  #define RK3288_GMAC_SPEED_10M		GRF_CLR_BIT(10)
> @@ -496,7 +496,7 @@ static const struct rk_gmac_ops rk3288_ops = {
>  #define RK3308_GRF_MAC_CON0		0x04a0
>  
>  /* RK3308_GRF_MAC_CON0 */
> -#define RK3308_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(4, 2, 4)
> +#define RK3308_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(4, 2, PHY_INTF_SEL_RMII)
>  #define RK3308_GMAC_FLOW_CTRL		GRF_BIT(3)
>  #define RK3308_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
>  #define RK3308_GMAC_SPEED_10M		GRF_CLR_BIT(0)
> @@ -535,8 +535,8 @@ static const struct rk_gmac_ops rk3308_ops = {
>  #define RK3328_GMAC_CLK_TX_DL_CFG(val)	GRF_FIELD(6, 0, val)
>  
>  /* RK3328_GRF_MAC_CON1 */
> -#define RK3328_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(6, 4, 1)
> -#define RK3328_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, 4)
> +#define RK3328_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RGMII)
> +#define RK3328_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RMII)
>  #define RK3328_GMAC_FLOW_CTRL		GRF_BIT(3)
>  #define RK3328_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
>  #define RK3328_GMAC_SPEED_10M		GRF_CLR_BIT(2)
> @@ -622,8 +622,8 @@ static const struct rk_gmac_ops rk3328_ops = {
>  #define RK3366_GRF_SOC_CON7	0x041c
>  
>  /* RK3366_GRF_SOC_CON6 */
> -#define RK3366_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(11, 9, 1)
> -#define RK3366_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(11, 9, 4)
> +#define RK3366_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(11, 9, PHY_INTF_SEL_RGMII)
> +#define RK3366_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(11, 9, PHY_INTF_SEL_RMII)
>  #define RK3366_GMAC_FLOW_CTRL		GRF_BIT(8)
>  #define RK3366_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
>  #define RK3366_GMAC_SPEED_10M		GRF_CLR_BIT(7)
> @@ -687,8 +687,8 @@ static const struct rk_gmac_ops rk3366_ops = {
>  #define RK3368_GRF_SOC_CON16	0x0440
>  
>  /* RK3368_GRF_SOC_CON15 */
> -#define RK3368_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(11, 9, 1)
> -#define RK3368_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(11, 9, 4)
> +#define RK3368_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(11, 9, PHY_INTF_SEL_RGMII)
> +#define RK3368_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(11, 9, PHY_INTF_SEL_RMII)
>  #define RK3368_GMAC_FLOW_CTRL		GRF_BIT(8)
>  #define RK3368_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
>  #define RK3368_GMAC_SPEED_10M		GRF_CLR_BIT(7)
> @@ -752,8 +752,8 @@ static const struct rk_gmac_ops rk3368_ops = {
>  #define RK3399_GRF_SOC_CON6	0xc218
>  
>  /* RK3399_GRF_SOC_CON5 */
> -#define RK3399_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(11, 9, 1)
> -#define RK3399_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(11, 9, 4)
> +#define RK3399_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(11, 9, PHY_INTF_SEL_RGMII)
> +#define RK3399_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(11, 9, PHY_INTF_SEL_RMII)
>  #define RK3399_GMAC_FLOW_CTRL		GRF_BIT(8)
>  #define RK3399_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
>  #define RK3399_GMAC_SPEED_10M		GRF_CLR_BIT(7)
> @@ -1015,8 +1015,8 @@ static const struct rk_gmac_ops rk3528_ops = {
>  #define RK3568_GRF_GMAC1_CON1		0x038c
>  
>  /* RK3568_GRF_GMAC0_CON1 && RK3568_GRF_GMAC1_CON1 */
> -#define RK3568_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(6, 4, 1)
> -#define RK3568_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, 4)
> +#define RK3568_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RGMII)
> +#define RK3568_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RMII)
>  #define RK3568_GMAC_FLOW_CTRL			GRF_BIT(3)
>  #define RK3568_GMAC_FLOW_CTRL_CLR		GRF_CLR_BIT(3)
>  #define RK3568_GMAC_RXCLK_DLY_ENABLE		GRF_BIT(1)
> @@ -1209,9 +1209,9 @@ static const struct rk_gmac_ops rk3576_ops = {
>  #define RK3588_GRF_CLK_CON1			0X0070
>  
>  #define RK3588_GMAC_PHY_INTF_SEL_RGMII(id)	\
> -	(GRF_FIELD(5, 3, 1) << ((id) * 6))
> +	(GRF_FIELD(5, 3, PHY_INTF_SEL_RGMII) << ((id) * 6))
>  #define RK3588_GMAC_PHY_INTF_SEL_RMII(id)	\
> -	(GRF_FIELD(5, 3, 4) << ((id) * 6))
> +	(GRF_FIELD(5, 3, PHY_INTF_SEL_RMII) << ((id) * 6))
>  
>  #define RK3588_GMAC_CLK_RMII_MODE(id)		GRF_BIT(5 * (id))
>  #define RK3588_GMAC_CLK_RGMII_MODE(id)		GRF_CLR_BIT(5 * (id))
> @@ -1328,7 +1328,7 @@ static const struct rk_gmac_ops rk3588_ops = {
>  #define RV1108_GRF_GMAC_CON0		0X0900
>  
>  /* RV1108_GRF_GMAC_CON0 */
> -#define RV1108_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, 4)
> +#define RV1108_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RMII)
>  #define RV1108_GMAC_FLOW_CTRL		GRF_BIT(3)
>  #define RV1108_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
>  #define RV1108_GMAC_SPEED_10M		GRF_CLR_BIT(2)
> @@ -1364,8 +1364,8 @@ static const struct rk_gmac_ops rv1108_ops = {
>  #define RV1126_GRF_GMAC_CON2		0X0078
>  
>  /* RV1126_GRF_GMAC_CON0 */
> -#define RV1126_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(6, 4, 1)
> -#define RV1126_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, 4)
> +#define RV1126_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RGMII)
> +#define RV1126_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RMII)
>  #define RV1126_GMAC_FLOW_CTRL			GRF_BIT(7)
>  #define RV1126_GMAC_FLOW_CTRL_CLR		GRF_CLR_BIT(7)
>  #define RV1126_GMAC_M0_RXCLK_DLY_ENABLE		GRF_BIT(1)



From maxime.chevallier at bootlin.com  Fri Nov 14 00:29:24 2025
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Fri, 14 Nov 2025 09:29:24 +0100
Subject: [PATCH net-next 4/4] net: stmmac: rk: use PHY_INTF_SEL_x in
 functions
In-Reply-To: <E1vJbPG-0000000EBqb-2cF2@rmk-PC.armlinux.org.uk>
References: <aRYZaKTIvfYoV3wE@shell.armlinux.org.uk>
 <E1vJbPG-0000000EBqb-2cF2@rmk-PC.armlinux.org.uk>
Message-ID: <0937e9a9-f79f-42e6-ab28-7fec0623ffa4@bootlin.com>



On 13/11/2025 18:46, Russell King (Oracle) wrote:
> Rather than defining one xxx_GMAC_PHY_INTF_SEL_xxx() for each mode,
> define xxx_GMAC_PHY_INTF_SEL() which takes the phy_intf_sel value.
> Pass the appropriate value into these new macros in the set_to_xxx()
> methods.
> 
> No change to produced code on aarch64.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Reviewed-by: Maxime Chevallier <maxime.chevallier at bootlin.com>

> ---
>  .../net/ethernet/stmicro/stmmac/dwmac-rk.c    | 91 +++++++++----------
>  1 file changed, 43 insertions(+), 48 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
> index 49076ee00877..6e75da577af5 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
> @@ -234,14 +234,14 @@ static void rk_gmac_integrated_fephy_powerdown(struct rk_priv_data *priv,
>  #define PX30_GRF_GMAC_CON1		0x0904
>  
>  /* PX30_GRF_GMAC_CON1 */
> -#define PX30_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RMII)
> +#define PX30_GMAC_PHY_INTF_SEL(val)	GRF_FIELD(6, 4, val)
>  #define PX30_GMAC_SPEED_10M		GRF_CLR_BIT(2)
>  #define PX30_GMAC_SPEED_100M		GRF_BIT(2)
>  
>  static void px30_set_to_rmii(struct rk_priv_data *bsp_priv)
>  {
>  	regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
> -		     PX30_GMAC_PHY_INTF_SEL_RMII);
> +		     PX30_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RMII));
>  }
>  
>  static int px30_set_speed(struct rk_priv_data *bsp_priv,
> @@ -290,8 +290,7 @@ static const struct rk_gmac_ops px30_ops = {
>  #define RK3128_GMAC_CLK_TX_DL_CFG(val) GRF_FIELD(6, 0, val)
>  
>  /* RK3128_GRF_MAC_CON1 */
> -#define RK3128_GMAC_PHY_INTF_SEL_RGMII GRF_FIELD(8, 6, PHY_INTF_SEL_RGMII)
> -#define RK3128_GMAC_PHY_INTF_SEL_RMII  GRF_FIELD(8, 6, PHY_INTF_SEL_RMII)
> +#define RK3128_GMAC_PHY_INTF_SEL(val)  GRF_FIELD(8, 6, val)
>  #define RK3128_GMAC_FLOW_CTRL          GRF_BIT(9)
>  #define RK3128_GMAC_FLOW_CTRL_CLR      GRF_CLR_BIT(9)
>  #define RK3128_GMAC_SPEED_10M          GRF_CLR_BIT(10)
> @@ -308,7 +307,7 @@ static void rk3128_set_to_rgmii(struct rk_priv_data *bsp_priv,
>  				int tx_delay, int rx_delay)
>  {
>  	regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
> -		     RK3128_GMAC_PHY_INTF_SEL_RGMII |
> +		     RK3128_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RGMII) |
>  		     RK3128_GMAC_RMII_MODE_CLR);
>  	regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON0,
>  		     DELAY_ENABLE(RK3128, tx_delay, rx_delay) |
> @@ -319,7 +318,8 @@ static void rk3128_set_to_rgmii(struct rk_priv_data *bsp_priv,
>  static void rk3128_set_to_rmii(struct rk_priv_data *bsp_priv)
>  {
>  	regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
> -		     RK3128_GMAC_PHY_INTF_SEL_RMII | RK3128_GMAC_RMII_MODE);
> +		     RK3128_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RMII) |
> +		     RK3128_GMAC_RMII_MODE);
>  }
>  
>  static const struct rk_reg_speed_data rk3128_reg_speed_data = {
> @@ -353,8 +353,7 @@ static const struct rk_gmac_ops rk3128_ops = {
>  #define RK3228_GMAC_CLK_TX_DL_CFG(val)	GRF_FIELD(6, 0, val)
>  
>  /* RK3228_GRF_MAC_CON1 */
> -#define RK3228_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RGMII)
> -#define RK3228_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RMII)
> +#define RK3228_GMAC_PHY_INTF_SEL(val)	GRF_FIELD(6, 4, val)
>  #define RK3228_GMAC_FLOW_CTRL		GRF_BIT(3)
>  #define RK3228_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
>  #define RK3228_GMAC_SPEED_10M		GRF_CLR_BIT(2)
> @@ -378,7 +377,7 @@ static void rk3228_set_to_rgmii(struct rk_priv_data *bsp_priv,
>  				int tx_delay, int rx_delay)
>  {
>  	regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
> -		     RK3228_GMAC_PHY_INTF_SEL_RGMII |
> +		     RK3228_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RGMII) |
>  		     RK3228_GMAC_RMII_MODE_CLR |
>  		     DELAY_ENABLE(RK3228, tx_delay, rx_delay));
>  
> @@ -390,7 +389,7 @@ static void rk3228_set_to_rgmii(struct rk_priv_data *bsp_priv,
>  static void rk3228_set_to_rmii(struct rk_priv_data *bsp_priv)
>  {
>  	regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
> -		     RK3228_GMAC_PHY_INTF_SEL_RMII |
> +		     RK3228_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RMII) |
>  		     RK3228_GMAC_RMII_MODE);
>  
>  	/* set MAC to RMII mode */
> @@ -432,8 +431,7 @@ static const struct rk_gmac_ops rk3228_ops = {
>  #define RK3288_GRF_SOC_CON3	0x0250
>  
>  /*RK3288_GRF_SOC_CON1*/
> -#define RK3288_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(8, 6, PHY_INTF_SEL_RGMII)
> -#define RK3288_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(8, 6, PHY_INTF_SEL_RMII)
> +#define RK3288_GMAC_PHY_INTF_SEL(val)	GRF_FIELD(8, 6, val)
>  #define RK3288_GMAC_FLOW_CTRL		GRF_BIT(9)
>  #define RK3288_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(9)
>  #define RK3288_GMAC_SPEED_10M		GRF_CLR_BIT(10)
> @@ -458,7 +456,7 @@ static void rk3288_set_to_rgmii(struct rk_priv_data *bsp_priv,
>  				int tx_delay, int rx_delay)
>  {
>  	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
> -		     RK3288_GMAC_PHY_INTF_SEL_RGMII |
> +		     RK3288_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RGMII) |
>  		     RK3288_GMAC_RMII_MODE_CLR);
>  	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON3,
>  		     DELAY_ENABLE(RK3288, tx_delay, rx_delay) |
> @@ -469,7 +467,8 @@ static void rk3288_set_to_rgmii(struct rk_priv_data *bsp_priv,
>  static void rk3288_set_to_rmii(struct rk_priv_data *bsp_priv)
>  {
>  	regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
> -		     RK3288_GMAC_PHY_INTF_SEL_RMII | RK3288_GMAC_RMII_MODE);
> +		     RK3288_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RMII) |
> +		     RK3288_GMAC_RMII_MODE);
>  }
>  
>  static const struct rk_reg_speed_data rk3288_reg_speed_data = {
> @@ -496,7 +495,7 @@ static const struct rk_gmac_ops rk3288_ops = {
>  #define RK3308_GRF_MAC_CON0		0x04a0
>  
>  /* RK3308_GRF_MAC_CON0 */
> -#define RK3308_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(4, 2, PHY_INTF_SEL_RMII)
> +#define RK3308_GMAC_PHY_INTF_SEL(val)	GRF_FIELD(4, 2, val)
>  #define RK3308_GMAC_FLOW_CTRL		GRF_BIT(3)
>  #define RK3308_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
>  #define RK3308_GMAC_SPEED_10M		GRF_CLR_BIT(0)
> @@ -505,7 +504,7 @@ static const struct rk_gmac_ops rk3288_ops = {
>  static void rk3308_set_to_rmii(struct rk_priv_data *bsp_priv)
>  {
>  	regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0,
> -		     RK3308_GMAC_PHY_INTF_SEL_RMII);
> +		     RK3308_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RMII));
>  }
>  
>  static const struct rk_reg_speed_data rk3308_reg_speed_data = {
> @@ -535,8 +534,7 @@ static const struct rk_gmac_ops rk3308_ops = {
>  #define RK3328_GMAC_CLK_TX_DL_CFG(val)	GRF_FIELD(6, 0, val)
>  
>  /* RK3328_GRF_MAC_CON1 */
> -#define RK3328_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RGMII)
> -#define RK3328_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RMII)
> +#define RK3328_GMAC_PHY_INTF_SEL(val)	GRF_FIELD(6, 4, val)
>  #define RK3328_GMAC_FLOW_CTRL		GRF_BIT(3)
>  #define RK3328_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
>  #define RK3328_GMAC_SPEED_10M		GRF_CLR_BIT(2)
> @@ -558,7 +556,7 @@ static void rk3328_set_to_rgmii(struct rk_priv_data *bsp_priv,
>  				int tx_delay, int rx_delay)
>  {
>  	regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
> -		     RK3328_GMAC_PHY_INTF_SEL_RGMII |
> +		     RK3328_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RGMII) |
>  		     RK3328_GMAC_RMII_MODE_CLR |
>  		     RK3328_GMAC_RXCLK_DLY_ENABLE |
>  		     RK3328_GMAC_TXCLK_DLY_ENABLE);
> @@ -576,7 +574,7 @@ static void rk3328_set_to_rmii(struct rk_priv_data *bsp_priv)
>  		  RK3328_GRF_MAC_CON1;
>  
>  	regmap_write(bsp_priv->grf, reg,
> -		     RK3328_GMAC_PHY_INTF_SEL_RMII |
> +		     RK3328_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RMII) |
>  		     RK3328_GMAC_RMII_MODE);
>  }
>  
> @@ -622,8 +620,7 @@ static const struct rk_gmac_ops rk3328_ops = {
>  #define RK3366_GRF_SOC_CON7	0x041c
>  
>  /* RK3366_GRF_SOC_CON6 */
> -#define RK3366_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(11, 9, PHY_INTF_SEL_RGMII)
> -#define RK3366_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(11, 9, PHY_INTF_SEL_RMII)
> +#define RK3366_GMAC_PHY_INTF_SEL(val)	GRF_FIELD(11, 9, val)
>  #define RK3366_GMAC_FLOW_CTRL		GRF_BIT(8)
>  #define RK3366_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
>  #define RK3366_GMAC_SPEED_10M		GRF_CLR_BIT(7)
> @@ -648,7 +645,7 @@ static void rk3366_set_to_rgmii(struct rk_priv_data *bsp_priv,
>  				int tx_delay, int rx_delay)
>  {
>  	regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
> -		     RK3366_GMAC_PHY_INTF_SEL_RGMII |
> +		     RK3366_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RGMII) |
>  		     RK3366_GMAC_RMII_MODE_CLR);
>  	regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON7,
>  		     DELAY_ENABLE(RK3366, tx_delay, rx_delay) |
> @@ -659,7 +656,8 @@ static void rk3366_set_to_rgmii(struct rk_priv_data *bsp_priv,
>  static void rk3366_set_to_rmii(struct rk_priv_data *bsp_priv)
>  {
>  	regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
> -		     RK3366_GMAC_PHY_INTF_SEL_RMII | RK3366_GMAC_RMII_MODE);
> +		     RK3366_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RMII) |
> +		     RK3366_GMAC_RMII_MODE);
>  }
>  
>  static const struct rk_reg_speed_data rk3366_reg_speed_data = {
> @@ -687,8 +685,7 @@ static const struct rk_gmac_ops rk3366_ops = {
>  #define RK3368_GRF_SOC_CON16	0x0440
>  
>  /* RK3368_GRF_SOC_CON15 */
> -#define RK3368_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(11, 9, PHY_INTF_SEL_RGMII)
> -#define RK3368_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(11, 9, PHY_INTF_SEL_RMII)
> +#define RK3368_GMAC_PHY_INTF_SEL(val)	GRF_FIELD(11, 9, val)
>  #define RK3368_GMAC_FLOW_CTRL		GRF_BIT(8)
>  #define RK3368_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
>  #define RK3368_GMAC_SPEED_10M		GRF_CLR_BIT(7)
> @@ -713,7 +710,7 @@ static void rk3368_set_to_rgmii(struct rk_priv_data *bsp_priv,
>  				int tx_delay, int rx_delay)
>  {
>  	regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
> -		     RK3368_GMAC_PHY_INTF_SEL_RGMII |
> +		     RK3368_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RGMII) |
>  		     RK3368_GMAC_RMII_MODE_CLR);
>  	regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON16,
>  		     DELAY_ENABLE(RK3368, tx_delay, rx_delay) |
> @@ -724,7 +721,8 @@ static void rk3368_set_to_rgmii(struct rk_priv_data *bsp_priv,
>  static void rk3368_set_to_rmii(struct rk_priv_data *bsp_priv)
>  {
>  	regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
> -		     RK3368_GMAC_PHY_INTF_SEL_RMII | RK3368_GMAC_RMII_MODE);
> +		     RK3368_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RMII) |
> +		     RK3368_GMAC_RMII_MODE);
>  }
>  
>  static const struct rk_reg_speed_data rk3368_reg_speed_data = {
> @@ -752,8 +750,7 @@ static const struct rk_gmac_ops rk3368_ops = {
>  #define RK3399_GRF_SOC_CON6	0xc218
>  
>  /* RK3399_GRF_SOC_CON5 */
> -#define RK3399_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(11, 9, PHY_INTF_SEL_RGMII)
> -#define RK3399_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(11, 9, PHY_INTF_SEL_RMII)
> +#define RK3399_GMAC_PHY_INTF_SEL(val)	GRF_FIELD(11, 9, val)
>  #define RK3399_GMAC_FLOW_CTRL		GRF_BIT(8)
>  #define RK3399_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(8)
>  #define RK3399_GMAC_SPEED_10M		GRF_CLR_BIT(7)
> @@ -778,7 +775,7 @@ static void rk3399_set_to_rgmii(struct rk_priv_data *bsp_priv,
>  				int tx_delay, int rx_delay)
>  {
>  	regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
> -		     RK3399_GMAC_PHY_INTF_SEL_RGMII |
> +		     RK3399_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RGMII) |
>  		     RK3399_GMAC_RMII_MODE_CLR);
>  	regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON6,
>  		     DELAY_ENABLE(RK3399, tx_delay, rx_delay) |
> @@ -789,7 +786,8 @@ static void rk3399_set_to_rgmii(struct rk_priv_data *bsp_priv,
>  static void rk3399_set_to_rmii(struct rk_priv_data *bsp_priv)
>  {
>  	regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
> -		     RK3399_GMAC_PHY_INTF_SEL_RMII | RK3399_GMAC_RMII_MODE);
> +		     RK3399_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RMII) |
> +		     RK3399_GMAC_RMII_MODE);
>  }
>  
>  static const struct rk_reg_speed_data rk3399_reg_speed_data = {
> @@ -1015,8 +1013,7 @@ static const struct rk_gmac_ops rk3528_ops = {
>  #define RK3568_GRF_GMAC1_CON1		0x038c
>  
>  /* RK3568_GRF_GMAC0_CON1 && RK3568_GRF_GMAC1_CON1 */
> -#define RK3568_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RGMII)
> -#define RK3568_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RMII)
> +#define RK3568_GMAC_PHY_INTF_SEL(val)	GRF_FIELD(6, 4, val)
>  #define RK3568_GMAC_FLOW_CTRL			GRF_BIT(3)
>  #define RK3568_GMAC_FLOW_CTRL_CLR		GRF_CLR_BIT(3)
>  #define RK3568_GMAC_RXCLK_DLY_ENABLE		GRF_BIT(1)
> @@ -1043,7 +1040,7 @@ static void rk3568_set_to_rgmii(struct rk_priv_data *bsp_priv,
>  		     RK3568_GMAC_CLK_TX_DL_CFG(tx_delay));
>  
>  	regmap_write(bsp_priv->grf, con1,
> -		     RK3568_GMAC_PHY_INTF_SEL_RGMII |
> +		     RK3568_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RGMII) |
>  		     RK3568_GMAC_RXCLK_DLY_ENABLE |
>  		     RK3568_GMAC_TXCLK_DLY_ENABLE);
>  }
> @@ -1054,7 +1051,8 @@ static void rk3568_set_to_rmii(struct rk_priv_data *bsp_priv)
>  
>  	con1 = (bsp_priv->id == 1) ? RK3568_GRF_GMAC1_CON1 :
>  				     RK3568_GRF_GMAC0_CON1;
> -	regmap_write(bsp_priv->grf, con1, RK3568_GMAC_PHY_INTF_SEL_RMII);
> +	regmap_write(bsp_priv->grf, con1,
> +		     RK3568_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RMII));
>  }
>  
>  static const struct rk_gmac_ops rk3568_ops = {
> @@ -1208,10 +1206,8 @@ static const struct rk_gmac_ops rk3576_ops = {
>  #define RK3588_GRF_GMAC_CON0			0X0008
>  #define RK3588_GRF_CLK_CON1			0X0070
>  
> -#define RK3588_GMAC_PHY_INTF_SEL_RGMII(id)	\
> -	(GRF_FIELD(5, 3, PHY_INTF_SEL_RGMII) << ((id) * 6))
> -#define RK3588_GMAC_PHY_INTF_SEL_RMII(id)	\
> -	(GRF_FIELD(5, 3, PHY_INTF_SEL_RMII) << ((id) * 6))
> +#define RK3588_GMAC_PHY_INTF_SEL(id, val)	\
> +	(GRF_FIELD(5, 3, val) << ((id) * 6))
>  
>  #define RK3588_GMAC_CLK_RMII_MODE(id)		GRF_BIT(5 * (id))
>  #define RK3588_GMAC_CLK_RGMII_MODE(id)		GRF_CLR_BIT(5 * (id))
> @@ -1241,7 +1237,7 @@ static void rk3588_set_to_rgmii(struct rk_priv_data *bsp_priv,
>  					 RK3588_GRF_GMAC_CON8;
>  
>  	regmap_write(bsp_priv->php_grf, RK3588_GRF_GMAC_CON0,
> -		     RK3588_GMAC_PHY_INTF_SEL_RGMII(id));
> +		     RK3588_GMAC_PHY_INTF_SEL(id, PHY_INTF_SEL_RGMII));
>  
>  	regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1,
>  		     RK3588_GMAC_CLK_RGMII_MODE(id));
> @@ -1258,7 +1254,7 @@ static void rk3588_set_to_rgmii(struct rk_priv_data *bsp_priv,
>  static void rk3588_set_to_rmii(struct rk_priv_data *bsp_priv)
>  {
>  	regmap_write(bsp_priv->php_grf, RK3588_GRF_GMAC_CON0,
> -		     RK3588_GMAC_PHY_INTF_SEL_RMII(bsp_priv->id));
> +		     RK3588_GMAC_PHY_INTF_SEL(bsp_priv->id, PHY_INTF_SEL_RMII));
>  
>  	regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1,
>  		     RK3588_GMAC_CLK_RMII_MODE(bsp_priv->id));
> @@ -1328,7 +1324,7 @@ static const struct rk_gmac_ops rk3588_ops = {
>  #define RV1108_GRF_GMAC_CON0		0X0900
>  
>  /* RV1108_GRF_GMAC_CON0 */
> -#define RV1108_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RMII)
> +#define RV1108_GMAC_PHY_INTF_SEL(val)	GRF_FIELD(6, 4, val)
>  #define RV1108_GMAC_FLOW_CTRL		GRF_BIT(3)
>  #define RV1108_GMAC_FLOW_CTRL_CLR	GRF_CLR_BIT(3)
>  #define RV1108_GMAC_SPEED_10M		GRF_CLR_BIT(2)
> @@ -1339,7 +1335,7 @@ static const struct rk_gmac_ops rk3588_ops = {
>  static void rv1108_set_to_rmii(struct rk_priv_data *bsp_priv)
>  {
>  	regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
> -		     RV1108_GMAC_PHY_INTF_SEL_RMII);
> +		     RV1108_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RMII));
>  }
>  
>  static const struct rk_reg_speed_data rv1108_reg_speed_data = {
> @@ -1364,8 +1360,7 @@ static const struct rk_gmac_ops rv1108_ops = {
>  #define RV1126_GRF_GMAC_CON2		0X0078
>  
>  /* RV1126_GRF_GMAC_CON0 */
> -#define RV1126_GMAC_PHY_INTF_SEL_RGMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RGMII)
> -#define RV1126_GMAC_PHY_INTF_SEL_RMII	GRF_FIELD(6, 4, PHY_INTF_SEL_RMII)
> +#define RV1126_GMAC_PHY_INTF_SEL(val)	GRF_FIELD(6, 4, val)
>  #define RV1126_GMAC_FLOW_CTRL			GRF_BIT(7)
>  #define RV1126_GMAC_FLOW_CTRL_CLR		GRF_CLR_BIT(7)
>  #define RV1126_GMAC_M0_RXCLK_DLY_ENABLE		GRF_BIT(1)
> @@ -1388,7 +1383,7 @@ static void rv1126_set_to_rgmii(struct rk_priv_data *bsp_priv,
>  				int tx_delay, int rx_delay)
>  {
>  	regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON0,
> -		     RV1126_GMAC_PHY_INTF_SEL_RGMII |
> +		     RV1126_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RGMII) |
>  		     RV1126_GMAC_M0_RXCLK_DLY_ENABLE |
>  		     RV1126_GMAC_M0_TXCLK_DLY_ENABLE |
>  		     RV1126_GMAC_M1_RXCLK_DLY_ENABLE |
> @@ -1406,7 +1401,7 @@ static void rv1126_set_to_rgmii(struct rk_priv_data *bsp_priv,
>  static void rv1126_set_to_rmii(struct rk_priv_data *bsp_priv)
>  {
>  	regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON0,
> -		     RV1126_GMAC_PHY_INTF_SEL_RMII);
> +		     RV1126_GMAC_PHY_INTF_SEL(PHY_INTF_SEL_RMII));
>  }
>  
>  static const struct rk_gmac_ops rv1126_ops = {



From dsimic at manjaro.org  Fri Nov 14 00:32:29 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Fri, 14 Nov 2025 09:32:29 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v6 1/3] =?utf-8?q?dt-bindings=3A?=
 =?utf-8?q?_arm=3A?==?utf-8?q?_rockchip=3A?= Add Radxa CM5 IO Board
In-Reply-To: <A3AD69295D2E2D65+db2dc8bd-054f-4dda-9dd1-3cc0c0feed35@radxa.com>
References: <20251105051335.17652-1-naoki@radxa.com>
 <20251105051335.17652-2-naoki@radxa.com>
 <ce6e6369-a7e4-4a35-80f8-70ef41c3b877@kernel.org>
 <A6C1199E2A0D3F37+f3fe0fd5-4ca5-4d3d-bc1d-45f46b48f89b@radxa.com>
 <93deab54-bd5e-433e-acbc-13f6ead47f43@kernel.org>
 <2177a0f0-68df-495c-b267-18e3d9b6ca80@kernel.org>
 <D88EE9EEB2B37D36+361d448f-d260-4d78-ae6b-abf1caabb94b@radxa.com>
 <b2833988-6319-4426-8a25-c0d34acffa47@kernel.org>
 <B6224BD6578686FF+dc81e00c-46f6-4791-af8a-99cf8e880f0c@radxa.com>
 <f112b806-b204-46b5-90b2-813ad5d0ceee@kernel.org> <A3AD69295D2E2D65+db2dc8bd-054f-4dda-9dd1-3cc0c0feed35@radxa.com>
Message-ID: <194908a1-f956-ba0a-656f-7b1e8456b51d@manjaro.org>

On Friday, November 14, 2025 09:24 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> On 11/14/25 16:51, Krzysztof Kozlowski wrote:
> > On 14/11/2025 08:47, FUKAUMI Naoki wrote:
> >> On 11/14/25 16:42, Krzysztof Kozlowski wrote:
> >>> On 14/11/2025 08:37, FUKAUMI Naoki wrote:
> >>>> Hi Krzysztof,
> >>>>
> >>>> On 11/14/25 16:12, Krzysztof Kozlowski wrote:
> >>>>> On 05/11/2025 08:08, Krzysztof Kozlowski wrote:
> >>>>>> On 05/11/2025 07:57, FUKAUMI Naoki wrote:
> >>>>>>> On 11/5/25 15:43, Krzysztof Kozlowski wrote:
> >>>>>>>> On 05/11/2025 06:13, FUKAUMI Naoki wrote:
> >>>>>>>>> Add device tree binding documentation for the Radxa CM5 IO Board.
> >>>>>>>>>
> >>>>>>>>> Link: https://dl.radxa.com/cm5/radxa_cm5_product_brief.pdf
> >>>>>>>>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> >>>>>>>>> Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
> >>>>>>>>
> >>>>>>>> Wrong DCO chain.
> >>>>>>>>
> >>>>>>>>> ---
> >>>>>>>>>      Documentation/devicetree/bindings/arm/rockchip.yaml | 7 +++++++
> >>>>>>>>
> >>>>>>>> NAK, you just stolen ownership of an already posted patch.
> >>>>>>>
> >>>>>>> Read "Changes in v6" and patches; my patches are not the same as v5.
> >>>>>>> Your reply is totally inappropriate.
> >>>>>>
> >>>>>> Inappropriate is taking authorship of someone's patch, because we all
> >>>>>> expect to preserve the original authorship. That's not only basic
> >>>>>> decency but actually a standard.
> >>>>>>
> >>>>>> Additionally, read Joseph's reply that he wants to continue the work:
> >>>>>> https://lore.kernel.org/all/CAMWSM7iHtAxewW4JkRqRsifVnccqeFviaCgeOyprKDr92FOurg at mail.gmail.com/
> >>>>>>
> >>>>>> You clearly do not understand how to continue with someone's work.
> >>>>>>
> >>>>>> It is still a NAK.
> >>>>>
> >>>>> And I still wait for justification why you took authorship of this
> >>>>> patch, because to my eye you changed here nothing.
> >>>>>
> >>>>> So what did you change HERE that you think you are the author now?
> >>>>
> >>>> Changes in v6:
> >>>> (Patch 1/3)
> >>>> - Fix description; "Radxa CM5" is the correct name
> >>>
> >>> HERE, in this patch. Don't paste me hundreds of unrelated code. Write
> >>> concise and precise answers/comments.
> >>
> >> https://lore.kernel.org/linux-rockchip/AE0735A6C797CCFF+10496d73-7c0a-4884-9561-24721305a24f at radxa.com/
> >>
> >> | By the way, at some point I switched from "continuing your work" to
> >> | "recreating a new one based on my current work." The results of my
> >> | current work(*3) have changed significantly.
> > 
> > So next time I will take your patch, your code, say "I recreated it" and
> > submit under my authorship and for you it is fine?
> 
> Regarding CM5 patches, I'm fine.
> 
> > Please take Joseph's patch instead. Read submitting patches doc to
> > understand which one more tag has to be added when sending somoene
> > else's work.
> > 
> > In the future, I sincerely suggest avoiding re-creating people's work
> > but building on top, because you just duplicate the effort.
> 
> I understand that you don't understand how I made efforts to build my 
> work on top of Joseph's patches.

Maybe a solution for this huge mess could be that Naoki submits
unmodified patches from Joseph first, using the standard procedure
for that, and then the additional patch(es) that improve Joseph's
work?  All that in the same series.



From krzk at kernel.org  Fri Nov 14 00:33:31 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 14 Nov 2025 09:33:31 +0100
Subject: [PATCH v6 1/3] dt-bindings: arm: rockchip: Add Radxa CM5 IO Board
In-Reply-To: <A3AD69295D2E2D65+db2dc8bd-054f-4dda-9dd1-3cc0c0feed35@radxa.com>
References: <20251105051335.17652-1-naoki@radxa.com>
 <20251105051335.17652-2-naoki@radxa.com>
 <ce6e6369-a7e4-4a35-80f8-70ef41c3b877@kernel.org>
 <A6C1199E2A0D3F37+f3fe0fd5-4ca5-4d3d-bc1d-45f46b48f89b@radxa.com>
 <93deab54-bd5e-433e-acbc-13f6ead47f43@kernel.org>
 <2177a0f0-68df-495c-b267-18e3d9b6ca80@kernel.org>
 <D88EE9EEB2B37D36+361d448f-d260-4d78-ae6b-abf1caabb94b@radxa.com>
 <b2833988-6319-4426-8a25-c0d34acffa47@kernel.org>
 <B6224BD6578686FF+dc81e00c-46f6-4791-af8a-99cf8e880f0c@radxa.com>
 <f112b806-b204-46b5-90b2-813ad5d0ceee@kernel.org>
 <A3AD69295D2E2D65+db2dc8bd-054f-4dda-9dd1-3cc0c0feed35@radxa.com>
Message-ID: <f6887de6-4479-4559-85a7-bfe606936855@kernel.org>

On 14/11/2025 09:24, FUKAUMI Naoki wrote:
>>>>>>
>>>>>> And I still wait for justification why you took authorship of this
>>>>>> patch, because to my eye you changed here nothing.
>>>>>>
>>>>>> So what did you change HERE that you think you are the author now?
>>>>>
>>>>> Changes in v6:
>>>>> (Patch 1/3)
>>>>> - Fix description; "Radxa CM5" is the correct name
>>>>
>>>> HERE, in this patch. Don't paste me hundreds of unrelated code. Write
>>>> concise and precise answers/comments.
>>>
>>> https://lore.kernel.org/linux-rockchip/AE0735A6C797CCFF+10496d73-7c0a-4884-9561-24721305a24f at radxa.com/
>>>
>>> | By the way, at some point I switched from "continuing your work" to
>>> | "recreating a new one based on my current work." The results of my
>>> | current work(*3) have changed significantly.
>>
>> So next time I will take your patch, your code, say "I recreated it" and
>> submit under my authorship and for you it is fine?
> 
> Regarding CM5 patches, I'm fine.
> 
>> Please take Joseph's patch instead. Read submitting patches doc to
>> understand which one more tag has to be added when sending somoene
>> else's work.
>>
>> In the future, I sincerely suggest avoiding re-creating people's work
>> but building on top, because you just duplicate the effort.
> 
> I understand that you don't understand how I made efforts to build my 
> work on top of Joseph's patches.

This patch, I speak about this patch.

Not patches.

Best regards,
Krzysztof


From naoki at radxa.com  Fri Nov 14 00:46:39 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Fri, 14 Nov 2025 17:46:39 +0900
Subject: [PATCH v6 0/3] Add Radxa CM5 and IO Board
In-Reply-To: <705A25012553039E+ea9a05c0-ccc5-4d70-930b-e989300e55a1@radxa.com>
References: <20251105051335.17652-1-naoki@radxa.com>
 <199E172C8E20ED38+71169242-5525-4d60-9e37-a03ad172d639@radxa.com>
 <705A25012553039E+ea9a05c0-ccc5-4d70-930b-e989300e55a1@radxa.com>
Message-ID: <5CDCCB3C8D98AFF4+865e773e-29b1-4e60-b8b1-3633b996619b@radxa.com>

(Sorry, "To:" was wrong in previous email)

Hi Joseph,

On 11/14/25 17:06, FUKAUMI Naoki wrote:
> Hi Joseph,
> 
> On 11/5/25 21:15, FUKAUMI Naoki wrote:
>> I'd like to clarify the situation regarding the v6 patch series I 
>> submitted.
>>
>> The original device tree work for the Radxa CM5 and IO Board was 
>> authored by Joseph Kogut. I took over the responsibility of getting it 
>> upstreamed with his agreement.
>>
>> However, I now understand that I should have preserved the original 
>> Signed-off-by chain (and DCO) in the v6 series. This was my oversight.
>>
>> To correct this, I would prefer for Joseph to post the patches 
>> himself, which will not include my Signed-off-by.
> 
> Could you please post the patches?

Please ignore the patches I sent as v6. Also, I don't claim my 
copyright. Feel free (not) to use them.

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> Best regards,
> 
> -- 
> FUKAUMI Naoki
> Radxa Computer (Shenzhen) Co., Ltd.
> 
>> My apologies for the confusion this caused. Thank you for pointing 
>> this out.
>>
>> Best regards,
>>
>> -- 
>> FUKAUMI Naoki
>> Radxa Computer (Shenzhen) Co., Ltd.
>>
>> On 11/5/25 14:13, FUKAUMI Naoki wrote:
>>> This patch series add support for the Radxa CM5 SoM and IO Board.
>>>
>>> Changes in v6:
>>> (Patch 1/3)
>>> - Fix description; "Radxa CM5" is the correct name
>>> (Patch 2/3)
>>> - Fix #include(s)
>>> - Include rk3588s.dtsi
>>> - Move alias for gmac1 from io board dts
>>> - Add Maskrom key
>>> - Add pinctrl-* for led-0
>>> - Add vcc_1v1_nldo_s3 regulator for pmic
>>> - Move gmac1 (except status) from io board dts
>>> - Fix phy-supply for gmac1
>>> - Fix compatible for vdd_cpu_big1_s0 regulator
>>> - Add eeprom on i2c0
>>> - Add vdd_npu_s0 regulator for rknn
>>> - Fix compatible for rgmii_phy1
>>> - Add pinctrl-* and reset-* for rgmii_phy1
>>> - Add domain-supply for pd_npu
>>> - Add rknn_*
>>> - Add saradc
>>> - Fix properties in sdhci
>>> - Move pmic from io board dts
>>> - Fix vcc*-supply for pmic
>>> - Add regulators in pmic
>>> - Add tsadc
>>> - Move vop(_mmu) from io board dts
>>> - Trivial changes (labels, names, etc)
>>> (Patch 3/3)
>>> - Fix #include(s)
>>> - Remove #include "rk3588s.dtsi"
>>> - Fix model
>>> - Add fan
>>> - Add Recovery key
>>> - Add pinctrl-* for vcc3v3_wf
>>> - Add vcc_sysin regulator
>>> - Add pinctrl-* for vbus5v0_typec
>>> - Add rfkill-bt and rfkill-wlan for M.2 module
>>> - Add sound for es8316
>>> - Add phy-supply for combphy2_psu
>>> - Fix power-role to "source" for fusb302
>>> - Add rtc for hym8536
>>> - Add audio-codec on i2c8 for es8316
>>> - Add i2s0_8ch for es8316
>>> - Add package_thermal for fan
>>> - Add pinctrl-* for pcie2x1l2
>>> - Add pwm11 for fan
>>> - Fix properties in sdmmmc
>>> - Add phy-supply for u2phy2_host and u2phy3_host
>>> - Remove usb_host0_ohci
>>> - Add pinctrl-* for usbdp_phy0
>>> - Trivial changes (labels, names, etc)
>>>
>>> Changes in v5:
>>> (Patch 2/3, per Jimmy)
>>> - Alias eMMC to mmc0
>>> - Remove unused sdio alias
>>> - Move gmac, hdmi0 nodes to carrier board dts
>>> (Patch 3/3, per Jimmy)
>>> - Enable hdmi0_sound and i2s5_8ch
>>> - Remove redundant enablement of sdhci
>>> - Enable usb_host2_xhci
>>>
>>> - Tested HDMI audio
>>>
>>> Changes in v4:
>>> - Fixed XHCI initialization bug by changing try-power-role from source
>>> ?? to sink
>>>
>>> Changes in v3:
>>> - Addressed YAML syntax error in dt binding (per Rob)
>>> - Fixed whitespace issue in dts reported by checkpatch.pl
>>> - Split base SoM and carrier board into separate patches
>>> - Added further details about the SoM and carrier to the commit
>>> ?? messages
>>>
>>> Changes in v2:
>>> - Added copyright header and data sheet links
>>> - Removed non-existent property
>>> - Sorted alphabetically
>>> - Removed errant whitespace
>>> - Moved status to the end of each node
>>> - Removed pinctrl-names property from leds (indicated by CHECK_DTBS)
>>> - Removed delays from gmac with internal delay
>>>
>>> Link: https://lore.kernel.org/r/20250617-rk3588s-cm5-io-dts-upstream- 
>>> v5-0-8d96854a5bbd at gmail.com
>>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
>>> Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
>>> ---
>>> I have communicated with Joseph privately and taken ownership of
>>> moving this forward, with his blessing. All bugs belong to me.
>>> ---
>>> FUKAUMI Naoki (3):
>>> ?? dt-bindings: arm: rockchip: Add Radxa CM5 IO Board
>>> ?? arm64: dts: rockchip: Add Radxa CM5
>>> ?? arm64: dts: rockchip: Add Radxa CM5 IO Board
>>>
>>> ? .../devicetree/bindings/arm/rockchip.yaml???? |?? 7 +
>>> ? arch/arm64/boot/dts/rockchip/Makefile???????? |?? 1 +
>>> ? .../dts/rockchip/rk3588s-radxa-cm5-io.dts???? | 503 +++++++++++++++
>>> ? .../boot/dts/rockchip/rk3588s-radxa-cm5.dtsi? | 602 ++++++++++++++++++
>>> ? 4 files changed, 1113 insertions(+)
>>> ? create mode 100644 arch/arm64/boot/dts/rockchip/rk3588s-radxa-cm5- 
>>> io.dts
>>> ? create mode 100644 arch/arm64/boot/dts/rockchip/rk3588s-radxa-cm5.dtsi
>>
>>
> 



From cristian.ciocaltea at collabora.com  Fri Nov 14 00:51:46 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Fri, 14 Nov 2025 10:51:46 +0200
Subject: [PATCH v6 0/3] Add Radxa CM5 and IO Board
In-Reply-To: <49c39864-3e58-2e0e-7abc-50502f2afb02@manjaro.org>
References: <20251105051335.17652-1-naoki@radxa.com>
 <199E172C8E20ED38+71169242-5525-4d60-9e37-a03ad172d639@radxa.com>
 <CAMWSM7gezjVSoF+-7ivboTeB=5gQAE-QVrbAbKu3M=obmb3Axg@mail.gmail.com>
 <617FDAB231C501DC+3f9809df-87df-4a02-bd5f-ebc6299b3aa7@radxa.com>
 <a10340af-1d0a-bb0b-4835-7b2c9e67d664@manjaro.org>
 <2892FE50237CD58E+0f15924c-a915-4446-954c-d81a782d23e9@radxa.com>
 <19ce0a41-563c-6202-6b94-b2c644a0b827@manjaro.org>
 <F02BA2E6B1111826+2445b38d-b5e0-499c-83e7-4521c57b2210@radxa.com>
 <f2bc30de-119b-4f4a-844a-8a908c9290b6@kernel.org>
 <49c39864-3e58-2e0e-7abc-50502f2afb02@manjaro.org>
Message-ID: <f156cd48-d764-43c8-99ed-24ab212d8eee@collabora.com>

On 11/14/25 9:17 AM, Dragan Simic wrote:
> Hello Krzysztof,
> 
> On Friday, November 14, 2025 08:10 CET, Krzysztof Kozlowski <krzk at kernel.org> wrote:
>> On 14/11/2025 06:03, FUKAUMI Naoki wrote:
>>> On 11/12/25 09:46, Dragan Simic wrote:
>>>> On Wednesday, November 12, 2025 00:26 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
>>>>> On 11/11/25 23:33, Dragan Simic wrote:
>>>>>> On Tuesday, November 11, 2025 12:52 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
>>>>>>> On 11/6/25 02:48, Joseph Kogut wrote:
>>>>>>>> On Wed, Nov 5, 2025 at 4:15?AM FUKAUMI Naoki <naoki at radxa.com> wrote:
>>>>>>>>> I'd like to clarify the situation regarding the v6 patch series I submitted.
>>>>>>>>>
>>>>>>>>> The original device tree work for the Radxa CM5 and IO Board was
>>>>>>>>> authored by Joseph Kogut. I took over the responsibility of getting it
>>>>>>>>> upstreamed with his agreement.
>>>>>>>>
>>>>>>>> I'll confirm this. I've been in communication with Naoki. They made a
>>>>>>>> large number of revisions to my original patch series, which I think
>>>>>>>> have technical merit. I suggested they submit the patches themselves,
>>>>>>>> and gave them explicit permission to add my Signed-off-by and CC me.
>>>>>>>>
>>>>>>>> I assume this was the correct way for them to continue the work I
>>>>>>>> started, but if not, please let us know the best way to proceed.
>>>>>>>
>>>>>>> Can anyone help us?
>>>>>>
>>>>>> I'm not exactly sure how to resolve the current situation, but for
>>>>>> Signed-off-by tags to be present, in this case you'd need to have
>>>>>> Co-developed-by tags as well, because the final patch versions,
>>>>>> which would be submitted by Naoki, would differ significantly from
>>>>>> the versions that Joseph actively worked on, if I understood
>>>>>> everything correctly.  Though, for Joseph's Signed-off-by tags to
>>>>>> be included there, he would also need to participate actively in
>>>>>> the development of the final patch versions.
>>>>>
>>>>> https://www.kernel.org/doc/html/latest/process/submitting-patches.html#when-to-use-acked-by-cc-and-co-developed-by
>>>>>
>>>>> If
>>>>> ----
>>>>> From: Joseph Kogut <joseph.kogut at gmail.com>
>>>>>
>>>>> <changelog>
>>>>>
>>>>> Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
>>>>> Co-developed-by: FUKAUMI Naoki <naoki at radxa.com>
>>>>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
>>>>> ----
>>>>> then I can submit my patch series?
>>>>
>>>> Actually, the Co-developed-by tags would be pointing to Joseph
>>>> in that case, but as I described it above, this approach basically
>>>> cannot be used, because Joseph's original work differs a lot from
>>>> what you'd actually submit to the mailing list(s).
>>>>
>>>>> Or,
>>>>>
>>>>>> Another option, technically a bit simpler, would be to include just
>>>>>> Originally-by tags for Joseph, which would indicate that Joseph gave
>>>>>> up on the development of the patches and handed them over to Naoki
>>>>>> for future development and submission to the mailing lists. Though,
>>>>>> that would require Joseph to publicly state exactly that.
>>>>>
>>>>> I cannot find any documentation about "Originally-by".
>>>>> Is this correct?
>>>>> ----
>>>>> <changelog>
>>>>>
>>>>> Originally-by: Joseph Kogut <joseph.kogut at gmail.com>
>>
>> There is no such tag. Don't invent tags.
> 
> True, it doesn't exist officially, but it's been used fairly often.

Hmm, actually this tag seems to be documented, or at least given as an example:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/maintainer-tip.rst?h=v6.18-rc5#n309


From shawn.lin at rock-chips.com  Fri Nov 14 01:16:21 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Fri, 14 Nov 2025 17:16:21 +0800
Subject: [PATCH] arm64: dts: rockchip: align bindings to PCIe spec
In-Reply-To: <aRazCssWVdAOmy7D@geday>
References: <4b5ffcccfef2a61838aa563521672a171acb27b2.1762321976.git.geraldogabriel@gmail.com>
 <ba120577-42da-424d-8102-9d085c1494c8@rock-chips.com>
 <aQsIXcQzeYop6a0B@geday>
 <67b605b0-7046-448a-bc9b-d3ac56333809@rock-chips.com>
 <aQ1c7ZDycxiOIy8Y@geday>
 <d9e257bd-806c-48b4-bb22-f1342e9fc15a@rock-chips.com>
 <aRLEbfsmXnGwyigS@geday>
 <AGsAmwCFJj0ZQ4vKzrqC84rs.3.1762847224180.Hmail.ye.zhang@rock-chips.com>
 <aRQ_R90S8T82th45@geday> <aRUvr0UggTYkkCZ_@geday> <aRazCssWVdAOmy7D@geday>
Message-ID: <e8524bf8-a90c-423f-8a58-9ef05a3db1dd@rock-chips.com>

? 2025/11/14 ??? 12:41, Geraldo Nascimento ??:
> On Wed, Nov 12, 2025 at 10:09:15PM -0300, Geraldo Nascimento wrote:
>> Hi Ye, Shawn,
>>
>> Here's more contained workaround without resorting to clearing DDR to
>> INPUT for every GPIO:
>>
>> diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c
>> index ee1822ca01db..1d89131ec6ac 100644
>> --- a/drivers/pci/controller/pcie-rockchip-host.c
>> +++ b/drivers/pci/controller/pcie-rockchip-host.c
>> @@ -315,7 +315,8 @@ static int rockchip_pcie_host_init_port(struct rockchip_pcie *rockchip)
>>   			    PCIE_CLIENT_CONFIG);
>>   
>>   	msleep(PCIE_T_PVPERL_MS);
>> -	gpiod_set_value_cansleep(rockchip->perst_gpio, 1);
>> +	gpiod_direction_input(rockchip->perst_gpio);
>> +	gpiod_direction_output(rockchip->perst_gpio, 1);
>>   
>>   	msleep(PCIE_RESET_CONFIG_WAIT_MS);
>>   
>> This results in working PCIe for me, pass initial link training.
> 
> Sorry for the inconvenience of more mail, but I'm providing as much
> detail as I can.
> 

Don't worry, it's helpful, so I think Ye could have a look.
May I ask if the failure only happened to one specific board?

Another thing I noticed is about one commit:
114b06ee108c ("PCI: rockchip: Set Target Link Speed to 5.0 GT/s before 
retraining")

It said: "Rockchip controllers can support up to 5.0 GT/s link speed."
But we issued an errata long time ago to announced it doesn't, you could
also check the PCIe part of RK3399 datasheet:
https://opensource.rock-chips.com/images/d/d7/Rockchip_RK3399_Datasheet_V2.1-20200323.pdf

Also we set max-link-speed to ONE in rk3399-base.dtsi but seems another
patch slip in: 755fff528b1b ("arm64: dts: rockchip: add variables for 
pcie completion to helios64")

> This hack has been confirmed to work in U-boot also.
> 
> diff --git a/drivers/pci/pcie_rockchip.c b/drivers/pci/pcie_rockchip.c
> index 19f9e58a640..5702b607ee6 100644
> --- a/drivers/pci/pcie_rockchip.c
> +++ b/drivers/pci/pcie_rockchip.c
> @@ -329,8 +329,10 @@ static int rockchip_pcie_init_port(struct udevice *dev)
>   	writel(PCIE_CLIENT_LINK_TRAIN_ENABLE,
>   	       priv->apb_base + PCIE_CLIENT_CONFIG);
>   
> -	if (dm_gpio_is_valid(&priv->ep_gpio))
> -		dm_gpio_set_value(&priv->ep_gpio, 1);
> +	if (dm_gpio_is_valid(&priv->ep_gpio)) {
> +		dm_gpio_set_dir_flags(&priv->ep_gpio, (priv->ep_gpio.flags & ~GPIOD_IS_OUT) | GPIOD_IS_IN);
> +		dm_gpio_set_dir_flags(&priv->ep_gpio, (priv->ep_gpio.flags & ~GPIOD_IS_IN) | GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
> +	}
>   
>   	ret = readl_poll_sleep_timeout
>   			(priv->apb_base + PCIE_CLIENT_BASIC_STATUS1,
> 
> So my report suggests this is not specific to Linux and because same
> workaround works in U-boot simplified driver model I suggest you check
> from your side.
> 
> Previously PCIe link training timeout, not working. Now I'm very happy
> with working PCIe in Linux and U-boot.
> 
> Thanks,
> Geraldo Nascimento
> 



From coiaprant at gmail.com  Fri Nov 14 01:21:15 2025
From: coiaprant at gmail.com (Coia Prant)
Date: Fri, 14 Nov 2025 17:21:15 +0800
Subject: [PATCH] arm64: dts: rockchip: fix PCIe 3.3V regulator voltage on 9Tripod X3568 v4
Message-ID: <20251114092114.62664-2-coiaprant@gmail.com>

The regulator type is "regulator-fixed" since its voltage always be
3.3v, min and max should be 3300000 make the regulator has a voltage

The regulator is supplied by dc_12v, so add the vin-supply.

Link: https://github.com/rockchip-linux/kernel/commit/17e9559f67d26f3c602e38a24feb5194e51ac782
Signed-off-by: Coia Prant <coiaprant at gmail.com>
---
 .../boot/dts/rockchip/rk3568-9tripod-x3568-v4.dts  | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4.dts b/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4.dts
index ad4d62060..32fda9f5e 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4.dts
@@ -170,16 +170,16 @@ vcc3v3_sys: regulator-vcc3v3-sys {
 	};
 
 	vcc3v3_pcie: regulator-vcc3v3-pcie {
-		compatible = "regulator-gpio";
-		regulator-name = "vcc3v3_pcie";
-		regulator-min-microvolt = <100000>;
-		regulator-max-microvolt = <3300000>;
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio3 RK_PC3 GPIO_ACTIVE_HIGH>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&vcc3v3_pcie_en_pin>;
-		gpios = <&gpio3 RK_PC3 GPIO_ACTIVE_HIGH>;
-		gpios-states = <1>;
-		states = <100000 0>, <3300000 1>;
+		regulator-name = "vcc3v3_pcie";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
 		startup-delay-us = <5000>;
+		vin-supply = <&dc_12v>;
 	};
 
 	vcc5v0_sys: regulator-vcc5v0-sys {
-- 
2.47.3



From ukleinek at kernel.org  Fri Nov 14 01:51:27 2025
From: ukleinek at kernel.org (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Fri, 14 Nov 2025 10:51:27 +0100
Subject: [PATCH v3 3/5] pwm: Add rockchip PWMv4 driver
In-Reply-To: <8a6e920b-9565-4161-9d71-63f924593c23@rock-chips.com>
References: <20251027-rk3576-pwm-v3-0-654a5cb1e3f8@collabora.com>
 <20251027-rk3576-pwm-v3-3-654a5cb1e3f8@collabora.com>
 <8a6e920b-9565-4161-9d71-63f924593c23@rock-chips.com>
Message-ID: <fgu42esufq2x4fcccncqs3hlotih2gqmws5atotlaznuahoslw@34vblr6vboze>

On Tue, Oct 28, 2025 at 04:16:26PM +0800, Damon Ding wrote:
> Hi Nicolas,
> 
> On 10/28/2025 1:11 AM, Nicolas Frattaroli wrote:
> > The Rockchip RK3576 brings with it a new PWM IP, in downstream code
> > referred to as "v4". This new IP is different enough from the previous
> > Rockchip IP that I felt it necessary to add a new driver for it, instead
> > of shoehorning it in the old one.
> > 
> > Add this new driver, based on the PWM core's waveform APIs. Its platform
> > device is registered by the parent mfpwm driver, from which it also
> > receives a little platform data struct, so that mfpwm can guarantee that
> > all the platform device drivers spread across different subsystems for
> > this specific hardware IP do not interfere with each other.
> > 
> > Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
> > ---
> >   MAINTAINERS                   |   1 +
> >   drivers/pwm/Kconfig           |  13 ++
> >   drivers/pwm/Makefile          |   1 +
> >   drivers/pwm/pwm-rockchip-v4.c | 353 ++++++++++++++++++++++++++++++++++++++++++
> >   4 files changed, 368 insertions(+)
> > 
> 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 8f3235ba825e..2079c2d51d5c 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -22372,6 +22372,7 @@ L:	linux-rockchip at lists.infradead.org
> >   L:	linux-pwm at vger.kernel.org
> >   S:	Maintained
> >   F:	Documentation/devicetree/bindings/pwm/rockchip,rk3576-pwm.yaml
> > +F:	drivers/pwm/pwm-rockchip-v4.c
> >   F:	drivers/soc/rockchip/mfpwm.c
> >   F:	include/soc/rockchip/mfpwm.h
> > diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
> > index c2fd3f4b62d9..b852a7b2a29d 100644
> > --- a/drivers/pwm/Kconfig
> > +++ b/drivers/pwm/Kconfig
> > @@ -615,6 +615,19 @@ config PWM_ROCKCHIP
> >   	  Generic PWM framework driver for the PWM controller found on
> >   	  Rockchip SoCs.
> > +config PWM_ROCKCHIP_V4
> > +	tristate "Rockchip PWM v4 support"
> > +	depends on ARCH_ROCKCHIP || COMPILE_TEST
> > +	depends on HAS_IOMEM
> > +	depends on MFD_ROCKCHIP_MFPWM
> > +	help
> > +	  Generic PWM framework driver for the PWM controller found on
> > +	  later Rockchip SoCs such as the RK3576.
> > +
> > +	  Uses the Rockchip Multi-function PWM controller driver infrastructure
> > +	  to guarantee fearlessly concurrent operation with other functions of
> > +	  the same device implemented by drivers in other subsystems.
> > +
> >   config PWM_SAMSUNG
> >   	tristate "Samsung PWM support"
> >   	depends on PLAT_SAMSUNG || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
> > diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
> > index dfa8b4966ee1..fe0d16558d99 100644
> > --- a/drivers/pwm/Makefile
> > +++ b/drivers/pwm/Makefile
> > @@ -55,6 +55,7 @@ obj-$(CONFIG_PWM_RENESAS_RZG2L_GPT)	+= pwm-rzg2l-gpt.o
> >   obj-$(CONFIG_PWM_RENESAS_RZ_MTU3)	+= pwm-rz-mtu3.o
> >   obj-$(CONFIG_PWM_RENESAS_TPU)	+= pwm-renesas-tpu.o
> >   obj-$(CONFIG_PWM_ROCKCHIP)	+= pwm-rockchip.o
> > +obj-$(CONFIG_PWM_ROCKCHIP_V4)	+= pwm-rockchip-v4.o
> >   obj-$(CONFIG_PWM_SAMSUNG)	+= pwm-samsung.o
> >   obj-$(CONFIG_PWM_SIFIVE)	+= pwm-sifive.o
> >   obj-$(CONFIG_PWM_SL28CPLD)	+= pwm-sl28cpld.o
> > diff --git a/drivers/pwm/pwm-rockchip-v4.c b/drivers/pwm/pwm-rockchip-v4.c
> > new file mode 100644
> > index 000000000000..7afa83f12b6a
> > --- /dev/null
> > +++ b/drivers/pwm/pwm-rockchip-v4.c
> > @@ -0,0 +1,353 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +/*
> > + * Copyright (c) 2025 Collabora Ltd.
> > + *
> > + * A Pulse-Width-Modulation (PWM) generator driver for the generators found in
> > + * Rockchip SoCs such as the RK3576, internally referred to as "PWM v4". Uses
> > + * the MFPWM infrastructure to guarantee exclusive use over the device without
> > + * other functions of the device from different drivers interfering with its
> > + * operation while it's active.
> > + *
> > + * Technical Reference Manual: Chapter 31 of the RK3506 TRM Part 1, a SoC which
> > + * uses the same PWM hardware and has a publicly available TRM.
> > + * https://opensource.rock-chips.com/images/3/36/Rockchip_RK3506_TRM_Part_1_V1.2-20250811.pdf
> > + *
> > + * Authors:
> > + *     Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
> > + *
> > + * Limitations:
> > + * - When the output is disabled, it will end abruptly without letting the
> > + *   current period complete.
> > + *   TODO: This can be fixed in the driver in the future by having the enable-
> > + *         to-disable transition switch to oneshot mode with one repetition,
> > + *         and then disable the pwmclk and release mfpwm when the oneshot
> > + *         complete interrupt fires.
> > + * - When the output is disabled, the pin will remain driven to whatever state
> > + *   it last had.
> > + * - Adjustments to the duty cycle will only take effect during the next period.
> > + * - Adjustments to the period length will only take effect during the next
> > + *   period.
> > + * - offset should be between 0 and (period - duty)
> > + */
> > +
> > +#include <linux/math64.h>
> > +#include <linux/mfd/rockchip-mfpwm.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/pwm.h>
> > +
> > +struct rockchip_pwm_v4 {
> > +	struct rockchip_mfpwm_func *pwmf;
> > +	struct pwm_chip chip;
> > +};
> > +
> > +struct rockchip_pwm_v4_wf {
> > +	u32 period;
> > +	u32 duty;
> > +	u32 offset;
> > +	u8 enable;
> > +};
> > +
> 
> ...
> 
> > +
> > +static int rockchip_pwm_v4_read_wf(struct pwm_chip *chip, struct pwm_device *pwm,
> > +				   void *_wfhw)
> > +{
> > +	struct rockchip_pwm_v4 *pc = to_rockchip_pwm_v4(chip);
> > +	struct rockchip_pwm_v4_wf *wfhw = _wfhw;
> > +	int ret = 0;
> > +
> 
> Redundant blank lin. ;-)
> 
> > +
> > +	ret = mfpwm_acquire(pc->pwmf);
> > +	if (ret)
> > +		return ret;
> > +
> > +	wfhw->period = mfpwm_reg_read(pc->pwmf->base, PWMV4_REG_PERIOD);
> > +	wfhw->duty = mfpwm_reg_read(pc->pwmf->base, PWMV4_REG_DUTY);
> > +	wfhw->offset = mfpwm_reg_read(pc->pwmf->base, PWMV4_REG_OFFSET);
> > +	wfhw->enable = mfpwm_reg_read(pc->pwmf->base, PWMV4_REG_ENABLE) & PWMV4_EN_BOTH_MASK;
> > +
> > +	mfpwm_release(pc->pwmf);
> > +
> > +	return 0;
> > +}
> > +
> 
> ...
> 
> > +MODULE_AUTHOR("Nicolas Frattaroli <nicolas.frattaroli at collabora.com>");
> > +MODULE_DESCRIPTION("Rockchip PWMv4 Driver");
> > +MODULE_LICENSE("GPL");
> > +MODULE_IMPORT_NS("ROCKCHIP_MFPWM");
> > +MODULE_ALIAS("platform:pwm-rockchip-v4");
> > 
> 
> Tested-by: Damon Ding <damon.ding at rock-chips.com>
> 
> I have tested all the PWM channels in continuous mode on my RK3576-IOTEST
> board.
> 
> Test commands are like:
> 
> cd /sys/class/pwm/pwmchip0/
> echo 0 > export
> cd pwm0
> echo 10000 > period
> echo 5000 > duty_cycle
> echo normal > polarity
> echo 1 > enable

Thanks for the test, very appreciated.

I wonder what made you test using sysfs instead of
https://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/libpwm.git/.
Is it unknown? Too complicated? Other problems?

Best regards
Uwe
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251114/9bed8832/attachment.sig>

From hverkuil+cisco at kernel.org  Fri Nov 14 01:53:58 2025
From: hverkuil+cisco at kernel.org (Hans Verkuil)
Date: Fri, 14 Nov 2025 10:53:58 +0100
Subject: [PATCH v9 5/8] media: v4l2-core: Introduce v4l2-isp.c
In-Reply-To: <20251108-extensible-parameters-validation-v9-5-6a7e22aa57d0@ideasonboard.com>
References: <20251108-extensible-parameters-validation-v9-0-6a7e22aa57d0@ideasonboard.com>
 <20251108-extensible-parameters-validation-v9-5-6a7e22aa57d0@ideasonboard.com>
Message-ID: <7a596b40-1fea-4dce-8ce9-0da805d2d1d5@kernel.org>

Hi Jacopo,

While reviewing your code in the Mali PR I found one thing confusing in the
v4l2-isp part. My apologies for not reviewing this before, I had too much
to do.

On 08/11/2025 10:36, Jacopo Mondi wrote:
> Add to the V4L2 framework helper functions to support drivers when
> validating a buffer of V4L2 ISP parameters.
> 
> Driver shall use v4l2_isp_params_validate_buffer_size() to verify the
> size correctness of the data received from userspace, and after having
> copied the data to a kernel-only memory location, complete the
> validation by calling v4l2_isp_params_validate_buffer().
> 
> Reviewed-by: Daniel Scally <dan.scally at ideasonboard.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas at ideasonboard.com>
> Reviewed-by: Michael Riesch <michael.riesch at collabora.com>
> Acked-by: Sakari Ailus <sakari.ailus at linux.intel.com>
> Tested-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> Signed-off-by: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
> ---
>  MAINTAINERS                        |   2 +
>  drivers/media/v4l2-core/Kconfig    |   4 ++
>  drivers/media/v4l2-core/Makefile   |   1 +
>  drivers/media/v4l2-core/v4l2-isp.c | 128 +++++++++++++++++++++++++++++++++++++
>  include/media/v4l2-isp.h           |  91 ++++++++++++++++++++++++++
>  5 files changed, 226 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index b4dd272a0790c317580d0747c8043738a1a58d8e..f9a86528a153f635a5a3db5ce9cf6854f699f47f 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -26860,6 +26860,8 @@ M:	Jacopo Mondi <jacopo.mondi at ideasonboard.com>
>  L:	linux-media at vger.kernel.org
>  S:	Maintained
>  F:	Documentation/userspace-api/media/v4l/v4l2-isp.rst
> +F:	drivers/media/v4l2-core/v4l2-isp.c
> +F:	include/media/v4l2-isp.h
>  F:	include/uapi/linux/media/v4l2-isp.h
>  
>  VF610 NAND DRIVER
> diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig
> index 331b8e535e5bbf33f22638b2ae8bc764ad5fc407..d50ccac9733cc39a43426ae7e7996dd0b5b45186 100644
> --- a/drivers/media/v4l2-core/Kconfig
> +++ b/drivers/media/v4l2-core/Kconfig
> @@ -82,3 +82,7 @@ config V4L2_CCI_I2C
>  	depends on I2C
>  	select REGMAP_I2C
>  	select V4L2_CCI
> +
> +config V4L2_ISP
> +	tristate
> +	depends on VIDEOBUF2_CORE
> diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile
> index 2177b9d63a8ffc1127c5a70118249a2ff63cd759..329f0eadce994cc1c8580beb435f68fa7e2a7aeb 100644
> --- a/drivers/media/v4l2-core/Makefile
> +++ b/drivers/media/v4l2-core/Makefile
> @@ -29,6 +29,7 @@ obj-$(CONFIG_V4L2_CCI) += v4l2-cci.o
>  obj-$(CONFIG_V4L2_FLASH_LED_CLASS) += v4l2-flash-led-class.o
>  obj-$(CONFIG_V4L2_FWNODE) += v4l2-fwnode.o
>  obj-$(CONFIG_V4L2_H264) += v4l2-h264.o
> +obj-$(CONFIG_V4L2_ISP) += v4l2-isp.o
>  obj-$(CONFIG_V4L2_JPEG_HELPER) += v4l2-jpeg.o
>  obj-$(CONFIG_V4L2_MEM2MEM_DEV) += v4l2-mem2mem.o
>  obj-$(CONFIG_V4L2_VP9) += v4l2-vp9.o
> diff --git a/drivers/media/v4l2-core/v4l2-isp.c b/drivers/media/v4l2-core/v4l2-isp.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..35f0b701f1729c3c0ccc34b1c89189b179e0b684
> --- /dev/null
> +++ b/drivers/media/v4l2-core/v4l2-isp.c
> @@ -0,0 +1,128 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Video4Linux2 generic ISP parameters and statistics support
> + *
> + * Copyright (C) 2025 Ideas On Board Oy
> + * Author: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
> + */
> +
> +#include <media/v4l2-isp.h>
> +
> +#include <linux/bitops.h>
> +#include <linux/device.h>
> +
> +#include <media/videobuf2-core.h>
> +
> +int v4l2_isp_params_validate_buffer_size(struct device *dev,
> +					 struct vb2_buffer *vb,
> +					 size_t max_size)
> +{
> +	size_t header_size = offsetof(struct v4l2_isp_params_buffer, data);
> +	size_t payload_size = vb2_get_plane_payload(vb, 0);
> +
> +	/* Payload size can't be greater than the destination buffer size */
> +	if (payload_size > max_size) {
> +		dev_dbg(dev, "Payload size is too large: %zu\n", payload_size);
> +		return -EINVAL;
> +	}
> +
> +	/* Payload size can't be smaller than the header size */
> +	if (payload_size < header_size) {
> +		dev_dbg(dev, "Payload size is too small: %zu\n", payload_size);
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(v4l2_isp_params_validate_buffer_size);
> +
> +int v4l2_isp_params_validate_buffer(struct device *dev, struct vb2_buffer *vb,
> +				    const struct v4l2_isp_params_buffer *buffer,
> +				    const struct v4l2_isp_params_block_info *info,
> +				    size_t num_blocks)
> +{
> +	size_t header_size = offsetof(struct v4l2_isp_params_buffer, data);
> +	size_t payload_size = vb2_get_plane_payload(vb, 0);
> +	size_t block_offset = 0;
> +	size_t buffer_size;
> +
> +	/*
> +	 * Currently only the first version of the V4L2 ISP parameters format is
> +	 * supported. We accept both V0 and V1 to support existing drivers
> +	 * compatible with V4L2 ISP that use either 0 or 1 as their "first
> +	 * version" identifiers.
> +	 */
> +	if (buffer->version != V4L2_ISP_PARAMS_VERSION_V0 &&
> +	    buffer->version != V4L2_ISP_PARAMS_VERSION_V1) {
> +		dev_dbg(dev,
> +			"Unsupported V4L2 ISP parameters format version: %u\n",
> +			buffer->version);
> +		return -EINVAL;
> +	}
> +
> +	/* Validate the size reported in the header */
> +	buffer_size = header_size + buffer->data_size;
> +	if (buffer_size != payload_size) {
> +		dev_dbg(dev, "Data size %zu and payload size %zu are different\n",
> +			buffer_size, payload_size);
> +		return -EINVAL;
> +	}
> +
> +	/* Walk the list of ISP configuration blocks and validate them. */
> +	buffer_size = buffer->data_size;
> +	while (buffer_size >= sizeof(struct v4l2_isp_params_block_header)) {
> +		const struct v4l2_isp_params_block_info *block_info;
> +		const struct v4l2_isp_params_block_header *block;
> +
> +		block = (const struct v4l2_isp_params_block_header *)
> +			(buffer->data + block_offset);
> +
> +		if (block->type >= num_blocks) {
> +			dev_dbg(dev,
> +				"Invalid block type %u at offset %zu\n",
> +				block->type, block_offset);
> +			return -EINVAL;
> +		}
> +
> +		if (block->size > buffer_size) {
> +			dev_dbg(dev, "Premature end of parameters data\n");
> +			return -EINVAL;
> +		}
> +
> +		/* It's invalid to specify both ENABLE and DISABLE. */
> +		if ((block->flags & (V4L2_ISP_PARAMS_FL_BLOCK_ENABLE |
> +				     V4L2_ISP_PARAMS_FL_BLOCK_DISABLE)) ==
> +		     (V4L2_ISP_PARAMS_FL_BLOCK_ENABLE |
> +		     V4L2_ISP_PARAMS_FL_BLOCK_DISABLE)) {
> +			dev_dbg(dev, "Invalid block flags %x at offset %zu\n",
> +				block->flags, block_offset);
> +			return -EINVAL;
> +		}
> +
> +		/*
> +		 * Match the block reported size against the info provided
> +		 * one, but allow the block to only contain the header in
> +		 * case it is going to be disabled.
> +		 */
> +		block_info = &info[block->type];
> +		if (block->size != block_info->size &&
> +		    (!(block->flags & V4L2_ISP_PARAMS_FL_BLOCK_DISABLE) ||
> +		    block->size != sizeof(*block))) {
> +			dev_dbg(dev,
> +				"Invalid block size %u (expected %zu) at offset %zu\n",
> +				block->size, block_info->size, block_offset);
> +			return -EINVAL;
> +		}
> +
> +		block_offset += block->size;
> +		buffer_size -= block->size;
> +	}
> +
> +	if (buffer_size) {
> +		dev_dbg(dev, "Unexpected data after the parameters buffer end\n");
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(v4l2_isp_params_validate_buffer);
> diff --git a/include/media/v4l2-isp.h b/include/media/v4l2-isp.h
> new file mode 100644
> index 0000000000000000000000000000000000000000..8b4695663699e7f176384739cf54ed7fa2c578f8
> --- /dev/null
> +++ b/include/media/v4l2-isp.h
> @@ -0,0 +1,91 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Video4Linux2 generic ISP parameters and statistics support
> + *
> + * Copyright (C) 2025 Ideas On Board Oy
> + * Author: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
> + */
> +
> +#ifndef _V4L2_ISP_H_
> +#define _V4L2_ISP_H_
> +
> +#include <linux/media/v4l2-isp.h>
> +
> +struct device;
> +struct vb2_buffer;
> +
> +/**
> + * v4l2_isp_params_buffer_size - Calculate size of v4l2_isp_params_buffer
> + * @max_params_size: The total size of the ISP configuration blocks
> + *
> + * Users of the v4l2 extensible parameters will have differing sized data arrays
> + * depending on their specific parameter buffers. Drivers and userspace will
> + * need to be able to calculate the appropriate size of the struct to
> + * accommodate all ISP configuration blocks provided by the platform.
> + * This macro provides a convenient tool for the calculation.
> + */
> +#define v4l2_isp_params_buffer_size(max_params_size) \
> +	(offsetof(struct v4l2_isp_params_buffer, data) + (max_params_size))
> +
> +/**
> + * v4l2_isp_params_validate_buffer_size - Validate a V4L2 ISP buffer sizes
> + * @dev: the driver's device pointer
> + * @vb: the videobuf2 buffer
> + * @max_size: the maximum allowed buffer size
> + *
> + * This function performs validation of the size of a V4L2 ISP parameters buffer
> + * before the driver can access the actual data buffer content.
> + *
> + * After the sizes validation, drivers should copy the buffer content to a
> + * kernel-only memory area to prevent userspace from modifying it,
> + * before completing validation using v4l2_isp_params_validate_buffer().
> + *
> + * The @vb buffer as received from the vb2 .buf_prepare() operation is checked
> + * against @max_size and it's validated to be large enough to accommodate at
> + * least one ISP configuration block.
> + */
> +int v4l2_isp_params_validate_buffer_size(struct device *dev,
> +					 struct vb2_buffer *vb,
> +					 size_t max_size);
> +
> +/**
> + * struct v4l2_isp_params_block_info - V4L2 ISP per-block info

Shouldn't this be v4l2_isp_params_block_type_info? After all, this
isn't info about a block but about a block type.

> + * @size: the block expected size
> + *
> + * The v4l2_isp_params_block_info collects information of the ISP configuration
> + * blocks for validation purposes. It currently only contains the expected

blocks -> block types

> + * block size.
> + *
> + * Drivers shall prepare a list of block info, indexed by block type, one for

a list of block type info

> + * each supported ISP block and correctly populate them with the expected block

block -> block type

> + * size.
> + */
> +struct v4l2_isp_params_block_info {
> +	size_t size;
> +};
> +
> +/**
> + * v4l2_isp_params_validate_buffer - Validate a V4L2 ISP parameters buffer
> + * @dev: the driver's device pointer
> + * @vb: the videobuf2 buffer
> + * @buffer: the V4L2 ISP parameters buffer
> + * @info: the list of per-block validation info

@type_info: the array of per-block-type validation info

> + * @num_blocks: the number of blocks

@num_block_types: the number of block types in the type_info array

Probably more places to correct.

It took me some time before I realized that this was about the block types,
not about the blocks themselves.

Regards,

	Hans

> + *
> + * This function completes the validation of a V4L2 ISP parameters buffer,
> + * verifying each configuration block correctness before the driver can use
> + * them to program the hardware.
> + *
> + * Drivers should use this function after having validated the correctness of
> + * the vb2 buffer sizes by using the v4l2_isp_params_validate_buffer_size()
> + * helper first. Once the buffer size has been validated, drivers should
> + * perform a copy of the user provided buffer into a kernel-only memory buffer
> + * to prevent userspace from modifying its content after it has been submitted
> + * to the driver, and then call this function to complete validation.
> + */
> +int v4l2_isp_params_validate_buffer(struct device *dev, struct vb2_buffer *vb,
> +				    const struct v4l2_isp_params_buffer *buffer,
> +				    const struct v4l2_isp_params_block_info *info,
> +				    size_t num_blocks);
> +
> +#endif /* _V4L2_ISP_H_ */
> 



From zhangqing at rock-chips.com  Fri Nov 14 01:55:53 2025
From: zhangqing at rock-chips.com (zhangqing)
Date: Fri, 14 Nov 2025 17:55:53 +0800
Subject: [PATCH v9 3/3] net: can: rockchip: add can for RK3576 Soc
In-Reply-To: <20251113-slim-foamy-gecko-2dc389-mkl@pengutronix.de>
References: <20251113075419.482940-1-zhangqing@rock-chips.com>
 <20251113075419.482940-4-zhangqing@rock-chips.com>
 <20251113-slim-foamy-gecko-2dc389-mkl@pengutronix.de>
Message-ID: <176d96b4-397c-49d4-8e8e-2f77a5d59c12@rock-chips.com>


? 2025/11/13 22:14, Marc Kleine-Budde ??:
> On 13.11.2025 15:54:19, Elaine Zhang wrote:
>> Is new controller, new register layout and Bit position definition:
> Let's improve the patch description a bit. What about:
>
> The CAN FD cores in the rk3576 SoC are a newer revision than those in
> the rk3568. The main differences are:
>
> - changed register layout
> - different bit position
> - ...
>
> I remember:
> - time stamp register removed
>
> Please go through this list and remove everything that was unchanged and
> add it to the list I started above.
>
>> Support CAN protocol, ISO 11898-1
>> Support transmit or receive error count
>> Support acceptance filter, more functional
>> Support interrupt and all interrupt can be masked
>> Support error code check
>> Support self test\silent\loop-back mode
>> Support auto retransmission mode
>> Support auto bus on after bus-off state
>> Support 2 transmit buffers
>> Support Internal Storage Mode
>>
>> Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
>> ---
>>   .../net/can/rockchip/rockchip_canfd-core.c    | 419 ++++++++++++++++++
>>   drivers/net/can/rockchip/rockchip_canfd-rx.c  | 103 +++++
>>   drivers/net/can/rockchip/rockchip_canfd-tx.c  |  20 +
>>   drivers/net/can/rockchip/rockchip_canfd.h     | 258 +++++++++++
>>   4 files changed, 800 insertions(+)
>>
>> diff --git a/drivers/net/can/rockchip/rockchip_canfd-core.c b/drivers/net/can/rockchip/rockchip_canfd-core.c
>> index 761cb36148ff..58fffcf97b20 100644
>> --- a/drivers/net/can/rockchip/rockchip_canfd-core.c
>> +++ b/drivers/net/can/rockchip/rockchip_canfd-core.c
>> @@ -31,6 +31,8 @@ static const char *__rkcanfd_get_model_str(enum rkcanfd_model model)
>>   		return "rk3568v2";
>>   	case RKCANFD_MODEL_RK3568V3:
>>   		return "rk3568v3";
>> +	case RKCAN_MODEL_RK3576:
>> +		return "rk3576";
>>   	}
>>
>>   	return "<unknown>";
>> @@ -176,6 +178,27 @@ static void rkcanfd_get_berr_counter_corrected(struct rkcanfd_priv *priv,
>>   		    !!(reg_state & RKCANFD_REG_STATE_ERROR_WARNING_STATE));
>>   }
>>
>> +static void rk3576can_get_berr_counter_corrected(struct rkcanfd_priv *priv,
>> +						 struct can_berr_counter *bec)
>> +{
>> +	struct can_berr_counter bec_raw;
> You've removed the workaround handling for the berr_counter. This means
> your SoC is not affected by it. So the bec_raw and taking care of
> priv->bec is not needed.
>
>> +	u32 reg_state;
>> +
>> +	bec->rxerr = rkcanfd_read(priv, RK3576CAN_REG_RXERRORCNT);
>> +	bec->txerr = rkcanfd_read(priv, RK3576CAN_REG_TXERRORCNT);
>> +	bec_raw = *bec;
> remove, see above
>
>> +
>> +	priv->bec = *bec;
> remove, see above
>
>> +
>> +	reg_state = rkcanfd_read(priv, RKCANFD_REG_STATE);
>> +	netdev_vdbg(priv->ndev,
>> +		    "%s: Raw/Cor: txerr=%3u/%3u rxerr=%3u/%3u Bus Off=%u Warning=%u\n",
>> +		    __func__,
>> +		    bec_raw.txerr, bec->txerr, bec_raw.rxerr, bec->rxerr,
>> +		    !!(reg_state & RK3576CAN_REG_STATE_BUS_OFF_STATE),
>> +		    !!(reg_state & RK3576CAN_REG_STATE_ERROR_WARNING_STATE));
> I think the vdbg can be removed, if the IP core is not affected by the
> problem.
>
>> +}
>> +
>>   static int rkcanfd_get_berr_counter(const struct net_device *ndev,
>>   				    struct can_berr_counter *bec)
>>   {
>> @@ -206,6 +229,11 @@ static void rkcanfd_chip_interrupts_disable(const struct rkcanfd_priv *priv)
>>   	rkcanfd_write(priv, RKCANFD_REG_INT_MASK, RKCANFD_REG_INT_ALL);
>>   }
>>
>> +static void rk3576can_chip_interrupts_disable(const struct rkcanfd_priv *priv)
>> +{
>> +	rkcanfd_write(priv, RK3576CAN_REG_INT_MASK, RK3576CAN_REG_INT_ALL);
>> +}
>> +
>>   static void rkcanfd_chip_fifo_setup(struct rkcanfd_priv *priv)
>>   {
>>   	u32 reg;
>> @@ -220,6 +248,48 @@ static void rkcanfd_chip_fifo_setup(struct rkcanfd_priv *priv)
>>   	netdev_reset_queue(priv->ndev);
>>   }
>>
>> +static void rk3576can_chip_fifo_setup(struct rkcanfd_priv *priv)
>> +{
>> +	u32 reg_ism, reg_water;
>> +
>> +	reg_ism = FIELD_PREP(RK3576CAN_REG_STR_CTL_ISM_SEL,
>> +			     RK3576CAN_REG_STR_CTL_ISM_SEL_CANFD_FIXED) |
>> +		  RK3576CAN_REG_STR_CTL_STORAGE_TIMEOUT_MODE;
>> +	reg_water = RK3576CAN_ISM_WATERMASK_CANFD;
>> +
>> +	/* internal sram mode */
>> +	rkcanfd_write(priv, RK3576CAN_REG_STR_CTL, reg_ism);
>> +	rkcanfd_write(priv, RK3576CAN_REG_STR_WTM, reg_water);
>> +	WRITE_ONCE(priv->tx_head, 0);
>> +	WRITE_ONCE(priv->tx_tail, 0);
>> +	netdev_reset_queue(priv->ndev);
>> +}
>> +
>> +static void rk3576can_atf_config(struct rkcanfd_priv *priv, int mode)
>> +{
>> +	int i;
>> +
>> +	switch (mode) {
>> +	case RK3576CAN_REG_ATFM_MASK_SEL_MASK_MODE:
>> +		for (i = 0; i < 5; i++) {
>> +			rkcanfd_write(priv, RK3576CAN_REG_ATF(i), 0);
>> +			rkcanfd_write(priv, RK3576CAN_REG_ATFM(i), RK3576CAN_REG_ATFM_ID);
>> +		}
>> +		break;
>> +	case RK3576CAN_REG_ATFM_MASK_SEL_LIST_MODE:
>> +		for (i = 0; i < 5; i++) {
>> +			rkcanfd_write(priv, RK3576CAN_REG_ATF(i), 0);
>> +			rkcanfd_write(priv, RK3576CAN_REG_ATFM(i), RK3576CAN_REG_ATFM_MASK_SEL);
>> +		}
>> +		break;
>> +	default:
>> +		rkcanfd_write(priv, RK3576CAN_REG_ATF_CTL, RK3576CAN_REG_ATF_CTL_ATF_DIS_ALL);
>> +		return;
>> +	}
>> +
>> +	rkcanfd_write(priv, RK3576CAN_REG_ATF_CTL, 0);
>> +}
>> +
>>   static void rkcanfd_chip_start(struct rkcanfd_priv *priv)
>>   {
>>   	u32 reg;
>> @@ -285,6 +355,61 @@ static void rkcanfd_chip_start(struct rkcanfd_priv *priv)
>>   		   rkcanfd_read(priv, RKCANFD_REG_MODE));
>>   }
>>
>> +static void rk3576can_chip_start(struct rkcanfd_priv *priv)
>> +
>> +{
>> +	u32 reg;
>> +
>> +	rkcanfd_chip_set_reset_mode(priv);
>> +
>> +	/* Receiving Filter: accept all */
>> +	rk3576can_atf_config(priv, RK3576CAN_REG_ATFM_MASK_SEL_MASK_MODE);
>> +
>> +	/* enable:
>> +	 * - WORK_MODE: transition from reset to working mode
>> +	 */
>> +	reg = rkcanfd_read(priv, RKCANFD_REG_MODE);
>> +	priv->reg_mode_default = reg | RKCANFD_REG_MODE_WORK_MODE;
>> +
>> +	if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
>> +		priv->reg_mode_default |= RKCANFD_REG_MODE_LBACK_MODE;
>> +		rkcanfd_write(priv, RK3576CAN_REG_ERROR_MASK,
>> +			      RK3576CAN_REG_ERROR_MASK_ACK_ERROR);
>> +	}
>> +
>> +	/* mask, i.e. ignore:
>> +	 * - RX_FINISH_INT - Rx finish interrupt
>> +	 */
>> +	priv->reg_int_mask_default = RK3576CAN_REG_INT_RX_FINISH_INT;
>> +
>> +	/* Do not mask the bus error interrupt if the bus error
>> +	 * reporting is requested.
>> +	 */
>> +	if (!(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING))
>> +		priv->reg_int_mask_default |= RKCANFD_REG_INT_ERROR_INT;
>> +
>> +	memset(&priv->bec, 0x0, sizeof(priv->bec));
>> +
>> +	rk3576can_chip_fifo_setup(priv);
>> +
>> +	rkcanfd_write(priv, RK3576CAN_REG_AUTO_RETX_CFG,
>> +		      RK3576CAN_REG_AUTO_RETX_CFG_AUTO_RETX_EN);
>> +
>> +	rkcanfd_write(priv, RK3576CAN_REG_BRS_CFG,
>> +		      RK3576CAN_REG_BRS_CFG_BRS_NEGSYNC_EN |
>> +		      RK3576CAN_REG_BRS_CFG_BRS_POSSYNC_EN);
>> +
>> +	rkcanfd_set_bittiming(priv);
>> +
>> +	priv->devtype_data.interrupts_disable(priv);
>> +	rkcanfd_chip_set_work_mode(priv);
>> +
>> +	priv->can.state = CAN_STATE_ERROR_ACTIVE;
>> +
>> +	netdev_dbg(priv->ndev, "%s: reg_mode=0x%08x\n", __func__,
>> +		   rkcanfd_read(priv, RKCANFD_REG_MODE));
>> +}
>> +
>>   static void __rkcanfd_chip_stop(struct rkcanfd_priv *priv, const enum can_state state)
>>   {
>>   	priv->can.state = state;
>> @@ -301,6 +426,13 @@ static void rkcanfd_chip_stop(struct rkcanfd_priv *priv, const enum can_state st
>>   	__rkcanfd_chip_stop(priv, state);
>>   }
>>
>> +static void rk3576can_chip_stop(struct rkcanfd_priv *priv, const enum can_state state)
>> +{
>> +	priv->can.state = state;
>> +
>> +	__rkcanfd_chip_stop(priv, state);
>> +}
>> +
>>   static void rkcanfd_chip_stop_sync(struct rkcanfd_priv *priv, const enum can_state state)
>>   {
>>   	priv->can.state = state;
>> @@ -309,6 +441,13 @@ static void rkcanfd_chip_stop_sync(struct rkcanfd_priv *priv, const enum can_sta
>>   	__rkcanfd_chip_stop(priv, state);
>>   }
>>
>> +static void rk3576can_chip_stop_sync(struct rkcanfd_priv *priv, const enum can_state state)
>> +{
>> +	priv->can.state = state;
>> +
>> +	__rkcanfd_chip_stop(priv, state);
>> +}
>> +
>>   static int rkcanfd_set_mode(struct net_device *ndev,
>>   			    enum can_mode mode)
>>   {
>> @@ -364,6 +503,9 @@ static const char *rkcanfd_get_error_type_str(unsigned int type)
>>   #define RKCAN_ERROR_CODE(reg_ec, code) \
>>   	((reg_ec) & RKCANFD_REG_ERROR_CODE_##code ? __stringify(code) " " : "")
>>
>> +#define RK3576CAN_ERROR_CODE(reg_ec, code) \
>> +	((reg_ec) & RK3576CAN_REG_ERROR_CODE_##code ? __stringify(code) " " : "")
>> +
>>   static void
>>   rkcanfd_handle_error_int_reg_ec(struct rkcanfd_priv *priv, struct can_frame *cf,
>>   				const u32 reg_ec)
>> @@ -493,6 +635,128 @@ rkcanfd_handle_error_int_reg_ec(struct rkcanfd_priv *priv, struct can_frame *cf,
>>   	}
>>   }
>>
>> +static void
>> +rk3576can_handle_error_int_reg_ec(struct rkcanfd_priv *priv, struct can_frame *cf,
>> +				  const u32 reg_ec)
>> +{
>> +	struct net_device_stats *stats = &priv->ndev->stats;
>> +	unsigned int type;
>> +	u32 reg_state, reg_cmd;
>> +
>> +	type = FIELD_GET(RK3576CAN_REG_ERROR_CODE_TYPE, reg_ec);
>> +	reg_cmd = rkcanfd_read(priv, RK3576CAN_REG_CMD);
>> +	reg_state = rkcanfd_read(priv, RK3576CAN_REG_STATE);
>> +
>> +	netdev_dbg(priv->ndev, "%s Error in %s %s Phase: %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s(0x%08x) CMD=%u RX=%u TX=%u Error-Warning=%u Bus-Off=%u\n",
>> +		   rkcanfd_get_error_type_str(type),
>> +		   reg_ec & RK3576CAN_REG_ERROR_CODE_DIRECTION_RX ? "RX" : "TX",
>> +		   reg_ec & RK3576CAN_REG_ERROR_CODE_PHASE ? "Data" : "Arbitration",
>> +		   RK3576CAN_ERROR_CODE(reg_ec, TX_ACK_EOF),
>> +		   RK3576CAN_ERROR_CODE(reg_ec, TX_CRC),
>> +		   RK3576CAN_ERROR_CODE(reg_ec, TX_STUFF_COUNT),
>> +		   RK3576CAN_ERROR_CODE(reg_ec, TX_DATA),
>> +		   RK3576CAN_ERROR_CODE(reg_ec, TX_SOF_DLC),
>> +		   RK3576CAN_ERROR_CODE(reg_ec, TX_IDLE),
>> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_ERROR),
>> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_OVERLOAD),
>> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_SPACE),
>> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_EOF),
>> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_ACK_LIM),
>> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_ACK),
>> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_CRC_LIM),
>> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_CRC),
>> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_STUFF_COUNT),
>> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_DATA),
>> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_DLC),
>> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_BRS_ESI),
>> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_RES),
>> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_FDF),
>> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_ID2_RTR),
>> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_SOF_IDE),
>> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_BUS_IDLE),
>> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_BUS_INT),
>> +		   RK3576CAN_ERROR_CODE(reg_ec, RX_STOP),
>> +		   reg_ec, reg_cmd,
>> +		   !!(reg_state & RK3576CAN_REG_STATE_RX_PERIOD),
>> +		   !!(reg_state & RK3576CAN_REG_STATE_TX_PERIOD),
>> +		   !!(reg_state & RK3576CAN_REG_STATE_ERROR_WARNING_STATE),
>> +		   !!(reg_state & RK3576CAN_REG_STATE_BUS_OFF_STATE));
>> +
>> +	priv->can.can_stats.bus_error++;
>> +
>> +	if (reg_ec & RK3576CAN_REG_ERROR_CODE_DIRECTION_RX)
>> +		stats->rx_errors++;
>> +	else
>> +		stats->tx_errors++;
>> +
>> +	if (!cf)
>> +		return;
>> +
>> +	if (reg_ec & RK3576CAN_REG_ERROR_CODE_DIRECTION_RX) {
>> +		if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_SOF_IDE)
>> +			cf->data[3] = CAN_ERR_PROT_LOC_SOF;
>> +		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_ID2_RTR)
>> +			cf->data[3] = CAN_ERR_PROT_LOC_RTR;
>> +		/* RKCANFD_REG_ERROR_CODE_RX_FDF */
>> +		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_RES)
>> +			cf->data[3] = CAN_ERR_PROT_LOC_RES0;
>> +		/* RKCANFD_REG_ERROR_CODE_RX_BRS_ESI */
>> +		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_DLC)
>> +			cf->data[3] = CAN_ERR_PROT_LOC_DLC;
>> +		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_DATA)
>> +			cf->data[3] = CAN_ERR_PROT_LOC_DATA;
>> +		/* RKCANFD_REG_ERROR_CODE_RX_STUFF_COUNT */
>> +		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_CRC)
>> +			cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
>> +		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_CRC_LIM)
>> +			cf->data[3] = CAN_ERR_PROT_LOC_ACK_DEL;
>> +		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_ACK)
>> +			cf->data[3] = CAN_ERR_PROT_LOC_ACK;
>> +		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_ACK_LIM)
>> +			cf->data[3] = CAN_ERR_PROT_LOC_ACK_DEL;
>> +		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_EOF)
>> +			cf->data[3] = CAN_ERR_PROT_LOC_EOF;
>> +		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_SPACE)
>> +			cf->data[3] = CAN_ERR_PROT_LOC_EOF;
>> +	} else {
>> +		cf->data[2] |= CAN_ERR_PROT_TX;
>> +
>> +		if (reg_ec & RK3576CAN_REG_ERROR_CODE_TX_SOF_DLC)
>> +			cf->data[3] = CAN_ERR_PROT_LOC_SOF;
>> +		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_TX_DATA)
>> +			cf->data[3] = CAN_ERR_PROT_LOC_DATA;
>> +		/* RKCANFD_REG_ERROR_CODE_TX_STUFF_COUNT */
>> +		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_TX_CRC)
>> +			cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
>> +		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_TX_ACK_EOF)
>> +			cf->data[3] = CAN_ERR_PROT_LOC_ACK_DEL;
>> +	}
>> +
>> +	switch (reg_ec & RK3576CAN_REG_ERROR_CODE_TYPE) {
>> +	case FIELD_PREP_CONST(RK3576CAN_REG_ERROR_CODE_TYPE,
>> +			      RK3576CAN_REG_ERROR_CODE_TYPE_BIT):
>> +
>> +		cf->data[2] |= CAN_ERR_PROT_BIT;
>> +		break;
>> +	case FIELD_PREP_CONST(RK3576CAN_REG_ERROR_CODE_TYPE,
>> +			      RK3576CAN_REG_ERROR_CODE_TYPE_STUFF):
>> +		cf->data[2] |= CAN_ERR_PROT_STUFF;
>> +		break;
>> +	case FIELD_PREP_CONST(RK3576CAN_REG_ERROR_CODE_TYPE,
>> +			      RK3576CAN_REG_ERROR_CODE_TYPE_FORM):
>> +		cf->data[2] |= CAN_ERR_PROT_FORM;
>> +		break;
>> +	case FIELD_PREP_CONST(RK3576CAN_REG_ERROR_CODE_TYPE,
>> +			      RK3576CAN_REG_ERROR_CODE_TYPE_ACK):
>> +		cf->can_id |= CAN_ERR_ACK;
>> +		break;
>> +	case FIELD_PREP_CONST(RK3576CAN_REG_ERROR_CODE_TYPE,
>> +			      RK3576CAN_REG_ERROR_CODE_TYPE_CRC):
>> +		cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
>> +		break;
>> +	}
>> +}
>> +
>>   static int rkcanfd_handle_error_int(struct rkcanfd_priv *priv)
>>   {
>>   	struct net_device_stats *stats = &priv->ndev->stats;
>> @@ -530,6 +794,41 @@ static int rkcanfd_handle_error_int(struct rkcanfd_priv *priv)
>>   	return 0;
>>   }
>>
>> +static int rkcanfd_handle_rk3576_error_int(struct rkcanfd_priv *priv)
>> +{
>> +	struct net_device_stats *stats = &priv->ndev->stats;
>> +	struct can_frame *cf = NULL;
>> +	u32 reg_ec;
>> +	struct sk_buff *skb;
>> +	int err;
>> +
>> +	reg_ec = rkcanfd_read(priv, RK3576CAN_REG_ERROR_CODE);
>> +	if (!reg_ec)
>> +		return 0;
>> +
>> +	if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) {
>> +		skb = alloc_can_err_skb(priv->ndev, &cf);
>> +		if (cf) {
>> +			struct can_berr_counter bec;
>> +
>> +			priv->devtype_data.get_berr_counter(priv, &bec);
>> +			cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR | CAN_ERR_CNT;
>> +			cf->data[6] = bec.txerr;
>> +			cf->data[7] = bec.rxerr;
>> +		}
>> +	}
>> +
>> +	rk3576can_handle_error_int_reg_ec(priv, cf, reg_ec);
>> +	if (!cf)
>> +		return 0;
>> +
>> +	err = can_rx_offload_queue_tail(&priv->offload, skb);
>> +	if (err)
>> +		stats->rx_fifo_errors++;
>> +
>> +	return 0;
>> +}
>> +
>>   static int rkcanfd_handle_state_error_int(struct rkcanfd_priv *priv)
>>   {
>>   	struct net_device_stats *stats = &priv->ndev->stats;
>> @@ -575,6 +874,50 @@ static int rkcanfd_handle_state_error_int(struct rkcanfd_priv *priv)
>>   	return 0;
>>   }
>>
>> +static int rkcanfd_handle_rk3576_state_error_int(struct rkcanfd_priv *priv)
>> +{
>> +	struct net_device_stats *stats = &priv->ndev->stats;
>> +	enum can_state new_state, rx_state, tx_state;
>> +	struct net_device *ndev = priv->ndev;
>> +	struct can_berr_counter bec;
>> +	struct can_frame *cf = NULL;
>> +	struct sk_buff *skb;
>> +	int err;
>> +
>> +	priv->devtype_data.get_berr_counter(priv, &bec);
> You're already in the rk3576 specific code.
>
>> +	can_state_get_by_berr_counter(ndev, &bec, &tx_state, &rx_state);
>> +
>> +	new_state = max(tx_state, rx_state);
>> +	if (new_state == priv->can.state)
>> +		return 0;
>> +
>> +	/* The skb allocation might fail, but can_change_state()
>> +	 * handles cf == NULL.
>> +	 */
>> +	skb = alloc_can_err_skb(priv->ndev, &cf);
>> +	can_change_state(ndev, cf, tx_state, rx_state);
>> +
>> +	if (new_state == CAN_STATE_BUS_OFF) {
>> +		priv->devtype_data.chip_stop(priv, CAN_STATE_BUS_OFF);
>> +		can_bus_off(ndev);
>> +	}
>> +
>> +	if (!skb)
>> +		return 0;
>> +
>> +	if (new_state != CAN_STATE_BUS_OFF) {
>> +		cf->can_id |= CAN_ERR_CNT;
>> +		cf->data[6] = bec.txerr;
>> +		cf->data[7] = bec.rxerr;
>> +	}
>> +
>> +	err = can_rx_offload_queue_tail(&priv->offload, skb);
>> +	if (err)
>> +		stats->rx_fifo_errors++;
>> +
>> +	return 0;
>> +}
>> +
>>   static int
>>   rkcanfd_handle_rx_fifo_overflow_int(struct rkcanfd_priv *priv)
>>   {
>> @@ -621,6 +964,55 @@ rkcanfd_handle_rx_fifo_overflow_int(struct rkcanfd_priv *priv)
>>   	err; \
>>   })
>>
>> +static irqreturn_t rk3576can_irq(int irq, void *dev_id)
>> +{
>> +	struct rkcanfd_priv *priv = dev_id;
>> +	u32 reg_int_unmasked, reg_int;
>> +
>> +	reg_int_unmasked = rkcanfd_read(priv, RK3576CAN_REG_INT);
>> +	reg_int = reg_int_unmasked & ~priv->reg_int_mask_default;
>> +
>> +	if (!reg_int)
>> +		return IRQ_NONE;
>> +
>> +	rkcanfd_write(priv, RK3576CAN_REG_INT, reg_int);
>> +
>> +	if (reg_int & (RK3576CAN_REG_INT_RXSTR_TIMEOUT_INT |
>> +		       RK3576CAN_REG_INT_ISM_WTM_INT |
>> +		       RK3576CAN_REG_INT_RX_FIFO_FULL_INT)) {
>> +		rkcanfd_write(priv, RK3576CAN_REG_INT_MASK,
>> +			      priv->reg_int_mask_default | RK3576CAN_REG_INT_ISM_WTM_INT |
>> +			      RK3576CAN_REG_INT_RXSTR_TIMEOUT_INT |
>> +			      RK3576CAN_REG_INT_RX_FINISH_INT);
>> +		rkcanfd_handle(priv, rk3576_rx_int);
>> +	}
>> +
>> +	if (reg_int & RK3576CAN_REG_INT_TX_FINISH_INT)
>> +		rkcanfd_handle(priv, rk3576_tx_int);
>> +
>> +	if (reg_int & RK3576CAN_REG_INT_ERROR_INT)
>> +		rkcanfd_handle(priv, rk3576_error_int);
>> +
>> +	if (reg_int & (RK3576CAN_REG_INT_BUS_OFF_INT |
>> +		       RK3576CAN_REG_INT_PASSIVE_ERROR_INT |
>> +		       RK3576CAN_REG_INT_ERROR_WARNING_INT) ||
>> +	    priv->can.state > CAN_STATE_ERROR_ACTIVE)
>> +		rkcanfd_handle(priv, rk3576_state_error_int);
>> +
>> +	if (reg_int & RK3576CAN_REG_INT_WAKEUP_INT)
>> +		netdev_info(priv->ndev, "%s: WAKEUP_INT\n", __func__);
>> +
>> +	if (reg_int & RK3576CAN_REG_INT_BUS_OFF_RECOVERY_INT)
>> +		netdev_info(priv->ndev, "%s: BUS_OFF_RECOVERY_INT\n", __func__);
>> +
>> +	if (reg_int & RK3576CAN_REG_INT_OVERLOAD_INT)
>> +		netdev_info(priv->ndev, "%s: OVERLOAD_INT\n", __func__);
>> +
>> +	can_rx_offload_irq_finish(&priv->offload);
>> +
>> +	return IRQ_HANDLED;
>> +}
>> +
>>   static irqreturn_t rkcanfd_irq(int irq, void *dev_id)
>>   {
>>   	struct rkcanfd_priv *priv = dev_id;
>> @@ -775,6 +1167,16 @@ static void rkcanfd_register_done(const struct rkcanfd_priv *priv)
>>   			    RKCANFD_ERRATUM_5_SYSCLOCK_HZ_MIN / MEGA);
>>   }
>>
>> +static void rk3576can_register_done(const struct rkcanfd_priv *priv)
>> +{
>> +	u32 dev_id;
>> +
>> +	dev_id = rkcanfd_read(priv, RK3576CAN_REG_RTL_VERSION);
>> +	netdev_info(priv->ndev,
>> +		    "Rockchip-CANFD %s rev%u.\n",
>> +		    rkcanfd_get_model_str(priv), dev_id);
> Please also print the activated errata.
>
>> +}
>> +
>>   static int rkcanfd_register(struct rkcanfd_priv *priv)
>>   {
>>   	struct net_device *ndev = priv->ndev;
>> @@ -856,6 +1258,20 @@ static const struct rkcanfd_devtype_data rkcanfd_devtype_data_rk3568v3 = {
>>   	.register_done = rkcanfd_register_done,
>>   };
>>
>> +/* The rk3576 CAN-FD */
>> +static const struct rkcanfd_devtype_data rkcan_devtype_data_rk3576 = {
>> +	.model = RKCAN_MODEL_RK3576,
>> +	.quirks = RKCANFD_QUIRK_CANFD_BROKEN,
> Is CAN-FD mode broken on the rk3576?
>
> Please test CAN-FD and please do the tests documented near the
> definition of RKCANFD_QUIRK_CANFD_BROKEN:
>
> | Tests on the rk3568v2 and rk3568v3 show that receiving certain
> | CAN-FD frames trigger an Error Interrupt.
> |
> | - Form Error in RX Arbitration Phase: TX_IDLE RX_STUFF_COUNT (0x0a010100) CMD=0 RX=0 TX=0
> |   Error-Warning=1 Bus-Off=0
> |   To reproduce:
> |   host:
> |     cansend can0 002##01f
> |   DUT:
> |     candump any,0:0,#FFFFFFFF -cexdHtA
> |
> | - Form Error in RX Arbitration Phase: TX_IDLE RX_CRC (0x0a010200) CMD=0 RX=0 TX=0
> |   Error-Warning=1 Bus-Off=0
> |   To reproduce:
> |   host:
> |     cansend can0 002##07217010000000000
> |   DUT:
> |     candump any,0:0,#FFFFFFFF -cexdHtA
There is no doubt about the other modifications above. They will be 
corrected in version V10.

CANFD requires authorization and is not supported by default.
After obtaining authorization, it can be used, so this place is not 
considered broken.
What's the best way to handle this situation?
>
> regards,
> Marc
>
> --
> Pengutronix e.K.                 | Marc Kleine-Budde          |
> Embedded Linux                   | https://www.pengutronix.de |
> Vertretung N?rnberg              | Phone: +49-5121-206917-129 |
> Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-9   |

-- 
??
???????????
Rockchip Electronics Co.,Ltd
????????????????89????A?21??
Add:No.21 Building, A District, No.89 Software Boulevard Fuzhou, Fujian 350003, P.R.China
Tel:+86-0591-83991906-8601
???350003
E-mail:elaine.zhang at rock-chips.com
****************************************************************************
??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

IMPORTANT NOTICE: This email is from Fuzhou Rockchip Electronics Co., Ltd .The contents of this email and any attachments may contain information that is privileged, confidential and/or exempt from disclosure under applicable law and relevant NDA. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution, or use of the information is STRICTLY PROHIBITED. Please immediately contact the sender as soon as possible and destroy the material in its entirety in any format. Thank you.

****************************************************************************



From heiko at sntech.de  Fri Nov 14 02:08:21 2025
From: heiko at sntech.de (Heiko =?UTF-8?B?U3TDvGJuZXI=?=)
Date: Fri, 14 Nov 2025 11:08:21 +0100
Subject: [PATCH v6 1/3] dt-bindings: arm: rockchip: Add Radxa CM5 IO Board
In-Reply-To: <194908a1-f956-ba0a-656f-7b1e8456b51d@manjaro.org>
References: <20251105051335.17652-1-naoki@radxa.com>
 <A3AD69295D2E2D65+db2dc8bd-054f-4dda-9dd1-3cc0c0feed35@radxa.com>
 <194908a1-f956-ba0a-656f-7b1e8456b51d@manjaro.org>
Message-ID: <1942576.CQOukoFCf9@diego>

Am Freitag, 14. November 2025, 09:32:29 Mitteleurop?ische Normalzeit schrieb Dragan Simic:
> On Friday, November 14, 2025 09:24 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> > On 11/14/25 16:51, Krzysztof Kozlowski wrote:
> > > On 14/11/2025 08:47, FUKAUMI Naoki wrote:
> > >> On 11/14/25 16:42, Krzysztof Kozlowski wrote:
> > >>> On 14/11/2025 08:37, FUKAUMI Naoki wrote:
> > >>>> Hi Krzysztof,
> > >>>>
> > >>>> On 11/14/25 16:12, Krzysztof Kozlowski wrote:
> > >>>>> On 05/11/2025 08:08, Krzysztof Kozlowski wrote:
> > >>>>>> On 05/11/2025 07:57, FUKAUMI Naoki wrote:
> > >>>>>>> On 11/5/25 15:43, Krzysztof Kozlowski wrote:
> > >>>>>>>> On 05/11/2025 06:13, FUKAUMI Naoki wrote:
> > >>>>>>>>> Add device tree binding documentation for the Radxa CM5 IO Board.
> > >>>>>>>>>
> > >>>>>>>>> Link: https://dl.radxa.com/cm5/radxa_cm5_product_brief.pdf
> > >>>>>>>>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> > >>>>>>>>> Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
> > >>>>>>>>
> > >>>>>>>> Wrong DCO chain.
> > >>>>>>>>
> > >>>>>>>>> ---
> > >>>>>>>>>      Documentation/devicetree/bindings/arm/rockchip.yaml | 7 +++++++
> > >>>>>>>>
> > >>>>>>>> NAK, you just stolen ownership of an already posted patch.
> > >>>>>>>
> > >>>>>>> Read "Changes in v6" and patches; my patches are not the same as v5.
> > >>>>>>> Your reply is totally inappropriate.
> > >>>>>>
> > >>>>>> Inappropriate is taking authorship of someone's patch, because we all
> > >>>>>> expect to preserve the original authorship. That's not only basic
> > >>>>>> decency but actually a standard.
> > >>>>>>
> > >>>>>> Additionally, read Joseph's reply that he wants to continue the work:
> > >>>>>> https://lore.kernel.org/all/CAMWSM7iHtAxewW4JkRqRsifVnccqeFviaCgeOyprKDr92FOurg at mail.gmail.com/
> > >>>>>>
> > >>>>>> You clearly do not understand how to continue with someone's work.
> > >>>>>>
> > >>>>>> It is still a NAK.
> > >>>>>
> > >>>>> And I still wait for justification why you took authorship of this
> > >>>>> patch, because to my eye you changed here nothing.
> > >>>>>
> > >>>>> So what did you change HERE that you think you are the author now?
> > >>>>
> > >>>> Changes in v6:
> > >>>> (Patch 1/3)
> > >>>> - Fix description; "Radxa CM5" is the correct name
> > >>>
> > >>> HERE, in this patch. Don't paste me hundreds of unrelated code. Write
> > >>> concise and precise answers/comments.
> > >>
> > >> https://lore.kernel.org/linux-rockchip/AE0735A6C797CCFF+10496d73-7c0a-4884-9561-24721305a24f at radxa.com/
> > >>
> > >> | By the way, at some point I switched from "continuing your work" to
> > >> | "recreating a new one based on my current work." The results of my
> > >> | current work(*3) have changed significantly.
> > > 
> > > So next time I will take your patch, your code, say "I recreated it" and
> > > submit under my authorship and for you it is fine?
> > 
> > Regarding CM5 patches, I'm fine.
> > 
> > > Please take Joseph's patch instead. Read submitting patches doc to
> > > understand which one more tag has to be added when sending somoene
> > > else's work.
> > > 
> > > In the future, I sincerely suggest avoiding re-creating people's work
> > > but building on top, because you just duplicate the effort.
> > 
> > I understand that you don't understand how I made efforts to build my 
> > work on top of Joseph's patches.
> 
> Maybe a solution for this huge mess could be that Naoki submits
> unmodified patches from Joseph first, using the standard procedure
> for that, and then the additional patch(es) that improve Joseph's
> work?  All that in the same series.

There is also Co-developed-by as an option.





From dsimic at manjaro.org  Fri Nov 14 02:12:22 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Fri, 14 Nov 2025 11:12:22 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v6 1/3] =?utf-8?q?dt-bindings=3A?=
 =?utf-8?q?_arm=3A?==?utf-8?q?_rockchip=3A?= Add Radxa CM5 IO Board
In-Reply-To: <1942576.CQOukoFCf9@diego>
References: <20251105051335.17652-1-naoki@radxa.com>
 <A3AD69295D2E2D65+db2dc8bd-054f-4dda-9dd1-3cc0c0feed35@radxa.com>
 <194908a1-f956-ba0a-656f-7b1e8456b51d@manjaro.org> <1942576.CQOukoFCf9@diego>
Message-ID: <21ea3b50-6000-5202-49cf-685310e6fa18@manjaro.org>

Hello Heiko,

On Friday, November 14, 2025 11:08 CET, Heiko St?bner <heiko at sntech.de> wrote:
> Am Freitag, 14. November 2025, 09:32:29 Mitteleurop?ische Normalzeit schrieb Dragan Simic:
> > On Friday, November 14, 2025 09:24 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
> > > On 11/14/25 16:51, Krzysztof Kozlowski wrote:
> > > > On 14/11/2025 08:47, FUKAUMI Naoki wrote:
> > > >> On 11/14/25 16:42, Krzysztof Kozlowski wrote:
> > > >>> On 14/11/2025 08:37, FUKAUMI Naoki wrote:
> > > >>>> Hi Krzysztof,
> > > >>>>
> > > >>>> On 11/14/25 16:12, Krzysztof Kozlowski wrote:
> > > >>>>> On 05/11/2025 08:08, Krzysztof Kozlowski wrote:
> > > >>>>>> On 05/11/2025 07:57, FUKAUMI Naoki wrote:
> > > >>>>>>> On 11/5/25 15:43, Krzysztof Kozlowski wrote:
> > > >>>>>>>> On 05/11/2025 06:13, FUKAUMI Naoki wrote:
> > > >>>>>>>>> Add device tree binding documentation for the Radxa CM5 IO Board.
> > > >>>>>>>>>
> > > >>>>>>>>> Link: https://dl.radxa.com/cm5/radxa_cm5_product_brief.pdf
> > > >>>>>>>>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> > > >>>>>>>>> Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
> > > >>>>>>>>
> > > >>>>>>>> Wrong DCO chain.
> > > >>>>>>>>
> > > >>>>>>>>> ---
> > > >>>>>>>>>      Documentation/devicetree/bindings/arm/rockchip.yaml | 7 +++++++
> > > >>>>>>>>
> > > >>>>>>>> NAK, you just stolen ownership of an already posted patch.
> > > >>>>>>>
> > > >>>>>>> Read "Changes in v6" and patches; my patches are not the same as v5.
> > > >>>>>>> Your reply is totally inappropriate.
> > > >>>>>>
> > > >>>>>> Inappropriate is taking authorship of someone's patch, because we all
> > > >>>>>> expect to preserve the original authorship. That's not only basic
> > > >>>>>> decency but actually a standard.
> > > >>>>>>
> > > >>>>>> Additionally, read Joseph's reply that he wants to continue the work:
> > > >>>>>> https://lore.kernel.org/all/CAMWSM7iHtAxewW4JkRqRsifVnccqeFviaCgeOyprKDr92FOurg at mail.gmail.com/
> > > >>>>>>
> > > >>>>>> You clearly do not understand how to continue with someone's work.
> > > >>>>>>
> > > >>>>>> It is still a NAK.
> > > >>>>>
> > > >>>>> And I still wait for justification why you took authorship of this
> > > >>>>> patch, because to my eye you changed here nothing.
> > > >>>>>
> > > >>>>> So what did you change HERE that you think you are the author now?
> > > >>>>
> > > >>>> Changes in v6:
> > > >>>> (Patch 1/3)
> > > >>>> - Fix description; "Radxa CM5" is the correct name
> > > >>>
> > > >>> HERE, in this patch. Don't paste me hundreds of unrelated code. Write
> > > >>> concise and precise answers/comments.
> > > >>
> > > >> https://lore.kernel.org/linux-rockchip/AE0735A6C797CCFF+10496d73-7c0a-4884-9561-24721305a24f at radxa.com/
> > > >>
> > > >> | By the way, at some point I switched from "continuing your work" to
> > > >> | "recreating a new one based on my current work." The results of my
> > > >> | current work(*3) have changed significantly.
> > > > 
> > > > So next time I will take your patch, your code, say "I recreated it" and
> > > > submit under my authorship and for you it is fine?
> > > 
> > > Regarding CM5 patches, I'm fine.
> > > 
> > > > Please take Joseph's patch instead. Read submitting patches doc to
> > > > understand which one more tag has to be added when sending somoene
> > > > else's work.
> > > > 
> > > > In the future, I sincerely suggest avoiding re-creating people's work
> > > > but building on top, because you just duplicate the effort.
> > > 
> > > I understand that you don't understand how I made efforts to build my 
> > > work on top of Joseph's patches.
> > 
> > Maybe a solution for this huge mess could be that Naoki submits
> > unmodified patches from Joseph first, using the standard procedure
> > for that, and then the additional patch(es) that improve Joseph's
> > work?  All that in the same series.
> 
> There is also Co-developed-by as an option.

Ah, that's what the above-described option #1 involves, but it also 
raises some possible concerns, described in one of my responses. [1]

[1] https://lore.kernel.org/linux-rockchip/c01b756a-73ea-3d0d-44b9-6ce8a535a103 at manjaro.org/



From nicolas.frattaroli at collabora.com  Fri Nov 14 02:13:29 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Fri, 14 Nov 2025 11:13:29 +0100
Subject: [PATCH v3 3/5] pwm: Add rockchip PWMv4 driver
In-Reply-To: <fgu42esufq2x4fcccncqs3hlotih2gqmws5atotlaznuahoslw@34vblr6vboze>
References: <20251027-rk3576-pwm-v3-0-654a5cb1e3f8@collabora.com>
 <8a6e920b-9565-4161-9d71-63f924593c23@rock-chips.com>
 <fgu42esufq2x4fcccncqs3hlotih2gqmws5atotlaznuahoslw@34vblr6vboze>
Message-ID: <9941350.lOV4Wx5bFT@workhorse>

On Friday, 14 November 2025 10:51:27 Central European Standard Time you wrote:
> On Tue, Oct 28, 2025 at 04:16:26PM +0800, Damon Ding wrote:
> > Hi Nicolas,
> > 
> > On 10/28/2025 1:11 AM, Nicolas Frattaroli wrote:
> > > [...]
> > > 
> > 
> > Tested-by: Damon Ding <damon.ding at rock-chips.com>
> > 
> > I have tested all the PWM channels in continuous mode on my RK3576-IOTEST
> > board.
> > 
> > Test commands are like:
> > 
> > cd /sys/class/pwm/pwmchip0/
> > echo 0 > export
> > cd pwm0
> > echo 10000 > period
> > echo 5000 > duty_cycle
> > echo normal > polarity
> > echo 1 > enable
> 
> Thanks for the test, very appreciated.
> 
> I wonder what made you test using sysfs instead of
> https://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/libpwm.git/.
> Is it unknown? Too complicated? Other problems?

Can't speak for Damon Ding but this is the first time I've heard of
libpwm, so I think you do need to market it better. :) Perhaps by
mentioning it in the PWM subsystem docs as a way to interface with
the kernel, if that's permitted by the docs people. (It should be,
since libiio is mentioned for IIO.)

Kind regards,
Nicolas Frattaroli

> 
> Best regards
> Uwe
> 




From herbert at gondor.apana.org.au  Fri Nov 14 02:20:37 2025
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Fri, 14 Nov 2025 18:20:37 +0800
Subject: [PATCH] crypto: rockchip - drop redundant
 crypto_skcipher_ivsize() calls
In-Reply-To: <20251105145204.2888978-1-k.yankevich@omp.ru>
References: <20251105145204.2888978-1-k.yankevich@omp.ru>
Message-ID: <aRcCdQu-d2byeFLY@gondor.apana.org.au>

On Wed, Nov 05, 2025 at 05:52:04PM +0300, Karina Yankevich wrote:
> The function already initialized the ivsize variable 
> at the point of declaration, let's use it instead of 
> calling crypto_skcipher_ivsize() extra couple times.
> 
> Found by Linux Verification Center (linuxtesting.org) with SVACE.
> 
> Fixes: 57d67c6e8219 ("crypto: rockchip - rework by using crypto_engine")
> Signed-off-by: Karina Yankevich <k.yankevich at omp.ru>
> Reviewed-by: Sergey Shtylyov <s.shtylyov at omp.ru>
> ---
>  drivers/crypto/rockchip/rk3288_crypto_skcipher.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)

Patch applied.  Thanks.
-- 
Email: Herbert Xu <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


From krzk at kernel.org  Fri Nov 14 02:30:59 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 14 Nov 2025 11:30:59 +0100
Subject: [PATCH v6 1/3] dt-bindings: arm: rockchip: Add Radxa CM5 IO Board
In-Reply-To: <21ea3b50-6000-5202-49cf-685310e6fa18@manjaro.org>
References: <20251105051335.17652-1-naoki@radxa.com>
 <A3AD69295D2E2D65+db2dc8bd-054f-4dda-9dd1-3cc0c0feed35@radxa.com>
 <194908a1-f956-ba0a-656f-7b1e8456b51d@manjaro.org> <1942576.CQOukoFCf9@diego>
 <21ea3b50-6000-5202-49cf-685310e6fa18@manjaro.org>
Message-ID: <5b58dda8-af68-41cd-af23-ec48bfc11d79@kernel.org>

On 14/11/2025 11:12, Dragan Simic wrote:
> Hello Heiko,
> 
> On Friday, November 14, 2025 11:08 CET, Heiko St?bner <heiko at sntech.de> wrote:
>> Am Freitag, 14. November 2025, 09:32:29 Mitteleurop?ische Normalzeit schrieb Dragan Simic:
>>> On Friday, November 14, 2025 09:24 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
>>>> On 11/14/25 16:51, Krzysztof Kozlowski wrote:
>>>>> On 14/11/2025 08:47, FUKAUMI Naoki wrote:
>>>>>> On 11/14/25 16:42, Krzysztof Kozlowski wrote:
>>>>>>> On 14/11/2025 08:37, FUKAUMI Naoki wrote:
>>>>>>>> Hi Krzysztof,
>>>>>>>>
>>>>>>>> On 11/14/25 16:12, Krzysztof Kozlowski wrote:
>>>>>>>>> On 05/11/2025 08:08, Krzysztof Kozlowski wrote:
>>>>>>>>>> On 05/11/2025 07:57, FUKAUMI Naoki wrote:
>>>>>>>>>>> On 11/5/25 15:43, Krzysztof Kozlowski wrote:
>>>>>>>>>>>> On 05/11/2025 06:13, FUKAUMI Naoki wrote:
>>>>>>>>>>>>> Add device tree binding documentation for the Radxa CM5 IO Board.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Link: https://dl.radxa.com/cm5/radxa_cm5_product_brief.pdf
>>>>>>>>>>>>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
>>>>>>>>>>>>> Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
>>>>>>>>>>>>
>>>>>>>>>>>> Wrong DCO chain.
>>>>>>>>>>>>
>>>>>>>>>>>>> ---
>>>>>>>>>>>>>      Documentation/devicetree/bindings/arm/rockchip.yaml | 7 +++++++
>>>>>>>>>>>>
>>>>>>>>>>>> NAK, you just stolen ownership of an already posted patch.
>>>>>>>>>>>
>>>>>>>>>>> Read "Changes in v6" and patches; my patches are not the same as v5.
>>>>>>>>>>> Your reply is totally inappropriate.
>>>>>>>>>>
>>>>>>>>>> Inappropriate is taking authorship of someone's patch, because we all
>>>>>>>>>> expect to preserve the original authorship. That's not only basic
>>>>>>>>>> decency but actually a standard.
>>>>>>>>>>
>>>>>>>>>> Additionally, read Joseph's reply that he wants to continue the work:
>>>>>>>>>> https://lore.kernel.org/all/CAMWSM7iHtAxewW4JkRqRsifVnccqeFviaCgeOyprKDr92FOurg at mail.gmail.com/
>>>>>>>>>>
>>>>>>>>>> You clearly do not understand how to continue with someone's work.
>>>>>>>>>>
>>>>>>>>>> It is still a NAK.
>>>>>>>>>
>>>>>>>>> And I still wait for justification why you took authorship of this
>>>>>>>>> patch, because to my eye you changed here nothing.
>>>>>>>>>
>>>>>>>>> So what did you change HERE that you think you are the author now?
>>>>>>>>
>>>>>>>> Changes in v6:
>>>>>>>> (Patch 1/3)
>>>>>>>> - Fix description; "Radxa CM5" is the correct name
>>>>>>>
>>>>>>> HERE, in this patch. Don't paste me hundreds of unrelated code. Write
>>>>>>> concise and precise answers/comments.
>>>>>>
>>>>>> https://lore.kernel.org/linux-rockchip/AE0735A6C797CCFF+10496d73-7c0a-4884-9561-24721305a24f at radxa.com/
>>>>>>
>>>>>> | By the way, at some point I switched from "continuing your work" to
>>>>>> | "recreating a new one based on my current work." The results of my
>>>>>> | current work(*3) have changed significantly.
>>>>>
>>>>> So next time I will take your patch, your code, say "I recreated it" and
>>>>> submit under my authorship and for you it is fine?
>>>>
>>>> Regarding CM5 patches, I'm fine.
>>>>
>>>>> Please take Joseph's patch instead. Read submitting patches doc to
>>>>> understand which one more tag has to be added when sending somoene
>>>>> else's work.
>>>>>
>>>>> In the future, I sincerely suggest avoiding re-creating people's work
>>>>> but building on top, because you just duplicate the effort.
>>>>
>>>> I understand that you don't understand how I made efforts to build my 
>>>> work on top of Joseph's patches.
>>>
>>> Maybe a solution for this huge mess could be that Naoki submits
>>> unmodified patches from Joseph first, using the standard procedure
>>> for that, and then the additional patch(es) that improve Joseph's
>>> work?  All that in the same series.
>>
>> There is also Co-developed-by as an option.
> 
> Ah, that's what the above-described option #1 involves, but it also 
> raises some possible concerns, described in one of my responses. [1]

There are no concerns to be raised. Please read DCO. The original author
GAVE certified what is necessary, thus any person taking this work
already can you that certification. You raised some uncertainty "I'm not
sure how fair is it for someone to become responsible" which is just not
right here. It is completely fair and completely correct from DCO point
of view, because the certification was already provided. Also from
certification point, there is no "weaker" form. Either you certify or not.

Best regards,
Krzysztof


From krzk at kernel.org  Fri Nov 14 02:34:27 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 14 Nov 2025 11:34:27 +0100
Subject: [PATCH v6 0/3] Add Radxa CM5 and IO Board
In-Reply-To: <f156cd48-d764-43c8-99ed-24ab212d8eee@collabora.com>
References: <20251105051335.17652-1-naoki@radxa.com>
 <199E172C8E20ED38+71169242-5525-4d60-9e37-a03ad172d639@radxa.com>
 <CAMWSM7gezjVSoF+-7ivboTeB=5gQAE-QVrbAbKu3M=obmb3Axg@mail.gmail.com>
 <617FDAB231C501DC+3f9809df-87df-4a02-bd5f-ebc6299b3aa7@radxa.com>
 <a10340af-1d0a-bb0b-4835-7b2c9e67d664@manjaro.org>
 <2892FE50237CD58E+0f15924c-a915-4446-954c-d81a782d23e9@radxa.com>
 <19ce0a41-563c-6202-6b94-b2c644a0b827@manjaro.org>
 <F02BA2E6B1111826+2445b38d-b5e0-499c-83e7-4521c57b2210@radxa.com>
 <f2bc30de-119b-4f4a-844a-8a908c9290b6@kernel.org>
 <49c39864-3e58-2e0e-7abc-50502f2afb02@manjaro.org>
 <f156cd48-d764-43c8-99ed-24ab212d8eee@collabora.com>
Message-ID: <99309e42-dfdc-4632-8681-c9763b9e8ad4@kernel.org>

On 14/11/2025 09:51, Cristian Ciocaltea wrote:
> On 11/14/25 9:17 AM, Dragan Simic wrote:
>> Hello Krzysztof,
>>
>> On Friday, November 14, 2025 08:10 CET, Krzysztof Kozlowski <krzk at kernel.org> wrote:
>>> On 14/11/2025 06:03, FUKAUMI Naoki wrote:
>>>> On 11/12/25 09:46, Dragan Simic wrote:
>>>>> On Wednesday, November 12, 2025 00:26 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
>>>>>> On 11/11/25 23:33, Dragan Simic wrote:
>>>>>>> On Tuesday, November 11, 2025 12:52 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
>>>>>>>> On 11/6/25 02:48, Joseph Kogut wrote:
>>>>>>>>> On Wed, Nov 5, 2025 at 4:15?AM FUKAUMI Naoki <naoki at radxa.com> wrote:
>>>>>>>>>> I'd like to clarify the situation regarding the v6 patch series I submitted.
>>>>>>>>>>
>>>>>>>>>> The original device tree work for the Radxa CM5 and IO Board was
>>>>>>>>>> authored by Joseph Kogut. I took over the responsibility of getting it
>>>>>>>>>> upstreamed with his agreement.
>>>>>>>>>
>>>>>>>>> I'll confirm this. I've been in communication with Naoki. They made a
>>>>>>>>> large number of revisions to my original patch series, which I think
>>>>>>>>> have technical merit. I suggested they submit the patches themselves,
>>>>>>>>> and gave them explicit permission to add my Signed-off-by and CC me.
>>>>>>>>>
>>>>>>>>> I assume this was the correct way for them to continue the work I
>>>>>>>>> started, but if not, please let us know the best way to proceed.
>>>>>>>>
>>>>>>>> Can anyone help us?
>>>>>>>
>>>>>>> I'm not exactly sure how to resolve the current situation, but for
>>>>>>> Signed-off-by tags to be present, in this case you'd need to have
>>>>>>> Co-developed-by tags as well, because the final patch versions,
>>>>>>> which would be submitted by Naoki, would differ significantly from
>>>>>>> the versions that Joseph actively worked on, if I understood
>>>>>>> everything correctly.  Though, for Joseph's Signed-off-by tags to
>>>>>>> be included there, he would also need to participate actively in
>>>>>>> the development of the final patch versions.
>>>>>>
>>>>>> https://www.kernel.org/doc/html/latest/process/submitting-patches.html#when-to-use-acked-by-cc-and-co-developed-by
>>>>>>
>>>>>> If
>>>>>> ----
>>>>>> From: Joseph Kogut <joseph.kogut at gmail.com>
>>>>>>
>>>>>> <changelog>
>>>>>>
>>>>>> Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
>>>>>> Co-developed-by: FUKAUMI Naoki <naoki at radxa.com>
>>>>>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
>>>>>> ----
>>>>>> then I can submit my patch series?
>>>>>
>>>>> Actually, the Co-developed-by tags would be pointing to Joseph
>>>>> in that case, but as I described it above, this approach basically
>>>>> cannot be used, because Joseph's original work differs a lot from
>>>>> what you'd actually submit to the mailing list(s).
>>>>>
>>>>>> Or,
>>>>>>
>>>>>>> Another option, technically a bit simpler, would be to include just
>>>>>>> Originally-by tags for Joseph, which would indicate that Joseph gave
>>>>>>> up on the development of the patches and handed them over to Naoki
>>>>>>> for future development and submission to the mailing lists. Though,
>>>>>>> that would require Joseph to publicly state exactly that.
>>>>>>
>>>>>> I cannot find any documentation about "Originally-by".
>>>>>> Is this correct?
>>>>>> ----
>>>>>> <changelog>
>>>>>>
>>>>>> Originally-by: Joseph Kogut <joseph.kogut at gmail.com>
>>>
>>> There is no such tag. Don't invent tags.
>>
>> True, it doesn't exist officially, but it's been used fairly often.
> 
> Hmm, actually this tag seems to be documented, or at least given as an example:
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/maintainer-tip.rst?h=v6.18-rc5#n309

Yes, for the tip folks (so three people). If you send to the TIP, their
maintainer profile applies. There are also other specific rules in TIP
which are in contrary to common (as most used) process, e.g. completely
reversed tags (see also Konstantin's explanation about the order which
he implemented in b4).

If you want to use it outside of tip, first this should be added to
common docs and checkpatch. Just like b4 should be changed if you want
to use their order of tags.

Best regards,
Krzysztof


From krzk at kernel.org  Fri Nov 14 02:35:55 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 14 Nov 2025 11:35:55 +0100
Subject: [PATCH v6 1/3] dt-bindings: arm: rockchip: Add Radxa CM5 IO Board
In-Reply-To: <5b58dda8-af68-41cd-af23-ec48bfc11d79@kernel.org>
References: <20251105051335.17652-1-naoki@radxa.com>
 <A3AD69295D2E2D65+db2dc8bd-054f-4dda-9dd1-3cc0c0feed35@radxa.com>
 <194908a1-f956-ba0a-656f-7b1e8456b51d@manjaro.org> <1942576.CQOukoFCf9@diego>
 <21ea3b50-6000-5202-49cf-685310e6fa18@manjaro.org>
 <5b58dda8-af68-41cd-af23-ec48bfc11d79@kernel.org>
Message-ID: <48feacac-55eb-4c5a-8466-77742c9d1e79@kernel.org>

On 14/11/2025 11:30, Krzysztof Kozlowski wrote:
> On 14/11/2025 11:12, Dragan Simic wrote:
>> Hello Heiko,
>>
>> On Friday, November 14, 2025 11:08 CET, Heiko St?bner <heiko at sntech.de> wrote:
>>> Am Freitag, 14. November 2025, 09:32:29 Mitteleurop?ische Normalzeit schrieb Dragan Simic:
>>>> On Friday, November 14, 2025 09:24 CET, FUKAUMI Naoki <naoki at radxa.com> wrote:
>>>>> On 11/14/25 16:51, Krzysztof Kozlowski wrote:
>>>>>> On 14/11/2025 08:47, FUKAUMI Naoki wrote:
>>>>>>> On 11/14/25 16:42, Krzysztof Kozlowski wrote:
>>>>>>>> On 14/11/2025 08:37, FUKAUMI Naoki wrote:
>>>>>>>>> Hi Krzysztof,
>>>>>>>>>
>>>>>>>>> On 11/14/25 16:12, Krzysztof Kozlowski wrote:
>>>>>>>>>> On 05/11/2025 08:08, Krzysztof Kozlowski wrote:
>>>>>>>>>>> On 05/11/2025 07:57, FUKAUMI Naoki wrote:
>>>>>>>>>>>> On 11/5/25 15:43, Krzysztof Kozlowski wrote:
>>>>>>>>>>>>> On 05/11/2025 06:13, FUKAUMI Naoki wrote:
>>>>>>>>>>>>>> Add device tree binding documentation for the Radxa CM5 IO Board.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Link: https://dl.radxa.com/cm5/radxa_cm5_product_brief.pdf
>>>>>>>>>>>>>> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
>>>>>>>>>>>>>> Signed-off-by: Joseph Kogut <joseph.kogut at gmail.com>
>>>>>>>>>>>>>
>>>>>>>>>>>>> Wrong DCO chain.
>>>>>>>>>>>>>
>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>      Documentation/devicetree/bindings/arm/rockchip.yaml | 7 +++++++
>>>>>>>>>>>>>
>>>>>>>>>>>>> NAK, you just stolen ownership of an already posted patch.
>>>>>>>>>>>>
>>>>>>>>>>>> Read "Changes in v6" and patches; my patches are not the same as v5.
>>>>>>>>>>>> Your reply is totally inappropriate.
>>>>>>>>>>>
>>>>>>>>>>> Inappropriate is taking authorship of someone's patch, because we all
>>>>>>>>>>> expect to preserve the original authorship. That's not only basic
>>>>>>>>>>> decency but actually a standard.
>>>>>>>>>>>
>>>>>>>>>>> Additionally, read Joseph's reply that he wants to continue the work:
>>>>>>>>>>> https://lore.kernel.org/all/CAMWSM7iHtAxewW4JkRqRsifVnccqeFviaCgeOyprKDr92FOurg at mail.gmail.com/
>>>>>>>>>>>
>>>>>>>>>>> You clearly do not understand how to continue with someone's work.
>>>>>>>>>>>
>>>>>>>>>>> It is still a NAK.
>>>>>>>>>>
>>>>>>>>>> And I still wait for justification why you took authorship of this
>>>>>>>>>> patch, because to my eye you changed here nothing.
>>>>>>>>>>
>>>>>>>>>> So what did you change HERE that you think you are the author now?
>>>>>>>>>
>>>>>>>>> Changes in v6:
>>>>>>>>> (Patch 1/3)
>>>>>>>>> - Fix description; "Radxa CM5" is the correct name
>>>>>>>>
>>>>>>>> HERE, in this patch. Don't paste me hundreds of unrelated code. Write
>>>>>>>> concise and precise answers/comments.
>>>>>>>
>>>>>>> https://lore.kernel.org/linux-rockchip/AE0735A6C797CCFF+10496d73-7c0a-4884-9561-24721305a24f at radxa.com/
>>>>>>>
>>>>>>> | By the way, at some point I switched from "continuing your work" to
>>>>>>> | "recreating a new one based on my current work." The results of my
>>>>>>> | current work(*3) have changed significantly.
>>>>>>
>>>>>> So next time I will take your patch, your code, say "I recreated it" and
>>>>>> submit under my authorship and for you it is fine?
>>>>>
>>>>> Regarding CM5 patches, I'm fine.
>>>>>
>>>>>> Please take Joseph's patch instead. Read submitting patches doc to
>>>>>> understand which one more tag has to be added when sending somoene
>>>>>> else's work.
>>>>>>
>>>>>> In the future, I sincerely suggest avoiding re-creating people's work
>>>>>> but building on top, because you just duplicate the effort.
>>>>>
>>>>> I understand that you don't understand how I made efforts to build my 
>>>>> work on top of Joseph's patches.
>>>>
>>>> Maybe a solution for this huge mess could be that Naoki submits
>>>> unmodified patches from Joseph first, using the standard procedure
>>>> for that, and then the additional patch(es) that improve Joseph's
>>>> work?  All that in the same series.
>>>
>>> There is also Co-developed-by as an option.
>>
>> Ah, that's what the above-described option #1 involves, but it also 
>> raises some possible concerns, described in one of my responses. [1]
> 
> There are no concerns to be raised. Please read DCO. The original author
> GAVE certified what is necessary, thus any person taking this work
> already can you that certification. You raised some uncertainty "I'm not

Huh, that's barely English... ok, one more try:

There are no concerns to be raised. Please read DCO. The original author
GAVE certification what is necessary, thus any person taking this work
already can use that certification. You raised some uncertainty "I'm not
sure how fair is it for someone to become responsible" which is just not
right here. It is completely fair and completely correct from DCO point
of view, because the certification was already provided. Also from
certification point, there is no "weaker" form. Either you certify or not.

> sure how fair is it for someone to become responsible" which is just not
> right here. It is completely fair and completely correct from DCO point
> of view, because the certification was already provided. Also from
> certification point, there is no "weaker" form. Either you certify or not.




Best regards,
Krzysztof


From ukleinek at kernel.org  Fri Nov 14 02:41:07 2025
From: ukleinek at kernel.org (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Fri, 14 Nov 2025 11:41:07 +0100
Subject: [PATCH v3 3/5] pwm: Add rockchip PWMv4 driver
In-Reply-To: <20251027-rk3576-pwm-v3-3-654a5cb1e3f8@collabora.com>
References: <20251027-rk3576-pwm-v3-0-654a5cb1e3f8@collabora.com>
 <20251027-rk3576-pwm-v3-3-654a5cb1e3f8@collabora.com>
Message-ID: <hgiib7nbvz34kmeusuhso6zvluyuvpbz5lm2kzkv6kkm4pq5ms@2xu44lkkdcap>

Hello Nicolas,

On Mon, Oct 27, 2025 at 06:11:58PM +0100, Nicolas Frattaroli wrote:
> The Rockchip RK3576 brings with it a new PWM IP, in downstream code
> referred to as "v4". This new IP is different enough from the previous
> Rockchip IP that I felt it necessary to add a new driver for it, instead
> of shoehorning it in the old one.
> 
> Add this new driver, based on the PWM core's waveform APIs. Its platform
> device is registered by the parent mfpwm driver, from which it also
> receives a little platform data struct, so that mfpwm can guarantee that
> all the platform device drivers spread across different subsystems for
> this specific hardware IP do not interfere with each other.
> 
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
> ---
>  MAINTAINERS                   |   1 +
>  drivers/pwm/Kconfig           |  13 ++
>  drivers/pwm/Makefile          |   1 +
>  drivers/pwm/pwm-rockchip-v4.c | 353 ++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 368 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 8f3235ba825e..2079c2d51d5c 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -22372,6 +22372,7 @@ L:	linux-rockchip at lists.infradead.org
>  L:	linux-pwm at vger.kernel.org
>  S:	Maintained
>  F:	Documentation/devicetree/bindings/pwm/rockchip,rk3576-pwm.yaml
> +F:	drivers/pwm/pwm-rockchip-v4.c
>  F:	drivers/soc/rockchip/mfpwm.c
>  F:	include/soc/rockchip/mfpwm.h
>  
> diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
> index c2fd3f4b62d9..b852a7b2a29d 100644
> --- a/drivers/pwm/Kconfig
> +++ b/drivers/pwm/Kconfig
> @@ -615,6 +615,19 @@ config PWM_ROCKCHIP
>  	  Generic PWM framework driver for the PWM controller found on
>  	  Rockchip SoCs.
>  
> +config PWM_ROCKCHIP_V4
> +	tristate "Rockchip PWM v4 support"
> +	depends on ARCH_ROCKCHIP || COMPILE_TEST
> +	depends on HAS_IOMEM
> +	depends on MFD_ROCKCHIP_MFPWM

IMHO it's a bit strange that PWM_ROCKCHIP_V4 depends on ARCH_ROCKCHIP
while MFD_ROCKCHIP_MFPWM doesn't. So you can enable the MFD on all
platforms but the PWM component driver only on rockchip.

> +	help
> +	  Generic PWM framework driver for the PWM controller found on
> +	  later Rockchip SoCs such as the RK3576.
> +
> +	  Uses the Rockchip Multi-function PWM controller driver infrastructure
> +	  to guarantee fearlessly concurrent operation with other functions of
> +	  the same device implemented by drivers in other subsystems.
> +
>  config PWM_SAMSUNG
>  	tristate "Samsung PWM support"
>  	depends on PLAT_SAMSUNG || ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
> diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
> index dfa8b4966ee1..fe0d16558d99 100644
> --- a/drivers/pwm/Makefile
> +++ b/drivers/pwm/Makefile
> @@ -55,6 +55,7 @@ obj-$(CONFIG_PWM_RENESAS_RZG2L_GPT)	+= pwm-rzg2l-gpt.o
>  obj-$(CONFIG_PWM_RENESAS_RZ_MTU3)	+= pwm-rz-mtu3.o
>  obj-$(CONFIG_PWM_RENESAS_TPU)	+= pwm-renesas-tpu.o
>  obj-$(CONFIG_PWM_ROCKCHIP)	+= pwm-rockchip.o
> +obj-$(CONFIG_PWM_ROCKCHIP_V4)	+= pwm-rockchip-v4.o
>  obj-$(CONFIG_PWM_SAMSUNG)	+= pwm-samsung.o
>  obj-$(CONFIG_PWM_SIFIVE)	+= pwm-sifive.o
>  obj-$(CONFIG_PWM_SL28CPLD)	+= pwm-sl28cpld.o
> diff --git a/drivers/pwm/pwm-rockchip-v4.c b/drivers/pwm/pwm-rockchip-v4.c
> new file mode 100644
> index 000000000000..7afa83f12b6a
> --- /dev/null
> +++ b/drivers/pwm/pwm-rockchip-v4.c
> @@ -0,0 +1,353 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2025 Collabora Ltd.
> + *
> + * A Pulse-Width-Modulation (PWM) generator driver for the generators found in
> + * Rockchip SoCs such as the RK3576, internally referred to as "PWM v4". Uses
> + * the MFPWM infrastructure to guarantee exclusive use over the device without
> + * other functions of the device from different drivers interfering with its
> + * operation while it's active.
> + *
> + * Technical Reference Manual: Chapter 31 of the RK3506 TRM Part 1, a SoC which
> + * uses the same PWM hardware and has a publicly available TRM.
> + * https://opensource.rock-chips.com/images/3/36/Rockchip_RK3506_TRM_Part_1_V1.2-20250811.pdf
> + *
> + * Authors:
> + *     Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
> + *
> + * Limitations:
> + * - When the output is disabled, it will end abruptly without letting the
> + *   current period complete.
> + *   TODO: This can be fixed in the driver in the future by having the enable-
> + *         to-disable transition switch to oneshot mode with one repetition,
> + *         and then disable the pwmclk and release mfpwm when the oneshot
> + *         complete interrupt fires.

I don't consider this behaviour a bug. So maybe:

  - The hardware supports both completing the currently running period
    on disable (by switching to oneshot mode with a single repetition
    and only disable when the complete irq fires) and abrupt disable.
    Only the latter is implemented in the driver.

> + * - When the output is disabled, the pin will remain driven to whatever state
> + *   it last had.
> + * - Adjustments to the duty cycle will only take effect during the next period.
> + * - Adjustments to the period length will only take effect during the next
> + *   period.

Is it possible that a race condition occurs here and between updating
duty and period a new cycle starts and thus a period with the new duty
and old period (or vice versa) is externally visible?

> + * - offset should be between 0 and (period - duty)

This sounds wrong here. Assuming the driver enforces that (it should,
didn't check yet), this should be:

  - The hardware only supports offsets in [0, period-duty_cycle]

> + */
> +
> +#include <linux/math64.h>
> +#include <linux/mfd/rockchip-mfpwm.h>
> +#include <linux/platform_device.h>
> +#include <linux/pwm.h>
> +
> +struct rockchip_pwm_v4 {
> +	struct rockchip_mfpwm_func *pwmf;
> +	struct pwm_chip chip;
> +};
> +
> +struct rockchip_pwm_v4_wf {
> +	u32 period;
> +	u32 duty;
> +	u32 offset;
> +	u8 enable;
> +};
> +
> +static inline struct rockchip_pwm_v4 *to_rockchip_pwm_v4(struct pwm_chip *chip)
> +{
> +	return pwmchip_get_drvdata(chip);
> +}
> +
> +/**
> + * rockchip_pwm_v4_round_single - convert a PWM parameter to hardware
> + * @rate: clock rate of the PWM clock, as per clk_get_rate
> + * @in_val: parameter in nanoseconds to convert
> + *
> + * Returns the rounded value, saturating at U32_MAX if too large
> + */
> +static u32 rockchip_pwm_v4_round_single(unsigned long rate, u64 in_val)
> +{
> +	u64 tmp;
> +
> +	tmp = mul_u64_u64_div_u64(rate, in_val, NSEC_PER_SEC);

This might overflow for rate > NSEC_PER_SEC and big values of in_val.

I suggest to call devm_clk_rate_exclusive_get() in .probe() and fail to
probe for rate > NSEC_PER_SEC.

> +	if (tmp > U32_MAX)
> +		tmp = U32_MAX;
> +
> +	return (u32)tmp;

unneeded cast.

> +}
> +
> +/**
> + * rockchip_pwm_v4_round_params - convert PWM parameters to hardware
> + * @rate: PWM clock rate to do the calculations at
> + * @duty: PWM duty cycle in nanoseconds
> + * @period: PWM period in nanoseconds
> + * @offset: PWM offset in nanoseconds
> + * @out_duty: pointer to where the rounded duty value should be stored
> + * @out_period: pointer to where the rounded period value should be stored
> + * @out_offset: pointer to where the rounded offset value should be stored
> + *
> + * Convert nanosecond-based duty/period/offset parameters to the PWM hardware's
> + * native rounded representation in number of cycles at clock rate @rate. Should
> + * any of the input parameters be out of range for the hardware, the
> + * corresponding output parameter is the maximum permissible value for said
> + * parameter with considerations to the others.
> + */
> +static void rockchip_pwm_v4_round_params(unsigned long rate, u64 duty,
> +					u64 period, u64 offset, u32 *out_duty,
> +					u32 *out_period, u32 *out_offset)

Hmm, it would be more natural to pass rate, wf and wfhw here, wouldn't
it?

> +{
> +	*out_period = rockchip_pwm_v4_round_single(rate, period);
> +
> +	*out_duty = rockchip_pwm_v4_round_single(rate, duty);
> +
> +	/* As per TRM, PWM_OFFSET: "The value ranges from 0 to (period-duty)" */
> +	*out_offset = rockchip_pwm_v4_round_single(rate, offset);
> +	if (*out_offset > (*out_period - *out_duty))

needless parenthesis

You rely on out_period >= out_duty. You can assume that
rockchip_pwm_v4_round_wf_tohw() is only called with wf->period_length_ns
>= wf->duty_offset_ns, but still worth a comment IMHO.

> +		*out_offset = *out_period - *out_duty;
> +}
> +
> +static int rockchip_pwm_v4_round_wf_tohw(struct pwm_chip *chip,
> +					 struct pwm_device *pwm,
> +					 const struct pwm_waveform *wf,
> +					 void *_wfhw)
> +{
> +	struct rockchip_pwm_v4 *pc = to_rockchip_pwm_v4(chip);
> +	struct rockchip_pwm_v4_wf *wfhw = _wfhw;
> +	unsigned long rate;
> +
> +	rate = clk_get_rate(pc->pwmf->core);
> +
> +	rockchip_pwm_v4_round_params(rate, wf->duty_length_ns,
> +				     wf->period_length_ns, wf->duty_offset_ns,
> +				     &wfhw->duty, &wfhw->period, &wfhw->offset);
> +
> +	if (wf->period_length_ns > 0)
> +		wfhw->enable = PWMV4_EN_BOTH_MASK;
> +	else
> +		wfhw->enable = 0;
> +
> +	dev_dbg(&chip->dev,
> +		"tohw: duty %llu -> %u, period %llu -> %u, offset %llu -> %u, rate %lu\n",
> +		wf->duty_length_ns, wfhw->duty, wf->period_length_ns,
> +		wfhw->period, wf->duty_offset_ns, wfhw->offset, rate);

Can you make that:

	dev_dbg(&chip->dev,
		"tohw: pwm#%u: %lld/%lld [+%lld] @%lu -> DUTY: %08x, PERIOD: %08x, OFFSET: %08x\n",
		pwm->hwpwm, wf->duty_length_ns, wf->period_length_ns,
		wf->duty_offset_ns, rate, wfhw->duty, wfhw->period,
		wfhw->offset);

to stick to the common way to format a struct pwm_waveform and have
input and output separated. (This is not objectively better than pairing
input and matching output parameter, but also it's not worse and matches
what other drivers are doing.)

> +
> +	return 0;
> +}
> +
> +static int rockchip_pwm_v4_round_wf_fromhw(struct pwm_chip *chip,
> +					   struct pwm_device *pwm,
> +					   const void *_wfhw,
> +					   struct pwm_waveform *wf)
> +{
> +	struct rockchip_pwm_v4 *pc = to_rockchip_pwm_v4(chip);
> +	const struct rockchip_pwm_v4_wf *wfhw = _wfhw;
> +	unsigned long rate;
> +
> +	rate = clk_get_rate(pc->pwmf->core);
> +
> +	if (rockchip_pwm_v4_is_enabled(wfhw->enable)) {
> +		if (!rate)
> +			return -EINVAL;

Can rate be 0? Either consider it fixed, or store rate in wfhw.

> +
> +		wf->period_length_ns = (u64)wfhw->period * NSEC_PER_SEC / rate;
> +		wf->duty_length_ns = (u64)wfhw->duty * NSEC_PER_SEC / rate;
> +		wf->duty_offset_ns = (u64)wfhw->offset * NSEC_PER_SEC / rate;

You need to round up here.

> +	} else {
> +		wf->period_length_ns = 0;
> +		wf->duty_length_ns = 0;
> +		wf->duty_offset_ns = 0;
> +	}
> +
> +	dev_dbg(&chip->dev,
> +		"fromhw: duty %u -> %llu, period %u -> %llu, offset %u -> %llu, rate %lu\n",
> +		wfhw->duty, wf->duty_length_ns, wfhw->period,
> +		wf->period_length_ns, wfhw->offset, wf->duty_offset_ns, rate);
> +
> +	return 0;
> +}
> +
> +static int rockchip_pwm_v4_read_wf(struct pwm_chip *chip, struct pwm_device *pwm,
> +				   void *_wfhw)
> +{
> +	struct rockchip_pwm_v4 *pc = to_rockchip_pwm_v4(chip);
> +	struct rockchip_pwm_v4_wf *wfhw = _wfhw;
> +	int ret = 0;
> +
> +
> +	ret = mfpwm_acquire(pc->pwmf);
> +	if (ret)
> +		return ret;
> +
> +	wfhw->period = mfpwm_reg_read(pc->pwmf->base, PWMV4_REG_PERIOD);
> +	wfhw->duty = mfpwm_reg_read(pc->pwmf->base, PWMV4_REG_DUTY);
> +	wfhw->offset = mfpwm_reg_read(pc->pwmf->base, PWMV4_REG_OFFSET);
> +	wfhw->enable = mfpwm_reg_read(pc->pwmf->base, PWMV4_REG_ENABLE) & PWMV4_EN_BOTH_MASK;

Can it happen that only a part of the bits in PWMV4_EN_BOTH_MASK are
set? rockchip_pwm_v4_is_enabled() then returns true.

> +
> +	mfpwm_release(pc->pwmf);
> +
> +	return 0;
> +}
> +
> +static int rockchip_pwm_v4_write_wf(struct pwm_chip *chip, struct pwm_device *pwm,
> +				    const void *_wfhw)
> +{
> +	struct rockchip_pwm_v4 *pc = to_rockchip_pwm_v4(chip);
> +	const struct rockchip_pwm_v4_wf *wfhw = _wfhw;
> +	bool was_enabled = false;
> +	int ret = 0;
> +
> +	ret = mfpwm_acquire(pc->pwmf);
> +	if (ret)
> +		return ret;
> +
> +	was_enabled = rockchip_pwm_v4_is_enabled(mfpwm_reg_read(pc->pwmf->base,
> +								PWMV4_REG_ENABLE));
> +
> +	/*
> +	 * "But Nicolas", you ask with valid concerns, "why would you enable the
> +	 * PWM before setting all the parameter registers?"
> +	 *
> +	 * Excellent question, Mr. Reader M. Strawman! The RK3576 TRM Part 1
> +	 * Section 34.6.3 specifies that this is the intended order of writes.
> +	 * Doing the PWM_EN and PWM_CLK_EN writes after the params but before
> +	 * the CTRL_UPDATE_EN, or even after the CTRL_UPDATE_EN, results in
> +	 * erratic behaviour where repeated turning on and off of the PWM may
> +	 * not turn it off under all circumstances. This is also why we don't
> +	 * use relaxed writes; it's not worth the footgun.
> +	 */
> +	mfpwm_reg_write(pc->pwmf->base, PWMV4_REG_ENABLE,
> +			FIELD_PREP_WM16(PWMV4_EN_BOTH_MASK, wfhw->enable));
> +
> +	mfpwm_reg_write(pc->pwmf->base, PWMV4_REG_PERIOD, wfhw->period);
> +	mfpwm_reg_write(pc->pwmf->base, PWMV4_REG_DUTY, wfhw->duty);
> +	mfpwm_reg_write(pc->pwmf->base, PWMV4_REG_OFFSET, wfhw->offset);
> +
> +	mfpwm_reg_write(pc->pwmf->base, PWMV4_REG_CTRL, PWMV4_CTRL_CONT_FLAGS);
> +
> +	/* Commit new configuration to hardware output. */
> +	mfpwm_reg_write(pc->pwmf->base, PWMV4_REG_ENABLE,
> +			PWMV4_CTRL_UPDATE_EN);
> +
> +	if (rockchip_pwm_v4_is_enabled(wfhw->enable)) {
> +		if (!was_enabled) {
> +			dev_dbg(&chip->dev, "Enabling PWM output\n");
> +			ret = clk_enable(pc->pwmf->core);
> +			if (ret)
> +				goto err_mfpwm_release;
> +			ret = clk_rate_exclusive_get(pc->pwmf->core);
> +			if (ret) {
> +				clk_disable(pc->pwmf->core);
> +				goto err_mfpwm_release;
> +			}
> +
> +			/*
> +			 * Output should be on now, acquire device to guarantee
> +			 * exclusion with other device functions while it's on.
> +			 */
> +			ret = mfpwm_acquire(pc->pwmf);
> +			if (ret)
> +				goto err_mfpwm_release;

Missing clk_disable() + clk_rate_exclusive_put() in the error path?
(Though that would violate that PWMV4_REG_ENABLE and clk state are in
sync.)

> +		}
> +	} else if (was_enabled) {
> +		dev_dbg(&chip->dev, "Disabling PWM output\n");
> +		clk_rate_exclusive_put(pc->pwmf->core);
> +		clk_disable(pc->pwmf->core);
> +		/* Output is off now, extra release to balance extra acquire */
> +		mfpwm_release(pc->pwmf);
> +	}
> +
> +err_mfpwm_release:
> +	mfpwm_release(pc->pwmf);
> +
> +	return ret;
> +}
> +
> +static const struct pwm_ops rockchip_pwm_v4_ops = {
> +	.sizeof_wfhw = sizeof(struct rockchip_pwm_v4_wf),
> +	.round_waveform_tohw = rockchip_pwm_v4_round_wf_tohw,
> +	.round_waveform_fromhw = rockchip_pwm_v4_round_wf_fromhw,
> +	.read_waveform = rockchip_pwm_v4_read_wf,
> +	.write_waveform = rockchip_pwm_v4_write_wf,
> +};
> +
> +static bool rockchip_pwm_v4_on_and_continuous(struct rockchip_pwm_v4 *pc)
> +{
> +	bool en;
> +	u32 val;
> +
> +	en = rockchip_pwm_v4_is_enabled(mfpwm_reg_read(pc->pwmf->base,
> +						       PWMV4_REG_ENABLE));
> +	val = mfpwm_reg_read(pc->pwmf->base, PWMV4_REG_CTRL);
> +
> +	return en && ((val & PWMV4_MODE_MASK) == PWMV4_MODE_CONT);
> +}
> +
> +static int rockchip_pwm_v4_probe(struct platform_device *pdev)
> +{
> +	struct rockchip_mfpwm_func *pwmf = dev_get_platdata(&pdev->dev);
> +	struct rockchip_pwm_v4 *pc;
> +	struct pwm_chip *chip;
> +	struct device *dev = &pdev->dev;
> +	int ret;
> +
> +	/*
> +	 * For referencing the PWM in the DT to work, we need the parent MFD
> +	 * device's OF node. Code shamelessly adapted from `drivers/pci/of.c`'s
> +	 * pci_set_of_node(), which does this for bus reasons.
> +	 */
> +	dev->parent->of_node_reused = true;

The help text for of_node_reused says: "Set if the device-tree node is
shared with an ancestor device". So I wonder if it's dev->of_node_reused
that should be set?

> +	device_set_node(dev,
> +			of_fwnode_handle(no_free_ptr(dev->parent->of_node)));

Huh, so you're setting dev->parent->of_node to NULL. Is that really what
should happen here?

> +	chip = devm_pwmchip_alloc(dev, 1, sizeof(*pc));
> +	if (IS_ERR(chip))
> +		return PTR_ERR(chip);
> +
> +	pc = to_rockchip_pwm_v4(chip);
> +	pc->pwmf = pwmf;
> +
> +	ret = mfpwm_acquire(pwmf);
> +	if (ret == -EBUSY)
> +		dev_warn(dev, "PWM hardware already in use, can't check initial state\n");

I think it's sensible to let .probe() fail here.

> +	else if (ret < 0)
> +		return dev_err_probe(dev, ret, "Couldn't acquire mfpwm in probe\n");
> +
> +	if (!rockchip_pwm_v4_on_and_continuous(pc))
> +		mfpwm_release(pwmf);
> +	else {
> +		dev_dbg(dev, "PWM was already on at probe time\n");
> +		ret = clk_enable(pwmf->core);
> +		if (ret)
> +			return dev_err_probe(dev, ret, "Enabling pwm clock failed\n");
> +		ret = clk_rate_exclusive_get(pc->pwmf->core);
> +		if (ret) {
> +			clk_disable(pwmf->core);
> +			return dev_err_probe(dev, ret, "Protecting pwm clock failed\n");
> +		}
> +	}
> +
> +	platform_set_drvdata(pdev, chip);
> +
> +	chip->ops = &rockchip_pwm_v4_ops;
> +
> +	ret = devm_pwmchip_add(dev, chip);
> +	if (ret)
> +		return dev_err_probe(dev, ret, "Failed to add PWM chip\n");

Missing mfpwm_release() if rockchip_pwm_v4_on_and_continuous() returned
true above.

> +
> +	return 0;
> +}
> +
> +static const struct platform_device_id rockchip_pwm_v4_ids[] = {
> +	{ .name = "pwm-rockchip-v4", },
> +	{ /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(platform, rockchip_pwm_v4_ids);
> +
> +static struct platform_driver rockchip_pwm_v4_driver = {
> +	.probe = rockchip_pwm_v4_probe,
> +	.driver = {
> +		.name = "pwm-rockchip-v4",
> +	},
> +	.id_table = rockchip_pwm_v4_ids,
> +};
> +module_platform_driver(rockchip_pwm_v4_driver);
> +
> +MODULE_AUTHOR("Nicolas Frattaroli <nicolas.frattaroli at collabora.com>");
> +MODULE_DESCRIPTION("Rockchip PWMv4 Driver");
> +MODULE_LICENSE("GPL");
> +MODULE_IMPORT_NS("ROCKCHIP_MFPWM");
> +MODULE_ALIAS("platform:pwm-rockchip-v4");

Best regards
Uwe
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251114/34c8ff69/attachment-0001.sig>

From mkl at pengutronix.de  Fri Nov 14 03:01:15 2025
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Fri, 14 Nov 2025 12:01:15 +0100
Subject: [PATCH v9 3/3] net: can: rockchip: add can for RK3576 Soc
In-Reply-To: <176d96b4-397c-49d4-8e8e-2f77a5d59c12@rock-chips.com>
References: <20251113075419.482940-1-zhangqing@rock-chips.com>
 <20251113075419.482940-4-zhangqing@rock-chips.com>
 <20251113-slim-foamy-gecko-2dc389-mkl@pengutronix.de>
 <176d96b4-397c-49d4-8e8e-2f77a5d59c12@rock-chips.com>
Message-ID: <20251114-utopian-cheerful-otter-33c1d5-mkl@pengutronix.de>

On 14.11.2025 17:55:53, zhangqing wrote:
> > > +/* The rk3576 CAN-FD */
> > > +static const struct rkcanfd_devtype_data rkcan_devtype_data_rk3576 = {
> > > +	.model = RKCAN_MODEL_RK3576,
> > > +	.quirks = RKCANFD_QUIRK_CANFD_BROKEN,
> > Is CAN-FD mode broken on the rk3576?
> >
> > Please test CAN-FD and please do the tests documented near the
> > definition of RKCANFD_QUIRK_CANFD_BROKEN:
> >
> > | Tests on the rk3568v2 and rk3568v3 show that receiving certain
> > | CAN-FD frames trigger an Error Interrupt.
> > |
> > | - Form Error in RX Arbitration Phase: TX_IDLE RX_STUFF_COUNT (0x0a010100) CMD=0 RX=0 TX=0
> > |   Error-Warning=1 Bus-Off=0
> > |   To reproduce:
> > |   host:
> > |     cansend can0 002##01f
> > |   DUT:
> > |     candump any,0:0,#FFFFFFFF -cexdHtA
> > |
> > | - Form Error in RX Arbitration Phase: TX_IDLE RX_CRC (0x0a010200) CMD=0 RX=0 TX=0
> > |   Error-Warning=1 Bus-Off=0
> > |   To reproduce:
> > |   host:
> > |     cansend can0 002##07217010000000000
> > |   DUT:
> > |     candump any,0:0,#FFFFFFFF -cexdHtA
> There is no doubt about the other modifications above. They will be
> corrected in version V10.
>
> CANFD requires authorization and is not supported by default.

Can you explain what you mean by authorization? What do you mean by "not
supported"?

> After obtaining authorization, it can be used, so this place is not
> considered broken.
> What's the best way to handle this situation?

regards,
Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde          |
Embedded Linux                   | https://www.pengutronix.de |
Vertretung N?rnberg              | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-9   |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251114/833b6842/attachment.sig>

From zhangqing at rock-chips.com  Fri Nov 14 04:14:13 2025
From: zhangqing at rock-chips.com (zhangqing)
Date: Fri, 14 Nov 2025 20:14:13 +0800
Subject: [PATCH v9 3/3] net: can: rockchip: add can for RK3576 Soc
In-Reply-To: <20251114-utopian-cheerful-otter-33c1d5-mkl@pengutronix.de>
References: <20251113075419.482940-1-zhangqing@rock-chips.com>
 <20251113075419.482940-4-zhangqing@rock-chips.com>
 <20251113-slim-foamy-gecko-2dc389-mkl@pengutronix.de>
 <176d96b4-397c-49d4-8e8e-2f77a5d59c12@rock-chips.com>
 <20251114-utopian-cheerful-otter-33c1d5-mkl@pengutronix.de>
Message-ID: <3233894e-9409-4b74-a954-0b30064c3c8c@rock-chips.com>


? 2025/11/14 19:01, Marc Kleine-Budde ??:
> On 14.11.2025 17:55:53, zhangqing wrote:
>>>> +/* The rk3576 CAN-FD */
>>>> +static const struct rkcanfd_devtype_data rkcan_devtype_data_rk3576 = {
>>>> +	.model = RKCAN_MODEL_RK3576,
>>>> +	.quirks = RKCANFD_QUIRK_CANFD_BROKEN,
>>> Is CAN-FD mode broken on the rk3576?
>>>
>>> Please test CAN-FD and please do the tests documented near the
>>> definition of RKCANFD_QUIRK_CANFD_BROKEN:
>>>
>>> | Tests on the rk3568v2 and rk3568v3 show that receiving certain
>>> | CAN-FD frames trigger an Error Interrupt.
>>> |
>>> | - Form Error in RX Arbitration Phase: TX_IDLE RX_STUFF_COUNT (0x0a010100) CMD=0 RX=0 TX=0
>>> |   Error-Warning=1 Bus-Off=0
>>> |   To reproduce:
>>> |   host:
>>> |     cansend can0 002##01f
>>> |   DUT:
>>> |     candump any,0:0,#FFFFFFFF -cexdHtA
>>> |
>>> | - Form Error in RX Arbitration Phase: TX_IDLE RX_CRC (0x0a010200) CMD=0 RX=0 TX=0
>>> |   Error-Warning=1 Bus-Off=0
>>> |   To reproduce:
>>> |   host:
>>> |     cansend can0 002##07217010000000000
>>> |   DUT:
>>> |     candump any,0:0,#FFFFFFFF -cexdHtA
>> There is no doubt about the other modifications above. They will be
>> corrected in version V10.
>>
>> CANFD requires authorization and is not supported by default.
> Can you explain what you mean by authorization? What do you mean by "not
> supported"?
For RK3576 SoC, the IC hardware design supports CANFD.
However, a license application is required before it can be used; 
otherwise, there will be legal risks.
>
>> After obtaining authorization, it can be used, so this place is not
>> considered broken.
>> What's the best way to handle this situation?
> regards,
> Marc
>
-- 
??
???????????
Rockchip Electronics Co.,Ltd
????????????????89????A?21??
Add:No.21 Building, A District, No.89 Software Boulevard Fuzhou, Fujian 350003, P.R.China
Tel:+86-0591-83991906-8601
???350003
E-mail:elaine.zhang at rock-chips.com
****************************************************************************
??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

IMPORTANT NOTICE: This email is from Fuzhou Rockchip Electronics Co., Ltd .The contents of this email and any attachments may contain information that is privileged, confidential and/or exempt from disclosure under applicable law and relevant NDA. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution, or use of the information is STRICTLY PROHIBITED. Please immediately contact the sender as soon as possible and destroy the material in its entirety in any format. Thank you.

****************************************************************************



From mkl at pengutronix.de  Fri Nov 14 05:22:42 2025
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Fri, 14 Nov 2025 14:22:42 +0100
Subject: [PATCH v9 3/3] net: can: rockchip: add can for RK3576 Soc
In-Reply-To: <3233894e-9409-4b74-a954-0b30064c3c8c@rock-chips.com>
References: <20251113075419.482940-1-zhangqing@rock-chips.com>
 <20251113075419.482940-4-zhangqing@rock-chips.com>
 <20251113-slim-foamy-gecko-2dc389-mkl@pengutronix.de>
 <176d96b4-397c-49d4-8e8e-2f77a5d59c12@rock-chips.com>
 <20251114-utopian-cheerful-otter-33c1d5-mkl@pengutronix.de>
 <3233894e-9409-4b74-a954-0b30064c3c8c@rock-chips.com>
Message-ID: <20251114-illegal-flounder-of-maturity-edc269-mkl@pengutronix.de>

On 14.11.2025 20:14:13, zhangqing wrote:
>
> ? 2025/11/14 19:01, Marc Kleine-Budde ??:
> > On 14.11.2025 17:55:53, zhangqing wrote:
> > > > > +/* The rk3576 CAN-FD */
> > > > > +static const struct rkcanfd_devtype_data rkcan_devtype_data_rk3576 = {
> > > > > +	.model = RKCAN_MODEL_RK3576,
> > > > > +	.quirks = RKCANFD_QUIRK_CANFD_BROKEN,
> > > > Is CAN-FD mode broken on the rk3576?
> > > >
> > > > Please test CAN-FD and please do the tests documented near the
> > > > definition of RKCANFD_QUIRK_CANFD_BROKEN:
> > > >
> > > > | Tests on the rk3568v2 and rk3568v3 show that receiving certain
> > > > | CAN-FD frames trigger an Error Interrupt.
> > > > |
> > > > | - Form Error in RX Arbitration Phase: TX_IDLE RX_STUFF_COUNT (0x0a010100) CMD=0 RX=0 TX=0
> > > > |   Error-Warning=1 Bus-Off=0
> > > > |   To reproduce:
> > > > |   host:
> > > > |     cansend can0 002##01f
> > > > |   DUT:
> > > > |     candump any,0:0,#FFFFFFFF -cexdHtA
> > > > |
> > > > | - Form Error in RX Arbitration Phase: TX_IDLE RX_CRC (0x0a010200) CMD=0 RX=0 TX=0
> > > > |   Error-Warning=1 Bus-Off=0
> > > > |   To reproduce:
> > > > |   host:
> > > > |     cansend can0 002##07217010000000000
> > > > |   DUT:
> > > > |     candump any,0:0,#FFFFFFFF -cexdHtA
> > > There is no doubt about the other modifications above. They will be
> > > corrected in version V10.
> > >
> > > CANFD requires authorization and is not supported by default.
> > Can you explain what you mean by authorization? What do you mean by "not
> > supported"?
>
> For RK3576 SoC, the IC hardware design supports CANFD.
> However, a license application is required before it can be used; otherwise,
> there will be legal risks.

INANL. If an SoC is supplied without a license for the IP cores that you
want to use in a product you sell, you must purchase a license from
Bosch:

https://www.bosch-semiconductors.com/products/ip-modules/can-protocol-license/can-protocol-license.html

I don't see why you should restrict the driver to CAN only, if CAN-FD is
functional.

Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde          |
Embedded Linux                   | https://www.pengutronix.de |
Vertretung N?rnberg              | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-9   |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251114/183f58bf/attachment.sig>

From mkl at pengutronix.de  Fri Nov 14 05:28:18 2025
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Fri, 14 Nov 2025 14:28:18 +0100
Subject: [PATCH v9 3/3] net: can: rockchip: add can for RK3576 Soc
In-Reply-To: <20251114-illegal-flounder-of-maturity-edc269-mkl@pengutronix.de>
References: <20251113075419.482940-1-zhangqing@rock-chips.com>
 <20251113075419.482940-4-zhangqing@rock-chips.com>
 <20251113-slim-foamy-gecko-2dc389-mkl@pengutronix.de>
 <176d96b4-397c-49d4-8e8e-2f77a5d59c12@rock-chips.com>
 <20251114-utopian-cheerful-otter-33c1d5-mkl@pengutronix.de>
 <3233894e-9409-4b74-a954-0b30064c3c8c@rock-chips.com>
 <20251114-illegal-flounder-of-maturity-edc269-mkl@pengutronix.de>
Message-ID: <20251114-amorphous-guillemot-of-awe-871e2c-mkl@pengutronix.de>

On 14.11.2025 14:22:42, Marc Kleine-Budde wrote:
> > For RK3576 SoC, the IC hardware design supports CANFD.
> > However, a license application is required before it can be used; otherwise,
> > there will be legal risks.
>
> INANL. If an SoC is supplied without a license for the IP cores that you
> want to use in a product you sell, you must purchase a license from
> Bosch:

AFAIK the same applies to the "CTU CAN-FD IP core", which is already mainline.

regards,
Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde          |
Embedded Linux                   | https://www.pengutronix.de |
Vertretung N?rnberg              | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-9   |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251114/a5f3997e/attachment.sig>

From michael.opdenacker at rootcommit.com  Fri Nov 14 05:54:58 2025
From: michael.opdenacker at rootcommit.com (Michael Opdenacker)
Date: Fri, 14 Nov 2025 13:54:58 +0000 (UTC)
Subject: [PATCH 2/2] arm64: dts: rockchip: add Tinkerboard 3 and 3S device
 tree
In-Reply-To: <dbacc018-2631-6606-7562-27371cf45d6f@manjaro.org>
References: <20251111172003.2324525-1-michael.opdenacker@rootcommit.com>
 <20251111172003.2324525-3-michael.opdenacker@rootcommit.com>
 <dbacc018-2631-6606-7562-27371cf45d6f@manjaro.org>
Message-ID: <01b16ed0-472d-49f5-a4ad-fce03a651de8@rootcommit.com>

Hi Dragan,

Thanks a lot for your review and feedback!

On 11/14/25 03:26, Dragan Simic wrote:
> Hello Michael,
>
> Thanks for this patch!  Please, see some comments below.
>
> On Tuesday, November 11, 2025 18:20 CET, michael.opdenacker at rootcommit.com wrote:
>> From: Michael Opdenacker <michael.opdenacker at rootcommit.com>
>>
>> Add initial device tree support for Asus Tinkerboard 3 [1] and 3S [2],
>> which are SBCs based on the Rockchip 3566 SoC.
> For consistency and because it's a proper noun, this should be
> s/Tinkerboard/Tinker Board/.

Fixed in all the patches.

>
> The board .dts/.dtb files should include "-board", i.e. these should
> be "rk3566-tinker-board-3.dtb" and "rk3566-tinker-board-3s.dtb"
> instead, because there's no real need for shortening.  These boards
> are simply named "Tinker Board", which should be preserved.

Done too. However, I used these names for consistency with what was used 
on arm(32) for the original Tinker Board:
arch/arm/boot/dts/rockchip/rk3288-tinker.dts
arch/arm/boot/dts/rockchip/rk3288-tinker-s.dts
arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi

I guess it's fine to ignore what arm did right? It won't live as long as 
arm64 (I attend Arnd's talk about arm 32).

>
>>   dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-bpi-r2-pro.dtb
>>   dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-v10.dtb
>>   dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-fastrhino-r66s.dtb
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3566-tinker-3.dts b/arch/arm64/boot/dts/rockchip/rk3566-tinker-3.dts
>> new file mode 100644
>> index 000000000000..938af35b9004
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/rockchip/rk3566-tinker-3.dts
>> @@ -0,0 +1,14 @@
>> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
>> +/*
>> + * Copyright (C) 2025 Michael Opdenacker <michael.opdenacker at rootcommit.com>
>> + */
>> +
>> +/dts-v1/;
>> +
>> +#include "rk3566-tinker-3.dtsi"
> The same comment from above about the naming applies here (as well
> as in other places), so we should have "rk3566-tinker-board-3.dtsi"
> here instead.
>
>> +
>> +/ {
>> +	model = "Rockchip RK3566 Asus Tinker Board 3";
> For consistency and to avoid redundancy, the "Rockchip RK3566"
> part should be removed.


Done.

>
>> +	compatible = "asus,rk3566-tinker-3", "rockchip,rk3566";
> Actually, the compatible should be "asus,rk3566-tinker-board-3"
> instead, because there's no real need for shortening it.


No problem to do it. However, here we have a slightly bigger problem: it 
would be inconsistent with the bindings for the original Tinker Board in 
the same rockchip.yaml file:

 ? ? ? - description: Asus Tinker board
 ? ? ? ? items:
 ? ? ? ? ? - const: asus,rk3288-tinker
 ? ? ? ? ? - const: rockchip,rk3288

 ? ? ? - description: Asus Tinker board S
 ? ? ? ? items:
 ? ? ? ? ? - const: asus,rk3288-tinker-s
 ? ? ? ? ? - const: rockchip,rk3288

What do you think? The discrepancy would be quite visiible.

>> +	compatible = "asus,rk3566-tinker-3s", "asus,rk3566-tinker-3", "rockchip,rk3566";
> The compatibles should be as below instead, for the same reasons
> as already explained above.
>
>    "asus,rk3566-tinker-board-3s", "asus,rk3566-tinker-board-3", "rockchip,rk3566"

Yes, whatever is decided for the compatible strings.
>
> Though, perhaps it would be better to not include the "asus,rk3566-
> tinker-board-3" part, because I think it's pretty much redundant.


My reasoning was that Tinker Board 3S is a superset of Tinker Board 3 
(additional eMMC and headers).
If someday some code is associated to the compatible string for Tinker 
3, than Tinker 3S should use it too, right? Unless we want to have the 
possibility to ignore some Tinker3 code in Tinker 3S for some reason. 
Then, it's better indeed that 3S doesn't use the Tinker 3 compatible 
string. It seems we have more options with what you're suggesting.

What do you think?

Thanks again,
Cheers
Michael.

-- 
Michael Opdenacker
Root Commit
Embedded Linux Training and Consulting
https://rootcommit.com



From dsimic at manjaro.org  Fri Nov 14 05:57:36 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Fri, 14 Nov 2025 14:57:36 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v6 1/3] =?utf-8?q?dt-bindings=3A?=
 =?utf-8?q?_arm=3A?==?utf-8?q?_rockchip=3A?= Add Radxa CM5 IO Board
In-Reply-To: <5b58dda8-af68-41cd-af23-ec48bfc11d79@kernel.org>
References: <20251105051335.17652-1-naoki@radxa.com>
 <A3AD69295D2E2D65+db2dc8bd-054f-4dda-9dd1-3cc0c0feed35@radxa.com>
 <194908a1-f956-ba0a-656f-7b1e8456b51d@manjaro.org> <1942576.CQOukoFCf9@diego>
 <21ea3b50-6000-5202-49cf-685310e6fa18@manjaro.org> <5b58dda8-af68-41cd-af23-ec48bfc11d79@kernel.org>
Message-ID: <da9b6e3b-6de3-5303-568b-27efd6772810@manjaro.org>

On Friday, November 14, 2025 11:30 CET, Krzysztof Kozlowski <krzk at kernel.org> wrote:
> On 14/11/2025 11:12, Dragan Simic wrote:
> > On Friday, November 14, 2025 11:08 CET, Heiko St?bner <heiko at sntech.de> wrote:
> >> There is also Co-developed-by as an option.
> > 
> > Ah, that's what the above-described option #1 involves, but it also 
> > raises some possible concerns, described in one of my responses. [1]
> 
> There are no concerns to be raised. Please read DCO. The original author
> GAVE certified what is necessary, thus any person taking this work
> already can you that certification. You raised some uncertainty "I'm not
> sure how fair is it for someone to become responsible" which is just not
> right here. It is completely fair and completely correct from DCO point
> of view, because the certification was already provided. Also from
> certification point, there is no "weaker" form. Either you certify or not.

I see, you're following the documentation strictly and rigidly.
In that case, I think Naoki now knows what's to be done when
submitting these patches again.



From dsimic at manjaro.org  Fri Nov 14 06:30:18 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Fri, 14 Nov 2025 15:30:18 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH 2/2] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= add Tinkerboard 3 and 3S device tree
In-Reply-To: <01b16ed0-472d-49f5-a4ad-fce03a651de8@rootcommit.com>
References: <20251111172003.2324525-1-michael.opdenacker@rootcommit.com>
 <20251111172003.2324525-3-michael.opdenacker@rootcommit.com>
 <dbacc018-2631-6606-7562-27371cf45d6f@manjaro.org> <01b16ed0-472d-49f5-a4ad-fce03a651de8@rootcommit.com>
Message-ID: <51b28810-9d17-0505-56e7-6a3e13749fd9@manjaro.org>

Hello Michael,

On Friday, November 14, 2025 14:54 CET, Michael Opdenacker <michael.opdenacker at rootcommit.com> wrote:
> Thanks a lot for your review and feedback!
> 
> On 11/14/25 03:26, Dragan Simic wrote:
> > Thanks for this patch!  Please, see some comments below.
> >
> > On Tuesday, November 11, 2025 18:20 CET, michael.opdenacker at rootcommit.com wrote:
> >> From: Michael Opdenacker <michael.opdenacker at rootcommit.com>
> >>
> >> Add initial device tree support for Asus Tinkerboard 3 [1] and 3S [2],
> >> which are SBCs based on the Rockchip 3566 SoC.
> > For consistency and because it's a proper noun, this should be
> > s/Tinkerboard/Tinker Board/.
> 
> Fixed in all the patches.

Thanks.

> > The board .dts/.dtb files should include "-board", i.e. these should
> > be "rk3566-tinker-board-3.dtb" and "rk3566-tinker-board-3s.dtb"
> > instead, because there's no real need for shortening.  These boards
> > are simply named "Tinker Board", which should be preserved.
> 
> Done too. However, I used these names for consistency with what was used 
> on arm(32) for the original Tinker Board:
> 
> arch/arm/boot/dts/rockchip/rk3288-tinker.dts
> arch/arm/boot/dts/rockchip/rk3288-tinker-s.dts
> arch/arm/boot/dts/rockchip/rk3288-tinker.dtsi
> 
> I guess it's fine to ignore what arm did right? It won't live as long as 
> arm64 (I attend Arnd's talk about arm 32).

Thanks.  Yes, I saw that naming for the other Tinker Board, based
on RK3288, which I'd consider a mistake from the past we should heed
from, instead of repeating it. :)

[snip]

> >> +/ {
> >> +	model = "Rockchip RK3566 Asus Tinker Board 3";
> > For consistency and to avoid redundancy, the "Rockchip RK3566"
> > part should be removed.
> 
> Done.

Thanks.

> >> +	compatible = "asus,rk3566-tinker-3", "rockchip,rk3566";
> >
> > Actually, the compatible should be "asus,rk3566-tinker-board-3"
> > instead, because there's no real need for shortening it.
> 
> No problem to do it. However, here we have a slightly bigger problem: it 
> would be inconsistent with the bindings for the original Tinker Board in 
> the same rockchip.yaml file:
> 
>  ? ? ? - description: Asus Tinker board
>  ? ? ? ? items:
>  ? ? ? ? ? - const: asus,rk3288-tinker
>  ? ? ? ? ? - const: rockchip,rk3288
> 
>  ? ? ? - description: Asus Tinker board S
>  ? ? ? ? items:
>  ? ? ? ? ? - const: asus,rk3288-tinker-s
>  ? ? ? ? ? - const: rockchip,rk3288
> 
> What do you think? The discrepancy would be quite visiible.

I'd still consider that old naming a mistake from the past we should
heed from, instead of repeating it for the sake of consistency that's
already lacking left and right.

> >> +	compatible = "asus,rk3566-tinker-3s", "asus,rk3566-tinker-3", "rockchip,rk3566";
> > The compatibles should be as below instead, for the same reasons
> > as already explained above.
> >
> >    "asus,rk3566-tinker-board-3s", "asus,rk3566-tinker-board-3", "rockchip,rk3566"
> 
> Yes, whatever is decided for the compatible strings.
>
> > Though, perhaps it would be better to not include the "asus,rk3566-
> > tinker-board-3" part, because I think it's pretty much redundant.
> 
> My reasoning was that Tinker Board 3S is a superset of Tinker Board 3 
> (additional eMMC and headers).
> If someday some code is associated to the compatible string for Tinker 
> 3, than Tinker 3S should use it too, right? Unless we want to have the 
> possibility to ignore some Tinker3 code in Tinker 3S for some reason. 
> Then, it's better indeed that 3S doesn't use the Tinker 3 compatible 
> string. It seems we have more options with what you're suggesting.

You were right about having "asus,rk3566-tinker-board-3" there
as well originally, because that would allow us to possibly define
some specifics later that apply to both the 3 and 3S variants.

Just like "asus,rk3566-tinker-board-3" refines "rockchip,rk3566"
and makes it more specific, "asus,rk3566-tinker-board-3s" also does
the same to "asus,rk3566-tinker-board-3".



From michael.opdenacker at rootcommit.com  Fri Nov 14 06:31:17 2025
From: michael.opdenacker at rootcommit.com (Michael Opdenacker)
Date: Fri, 14 Nov 2025 14:31:17 +0000 (UTC)
Subject: [PATCH 2/2] arm64: dts: rockchip: add Tinkerboard 3 and 3S device
 tree
In-Reply-To: <3310785.5fSG56mABF@diego>
References: <20251111172003.2324525-1-michael.opdenacker@rootcommit.com>
 <20251111172003.2324525-3-michael.opdenacker@rootcommit.com>
 <3310785.5fSG56mABF@diego>
Message-ID: <8ad09a33-6464-4429-a58f-2769b78ada93@rootcommit.com>

Hi Heiko

Thanks a lot for the review!

On 11/13/25 23:35, Heiko St?bner wrote:
> Hi Michael,
>
> Am Dienstag, 11. November 2025, 18:20:23 Mitteleurop?ische Normalzeit schrieb michael.opdenacker at rootcommit.com:
>> From: Michael Opdenacker <michael.opdenacker at rootcommit.com>
>>
>> Add initial device tree support for Asus Tinkerboard 3 [1] and 3S [2],
>> which are SBCs based on the Rockchip 3566 SoC.
>>
>> The "3S" version ("S" for "storage") just adds a 16 GB eMMC
>> and a "mask ROM" DIP switch (to mask the eMMC and enter "Mask ROM"
>> mode for recovery) to the "3" version.
>>
>> This adds support for:
>> - Debug UART (/dev/ttyS2)
>> - SD card (/dev/mmcblk1)
>> - eMMC (/dev/mmcblk0, only on Tinkerboard 3S)
>> - I2C:
>>    - i2c0 (internal bus with a PMIC and regulators)
>>    - i2c2 (internal bus with an at24 eeprom and an RTC device)
>> - USB 2.0 ports
>> - 2 GPIO LEDS
>>
>> Link: https://tinker-board.asus.com/series/tinker-board-3.html [1]
>> Link: https://tinker-board.asus.com/series/tinker-board-3s.html [2]
>> Signed-off-by: Michael Opdenacker <michael.opdenacker at rootcommit.com>
>> ---
> please follow the DTS coding style
> https://docs.kernel.org/devicetree/bindings/dts-coding-style.html
Great, I was looking for such a document :)
>
>
>> +/ {
>> +	aliases {
>> +		serial2 = &uart2;
>> +		mmc1 = &sdmmc0;
>> +		i2c0 = &i2c0;
>> +		i2c2 = &i2c2;
> alphabetical property order
Fixed.
>
>
>> +	};
>> +
>> +	chosen {
>> +		stdout-path = "serial2:1500000n8";
>> +	};
>> +
>> +	vcc3v3_sys: regulator-3v3-vcc-sys {
>> +		compatible = "regulator-fixed";
>> +		regulator-name = "vcc3v3_sys";
>> +		regulator-always-on;
>> +		regulator-boot-on;
>> +		regulator-min-microvolt = <3300000>;
>> +		regulator-max-microvolt = <3300000>;
>> +		vin-supply = <&vcc5v0_sys>;
>> +	};
>> +
>> +	vcc5v0_sys: regulator-5v0-vcc-sys {
>> +		compatible = "regulator-fixed";
>> +		regulator-name = "vcc5v0_sys";
>> +		regulator-always-on;
>> +		regulator-boot-on;
>> +		regulator-min-microvolt = <5000000>;
>> +		regulator-max-microvolt = <5000000>;
>> +	};
>> +
>> +	vcc5v0_usb_host: regulator-5v0-vcc-usb-host {
>> +		compatible = "regulator-fixed";
>> +		enable-active-high;
>> +		gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
>> +		pinctrl-names = "default";
>> +		pinctrl-0 = <&usb_host_pwren_h>;
>> +		regulator-name = "vcc5v0_usb_host";
>> +		regulator-min-microvolt = <5000000>;
>> +		regulator-max-microvolt = <5000000>;
>> +		vin-supply = <&vcc5v0_sys>;
>> +	};
>> +
>> +	gpio_leds: gpio-leds {
> gpio-foo before regulator-bar
Done
>
>> +		compatible = "gpio-leds";
>> +
>> +		act-led {
>> +			gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>;
>> +			linux,default-trigger="mmc1";
>> +};
> missing indentation
Oops, fixed.
>
>> +
>> +		rsv-led {
>> +			gpios = <&gpio0 RK_PD6 GPIO_ACTIVE_HIGH>;
>> +			linux,default-trigger="none";
>> +		};
>> +	};
>> +};
>>
>>
>>> Heiko
>>>
>>>
>> +
>> +&uart2 {
> alphabetical ordering of phandles please (uart2 definitly somewhere after i2c0)
Indeed. Done.
>
>> +	status = "okay";
>> +};
>> +
>> +&i2c0 {
>> +	status = "okay";
>> +
>> +	rk809: pmic at 20 {
>> +		compatible = "rockchip,rk809";
>> +		reg = <0x20>;
>> +		assigned-clocks = <&cru I2S1_MCLKOUT_TX>;
>> +		assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>;
>> +		#clock-cells = <1>;
>> +		clocks = <&cru I2S1_MCLKOUT_TX>;
>> +		clock-names = "mclk";
>> +		clock-output-names = "rk809-clkout1", "rk809-clkout2";
>> +		interrupt-parent = <&gpio0>;
>> +		interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
>> +		pinctrl-names = "default";
>> +		pinctrl-0 = <&pmic_int_l>, <&i2s1m0_mclk>;
>> +		#sound-dai-cells = <0>;
>> +		system-power-controller;
>> +		wakeup-source;
>> +
>> +		vcc1-supply = <&vcc3v3_sys>;
>> +		vcc2-supply = <&vcc3v3_sys>;
>> +		vcc3-supply = <&vcc3v3_sys>;
>> +		vcc4-supply = <&vcc3v3_sys>;
>> +		vcc5-supply = <&vcc3v3_sys>;
>> +		vcc6-supply = <&vcc3v3_sys>;
>> +		vcc7-supply = <&vcc3v3_sys>;
>> +		vcc8-supply = <&vcc3v3_sys>;
>> +		vcc9-supply = <&vcc3v3_sys>;
>> +
>> +		regulators {
>> +			vcc_1v8: DCDC_REG5 {
>> +				regulator-name = "vcc_1v8";
>> +				regulator-always-on;
>> +				regulator-boot-on;
>> +				regulator-min-microvolt = <1800000>;
>> +				regulator-max-microvolt = <1800000>;
>> +
>> +				regulator-state-mem {
>> +					regulator-off-in-suspend;
>> +				};
>> +			};
>> +
>> +			vcc3v3_sd: SWITCH_REG2 {
>> +				regulator-name = "vcc3v3_sd";
>> +				regulator-always-on;
>> +				regulator-boot-on;
>> +
>> +				regulator-state-mem {
>> +					regulator-off-in-suspend;
>> +				};
>> +			};
>> +
>> +			vccio_sd: LDO_REG5 {
>> +				regulator-name = "vccio_sd";
>> +				regulator-always-on;
>> +				regulator-boot-on;
>> +				regulator-min-microvolt = <1800000>;
>> +				regulator-max-microvolt = <3300000>;
>> +
>> +				regulator-state-mem {
>> +					regulator-off-in-suspend;
>> +				};
>> +			};
>> +
>> +			vcc_3v3: SWITCH_REG1 {
>> +				regulator-name = "vcc_3v3";
>> +				regulator-always-on;
>> +				regulator-boot-on;
>> +
>> +				regulator-state-mem {
>> +					regulator-off-in-suspend;
>> +				};
>> +			};
>> +		};
>> +	};
>> +
>> +	vdd_cpu: regulator at 40 {
> you probably need &cpu0 phandles to set this regulator-supply?


Oh, you're the maintainer on this one :)
Good catch. I was imitating the Orange Pi 3B DT, and since the board 
seemed to boot fine, I didn't pay attention to the fact that vdd_cpu was 
needed elsewhere.
Fixed.

>
>> +		compatible = "silergy,syr827";
>> +		reg = <0x40>;
>> +		fcs,suspend-voltage-selector = <1>;
>> +		regulator-name = "vdd_cpu";
>> +		regulator-always-on;
>> +		regulator-boot-on;
>> +		regulator-min-microvolt = <830000>;
>> +		regulator-max-microvolt = <1200000>;
>> +		regulator-ramp-delay = <2300>;
>> +		vin-supply = <&vcc3v3_sys>;
>> +
>> +		regulator-state-mem {
>> +			regulator-off-in-suspend;
>> +		};
>> +	};
>> +};
>> +
>> +&i2c2 {
>> +	status = "okay";
>> +
>> +	m24c08 at 50 {
> I guess eeprom at 50 ?

Indeed. Fixed too.
Thanks again,
Michael.

-- 
Michael Opdenacker
Root Commit
Embedded Linux Training and Consulting
https://rootcommit.com



From devnull+michael.riesch.collabora.com at kernel.org  Fri Nov 14 07:20:24 2025
From: devnull+michael.riesch.collabora.com at kernel.org (Michael Riesch via B4 Relay)
Date: Fri, 14 Nov 2025 16:20:24 +0100
Subject: [PATCH v15 13/14] arm64: dts: rockchip: add vicap node to rk356x
In-Reply-To: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
References: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
Message-ID: <20240220-rk3568-vicap-v15-13-8f4915ee365d@collabora.com>

From: Michael Riesch <michael.riesch at collabora.com>

Add the device tree node for the RK356x Video Capture (VICAP) unit.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
Signed-off-by: Michael Riesch <michael.riesch at collabora.com>
---
 arch/arm64/boot/dts/rockchip/rk356x-base.dtsi | 44 +++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
index fd2214b6fad4..e0e4dc85a3a9 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
@@ -564,6 +564,50 @@ gpu: gpu at fde60000 {
 		status = "disabled";
 	};
 
+	vicap: video-capture at fdfe0000 {
+		compatible = "rockchip,rk3568-vicap";
+		reg = <0x0 0xfdfe0000 0x0 0x200>;
+		interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
+		assigned-clocks = <&cru DCLK_VICAP>;
+		assigned-clock-rates = <300000000>;
+		clocks = <&cru ACLK_VICAP>, <&cru HCLK_VICAP>,
+			 <&cru DCLK_VICAP>, <&cru ICLK_VICAP_G>;
+		clock-names = "aclk", "hclk", "dclk", "iclk";
+		iommus = <&vicap_mmu>;
+		power-domains = <&power RK3568_PD_VI>;
+		resets = <&cru SRST_A_VICAP>, <&cru SRST_H_VICAP>,
+			 <&cru SRST_D_VICAP>, <&cru SRST_P_VICAP>,
+			 <&cru SRST_I_VICAP>;
+		reset-names = "arst", "hrst", "drst", "prst", "irst";
+		rockchip,grf = <&grf>;
+		status = "disabled";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			vicap_dvp: port at 0 {
+				reg = <0>;
+			};
+
+			vicap_mipi: port at 1 {
+				reg = <1>;
+			};
+		};
+	};
+
+	vicap_mmu: iommu at fdfe0800 {
+		compatible = "rockchip,rk3568-iommu";
+		reg = <0x0 0xfdfe0800 0x0 0x100>;
+		interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru ACLK_VICAP>, <&cru HCLK_VICAP>;
+		clock-names = "aclk", "iface";
+		#iommu-cells = <0>;
+		power-domains = <&power RK3568_PD_VI>;
+		rockchip,disable-mmu-reset;
+		status = "disabled";
+	};
+
 	vpu: video-codec at fdea0400 {
 		compatible = "rockchip,rk3568-vpu";
 		reg = <0x0 0xfdea0000 0x0 0x800>;

-- 
2.39.5




From devnull+michael.riesch.collabora.com at kernel.org  Fri Nov 14 07:20:14 2025
From: devnull+michael.riesch.collabora.com at kernel.org (Michael Riesch via B4 Relay)
Date: Fri, 14 Nov 2025 16:20:14 +0100
Subject: [PATCH v15 03/14] media: dt-bindings: add rockchip px30 vip
In-Reply-To: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
References: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
Message-ID: <20240220-rk3568-vicap-v15-3-8f4915ee365d@collabora.com>

From: Mehdi Djait <mehdi.djait at bootlin.com>

Add documentation for the Rockchip PX30 Video Input Processor (VIP).

Signed-off-by: Mehdi Djait <mehdi.djait at bootlin.com>
[revised description]
Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
Signed-off-by: Michael Riesch <michael.riesch at collabora.com>
---
 .../bindings/media/rockchip,px30-vip.yaml          | 124 +++++++++++++++++++++
 MAINTAINERS                                        |   1 +
 2 files changed, 125 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml b/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml
new file mode 100644
index 000000000000..cc08ce94bef7
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml
@@ -0,0 +1,124 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/rockchip,px30-vip.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip PX30 Video Input Processor (VIP)
+
+maintainers:
+  - Mehdi Djait <mehdi.djait at linux.intel.com>
+  - Michael Riesch <michael.riesch at collabora.com>
+
+description:
+  The Rockchip PX30 Video Input Processor (VIP) receives the data from a camera
+  sensor or CCIR656 encoder and transfers it into system main memory by AXI bus.
+
+properties:
+  compatible:
+    const: rockchip,px30-vip
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: ACLK
+      - description: HCLK
+      - description: PCLK
+
+  clock-names:
+    items:
+      - const: aclk
+      - const: hclk
+      - const: pclk
+
+  resets:
+    items:
+      - description: AXI
+      - description: AHB
+      - description: PCLK IN
+
+  reset-names:
+    items:
+      - const: axi
+      - const: ahb
+      - const: pclkin
+
+  power-domains:
+    maxItems: 1
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port at 0:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description: input port on the parallel interface
+
+        properties:
+          endpoint:
+            $ref: video-interfaces.yaml#
+            unevaluatedProperties: false
+
+            properties:
+              bus-type:
+                enum:
+                  - 5 # MEDIA_BUS_TYPE_PARALLEL
+                  - 6 # MEDIA_BUS_TYPE_BT656
+
+            required:
+              - bus-type
+
+    required:
+      - port at 0
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/px30-cru.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/media/video-interfaces.h>
+    #include <dt-bindings/power/px30-power.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        video-capture at ff490000 {
+            compatible = "rockchip,px30-vip";
+            reg = <0x0 0xff490000 0x0 0x200>;
+            interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+            clocks = <&cru ACLK_CIF>, <&cru HCLK_CIF>, <&cru PCLK_CIF>;
+            clock-names = "aclk", "hclk", "pclk";
+            power-domains = <&power PX30_PD_VI>;
+            resets = <&cru SRST_CIF_A>, <&cru SRST_CIF_H>, <&cru SRST_CIF_PCLKIN>;
+            reset-names = "axi", "ahb", "pclkin";
+
+            ports {
+                #address-cells = <1>;
+                #size-cells = <0>;
+
+                port at 0 {
+                    reg = <0>;
+
+                    cif_in: endpoint {
+                        remote-endpoint = <&tw9900_out>;
+                        bus-type = <MEDIA_BUS_TYPE_BT656>;
+                    };
+                };
+            };
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 2e1f959bb5f4..3fa175e2b61f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22248,6 +22248,7 @@ M:	Michael Riesch <michael.riesch at collabora.com>
 L:	linux-media at vger.kernel.org
 S:	Maintained
 F:	Documentation/admin-guide/media/rkcif*
+F:	Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml
 
 ROCKCHIP CRYPTO DRIVERS
 M:	Corentin Labbe <clabbe at baylibre.com>

-- 
2.39.5




From devnull+michael.riesch.collabora.com at kernel.org  Fri Nov 14 07:20:11 2025
From: devnull+michael.riesch.collabora.com at kernel.org (Michael Riesch via B4 Relay)
Date: Fri, 14 Nov 2025 16:20:11 +0100
Subject: [PATCH v15 00/14] media: rockchip: add a driver for the rockchip
 camera interface
Message-ID: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>

Habidere,

This series introduces support for the Rockchip Camera Interface (CIF),
which is featured in many Rockchip SoCs in different variations.
The series has now been around for a while and has received many comments
and reviews. Thus, it should be ready for mainline by now.

The last issue we discussed (see thread to v14, link below) was the
necessary integration of a mux subdevice, as the MIPI CSI-2 data can
be passed to the ISP and/or to the VICAP on RK3568. In order to avoid
any uAPI breakage, the MIPI CSI-2 receiver support has been removed in v15
(following an off-list discussion with Sakari).

Therefore, the v15 of the series adds a media controller centric V4L2
device driver for the Rockchip CIF with
 - support for the PX30 VIP (not tested, though, due to the lack of HW)
 - support for the RK3568 VICAP, including
    - capturing frames from the DVP
    - capturing frames from the MIPI CSI-2 receiver
 - abstraction for the ping-pong scheme to allow for future extensions
 - abstraction for the INTERFACE and CROP parts to allow for future
   extensions
 - initial support for different virtual channels (not tested, though,
   due to the lack of HW)

Apart from that, there are no changes compared to v14.

Looking forward to your comments!

To: Mehdi Djait <mehdi.djait at linux.intel.com>
To: Maxime Chevallier <maxime.chevallier at bootlin.com>
To: Th?o Lebrun <theo.lebrun at bootlin.com>
To: Thomas Petazzoni <thomas.petazzoni at bootlin.com>
To: Gerald Loacker <gerald.loacker at wolfvision.net>
To: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
To: Markus Elfring <Markus.Elfring at web.de>
To: Sakari Ailus <sakari.ailus at iki.fi>
To: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
To: Mauro Carvalho Chehab <mchehab at kernel.org>
To: Rob Herring <robh+dt at kernel.org>
To: Krzysztof Kozlowski <krzk+dt at kernel.org>
To: Conor Dooley <conor+dt at kernel.org>
To: Heiko Stuebner <heiko at sntech.de>
To: Kever Yang <kever.yang at rock-chips.com>
To: Nicolas Dufresne <nicolas.dufresne at collabora.com>
To: Sebastian Reichel <sebastian.reichel at collabora.com>
To: Collabora Kernel Team <kernel at collabora.com>
To: Paul Kocialkowski <paulk at sys-base.io>
To: Alexander Shiyan <eagle.alexander923 at gmail.com>
To: Val Packett <val at packett.cool>
To: Rob Herring <robh at kernel.org>
To: Philipp Zabel <p.zabel at pengutronix.de>
Cc: linux-media at vger.kernel.org
Cc: devicetree at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-rockchip at lists.infradead.org
Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
Signed-off-by: Michael Riesch <michael.riesch at collabora.com>

Changes in v15:
- dropped everything related to MIPI CSI-2 receiver
- Link to v14: https://lore.kernel.org/r/20240220-rk3568-vicap-v14-0-b38b6da0fc80 at collabora.com

Changes in v14:
- rkcsi: fixed invalid format handling in _set_fmt() (v4l2-compliance)
- rkcif-interface: fixed crop, reset crop at source when sink format
  is changed (v4l2-compliance)
- rebased onto media-committers/next
- Link to v13: https://lore.kernel.org/r/20240220-rk3568-vicap-v13-0-da164b4918fe at collabora.com

Changes in v13:
- fixed interrupt names in CSI-2 reciever bindings example (Rob's bot)
- revised Radxa Camera 8M device tree overlay
- Link to v12: https://lore.kernel.org/r/20240220-rk3568-vicap-v12-0-c6dbece6bb98 at collabora.com

Changes in v12:
- added Radxa Camera 8M device tree overlay
- rebased onto v6.18-rc1
- fixed IOMMU pagefaults caused by wrong VLW (Mehdi)
- fixed indentation of register defines in -regs.h (Sakari)
- renamed CSI-2 receiver interrupts (Rob)
- added MEDIA_BUS_TYPE_* as comments in DT bindings (Bryan)
- added newline in rkcif-dev.c (Bryan)
- Link to v11: https://lore.kernel.org/r/20240220-rk3568-vicap-v11-0-af0eada54e5d at collabora.com

Changes in v11:
- rkcif: split large driver patch (6/13 of v10) into smaller
  patches (6-11/17 of v11) (Bryan)
- rkcsi: replaced devm_reset_control_array_get_exclusive with 
  devm_reset_control_get_exclusive (Philipp)
- Link to v10: https://lore.kernel.org/r/20240220-rk3568-vicap-v10-0-62d8a7b209b4 at collabora.com

Changes in v10:
- rkcsi: fixed error handling in rkcsi_start (Bryan)
- rkcsi: fixed interrupt references in device tree and bindings
  (Rob's bot)
- added missing call to rkcif_mipi_stop_streaming from rkcif_mipi_isr
  (Mehdi)
- renamed remaining instances "cif_" -> "rkcif_" in functions
- Link to v9: https://lore.kernel.org/r/20240220-rk3568-vicap-v9-0-ace1e5cc4a82 at collabora.com

Changes in v9:
- added compatible for RK3588 MIPI CSI-2 receiver, thus dropped
  Krzysztof's R-b
- added interrupts to rkcsi DT binding and RK356x DT
- added variant specific callback to rkcif-capture-mipi that puts
  together the CTRL0 register content (which varies between RK3568
  and RK3588)
- fixed v4l2_fill_pixfmt_mp() return value handling (Mehdi)
- Link to v8: https://lore.kernel.org/r/20240220-rk3568-vicap-v8-0-9d9cbc4b524d at collabora.com

Changes in v8:
- rebased onto v6.16-rc1
- fixed RKCIF_MIPI_MAX value in rkcif-common.h
- fixed rkcsi Kconfig (kernel test robot)
- sorted rkcsi DT bindings document properly, completed example
  (Krzysztof)
- squashed the defconfig patches (Krzysztof), dropped Bryan's R-b
- Link to v7: https://lore.kernel.org/r/20240220-rk3568-vicap-v7-0-7581fd96a33a at collabora.com

Changes in v7:
- moved MIPI CSI-2 receiver driver into separate directory (Laurent)
- rkcsi: fixed return values (Bryan)
- rkcsi: fixed v4l2_get_link_freq to use pad instead of control
  handler (Sakari)
- rkcsi: added data-lanes property (Mehdi)
- rkcif: fixed formatting (Bryan)
- fixed "int" -> "unsigned int" in all for loops (Sakari)
- rkcif-stream: fixed minimum number of required buffers (Mehdi)
- rkcif-stream: used guards for the spinlock (Markus and Mehdi)
- rkcif-stream: made driver less noisy with dev_dbg (Mehdi)
- rkcif-stream: fixed issues detected by v4l2-compliance (Mehdi)
- rkcif-dvp-capture: fixed return value propagation in _register()
  (Mehdi)
- removed stray "phy-names" from required properties (Rob's bot)
- Link to v6: https://lore.kernel.org/r/20240220-rk3568-vicap-v6-0-d2f5fbee1551 at collabora.com

Changes in v6:
- rebased onto v6.15-rc1
- renamed "MIPI CSI HOST" -> "MIPI CSI RECEIVER" (Laurent)
- s/@wolfvision.net/@collabora.com where appropriate
- renamed DVP delay property and moved it to the endpoint (Sakari)
- implemented DT review comments (Krzysztof and Sakari)
- implemented driver review comments (Sakari)
- fixed issues raised by media-ci (yet again)
- added documentation including a RK3568 topology (new patch 1)
  (Sakari)
- added patch that enables rkcif in the defconfig (new patch 9)
- Link to v5: https://lore.kernel.org/r/20250306-v6-8-topic-rk3568-vicap-v5-0-f02152534f3c at wolfvision.net

Changes in v5:
- fixed issues raised by media-ci
- fixed dt bindings (comments by Rob and Sakari)
- fixed probe on systems with no DVP in DT (comment by Alexander)
- fixed error path in register offset calculation
- split off MIPI CSI host driver into separate module (comment
  by Mehdi)
- added MODULE_DEVICE_TABLE() for both drivers (comment by Mehdi)
- Link to v4: https://lore.kernel.org/r/20250219-v6-8-topic-rk3568-vicap-v4-0-e906600ae3b0 at wolfvision.net

Changes in v4:
- added support for the MIPI CSI-2 receiver (new patches 4, 6, 7, 10)
- fixed asserts on stream stop
- fixed register address lookup
- fixed link validiation callback
- fixed issues raised by Rob's bot, kernel test robot, and media-ci
- Link to v3: https://lore.kernel.org/r/20250206-v6-8-topic-rk3568-vicap-v3-0-69d1f19e5c40 at wolfvision.net

Changes in v3:
- renamed the driver "cif" -> "rkcif"
- rebased onto v6.14-rc1
- abstracted the generic INTERFACE+CROP part
- addressed comments by Rob and Sakari
- added V4L2 MPLANE formats to DVP
- added patch that enables the RK3568 VICAP DVP on PF5 IO Expander
- fixed formatting issues raised by media-ci bot
- Link to v2: https://lore.kernel.org/r/20241217-v6-8-topic-rk3568-vicap-v2-0-b1d488fcc0d3 at wolfvision.net

Changes in v2:
- merged with Mehdi's v13
- refactored the complete driver towards a media controller centric driver
- abstracted the generic ping-pong stream (can be used for DVP as well as for CSI-2)
- switched to MPLANE API
- added support for notifications
- Link to v1: https://lore.kernel.org/r/20240220-v6-8-topic-rk3568-vicap-v1-0-2680a1fa640b at wolfvision.net

---
Mehdi Djait (2):
      media: dt-bindings: add rockchip px30 vip
      arm64: dts: rockchip: add the vip node to px30

Michael Riesch (12):
      Documentation: admin-guide: media: add rockchip camera interface
      media: dt-bindings: video-interfaces: add defines for sampling modes
      media: dt-bindings: add rockchip rk3568 vicap
      media: rockchip: add driver for the rockchip camera interface
      media: rockchip: rkcif: add abstraction for interface and crop blocks
      media: rockchip: rkcif: add abstraction for dma blocks
      media: rockchip: rkcif: add support for px30 vip dvp capture
      media: rockchip: rkcif: add support for rk3568 vicap dvp capture
      media: rockchip: rkcif: add support for rk3568 vicap mipi capture
      arm64: defconfig: enable rockchip camera interface
      arm64: dts: rockchip: add vicap node to rk356x
      arm64: dts: rockchip: enable vicap dvp on wolfvision pf5 io expander

 .../admin-guide/media/rkcif-rk3568-vicap.dot       |   8 +
 Documentation/admin-guide/media/rkcif.rst          |  79 ++
 Documentation/admin-guide/media/v4l-drivers.rst    |   1 +
 .../bindings/media/rockchip,px30-vip.yaml          | 124 +++
 .../bindings/media/rockchip,rk3568-vicap.yaml      | 172 ++++
 MAINTAINERS                                        |  10 +
 arch/arm64/boot/dts/rockchip/px30.dtsi             |  12 +
 .../rk3568-wolfvision-pf5-io-expander.dtso         |  20 +
 arch/arm64/boot/dts/rockchip/rk356x-base.dtsi      |  44 ++
 arch/arm64/configs/defconfig                       |   1 +
 drivers/media/platform/rockchip/Kconfig            |   1 +
 drivers/media/platform/rockchip/Makefile           |   1 +
 drivers/media/platform/rockchip/rkcif/Kconfig      |  18 +
 drivers/media/platform/rockchip/rkcif/Makefile     |   8 +
 .../platform/rockchip/rkcif/rkcif-capture-dvp.c    | 865 +++++++++++++++++++++
 .../platform/rockchip/rkcif/rkcif-capture-dvp.h    |  25 +
 .../platform/rockchip/rkcif/rkcif-capture-mipi.c   | 777 ++++++++++++++++++
 .../platform/rockchip/rkcif/rkcif-capture-mipi.h   |  23 +
 .../media/platform/rockchip/rkcif/rkcif-common.h   | 250 ++++++
 drivers/media/platform/rockchip/rkcif/rkcif-dev.c  | 303 ++++++++
 .../platform/rockchip/rkcif/rkcif-interface.c      | 442 +++++++++++
 .../platform/rockchip/rkcif/rkcif-interface.h      |  31 +
 drivers/media/platform/rockchip/rkcif/rkcif-regs.h | 153 ++++
 .../media/platform/rockchip/rkcif/rkcif-stream.c   | 638 +++++++++++++++
 .../media/platform/rockchip/rkcif/rkcif-stream.h   |  32 +
 include/dt-bindings/media/video-interfaces.h       |   4 +
 26 files changed, 4042 insertions(+)
---
base-commit: d363bdfa0ec6b19a4f40b572cec70430d5b13ad6
change-id: 20240220-rk3568-vicap-b9b3f9925f44

Best regards,
-- 
Michael Riesch <michael.riesch at collabora.com>




From devnull+michael.riesch.collabora.com at kernel.org  Fri Nov 14 07:20:16 2025
From: devnull+michael.riesch.collabora.com at kernel.org (Michael Riesch via B4 Relay)
Date: Fri, 14 Nov 2025 16:20:16 +0100
Subject: [PATCH v15 05/14] media: rockchip: add driver for the rockchip
 camera interface
In-Reply-To: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
References: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
Message-ID: <20240220-rk3568-vicap-v15-5-8f4915ee365d@collabora.com>

From: Michael Riesch <michael.riesch at collabora.com>

Add the skeleton for a media controller centric V4L2 driver for the
Rockchip Camera Interface (CIF).
The skeleton features support for the PX30 Video Input Processor (VIP)
and the RK3568 Video Capture (VICAP) unit.

Tested-by: Gerald Loacker <gerald.loacker at wolfvision.net>
Reviewed-by: Gerald Loacker <gerald.loacker at wolfvision.net>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
Reviewed-by: Mehdi Djait <mehdi.djait at linux.intel.com>
Signed-off-by: Michael Riesch <michael.riesch at collabora.com>
---
 MAINTAINERS                                        |   1 +
 drivers/media/platform/rockchip/Kconfig            |   1 +
 drivers/media/platform/rockchip/Makefile           |   1 +
 drivers/media/platform/rockchip/rkcif/Kconfig      |  18 ++
 drivers/media/platform/rockchip/rkcif/Makefile     |   4 +
 .../media/platform/rockchip/rkcif/rkcif-common.h   |  55 +++++
 drivers/media/platform/rockchip/rkcif/rkcif-dev.c  | 262 +++++++++++++++++++++
 7 files changed, 342 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 0a3959696154..8d00d6d4b5bf 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22250,6 +22250,7 @@ S:	Maintained
 F:	Documentation/admin-guide/media/rkcif*
 F:	Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml
 F:	Documentation/devicetree/bindings/media/rockchip,rk3568-vicap.yaml
+F:	drivers/media/platform/rockchip/rkcif/
 
 ROCKCHIP CRYPTO DRIVERS
 M:	Corentin Labbe <clabbe at baylibre.com>
diff --git a/drivers/media/platform/rockchip/Kconfig b/drivers/media/platform/rockchip/Kconfig
index 9bbeec4996aa..ba401d32f01b 100644
--- a/drivers/media/platform/rockchip/Kconfig
+++ b/drivers/media/platform/rockchip/Kconfig
@@ -3,5 +3,6 @@
 comment "Rockchip media platform drivers"
 
 source "drivers/media/platform/rockchip/rga/Kconfig"
+source "drivers/media/platform/rockchip/rkcif/Kconfig"
 source "drivers/media/platform/rockchip/rkisp1/Kconfig"
 source "drivers/media/platform/rockchip/rkvdec/Kconfig"
diff --git a/drivers/media/platform/rockchip/Makefile b/drivers/media/platform/rockchip/Makefile
index 286dc5c53f7e..0e0b2cbbd4bd 100644
--- a/drivers/media/platform/rockchip/Makefile
+++ b/drivers/media/platform/rockchip/Makefile
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-y += rga/
+obj-y += rkcif/
 obj-y += rkisp1/
 obj-y += rkvdec/
diff --git a/drivers/media/platform/rockchip/rkcif/Kconfig b/drivers/media/platform/rockchip/rkcif/Kconfig
new file mode 100644
index 000000000000..efd82ac35bd8
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkcif/Kconfig
@@ -0,0 +1,18 @@
+config VIDEO_ROCKCHIP_CIF
+	tristate "Rockchip Camera Interface (CIF)"
+	depends on VIDEO_DEV
+	depends on ARCH_ROCKCHIP || COMPILE_TEST
+	depends on V4L_PLATFORM_DRIVERS
+	depends on PM && COMMON_CLK
+	select MEDIA_CONTROLLER
+	select VIDEOBUF2_DMA_CONTIG
+	select V4L2_FWNODE
+	select VIDEO_V4L2_SUBDEV_API
+	help
+	  This is a driver for Rockchip Camera Interface (CIF). It is featured
+	  in many Rockchips SoCs in different variations, such as the PX30
+	  Video Input Processor (VIP, one Digital Video Port (DVP)) or the
+	  RK3568 Video Capture (VICAP, one DVP, one MIPI CSI-2 receiver) unit.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called rockchip-cif.
diff --git a/drivers/media/platform/rockchip/rkcif/Makefile b/drivers/media/platform/rockchip/rkcif/Makefile
new file mode 100644
index 000000000000..c6837ed2f65c
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkcif/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_VIDEO_ROCKCHIP_CIF) += rockchip-cif.o
+
+rockchip-cif-objs += rkcif-dev.o
diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-common.h b/drivers/media/platform/rockchip/rkcif/rkcif-common.h
new file mode 100644
index 000000000000..b456a56b5ac4
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkcif/rkcif-common.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Rockchip Camera Interface (CIF) Driver
+ *
+ * Copyright (C) 2018 Rockchip Electronics Co., Ltd.
+ * Copyright (C) 2023 Mehdi Djait <mehdi.djait at bootlin.com>
+ * Copyright (C) 2025 Michael Riesch <michael.riesch at wolfvision.net>
+ * Copyright (C) 2025 Collabora, Ltd.
+ */
+
+#ifndef _RKCIF_COMMON_H
+#define _RKCIF_COMMON_H
+
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/regmap.h>
+
+#include <media/media-device.h>
+#include <media/media-entity.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-mc.h>
+#include <media/v4l2-subdev.h>
+#include <media/videobuf2-v4l2.h>
+
+#define RKCIF_DRIVER_NAME "rockchip-cif"
+#define RKCIF_CLK_MAX	  4
+
+struct rkcif_remote {
+	struct v4l2_async_connection async_conn;
+	struct v4l2_subdev *sd;
+};
+
+struct rkcif_match_data {
+	const char *const *clks;
+	unsigned int clks_num;
+};
+
+struct rkcif_device {
+	struct device *dev;
+
+	const struct rkcif_match_data *match_data;
+	struct clk_bulk_data clks[RKCIF_CLK_MAX];
+	unsigned int clks_num;
+	struct regmap *grf;
+	struct reset_control *reset;
+	void __iomem *base_addr;
+
+	struct media_device media_dev;
+	struct v4l2_device v4l2_dev;
+	struct v4l2_async_notifier notifier;
+};
+
+#endif
diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-dev.c b/drivers/media/platform/rockchip/rkcif/rkcif-dev.c
new file mode 100644
index 000000000000..9215dbe90353
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkcif/rkcif-dev.c
@@ -0,0 +1,262 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip Camera Interface (CIF) Driver
+ *
+ * Copyright (C) 2018 Rockchip Electronics Co., Ltd.
+ * Copyright (C) 2020 Maxime Chevallier <maxime.chevallier at bootlin.com>
+ * Copyright (C) 2023 Mehdi Djait <mehdi.djait at bootlin.com>
+ * Copyright (C) 2025 Michael Riesch <michael.riesch at wolfvision.net>
+ * Copyright (C) 2025 Collabora, Ltd.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
+#include <linux/of_platform.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-mc.h>
+
+#include "rkcif-common.h"
+
+static const char *const px30_vip_clks[] = {
+	"aclk",
+	"hclk",
+	"pclk",
+};
+
+static const struct rkcif_match_data px30_vip_match_data = {
+	.clks = px30_vip_clks,
+	.clks_num = ARRAY_SIZE(px30_vip_clks),
+};
+
+static const char *const rk3568_vicap_clks[] = {
+	"aclk",
+	"hclk",
+	"dclk",
+	"iclk",
+};
+
+static const struct rkcif_match_data rk3568_vicap_match_data = {
+	.clks = rk3568_vicap_clks,
+	.clks_num = ARRAY_SIZE(rk3568_vicap_clks),
+};
+
+static const struct of_device_id rkcif_plat_of_match[] = {
+	{
+		.compatible = "rockchip,px30-vip",
+		.data = &px30_vip_match_data,
+	},
+	{
+		.compatible = "rockchip,rk3568-vicap",
+		.data = &rk3568_vicap_match_data,
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(of, rkcif_plat_of_match);
+
+static int rkcif_register(struct rkcif_device *rkcif)
+{
+	return 0;
+}
+
+static void rkcif_unregister(struct rkcif_device *rkcif)
+{
+}
+
+static int rkcif_notifier_bound(struct v4l2_async_notifier *notifier,
+				struct v4l2_subdev *sd,
+				struct v4l2_async_connection *asd)
+{
+	struct rkcif_remote *remote =
+		container_of(asd, struct rkcif_remote, async_conn);
+
+	remote->sd = sd;
+
+	return 0;
+}
+
+static int rkcif_notifier_complete(struct v4l2_async_notifier *notifier)
+{
+	struct rkcif_device *rkcif =
+		container_of(notifier, struct rkcif_device, notifier);
+
+	return v4l2_device_register_subdev_nodes(&rkcif->v4l2_dev);
+}
+
+static const struct v4l2_async_notifier_operations rkcif_notifier_ops = {
+	.bound = rkcif_notifier_bound,
+	.complete = rkcif_notifier_complete,
+};
+
+static irqreturn_t rkcif_isr(int irq, void *ctx)
+{
+	irqreturn_t ret = IRQ_NONE;
+
+	return ret;
+}
+
+static int rkcif_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct rkcif_device *rkcif;
+	int ret, irq;
+
+	rkcif = devm_kzalloc(dev, sizeof(*rkcif), GFP_KERNEL);
+	if (!rkcif)
+		return -ENOMEM;
+
+	rkcif->match_data = of_device_get_match_data(dev);
+	if (!rkcif->match_data)
+		return -ENODEV;
+
+	dev_set_drvdata(dev, rkcif);
+	rkcif->dev = dev;
+
+	rkcif->base_addr = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(rkcif->base_addr))
+		return PTR_ERR(rkcif->base_addr);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
+
+	ret = devm_request_irq(dev, irq, rkcif_isr, IRQF_SHARED,
+			       dev_driver_string(dev), dev);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to request irq\n");
+
+	if (rkcif->match_data->clks_num > RKCIF_CLK_MAX)
+		return dev_err_probe(dev, -EINVAL, "invalid number of clocks\n");
+
+	rkcif->clks_num = rkcif->match_data->clks_num;
+	for (unsigned int i = 0; i < rkcif->clks_num; i++)
+		rkcif->clks[i].id = rkcif->match_data->clks[i];
+	ret = devm_clk_bulk_get(dev, rkcif->clks_num, rkcif->clks);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to get clocks\n");
+
+	rkcif->reset = devm_reset_control_array_get_exclusive(dev);
+	if (IS_ERR(rkcif->reset))
+		return PTR_ERR(rkcif->reset);
+
+	rkcif->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
+						     "rockchip,grf");
+	if (IS_ERR(rkcif->grf))
+		rkcif->grf = NULL;
+
+	pm_runtime_enable(&pdev->dev);
+
+	rkcif->media_dev.dev = dev;
+	strscpy(rkcif->media_dev.model, RKCIF_DRIVER_NAME,
+		sizeof(rkcif->media_dev.model));
+	media_device_init(&rkcif->media_dev);
+
+	rkcif->v4l2_dev.mdev = &rkcif->media_dev;
+	ret = v4l2_device_register(dev, &rkcif->v4l2_dev);
+	if (ret)
+		goto err_media_dev_cleanup;
+
+	ret = media_device_register(&rkcif->media_dev);
+	if (ret < 0) {
+		dev_err(dev, "failed to register media device: %d\n", ret);
+		goto err_v4l2_dev_unregister;
+	}
+
+	v4l2_async_nf_init(&rkcif->notifier, &rkcif->v4l2_dev);
+	rkcif->notifier.ops = &rkcif_notifier_ops;
+
+	ret = rkcif_register(rkcif);
+	if (ret) {
+		dev_err(dev, "failed to register media entities: %d\n", ret);
+		goto err_notifier_cleanup;
+	}
+
+	ret = v4l2_async_nf_register(&rkcif->notifier);
+	if (ret)
+		goto err_rkcif_unregister;
+
+	return 0;
+
+err_rkcif_unregister:
+	rkcif_unregister(rkcif);
+err_notifier_cleanup:
+	v4l2_async_nf_cleanup(&rkcif->notifier);
+	media_device_unregister(&rkcif->media_dev);
+err_v4l2_dev_unregister:
+	v4l2_device_unregister(&rkcif->v4l2_dev);
+err_media_dev_cleanup:
+	media_device_cleanup(&rkcif->media_dev);
+	pm_runtime_disable(&pdev->dev);
+	return ret;
+}
+
+static void rkcif_remove(struct platform_device *pdev)
+{
+	struct rkcif_device *rkcif = platform_get_drvdata(pdev);
+
+	v4l2_async_nf_unregister(&rkcif->notifier);
+	rkcif_unregister(rkcif);
+	v4l2_async_nf_cleanup(&rkcif->notifier);
+	media_device_unregister(&rkcif->media_dev);
+	v4l2_device_unregister(&rkcif->v4l2_dev);
+	media_device_cleanup(&rkcif->media_dev);
+	pm_runtime_disable(&pdev->dev);
+}
+
+static int rkcif_runtime_suspend(struct device *dev)
+{
+	struct rkcif_device *rkcif = dev_get_drvdata(dev);
+
+	/*
+	 * Reset CIF (CRU, DMA, FIFOs) to allow a clean resume.
+	 * Since this resets the IOMMU too, we cannot issue this reset when
+	 * resuming.
+	 */
+	reset_control_assert(rkcif->reset);
+	udelay(5);
+	reset_control_deassert(rkcif->reset);
+
+	clk_bulk_disable_unprepare(rkcif->clks_num, rkcif->clks);
+
+	return 0;
+}
+
+static int rkcif_runtime_resume(struct device *dev)
+{
+	struct rkcif_device *rkcif = dev_get_drvdata(dev);
+	int ret;
+
+	ret = clk_bulk_prepare_enable(rkcif->clks_num, rkcif->clks);
+	if (ret) {
+		dev_err(dev, "failed to enable clocks\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct dev_pm_ops rkcif_plat_pm_ops = {
+	.runtime_suspend = rkcif_runtime_suspend,
+	.runtime_resume = rkcif_runtime_resume,
+};
+
+static struct platform_driver rkcif_plat_drv = {
+	.driver = {
+		   .name = RKCIF_DRIVER_NAME,
+		   .of_match_table = rkcif_plat_of_match,
+		   .pm = &rkcif_plat_pm_ops,
+	},
+	.probe = rkcif_probe,
+	.remove = rkcif_remove,
+};
+module_platform_driver(rkcif_plat_drv);
+
+MODULE_DESCRIPTION("Rockchip Camera Interface (CIF) platform driver");
+MODULE_LICENSE("GPL");

-- 
2.39.5




From devnull+michael.riesch.collabora.com at kernel.org  Fri Nov 14 07:20:13 2025
From: devnull+michael.riesch.collabora.com at kernel.org (Michael Riesch via B4 Relay)
Date: Fri, 14 Nov 2025 16:20:13 +0100
Subject: [PATCH v15 02/14] media: dt-bindings: video-interfaces: add
 defines for sampling modes
In-Reply-To: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
References: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
Message-ID: <20240220-rk3568-vicap-v15-2-8f4915ee365d@collabora.com>

From: Michael Riesch <michael.riesch at collabora.com>

Add defines for the pixel clock sampling modes (rising edge, falling edge,
dual edge) for parallel video interfaces.
This avoids hardcoded constants in device tree sources.

Acked-by: Rob Herring <robh at kernel.org>
Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
Signed-off-by: Michael Riesch <michael.riesch at collabora.com>
---
 include/dt-bindings/media/video-interfaces.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/include/dt-bindings/media/video-interfaces.h b/include/dt-bindings/media/video-interfaces.h
index 88b9d05d8075..0b19c9b2e627 100644
--- a/include/dt-bindings/media/video-interfaces.h
+++ b/include/dt-bindings/media/video-interfaces.h
@@ -20,4 +20,8 @@
 #define MEDIA_BUS_CSI2_CPHY_LINE_ORDER_CAB	4
 #define MEDIA_BUS_CSI2_CPHY_LINE_ORDER_CBA	5
 
+#define MEDIA_PCLK_SAMPLE_FALLING_EDGE		0
+#define MEDIA_PCLK_SAMPLE_RISING_EDGE		1
+#define MEDIA_PCLK_SAMPLE_DUAL_EDGE		2
+
 #endif /* __DT_BINDINGS_MEDIA_VIDEO_INTERFACES_H__ */

-- 
2.39.5




From devnull+michael.riesch.collabora.com at kernel.org  Fri Nov 14 07:20:18 2025
From: devnull+michael.riesch.collabora.com at kernel.org (Michael Riesch via B4 Relay)
Date: Fri, 14 Nov 2025 16:20:18 +0100
Subject: [PATCH v15 07/14] media: rockchip: rkcif: add abstraction for dma
 blocks
In-Reply-To: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
References: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
Message-ID: <20240220-rk3568-vicap-v15-7-8f4915ee365d@collabora.com>

From: Michael Riesch <michael.riesch at collabora.com>

Add an abstraction for the DMA parts and the ping-pong scheme (a
double-buffering mechanism) of the different CIF variants. Each
stream is represented as V4L2 device whose corresponding media
entity has one sink pad. This sink pad is connected to an instance
of the INTERFACE/CROP abstraction.

Tested-by: Gerald Loacker <gerald.loacker at wolfvision.net>
Reviewed-by: Gerald Loacker <gerald.loacker at wolfvision.net>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
Reviewed-by: Mehdi Djait <mehdi.djait at linux.intel.com>
Signed-off-by: Michael Riesch <michael.riesch at collabora.com>
---
 drivers/media/platform/rockchip/rkcif/Makefile     |   1 +
 .../media/platform/rockchip/rkcif/rkcif-common.h   |  67 +++
 .../platform/rockchip/rkcif/rkcif-interface.c      |  37 ++
 .../media/platform/rockchip/rkcif/rkcif-stream.c   | 638 +++++++++++++++++++++
 .../media/platform/rockchip/rkcif/rkcif-stream.h   |  32 ++
 5 files changed, 775 insertions(+)

diff --git a/drivers/media/platform/rockchip/rkcif/Makefile b/drivers/media/platform/rockchip/rkcif/Makefile
index 9d535fc27e51..256335d95050 100644
--- a/drivers/media/platform/rockchip/rkcif/Makefile
+++ b/drivers/media/platform/rockchip/rkcif/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_VIDEO_ROCKCHIP_CIF) += rockchip-cif.o
 
 rockchip-cif-objs += rkcif-dev.o
 rockchip-cif-objs += rkcif-interface.o
+rockchip-cif-objs += rkcif-stream.o
diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-common.h b/drivers/media/platform/rockchip/rkcif/rkcif-common.h
index f01536727a5d..63d5b45c7afe 100644
--- a/drivers/media/platform/rockchip/rkcif/rkcif-common.h
+++ b/drivers/media/platform/rockchip/rkcif/rkcif-common.h
@@ -33,6 +33,14 @@ enum rkcif_format_type {
 	RKCIF_FMT_TYPE_RAW,
 };
 
+enum rkcif_id_index {
+	RKCIF_ID0,
+	RKCIF_ID1,
+	RKCIF_ID2,
+	RKCIF_ID3,
+	RKCIF_ID_MAX
+};
+
 enum rkcif_interface_index {
 	RKCIF_DVP,
 	RKCIF_MIPI_BASE,
@@ -63,6 +71,19 @@ enum rkcif_interface_type {
 	RKCIF_IF_MIPI,
 };
 
+struct rkcif_buffer {
+	struct vb2_v4l2_buffer vb;
+	struct list_head queue;
+	dma_addr_t buff_addr[VIDEO_MAX_PLANES];
+	bool is_dummy;
+};
+
+struct rkcif_dummy_buffer {
+	struct rkcif_buffer buffer;
+	void *vaddr;
+	u32 size;
+};
+
 struct rkcif_input_fmt {
 	u32 mbus_code;
 
@@ -70,6 +91,12 @@ struct rkcif_input_fmt {
 	enum v4l2_field field;
 };
 
+struct rkcif_output_fmt {
+	u32 fourcc;
+	u32 mbus_code;
+	u8 cplanes;
+};
+
 struct rkcif_interface;
 
 struct rkcif_remote {
@@ -79,6 +106,42 @@ struct rkcif_remote {
 	struct rkcif_interface *interface;
 };
 
+struct rkcif_stream {
+	enum rkcif_id_index id;
+	struct rkcif_device *rkcif;
+	struct rkcif_interface *interface;
+	const struct rkcif_output_fmt *out_fmts;
+	unsigned int out_fmts_num;
+
+	/* in ping-pong mode, two buffers can be provided to the HW */
+	struct rkcif_buffer *buffers[2];
+	int frame_idx;
+	int frame_phase;
+
+	/* in case of no available buffer, HW can write to the dummy buffer */
+	struct rkcif_dummy_buffer dummy;
+
+	bool stopping;
+	wait_queue_head_t wq_stopped;
+
+	/* queue of available buffers plus spinlock that protects it */
+	spinlock_t driver_queue_lock;
+	struct list_head driver_queue;
+
+	/* lock used by the V4L2 core */
+	struct mutex vlock;
+
+	struct media_pad pad;
+	struct media_pipeline pipeline;
+	struct v4l2_pix_format_mplane pix;
+	struct vb2_queue buf_queue;
+	struct video_device vdev;
+
+	void (*queue_buffer)(struct rkcif_stream *stream, unsigned int index);
+	int (*start_streaming)(struct rkcif_stream *stream);
+	void (*stop_streaming)(struct rkcif_stream *stream);
+};
+
 struct rkcif_dvp {
 	u32 dvp_clk_delay;
 };
@@ -89,6 +152,8 @@ struct rkcif_interface {
 	enum rkcif_interface_index index;
 	struct rkcif_device *rkcif;
 	struct rkcif_remote *remote;
+	struct rkcif_stream streams[RKCIF_ID_MAX];
+	unsigned int streams_num;
 	const struct rkcif_input_fmt *in_fmts;
 	unsigned int in_fmts_num;
 
@@ -99,6 +164,8 @@ struct rkcif_interface {
 	union {
 		struct rkcif_dvp dvp;
 	};
+
+	void (*set_crop)(struct rkcif_stream *stream, u16 left, u16 top);
 };
 
 struct rkcif_match_data {
diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-interface.c b/drivers/media/platform/rockchip/rkcif/rkcif-interface.c
index 0fe9410e23ed..523103872b7a 100644
--- a/drivers/media/platform/rockchip/rkcif/rkcif-interface.c
+++ b/drivers/media/platform/rockchip/rkcif/rkcif-interface.c
@@ -157,15 +157,41 @@ static int rkcif_interface_set_routing(struct v4l2_subdev *sd,
 	if (ret)
 		return ret;
 
+	for (unsigned int i = 0; i < routing->num_routes; i++) {
+		const struct v4l2_subdev_route *route = &routing->routes[i];
+
+		if (route->source_stream >= RKCIF_ID_MAX)
+			return -EINVAL;
+	}
+
 	ret = v4l2_subdev_set_routing(sd, state, routing);
 
 	return ret;
 }
 
+static int rkcif_interface_apply_crop(struct rkcif_stream *stream,
+				      struct v4l2_subdev_state *state)
+{
+	struct rkcif_interface *interface = stream->interface;
+	struct v4l2_rect *crop;
+
+	crop = v4l2_subdev_state_get_crop(state, RKCIF_IF_PAD_SRC, stream->id);
+	if (!crop)
+		return -EINVAL;
+
+	if (interface->set_crop)
+		interface->set_crop(stream, crop->left, crop->top);
+
+	return 0;
+}
+
 static int rkcif_interface_enable_streams(struct v4l2_subdev *sd,
 					  struct v4l2_subdev_state *state,
 					  u32 pad, u64 streams_mask)
 {
+	struct rkcif_interface *interface = to_rkcif_interface(sd);
+	struct rkcif_stream *stream;
+	struct v4l2_subdev_route *route;
 	struct v4l2_subdev *remote_sd;
 	struct media_pad *remote_pad;
 	u64 mask;
@@ -174,6 +200,17 @@ static int rkcif_interface_enable_streams(struct v4l2_subdev *sd,
 		media_pad_remote_pad_first(&sd->entity.pads[RKCIF_IF_PAD_SINK]);
 	remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity);
 
+	/* DVP has one crop setting for all IDs */
+	if (interface->type == RKCIF_IF_DVP) {
+		stream = &interface->streams[RKCIF_ID0];
+		rkcif_interface_apply_crop(stream, state);
+	} else {
+		for_each_active_route(&state->routing, route) {
+			stream = &interface->streams[route->sink_stream];
+			rkcif_interface_apply_crop(stream, state);
+		}
+	}
+
 	mask = v4l2_subdev_state_xlate_streams(state, RKCIF_IF_PAD_SINK,
 					       RKCIF_IF_PAD_SRC, &streams_mask);
 
diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-stream.c b/drivers/media/platform/rockchip/rkcif/rkcif-stream.c
new file mode 100644
index 000000000000..fd6593f4702f
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkcif/rkcif-stream.c
@@ -0,0 +1,638 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip Camera Interface (CIF) Driver
+ *
+ * Copyright (C) 2025 Michael Riesch <michael.riesch at wolfvision.net>
+ * Copyright (C) 2025 Collabora, Ltd.
+ */
+
+#include <linux/pm_runtime.h>
+
+#include <media/v4l2-common.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-mc.h>
+#include <media/v4l2-subdev.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "rkcif-common.h"
+#include "rkcif-stream.h"
+
+#define CIF_REQ_BUFS_MIN 1
+#define CIF_MIN_WIDTH	 64
+#define CIF_MIN_HEIGHT	 64
+#define CIF_MAX_WIDTH	 8192
+#define CIF_MAX_HEIGHT	 8192
+
+static inline struct rkcif_buffer *to_rkcif_buffer(struct vb2_v4l2_buffer *vb)
+{
+	return container_of(vb, struct rkcif_buffer, vb);
+}
+
+static inline struct rkcif_stream *to_rkcif_stream(struct video_device *vdev)
+{
+	return container_of(vdev, struct rkcif_stream, vdev);
+}
+
+static struct rkcif_buffer *rkcif_stream_pop_buffer(struct rkcif_stream *stream)
+{
+	struct rkcif_buffer *buffer;
+
+	guard(spinlock_irqsave)(&stream->driver_queue_lock);
+
+	if (list_empty(&stream->driver_queue))
+		return NULL;
+
+	buffer = list_first_entry(&stream->driver_queue, struct rkcif_buffer,
+				  queue);
+	list_del(&buffer->queue);
+
+	return buffer;
+}
+
+static void rkcif_stream_push_buffer(struct rkcif_stream *stream,
+				     struct rkcif_buffer *buffer)
+{
+	guard(spinlock_irqsave)(&stream->driver_queue_lock);
+
+	list_add_tail(&buffer->queue, &stream->driver_queue);
+}
+
+static inline void rkcif_stream_return_buffer(struct rkcif_buffer *buffer,
+					      enum vb2_buffer_state state)
+{
+	struct vb2_v4l2_buffer *vb = &buffer->vb;
+
+	vb2_buffer_done(&vb->vb2_buf, state);
+}
+
+static void rkcif_stream_complete_buffer(struct rkcif_stream *stream,
+					 struct rkcif_buffer *buffer)
+{
+	struct vb2_v4l2_buffer *vb = &buffer->vb;
+
+	vb->vb2_buf.timestamp = ktime_get_ns();
+	vb->sequence = stream->frame_idx;
+	vb2_buffer_done(&vb->vb2_buf, VB2_BUF_STATE_DONE);
+	stream->frame_idx++;
+}
+
+void rkcif_stream_pingpong(struct rkcif_stream *stream)
+{
+	struct rkcif_buffer *buffer;
+
+	buffer = stream->buffers[stream->frame_phase];
+	if (!buffer->is_dummy)
+		rkcif_stream_complete_buffer(stream, buffer);
+
+	buffer = rkcif_stream_pop_buffer(stream);
+	if (buffer) {
+		stream->buffers[stream->frame_phase] = buffer;
+		stream->buffers[stream->frame_phase]->is_dummy = false;
+	} else {
+		stream->buffers[stream->frame_phase] = &stream->dummy.buffer;
+		stream->buffers[stream->frame_phase]->is_dummy = true;
+		dev_dbg(stream->rkcif->dev,
+			"no buffer available, frame will be dropped\n");
+	}
+
+	if (stream->queue_buffer)
+		stream->queue_buffer(stream, stream->frame_phase);
+
+	stream->frame_phase = 1 - stream->frame_phase;
+}
+
+static int rkcif_stream_init_buffers(struct rkcif_stream *stream)
+{
+	struct v4l2_pix_format_mplane *pix = &stream->pix;
+
+	stream->buffers[0] = rkcif_stream_pop_buffer(stream);
+	if (!stream->buffers[0])
+		goto err_buff_0;
+
+	stream->buffers[1] = rkcif_stream_pop_buffer(stream);
+	if (!stream->buffers[1])
+		goto err_buff_1;
+
+	if (stream->queue_buffer) {
+		stream->queue_buffer(stream, 0);
+		stream->queue_buffer(stream, 1);
+	}
+
+	stream->dummy.size = pix->num_planes * pix->plane_fmt[0].sizeimage;
+	stream->dummy.vaddr =
+		dma_alloc_attrs(stream->rkcif->dev, stream->dummy.size,
+				&stream->dummy.buffer.buff_addr[0], GFP_KERNEL,
+				DMA_ATTR_NO_KERNEL_MAPPING);
+	if (!stream->dummy.vaddr)
+		goto err_dummy;
+
+	for (unsigned int i = 1; i < pix->num_planes; i++)
+		stream->dummy.buffer.buff_addr[i] =
+			stream->dummy.buffer.buff_addr[i - 1] +
+			pix->plane_fmt[i - 1].bytesperline * pix->height;
+
+	return 0;
+
+err_dummy:
+	rkcif_stream_return_buffer(stream->buffers[1], VB2_BUF_STATE_QUEUED);
+	stream->buffers[1] = NULL;
+
+err_buff_1:
+	rkcif_stream_return_buffer(stream->buffers[0], VB2_BUF_STATE_QUEUED);
+	stream->buffers[0] = NULL;
+err_buff_0:
+	return -EINVAL;
+}
+
+static void rkcif_stream_return_all_buffers(struct rkcif_stream *stream,
+					    enum vb2_buffer_state state)
+{
+	struct rkcif_buffer *buffer;
+
+	if (stream->buffers[0] && !stream->buffers[0]->is_dummy) {
+		rkcif_stream_return_buffer(stream->buffers[0], state);
+		stream->buffers[0] = NULL;
+	}
+
+	if (stream->buffers[1] && !stream->buffers[1]->is_dummy) {
+		rkcif_stream_return_buffer(stream->buffers[1], state);
+		stream->buffers[1] = NULL;
+	}
+
+	while ((buffer = rkcif_stream_pop_buffer(stream)))
+		rkcif_stream_return_buffer(buffer, state);
+
+	if (stream->dummy.vaddr) {
+		dma_free_attrs(stream->rkcif->dev, stream->dummy.size,
+			       stream->dummy.vaddr,
+			       stream->dummy.buffer.buff_addr[0],
+			       DMA_ATTR_NO_KERNEL_MAPPING);
+		stream->dummy.vaddr = NULL;
+	}
+}
+
+static int rkcif_stream_setup_queue(struct vb2_queue *queue,
+				    unsigned int *num_buffers,
+				    unsigned int *num_planes,
+				    unsigned int sizes[],
+				    struct device *alloc_devs[])
+{
+	struct rkcif_stream *stream = queue->drv_priv;
+	struct v4l2_pix_format_mplane *pix = &stream->pix;
+
+	if (*num_planes) {
+		if (*num_planes != pix->num_planes)
+			return -EINVAL;
+
+		for (unsigned int i = 0; i < pix->num_planes; i++)
+			if (sizes[i] < pix->plane_fmt[i].sizeimage)
+				return -EINVAL;
+	} else {
+		*num_planes = pix->num_planes;
+		for (unsigned int i = 0; i < pix->num_planes; i++)
+			sizes[i] = pix->plane_fmt[i].sizeimage;
+	}
+
+	return 0;
+}
+
+static int rkcif_stream_prepare_buffer(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct rkcif_buffer *buffer = to_rkcif_buffer(vbuf);
+	struct rkcif_stream *stream = vb->vb2_queue->drv_priv;
+	const struct rkcif_output_fmt *fmt;
+	struct v4l2_pix_format_mplane *pix = &stream->pix;
+	unsigned int i;
+
+	memset(buffer->buff_addr, 0, sizeof(buffer->buff_addr));
+	for (i = 0; i < pix->num_planes; i++)
+		buffer->buff_addr[i] = vb2_dma_contig_plane_dma_addr(vb, i);
+
+	/* apply fallback for non-mplane formats, if required */
+	if (pix->num_planes == 1) {
+		fmt = rkcif_stream_find_output_fmt(stream, true,
+						   pix->pixelformat);
+		for (i = 1; i < fmt->cplanes; i++)
+			buffer->buff_addr[i] =
+				buffer->buff_addr[i - 1] +
+				pix->plane_fmt[i - 1].bytesperline *
+					pix->height;
+	}
+
+	for (i = 0; i < pix->num_planes; i++) {
+		unsigned long size = pix->plane_fmt[i].sizeimage;
+
+		if (vb2_plane_size(vb, i) < size) {
+			dev_err(stream->rkcif->dev,
+				"user buffer too small (%ld < %ld)\n",
+				vb2_plane_size(vb, i), size);
+			return -EINVAL;
+		}
+
+		vb2_set_plane_payload(vb, i, size);
+	}
+
+	vbuf->field = V4L2_FIELD_NONE;
+
+	return 0;
+}
+
+static void rkcif_stream_queue_buffer(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct rkcif_buffer *buffer = to_rkcif_buffer(vbuf);
+	struct rkcif_stream *stream = vb->vb2_queue->drv_priv;
+
+	rkcif_stream_push_buffer(stream, buffer);
+}
+
+static int rkcif_stream_start_streaming(struct vb2_queue *queue,
+					unsigned int count)
+{
+	struct rkcif_stream *stream = queue->drv_priv;
+	struct rkcif_device *rkcif = stream->rkcif;
+	u64 mask;
+	int ret;
+
+	stream->frame_idx = 0;
+	stream->frame_phase = 0;
+
+	ret = video_device_pipeline_start(&stream->vdev, &stream->pipeline);
+	if (ret) {
+		dev_err(rkcif->dev, "failed to start pipeline %d\n", ret);
+		goto err_out;
+	}
+
+	ret = pm_runtime_resume_and_get(rkcif->dev);
+	if (ret < 0) {
+		dev_err(rkcif->dev, "failed to get runtime pm, %d\n", ret);
+		goto err_pipeline_stop;
+	}
+
+	ret = rkcif_stream_init_buffers(stream);
+	if (ret)
+		goto err_runtime_put;
+
+	if (stream->start_streaming) {
+		ret = stream->start_streaming(stream);
+		if (ret < 0)
+			goto err_runtime_put;
+	}
+
+	mask = BIT_ULL(stream->id);
+	ret = v4l2_subdev_enable_streams(&stream->interface->sd,
+					 RKCIF_IF_PAD_SRC, mask);
+	if (ret < 0)
+		goto err_stop_stream;
+
+	return 0;
+
+err_stop_stream:
+	if (stream->stop_streaming)
+		stream->stop_streaming(stream);
+err_runtime_put:
+	pm_runtime_put(rkcif->dev);
+err_pipeline_stop:
+	video_device_pipeline_stop(&stream->vdev);
+err_out:
+	rkcif_stream_return_all_buffers(stream, VB2_BUF_STATE_QUEUED);
+	return ret;
+}
+
+static void rkcif_stream_stop_streaming(struct vb2_queue *queue)
+{
+	struct rkcif_stream *stream = queue->drv_priv;
+	struct rkcif_device *rkcif = stream->rkcif;
+	u64 mask;
+	int ret;
+
+	mask = BIT_ULL(stream->id);
+	v4l2_subdev_disable_streams(&stream->interface->sd, RKCIF_IF_PAD_SRC,
+				    mask);
+
+	stream->stopping = true;
+	ret = wait_event_timeout(stream->wq_stopped, !stream->stopping,
+				 msecs_to_jiffies(1000));
+
+	if (!ret && stream->stop_streaming)
+		stream->stop_streaming(stream);
+
+	pm_runtime_put(rkcif->dev);
+
+	rkcif_stream_return_all_buffers(stream, VB2_BUF_STATE_ERROR);
+
+	video_device_pipeline_stop(&stream->vdev);
+}
+
+static const struct vb2_ops rkcif_stream_vb2_ops = {
+	.queue_setup = rkcif_stream_setup_queue,
+	.buf_prepare = rkcif_stream_prepare_buffer,
+	.buf_queue = rkcif_stream_queue_buffer,
+	.wait_prepare = vb2_ops_wait_prepare,
+	.wait_finish = vb2_ops_wait_finish,
+	.start_streaming = rkcif_stream_start_streaming,
+	.stop_streaming = rkcif_stream_stop_streaming,
+};
+
+static int rkcif_stream_fill_format(struct rkcif_stream *stream,
+				    struct v4l2_pix_format_mplane *pix)
+{
+	const struct rkcif_output_fmt *fmt;
+	u32 height, width;
+	int ret;
+
+	fmt = rkcif_stream_find_output_fmt(stream, true, pix->pixelformat);
+	height = clamp_t(u32, pix->height, CIF_MIN_HEIGHT, CIF_MAX_HEIGHT);
+	width = clamp_t(u32, pix->width, CIF_MIN_WIDTH, CIF_MAX_WIDTH);
+	ret = v4l2_fill_pixfmt_mp(pix, fmt->fourcc, width, height);
+	if (ret)
+		return ret;
+
+	pix->field = V4L2_FIELD_NONE;
+
+	return 0;
+}
+
+static int rkcif_stream_try_format(struct file *file, void *fh,
+				   struct v4l2_format *f)
+{
+	struct rkcif_stream *stream = video_drvdata(file);
+	struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
+
+	return rkcif_stream_fill_format(stream, pix);
+}
+
+static int rkcif_stream_set_format(struct file *file, void *priv,
+				   struct v4l2_format *f)
+{
+	struct rkcif_stream *stream = video_drvdata(file);
+	struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
+	int ret;
+
+	if (vb2_is_busy(&stream->buf_queue))
+		return -EBUSY;
+
+	ret = rkcif_stream_try_format(file, priv, f);
+	if (ret)
+		return ret;
+
+	stream->pix = *pix;
+
+	return 0;
+}
+
+static int rkcif_stream_get_format(struct file *file, void *fh,
+				   struct v4l2_format *f)
+{
+	struct rkcif_stream *stream = video_drvdata(file);
+
+	f->fmt.pix_mp = stream->pix;
+
+	return 0;
+}
+
+static int rkcif_stream_enum_formats(struct file *file, void *priv,
+				     struct v4l2_fmtdesc *f)
+{
+	struct rkcif_stream *stream = video_drvdata(file);
+
+	if (f->index >= stream->out_fmts_num)
+		return -EINVAL;
+
+	f->pixelformat = stream->out_fmts[f->index].fourcc;
+
+	return 0;
+}
+
+static int rkcif_stream_enum_framesizes(struct file *file, void *fh,
+					struct v4l2_frmsizeenum *fsize)
+{
+	struct rkcif_stream *stream = video_drvdata(file);
+
+	if (fsize->index > 0)
+		return -EINVAL;
+
+	if (!rkcif_stream_find_output_fmt(stream, false, fsize->pixel_format))
+		return -EINVAL;
+
+	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
+	fsize->stepwise.min_width = CIF_MIN_WIDTH;
+	fsize->stepwise.max_width = CIF_MAX_WIDTH;
+	fsize->stepwise.step_width = 8;
+	fsize->stepwise.min_height = CIF_MIN_HEIGHT;
+	fsize->stepwise.max_height = CIF_MAX_HEIGHT;
+	fsize->stepwise.step_height = 8;
+
+	return 0;
+}
+
+static int rkcif_stream_querycap(struct file *file, void *priv,
+				 struct v4l2_capability *cap)
+{
+	struct rkcif_stream *stream = video_drvdata(file);
+	struct device *dev = stream->rkcif->dev;
+
+	strscpy(cap->driver, dev->driver->name, sizeof(cap->driver));
+	strscpy(cap->card, dev->driver->name, sizeof(cap->card));
+
+	return 0;
+}
+
+static const struct v4l2_ioctl_ops rkcif_stream_ioctl_ops = {
+	.vidioc_reqbufs = vb2_ioctl_reqbufs,
+	.vidioc_querybuf = vb2_ioctl_querybuf,
+	.vidioc_create_bufs = vb2_ioctl_create_bufs,
+	.vidioc_qbuf = vb2_ioctl_qbuf,
+	.vidioc_expbuf = vb2_ioctl_expbuf,
+	.vidioc_dqbuf = vb2_ioctl_dqbuf,
+	.vidioc_prepare_buf = vb2_ioctl_prepare_buf,
+	.vidioc_streamon = vb2_ioctl_streamon,
+	.vidioc_streamoff = vb2_ioctl_streamoff,
+	.vidioc_try_fmt_vid_cap_mplane = rkcif_stream_try_format,
+	.vidioc_s_fmt_vid_cap_mplane = rkcif_stream_set_format,
+	.vidioc_g_fmt_vid_cap_mplane = rkcif_stream_get_format,
+	.vidioc_enum_fmt_vid_cap = rkcif_stream_enum_formats,
+	.vidioc_enum_framesizes = rkcif_stream_enum_framesizes,
+	.vidioc_querycap = rkcif_stream_querycap,
+};
+
+static int rkcif_stream_link_validate(struct media_link *link)
+{
+	struct video_device *vdev =
+		media_entity_to_video_device(link->sink->entity);
+	struct v4l2_mbus_framefmt *source_fmt;
+	struct v4l2_subdev *sd;
+	struct v4l2_subdev_state *state;
+	struct rkcif_stream *stream = to_rkcif_stream(vdev);
+	int ret = -EINVAL;
+
+	if (!media_entity_remote_source_pad_unique(link->sink->entity))
+		return -ENOTCONN;
+
+	sd = media_entity_to_v4l2_subdev(link->source->entity);
+
+	state = v4l2_subdev_lock_and_get_active_state(sd);
+
+	source_fmt = v4l2_subdev_state_get_format(state, link->source->index,
+						  stream->id);
+	if (!source_fmt)
+		goto out;
+
+	if (source_fmt->height != stream->pix.height ||
+	    source_fmt->width != stream->pix.width) {
+		dev_dbg(stream->rkcif->dev,
+			"link '%s':%u -> '%s':%u not valid: %ux%u != %ux%u\n",
+			link->source->entity->name, link->source->index,
+			link->sink->entity->name, link->sink->index,
+			source_fmt->width, source_fmt->height,
+			stream->pix.width, stream->pix.height);
+		goto out;
+	}
+
+	ret = 0;
+
+out:
+	v4l2_subdev_unlock_state(state);
+	return ret;
+}
+
+static const struct media_entity_operations rkcif_stream_media_ops = {
+	.link_validate = rkcif_stream_link_validate,
+};
+
+static const struct v4l2_file_operations rkcif_stream_file_ops = {
+	.open = v4l2_fh_open,
+	.release = vb2_fop_release,
+	.unlocked_ioctl = video_ioctl2,
+	.poll = vb2_fop_poll,
+	.mmap = vb2_fop_mmap,
+};
+
+static int rkcif_stream_init_vb2_queue(struct vb2_queue *q,
+				       struct rkcif_stream *stream)
+{
+	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+	q->io_modes = VB2_MMAP | VB2_DMABUF;
+	q->drv_priv = stream;
+	q->ops = &rkcif_stream_vb2_ops;
+	q->mem_ops = &vb2_dma_contig_memops;
+	q->buf_struct_size = sizeof(struct rkcif_buffer);
+	q->min_queued_buffers = CIF_REQ_BUFS_MIN;
+	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+	q->lock = &stream->vlock;
+	q->dev = stream->rkcif->dev;
+
+	return vb2_queue_init(q);
+}
+
+int rkcif_stream_register(struct rkcif_device *rkcif,
+			  struct rkcif_stream *stream)
+{
+	struct rkcif_interface *interface = stream->interface;
+	struct v4l2_device *v4l2_dev = &rkcif->v4l2_dev;
+	struct video_device *vdev = &stream->vdev;
+	u32 link_flags = 0;
+	int ret;
+
+	stream->rkcif = rkcif;
+
+	INIT_LIST_HEAD(&stream->driver_queue);
+	spin_lock_init(&stream->driver_queue_lock);
+
+	init_waitqueue_head(&stream->wq_stopped);
+
+	mutex_init(&stream->vlock);
+
+	vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_STREAMING |
+			    V4L2_CAP_IO_MC;
+	vdev->entity.ops = &rkcif_stream_media_ops;
+	vdev->fops = &rkcif_stream_file_ops;
+	vdev->ioctl_ops = &rkcif_stream_ioctl_ops;
+	vdev->lock = &stream->vlock;
+	vdev->minor = -1;
+	vdev->release = video_device_release_empty;
+	vdev->v4l2_dev = v4l2_dev;
+	vdev->vfl_dir = VFL_DIR_RX;
+	video_set_drvdata(vdev, stream);
+
+	stream->pad.flags = MEDIA_PAD_FL_SINK;
+
+	stream->pix.height = CIF_MIN_HEIGHT;
+	stream->pix.width = CIF_MIN_WIDTH;
+	rkcif_stream_fill_format(stream, &stream->pix);
+
+	rkcif_stream_init_vb2_queue(&stream->buf_queue, stream);
+
+	vdev->queue = &stream->buf_queue;
+	if (interface->type == RKCIF_IF_DVP)
+		snprintf(vdev->name, sizeof(vdev->name), "rkcif-dvp0-id%d",
+			 stream->id);
+	else if (interface->type == RKCIF_IF_MIPI)
+		snprintf(vdev->name, sizeof(vdev->name), "rkcif-mipi%d-id%d",
+			 interface->index - RKCIF_MIPI_BASE, stream->id);
+
+	ret = media_entity_pads_init(&vdev->entity, 1, &stream->pad);
+	if (ret < 0) {
+		dev_err(rkcif->dev,
+			"failed to initialize stream media pad: %d\n", ret);
+		return ret;
+	}
+
+	ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
+	if (ret < 0) {
+		dev_err(rkcif->dev, "failed to register video device: %d\n",
+			ret);
+		goto err_media_entity_cleanup;
+	}
+
+	/* enable only stream ID0 by default */
+	if (stream->id == RKCIF_ID0)
+		link_flags |= MEDIA_LNK_FL_ENABLED;
+
+	ret = media_create_pad_link(&interface->sd.entity, RKCIF_IF_PAD_SRC,
+				    &stream->vdev.entity, 0, link_flags);
+	if (ret) {
+		dev_err(rkcif->dev, "failed to link stream media pad: %d\n",
+			ret);
+		goto err_video_unregister;
+	}
+
+	v4l2_info(v4l2_dev, "registered %s as /dev/video%d\n", vdev->name,
+		  vdev->num);
+
+	return 0;
+
+err_video_unregister:
+	video_unregister_device(&stream->vdev);
+err_media_entity_cleanup:
+	media_entity_cleanup(&stream->vdev.entity);
+	return ret;
+}
+
+void rkcif_stream_unregister(struct rkcif_stream *stream)
+{
+	video_unregister_device(&stream->vdev);
+	media_entity_cleanup(&stream->vdev.entity);
+}
+
+const struct rkcif_output_fmt *
+rkcif_stream_find_output_fmt(struct rkcif_stream *stream, bool ret_def,
+			     u32 pixelfmt)
+{
+	const struct rkcif_output_fmt *fmt;
+
+	WARN_ON(stream->out_fmts_num == 0);
+
+	for (unsigned int i = 0; i < stream->out_fmts_num; i++) {
+		fmt = &stream->out_fmts[i];
+		if (fmt->fourcc == pixelfmt)
+			return fmt;
+	}
+
+	if (ret_def)
+		return &stream->out_fmts[0];
+	else
+		return NULL;
+}
diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-stream.h b/drivers/media/platform/rockchip/rkcif/rkcif-stream.h
new file mode 100644
index 000000000000..590faf5d1a87
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkcif/rkcif-stream.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Rockchip Camera Interface (CIF) Driver
+ *
+ * Abstraction for the DMA part and the ping-pong scheme (a double-buffering
+ * mechanism) of the different CIF variants.
+ * Each stream is represented as V4L2 device whose corresponding media entity
+ * has one sink pad.
+ * The sink pad is connected to an instance of the INTERFACE/CROP abstraction
+ * in rkcif-interface.c.
+ *
+ * Copyright (C) 2025 Michael Riesch <michael.riesch at wolfvision.net>
+ * Copyright (C) 2025 Collabora, Ltd.
+ */
+
+#ifndef _RKCIF_STREAM_H
+#define _RKCIF_STREAM_H
+
+#include "rkcif-common.h"
+
+void rkcif_stream_pingpong(struct rkcif_stream *stream);
+
+int rkcif_stream_register(struct rkcif_device *rkcif,
+			  struct rkcif_stream *stream);
+
+void rkcif_stream_unregister(struct rkcif_stream *stream);
+
+const struct rkcif_output_fmt *
+rkcif_stream_find_output_fmt(struct rkcif_stream *stream, bool ret_def,
+			     u32 pixelfmt);
+
+#endif

-- 
2.39.5




From devnull+michael.riesch.collabora.com at kernel.org  Fri Nov 14 07:20:15 2025
From: devnull+michael.riesch.collabora.com at kernel.org (Michael Riesch via B4 Relay)
Date: Fri, 14 Nov 2025 16:20:15 +0100
Subject: [PATCH v15 04/14] media: dt-bindings: add rockchip rk3568 vicap
In-Reply-To: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
References: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
Message-ID: <20240220-rk3568-vicap-v15-4-8f4915ee365d@collabora.com>

From: Michael Riesch <michael.riesch at collabora.com>

Add documentation for the Rockchip RK3568 Video Capture (VICAP) unit.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
Signed-off-by: Michael Riesch <michael.riesch at collabora.com>
---
 .../bindings/media/rockchip,rk3568-vicap.yaml      | 172 +++++++++++++++++++++
 MAINTAINERS                                        |   1 +
 2 files changed, 173 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/rockchip,rk3568-vicap.yaml b/Documentation/devicetree/bindings/media/rockchip,rk3568-vicap.yaml
new file mode 100644
index 000000000000..18cd0a5a5318
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/rockchip,rk3568-vicap.yaml
@@ -0,0 +1,172 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/rockchip,rk3568-vicap.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip RK3568 Video Capture (VICAP)
+
+maintainers:
+  - Michael Riesch <michael.riesch at collabora.com>
+
+description:
+  The Rockchip RK3568 Video Capture (VICAP) block features a digital video
+  port (DVP, a parallel video interface) and a MIPI CSI-2 port. It receives
+  the data from camera sensors, video decoders, or other companion ICs and
+  transfers it into system main memory by AXI bus.
+
+properties:
+  compatible:
+    const: rockchip,rk3568-vicap
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: ACLK
+      - description: HCLK
+      - description: DCLK
+      - description: ICLK
+
+  clock-names:
+    items:
+      - const: aclk
+      - const: hclk
+      - const: dclk
+      - const: iclk
+
+  iommus:
+    maxItems: 1
+
+  resets:
+    items:
+      - description: ARST
+      - description: HRST
+      - description: DRST
+      - description: PRST
+      - description: IRST
+
+  reset-names:
+    items:
+      - const: arst
+      - const: hrst
+      - const: drst
+      - const: prst
+      - const: irst
+
+  rockchip,grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: Phandle to general register file used for video input block control.
+
+  power-domains:
+    maxItems: 1
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port at 0:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description: The digital video port (DVP, a parallel video interface).
+
+        properties:
+          endpoint:
+            $ref: video-interfaces.yaml#
+            unevaluatedProperties: false
+
+            properties:
+              bus-type:
+                enum:
+                  - 5 # MEDIA_BUS_TYPE_PARALLEL
+                  - 6 # MEDIA_BUS_TYPE_BT656
+
+              rockchip,dvp-clk-delay:
+                $ref: /schemas/types.yaml#/definitions/uint32
+                default: 0
+                minimum: 0
+                maximum: 127
+                description:
+                  Delay the DVP path clock input to align the sampling phase,
+                  only valid in dual edge sampling mode. Delay is zero by
+                  default and can be adjusted optionally.
+
+            required:
+              - bus-type
+
+      port at 1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: Port connected to the MIPI CSI-2 receiver output.
+
+        properties:
+          endpoint:
+            $ref: video-interfaces.yaml#
+            unevaluatedProperties: false
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/rk3568-cru.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/power/rk3568-power.h>
+    #include <dt-bindings/media/video-interfaces.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        vicap: video-capture at fdfe0000 {
+            compatible = "rockchip,rk3568-vicap";
+            reg = <0x0 0xfdfe0000 0x0 0x200>;
+            interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
+            assigned-clocks = <&cru DCLK_VICAP>;
+            assigned-clock-rates = <300000000>;
+            clocks = <&cru ACLK_VICAP>, <&cru HCLK_VICAP>,
+                     <&cru DCLK_VICAP>, <&cru ICLK_VICAP_G>;
+            clock-names = "aclk", "hclk", "dclk", "iclk";
+            iommus = <&vicap_mmu>;
+            power-domains = <&power RK3568_PD_VI>;
+            resets = <&cru SRST_A_VICAP>, <&cru SRST_H_VICAP>,
+                     <&cru SRST_D_VICAP>, <&cru SRST_P_VICAP>,
+                     <&cru SRST_I_VICAP>;
+            reset-names = "arst", "hrst", "drst", "prst", "irst";
+            rockchip,grf = <&grf>;
+
+            ports {
+                #address-cells = <1>;
+                #size-cells = <0>;
+
+                vicap_dvp: port at 0 {
+                    reg = <0>;
+
+                    vicap_dvp_input: endpoint {
+                        bus-type = <MEDIA_BUS_TYPE_BT656>;
+                        bus-width = <16>;
+                        pclk-sample = <MEDIA_PCLK_SAMPLE_DUAL_EDGE>;
+                        remote-endpoint = <&it6801_output>;
+                    };
+                };
+
+                vicap_mipi: port at 1 {
+                    reg = <1>;
+
+                    vicap_mipi_input: endpoint {
+                        remote-endpoint = <&csi_output>;
+                    };
+                };
+            };
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 3fa175e2b61f..0a3959696154 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22249,6 +22249,7 @@ L:	linux-media at vger.kernel.org
 S:	Maintained
 F:	Documentation/admin-guide/media/rkcif*
 F:	Documentation/devicetree/bindings/media/rockchip,px30-vip.yaml
+F:	Documentation/devicetree/bindings/media/rockchip,rk3568-vicap.yaml
 
 ROCKCHIP CRYPTO DRIVERS
 M:	Corentin Labbe <clabbe at baylibre.com>

-- 
2.39.5




From devnull+michael.riesch.collabora.com at kernel.org  Fri Nov 14 07:20:19 2025
From: devnull+michael.riesch.collabora.com at kernel.org (Michael Riesch via B4 Relay)
Date: Fri, 14 Nov 2025 16:20:19 +0100
Subject: [PATCH v15 08/14] media: rockchip: rkcif: add support for px30 vip
 dvp capture
In-Reply-To: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
References: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
Message-ID: <20240220-rk3568-vicap-v15-8-8f4915ee365d@collabora.com>

From: Michael Riesch <michael.riesch at collabora.com>

The PX30 Video Input Processor (VIP) unit features a Digital Video
Port (DVP). Add support for the DVP in general and for the PX30
VIP DVP in particular.

Tested-by: Gerald Loacker <gerald.loacker at wolfvision.net>
Reviewed-by: Gerald Loacker <gerald.loacker at wolfvision.net>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
Reviewed-by: Mehdi Djait <mehdi.djait at linux.intel.com>
Signed-off-by: Michael Riesch <michael.riesch at collabora.com>
---
 drivers/media/platform/rockchip/rkcif/Makefile     |   1 +
 .../platform/rockchip/rkcif/rkcif-capture-dvp.c    | 589 +++++++++++++++++++++
 .../platform/rockchip/rkcif/rkcif-capture-dvp.h    |  24 +
 .../media/platform/rockchip/rkcif/rkcif-common.h   |  28 +
 drivers/media/platform/rockchip/rkcif/rkcif-dev.c  |  15 +
 drivers/media/platform/rockchip/rkcif/rkcif-regs.h | 131 +++++
 6 files changed, 788 insertions(+)

diff --git a/drivers/media/platform/rockchip/rkcif/Makefile b/drivers/media/platform/rockchip/rkcif/Makefile
index 256335d95050..a36e294d569d 100644
--- a/drivers/media/platform/rockchip/rkcif/Makefile
+++ b/drivers/media/platform/rockchip/rkcif/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_VIDEO_ROCKCHIP_CIF) += rockchip-cif.o
 
+rockchip-cif-objs += rkcif-capture-dvp.o
 rockchip-cif-objs += rkcif-dev.o
 rockchip-cif-objs += rkcif-interface.o
 rockchip-cif-objs += rkcif-stream.o
diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-capture-dvp.c b/drivers/media/platform/rockchip/rkcif/rkcif-capture-dvp.c
new file mode 100644
index 000000000000..b40135035ab8
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkcif/rkcif-capture-dvp.c
@@ -0,0 +1,589 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip Camera Interface (CIF) Driver
+ *
+ * Copyright (C) 2018 Rockchip Electronics Co., Ltd.
+ * Copyright (C) 2020 Maxime Chevallier <maxime.chevallier at bootlin.com>
+ * Copyright (C) 2023 Mehdi Djait <mehdi.djait at bootlin.com>
+ * Copyright (C) 2025 Michael Riesch <michael.riesch at wolfvision.net>
+ * Copyright (C) 2025 Collabora, Ltd.
+ */
+
+#include <media/v4l2-common.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-mc.h>
+#include <media/v4l2-subdev.h>
+
+#include "rkcif-capture-dvp.h"
+#include "rkcif-common.h"
+#include "rkcif-interface.h"
+#include "rkcif-regs.h"
+#include "rkcif-stream.h"
+
+static const struct rkcif_output_fmt dvp_out_fmts[] = {
+	{
+		.fourcc = V4L2_PIX_FMT_NV16,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_OUTPUT_422 |
+			       RKCIF_FORMAT_UV_STORAGE_ORDER_UVUV,
+		.cplanes = 2,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_NV16M,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_OUTPUT_422 |
+			       RKCIF_FORMAT_UV_STORAGE_ORDER_UVUV,
+		.cplanes = 2,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_NV61,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_OUTPUT_422 |
+			       RKCIF_FORMAT_UV_STORAGE_ORDER_VUVU,
+		.cplanes = 2,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_NV61M,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_OUTPUT_422 |
+			       RKCIF_FORMAT_UV_STORAGE_ORDER_VUVU,
+		.cplanes = 2,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_NV12,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_OUTPUT_420 |
+			       RKCIF_FORMAT_UV_STORAGE_ORDER_UVUV,
+		.cplanes = 2,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_NV12M,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_OUTPUT_420 |
+			       RKCIF_FORMAT_UV_STORAGE_ORDER_UVUV,
+		.cplanes = 2,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_NV21,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_OUTPUT_420 |
+			       RKCIF_FORMAT_UV_STORAGE_ORDER_VUVU,
+		.cplanes = 2,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_NV21M,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_OUTPUT_420 |
+			       RKCIF_FORMAT_UV_STORAGE_ORDER_VUVU,
+		.cplanes = 2,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_RGB24,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_RGB565,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_BGR666,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SRGGB8,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SGRBG8,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SGBRG8,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SBGGR8,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SRGGB10,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SGRBG10,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SGBRG10,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SBGGR10,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SRGGB12,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SGRBG12,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SGBRG12,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SBGGR12,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SBGGR16,
+		.cplanes = 1,
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_Y16,
+		.cplanes = 1,
+	},
+};
+
+static const struct rkcif_input_fmt px30_dvp_in_fmts[] = {
+	{
+		.mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_INPUT_422 |
+			       RKCIF_FORMAT_YUV_INPUT_ORDER_YUYV,
+		.fmt_type = RKCIF_FMT_TYPE_YUV,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_INPUT_422 |
+			       RKCIF_FORMAT_YUV_INPUT_ORDER_YUYV,
+		.fmt_type = RKCIF_FMT_TYPE_YUV,
+		.field = V4L2_FIELD_INTERLACED,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_YVYU8_2X8,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_INPUT_422 |
+			       RKCIF_FORMAT_YUV_INPUT_ORDER_YVYU,
+		.fmt_type = RKCIF_FMT_TYPE_YUV,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_YVYU8_2X8,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_INPUT_422 |
+			       RKCIF_FORMAT_YUV_INPUT_ORDER_YVYU,
+		.fmt_type = RKCIF_FMT_TYPE_YUV,
+		.field = V4L2_FIELD_INTERLACED,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_UYVY8_2X8,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_INPUT_422 |
+			       RKCIF_FORMAT_YUV_INPUT_ORDER_UYVY,
+		.fmt_type = RKCIF_FMT_TYPE_YUV,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_UYVY8_2X8,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_INPUT_422 |
+			       RKCIF_FORMAT_YUV_INPUT_ORDER_UYVY,
+		.fmt_type = RKCIF_FMT_TYPE_YUV,
+		.field = V4L2_FIELD_INTERLACED,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_VYUY8_2X8,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_INPUT_422 |
+			       RKCIF_FORMAT_YUV_INPUT_ORDER_VYUY,
+		.fmt_type = RKCIF_FMT_TYPE_YUV,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_VYUY8_2X8,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_INPUT_422 |
+			       RKCIF_FORMAT_YUV_INPUT_ORDER_VYUY,
+		.fmt_type = RKCIF_FMT_TYPE_YUV,
+		.field = V4L2_FIELD_INTERLACED,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,
+		.dvp_fmt_val = RKCIF_FORMAT_INPUT_MODE_RAW |
+			       RKCIF_FORMAT_RAW_DATA_WIDTH_8,
+		.fmt_type = RKCIF_FMT_TYPE_RAW,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8,
+		.dvp_fmt_val = RKCIF_FORMAT_INPUT_MODE_RAW |
+			       RKCIF_FORMAT_RAW_DATA_WIDTH_8,
+		.fmt_type = RKCIF_FMT_TYPE_RAW,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8,
+		.dvp_fmt_val = RKCIF_FORMAT_INPUT_MODE_RAW |
+			       RKCIF_FORMAT_RAW_DATA_WIDTH_8,
+		.fmt_type = RKCIF_FMT_TYPE_RAW,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8,
+		.dvp_fmt_val = RKCIF_FORMAT_INPUT_MODE_RAW |
+			       RKCIF_FORMAT_RAW_DATA_WIDTH_8,
+		.fmt_type = RKCIF_FMT_TYPE_RAW,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10,
+		.dvp_fmt_val = RKCIF_FORMAT_INPUT_MODE_RAW |
+			       RKCIF_FORMAT_RAW_DATA_WIDTH_10,
+		.fmt_type = RKCIF_FMT_TYPE_RAW,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10,
+		.dvp_fmt_val = RKCIF_FORMAT_INPUT_MODE_RAW |
+			       RKCIF_FORMAT_RAW_DATA_WIDTH_10,
+		.fmt_type = RKCIF_FMT_TYPE_RAW,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10,
+		.dvp_fmt_val = RKCIF_FORMAT_INPUT_MODE_RAW |
+			       RKCIF_FORMAT_RAW_DATA_WIDTH_10,
+		.fmt_type = RKCIF_FMT_TYPE_RAW,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10,
+		.dvp_fmt_val = RKCIF_FORMAT_INPUT_MODE_RAW |
+			       RKCIF_FORMAT_RAW_DATA_WIDTH_10,
+		.fmt_type = RKCIF_FMT_TYPE_RAW,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12,
+		.dvp_fmt_val = RKCIF_FORMAT_INPUT_MODE_RAW |
+			       RKCIF_FORMAT_RAW_DATA_WIDTH_12,
+		.fmt_type = RKCIF_FMT_TYPE_RAW,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12,
+		.dvp_fmt_val = RKCIF_FORMAT_INPUT_MODE_RAW |
+			       RKCIF_FORMAT_RAW_DATA_WIDTH_12,
+		.fmt_type = RKCIF_FMT_TYPE_RAW,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12,
+		.dvp_fmt_val = RKCIF_FORMAT_INPUT_MODE_RAW |
+			       RKCIF_FORMAT_RAW_DATA_WIDTH_12,
+		.fmt_type = RKCIF_FMT_TYPE_RAW,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12,
+		.dvp_fmt_val = RKCIF_FORMAT_INPUT_MODE_RAW |
+			       RKCIF_FORMAT_RAW_DATA_WIDTH_12,
+		.fmt_type = RKCIF_FMT_TYPE_RAW,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_RGB888_1X24,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_Y8_1X8,
+		.dvp_fmt_val = RKCIF_FORMAT_INPUT_MODE_RAW |
+			       RKCIF_FORMAT_RAW_DATA_WIDTH_8,
+		.fmt_type = RKCIF_FMT_TYPE_RAW,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_Y10_1X10,
+		.dvp_fmt_val = RKCIF_FORMAT_INPUT_MODE_RAW |
+			       RKCIF_FORMAT_RAW_DATA_WIDTH_10,
+		.fmt_type = RKCIF_FMT_TYPE_RAW,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_Y12_1X12,
+		.dvp_fmt_val = RKCIF_FORMAT_INPUT_MODE_RAW |
+			       RKCIF_FORMAT_RAW_DATA_WIDTH_12,
+		.fmt_type = RKCIF_FMT_TYPE_RAW,
+		.field = V4L2_FIELD_NONE,
+	}
+};
+
+const struct rkcif_dvp_match_data rkcif_px30_vip_dvp_match_data = {
+	.in_fmts = px30_dvp_in_fmts,
+	.in_fmts_num = ARRAY_SIZE(px30_dvp_in_fmts),
+	.out_fmts = dvp_out_fmts,
+	.out_fmts_num = ARRAY_SIZE(dvp_out_fmts),
+	.has_scaler = true,
+	.regs = {
+		[RKCIF_DVP_CTRL] = 0x00,
+		[RKCIF_DVP_INTEN] = 0x04,
+		[RKCIF_DVP_INTSTAT] = 0x08,
+		[RKCIF_DVP_FOR] = 0x0c,
+		[RKCIF_DVP_LINE_NUM_ADDR] = 0x10,
+		[RKCIF_DVP_FRM0_ADDR_Y] = 0x14,
+		[RKCIF_DVP_FRM0_ADDR_UV] = 0x18,
+		[RKCIF_DVP_FRM1_ADDR_Y] = 0x1c,
+		[RKCIF_DVP_FRM1_ADDR_UV] = 0x20,
+		[RKCIF_DVP_VIR_LINE_WIDTH] = 0x24,
+		[RKCIF_DVP_SET_SIZE] = 0x28,
+		[RKCIF_DVP_SCL_CTRL] = 0x48,
+		[RKCIF_DVP_FRAME_STATUS] = 0x60,
+		[RKCIF_DVP_LAST_LINE] = 0x68,
+		[RKCIF_DVP_LAST_PIX] = 0x6c,
+	},
+};
+
+static inline unsigned int rkcif_dvp_get_addr(struct rkcif_device *rkcif,
+					      unsigned int index)
+{
+	if (WARN_ON_ONCE(index >= RKCIF_DVP_REGISTER_MAX))
+		return RKCIF_REGISTER_NOTSUPPORTED;
+
+	return rkcif->match_data->dvp->regs[index];
+}
+
+static inline __maybe_unused void rkcif_dvp_write(struct rkcif_device *rkcif,
+						  unsigned int index, u32 val)
+{
+	unsigned int addr = rkcif_dvp_get_addr(rkcif, index);
+
+	if (addr == RKCIF_REGISTER_NOTSUPPORTED)
+		return;
+
+	writel(val, rkcif->base_addr + addr);
+}
+
+static inline __maybe_unused u32 rkcif_dvp_read(struct rkcif_device *rkcif,
+						unsigned int index)
+{
+	unsigned int addr = rkcif_dvp_get_addr(rkcif, index);
+
+	if (addr == RKCIF_REGISTER_NOTSUPPORTED)
+		return 0;
+
+	return readl(rkcif->base_addr + addr);
+}
+
+static void rkcif_dvp_queue_buffer(struct rkcif_stream *stream,
+				   unsigned int index)
+{
+	struct rkcif_device *rkcif = stream->rkcif;
+	struct rkcif_buffer *buffer = stream->buffers[index];
+	u32 frm_addr_y, frm_addr_uv;
+
+	frm_addr_y = index ? RKCIF_DVP_FRM1_ADDR_Y : RKCIF_DVP_FRM0_ADDR_Y;
+	frm_addr_uv = index ? RKCIF_DVP_FRM1_ADDR_UV : RKCIF_DVP_FRM0_ADDR_UV;
+
+	rkcif_dvp_write(rkcif, frm_addr_y, buffer->buff_addr[RKCIF_PLANE_Y]);
+	rkcif_dvp_write(rkcif, frm_addr_uv, buffer->buff_addr[RKCIF_PLANE_UV]);
+}
+
+static int rkcif_dvp_start_streaming(struct rkcif_stream *stream)
+{
+	struct rkcif_device *rkcif = stream->rkcif;
+	struct rkcif_interface *interface = stream->interface;
+	struct v4l2_mbus_config_parallel *parallel;
+	struct v4l2_mbus_framefmt *source_fmt;
+	struct v4l2_subdev_state *state;
+	const struct rkcif_input_fmt *active_in_fmt;
+	const struct rkcif_output_fmt *active_out_fmt;
+	u32 val = 0;
+	int ret = -EINVAL;
+
+	state = v4l2_subdev_lock_and_get_active_state(&interface->sd);
+	source_fmt = v4l2_subdev_state_get_format(state, RKCIF_IF_PAD_SRC,
+						  stream->id);
+	if (!source_fmt)
+		goto out;
+
+	active_in_fmt = rkcif_interface_find_input_fmt(interface, false,
+						       source_fmt->code);
+	active_out_fmt = rkcif_stream_find_output_fmt(stream, false,
+						      stream->pix.pixelformat);
+	if (!active_in_fmt || !active_out_fmt)
+		goto out;
+
+	parallel = &interface->vep.bus.parallel;
+	if (parallel->bus_width == 16 &&
+	    (parallel->flags & V4L2_MBUS_PCLK_SAMPLE_DUALEDGE))
+		val |= RKCIF_FORMAT_BT1120_CLOCK_DOUBLE_EDGES;
+	val |= active_in_fmt->dvp_fmt_val;
+	val |= active_out_fmt->dvp_fmt_val;
+	rkcif_dvp_write(rkcif, RKCIF_DVP_FOR, val);
+
+	val = stream->pix.width;
+	if (active_in_fmt->fmt_type == RKCIF_FMT_TYPE_RAW)
+		val = stream->pix.width * 2;
+	rkcif_dvp_write(rkcif, RKCIF_DVP_VIR_LINE_WIDTH, val);
+
+	val = RKCIF_XY_COORD(stream->pix.width, stream->pix.height);
+	rkcif_dvp_write(rkcif, RKCIF_DVP_SET_SIZE, val);
+
+	rkcif_dvp_write(rkcif, RKCIF_DVP_FRAME_STATUS, RKCIF_FRAME_STAT_CLS);
+	rkcif_dvp_write(rkcif, RKCIF_DVP_INTSTAT, RKCIF_INTSTAT_CLS);
+	if (rkcif->match_data->dvp->has_scaler) {
+		val = active_in_fmt->fmt_type == RKCIF_FMT_TYPE_YUV ?
+			      RKCIF_SCL_CTRL_ENABLE_YUV_16BIT_BYPASS :
+			      RKCIF_SCL_CTRL_ENABLE_RAW_16BIT_BYPASS;
+		rkcif_dvp_write(rkcif, RKCIF_DVP_SCL_CTRL, val);
+	}
+
+	rkcif_dvp_write(rkcif, RKCIF_DVP_INTEN,
+			RKCIF_INTEN_FRAME_END_EN |
+			RKCIF_INTEN_PST_INF_FRAME_END_EN);
+
+	rkcif_dvp_write(rkcif, RKCIF_DVP_CTRL,
+			RKCIF_CTRL_AXI_BURST_16 | RKCIF_CTRL_MODE_PINGPONG |
+			RKCIF_CTRL_ENABLE_CAPTURE);
+
+	ret = 0;
+
+out:
+	v4l2_subdev_unlock_state(state);
+	return ret;
+}
+
+static void rkcif_dvp_stop_streaming(struct rkcif_stream *stream)
+{
+	struct rkcif_device *rkcif = stream->rkcif;
+	u32 val;
+
+	val = rkcif_dvp_read(rkcif, RKCIF_DVP_CTRL);
+	rkcif_dvp_write(rkcif, RKCIF_DVP_CTRL,
+			val & (~RKCIF_CTRL_ENABLE_CAPTURE));
+	rkcif_dvp_write(rkcif, RKCIF_DVP_INTEN, 0x0);
+	rkcif_dvp_write(rkcif, RKCIF_DVP_INTSTAT, 0x3ff);
+	rkcif_dvp_write(rkcif, RKCIF_DVP_FRAME_STATUS, 0x0);
+
+	stream->stopping = false;
+}
+
+static void rkcif_dvp_reset_stream(struct rkcif_device *rkcif)
+{
+	u32 ctl = rkcif_dvp_read(rkcif, RKCIF_DVP_CTRL);
+
+	rkcif_dvp_write(rkcif, RKCIF_DVP_CTRL,
+			ctl & (~RKCIF_CTRL_ENABLE_CAPTURE));
+	rkcif_dvp_write(rkcif, RKCIF_DVP_CTRL, ctl | RKCIF_CTRL_ENABLE_CAPTURE);
+}
+
+static void rkcif_dvp_set_crop(struct rkcif_stream *stream, u16 left, u16 top)
+{
+	struct rkcif_device *rkcif = stream->rkcif;
+	u32 val;
+
+	val = RKCIF_XY_COORD(left, top);
+	rkcif_dvp_write(rkcif, RKCIF_DVP_CROP, val);
+}
+
+irqreturn_t rkcif_dvp_isr(int irq, void *ctx)
+{
+	struct device *dev = ctx;
+	struct rkcif_device *rkcif = dev_get_drvdata(dev);
+	struct rkcif_stream *stream;
+	u32 intstat, lastline, lastpix, cif_frmst;
+	irqreturn_t ret = IRQ_NONE;
+
+	if (!rkcif->match_data->dvp)
+		return ret;
+
+	intstat = rkcif_dvp_read(rkcif, RKCIF_DVP_INTSTAT);
+	cif_frmst = rkcif_dvp_read(rkcif, RKCIF_DVP_FRAME_STATUS);
+	lastline = RKCIF_FETCH_Y(rkcif_dvp_read(rkcif, RKCIF_DVP_LAST_LINE));
+	lastpix = RKCIF_FETCH_Y(rkcif_dvp_read(rkcif, RKCIF_DVP_LAST_PIX));
+
+	if (intstat & RKCIF_INTSTAT_FRAME_END) {
+		rkcif_dvp_write(rkcif, RKCIF_DVP_INTSTAT,
+				RKCIF_INTSTAT_FRAME_END_CLR |
+				RKCIF_INTSTAT_LINE_END_CLR);
+
+		stream = &rkcif->interfaces[RKCIF_DVP].streams[RKCIF_ID0];
+
+		if (stream->stopping) {
+			rkcif_dvp_stop_streaming(stream);
+			wake_up(&stream->wq_stopped);
+			ret = IRQ_HANDLED;
+			goto out;
+		}
+
+		if (lastline != stream->pix.height) {
+			v4l2_err(&rkcif->v4l2_dev,
+				 "bad frame, irq:%#x frmst:%#x size:%dx%d\n",
+				 intstat, cif_frmst, lastpix, lastline);
+
+			rkcif_dvp_reset_stream(rkcif);
+		}
+
+		rkcif_stream_pingpong(stream);
+
+		ret = IRQ_HANDLED;
+	}
+out:
+	return ret;
+}
+
+int rkcif_dvp_register(struct rkcif_device *rkcif)
+{
+	struct rkcif_interface *interface;
+	unsigned int streams_num;
+	int ret;
+
+	if (!rkcif->match_data->dvp)
+		return 0;
+
+	interface = &rkcif->interfaces[RKCIF_DVP];
+	interface->index = RKCIF_DVP;
+	interface->type = RKCIF_IF_DVP;
+	interface->in_fmts = rkcif->match_data->dvp->in_fmts;
+	interface->in_fmts_num = rkcif->match_data->dvp->in_fmts_num;
+	interface->set_crop = rkcif_dvp_set_crop;
+	ret = rkcif_interface_register(rkcif, interface);
+	if (ret)
+		return ret;
+
+	if (rkcif->match_data->dvp->setup)
+		rkcif->match_data->dvp->setup(rkcif);
+
+	streams_num = rkcif->match_data->dvp->has_ids ? 4 : 1;
+	for (unsigned int i = 0; i < streams_num; i++) {
+		struct rkcif_stream *stream = &interface->streams[i];
+
+		stream->id = i;
+		stream->interface = interface;
+		stream->out_fmts = rkcif->match_data->dvp->out_fmts;
+		stream->out_fmts_num = rkcif->match_data->dvp->out_fmts_num;
+		stream->queue_buffer = rkcif_dvp_queue_buffer;
+		stream->start_streaming = rkcif_dvp_start_streaming;
+		stream->stop_streaming = rkcif_dvp_stop_streaming;
+
+		ret = rkcif_stream_register(rkcif, stream);
+		if (ret)
+			goto err_streams_unregister;
+
+		interface->streams_num++;
+	}
+
+	return 0;
+
+err_streams_unregister:
+	for (unsigned int i = 0; i < interface->streams_num; i++)
+		rkcif_stream_unregister(&interface->streams[i]);
+
+	rkcif_interface_unregister(interface);
+
+	return ret;
+}
+
+void rkcif_dvp_unregister(struct rkcif_device *rkcif)
+{
+	struct rkcif_interface *interface;
+
+	if (!rkcif->match_data->dvp)
+		return;
+
+	interface = &rkcif->interfaces[RKCIF_DVP];
+
+	for (unsigned int i = 0; i < interface->streams_num; i++)
+		rkcif_stream_unregister(&interface->streams[i]);
+
+	rkcif_interface_unregister(interface);
+}
diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-capture-dvp.h b/drivers/media/platform/rockchip/rkcif/rkcif-capture-dvp.h
new file mode 100644
index 000000000000..7b2da11497c3
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkcif/rkcif-capture-dvp.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Rockchip Camera Interface (CIF) Driver
+ *
+ * Copyright (C) 2018 Rockchip Electronics Co., Ltd.
+ * Copyright (C) 2023 Mehdi Djait <mehdi.djait at bootlin.com>
+ * Copyright (C) 2025 Michael Riesch <michael.riesch at wolfvision.net>
+ * Copyright (C) 2025 Collabora, Ltd.
+ */
+
+#ifndef _RKCIF_CAPTURE_DVP_H
+#define _RKCIF_CAPTURE_DVP_H
+
+#include "rkcif-common.h"
+
+extern const struct rkcif_dvp_match_data rkcif_px30_vip_dvp_match_data;
+
+int rkcif_dvp_register(struct rkcif_device *rkcif);
+
+void rkcif_dvp_unregister(struct rkcif_device *rkcif);
+
+irqreturn_t rkcif_dvp_isr(int irq, void *ctx);
+
+#endif
diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-common.h b/drivers/media/platform/rockchip/rkcif/rkcif-common.h
index 63d5b45c7afe..c6ec578e1049 100644
--- a/drivers/media/platform/rockchip/rkcif/rkcif-common.h
+++ b/drivers/media/platform/rockchip/rkcif/rkcif-common.h
@@ -24,6 +24,8 @@
 #include <media/v4l2-subdev.h>
 #include <media/videobuf2-v4l2.h>
 
+#include "rkcif-regs.h"
+
 #define RKCIF_DRIVER_NAME "rockchip-cif"
 #define RKCIF_CLK_MAX	  4
 
@@ -84,17 +86,31 @@ struct rkcif_dummy_buffer {
 	u32 size;
 };
 
+enum rkcif_plane_index {
+	RKCIF_PLANE_Y,
+	RKCIF_PLANE_UV,
+	RKCIF_PLANE_MAX
+};
+
 struct rkcif_input_fmt {
 	u32 mbus_code;
 
 	enum rkcif_format_type fmt_type;
 	enum v4l2_field field;
+
+	union {
+		u32 dvp_fmt_val;
+	};
 };
 
 struct rkcif_output_fmt {
 	u32 fourcc;
 	u32 mbus_code;
 	u8 cplanes;
+
+	union {
+		u32 dvp_fmt_val;
+	};
 };
 
 struct rkcif_interface;
@@ -168,9 +184,21 @@ struct rkcif_interface {
 	void (*set_crop)(struct rkcif_stream *stream, u16 left, u16 top);
 };
 
+struct rkcif_dvp_match_data {
+	const struct rkcif_input_fmt *in_fmts;
+	unsigned int in_fmts_num;
+	const struct rkcif_output_fmt *out_fmts;
+	unsigned int out_fmts_num;
+	void (*setup)(struct rkcif_device *rkcif);
+	bool has_scaler;
+	bool has_ids;
+	unsigned int regs[RKCIF_DVP_REGISTER_MAX];
+};
+
 struct rkcif_match_data {
 	const char *const *clks;
 	unsigned int clks_num;
+	const struct rkcif_dvp_match_data *dvp;
 };
 
 struct rkcif_device {
diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-dev.c b/drivers/media/platform/rockchip/rkcif/rkcif-dev.c
index 49e53f70715c..207802073fd3 100644
--- a/drivers/media/platform/rockchip/rkcif/rkcif-dev.c
+++ b/drivers/media/platform/rockchip/rkcif/rkcif-dev.c
@@ -23,6 +23,7 @@
 #include <media/v4l2-fwnode.h>
 #include <media/v4l2-mc.h>
 
+#include "rkcif-capture-dvp.h"
 #include "rkcif-common.h"
 
 static const char *const px30_vip_clks[] = {
@@ -34,6 +35,7 @@ static const char *const px30_vip_clks[] = {
 static const struct rkcif_match_data px30_vip_match_data = {
 	.clks = px30_vip_clks,
 	.clks_num = ARRAY_SIZE(px30_vip_clks),
+	.dvp = &rkcif_px30_vip_dvp_match_data,
 };
 
 static const char *const rk3568_vicap_clks[] = {
@@ -63,11 +65,21 @@ MODULE_DEVICE_TABLE(of, rkcif_plat_of_match);
 
 static int rkcif_register(struct rkcif_device *rkcif)
 {
+	int ret;
+
+	ret = rkcif_dvp_register(rkcif);
+	if (ret && ret != -ENODEV)
+		goto err;
+
 	return 0;
+
+err:
+	return ret;
 }
 
 static void rkcif_unregister(struct rkcif_device *rkcif)
 {
+	rkcif_dvp_unregister(rkcif);
 }
 
 static int rkcif_notifier_bound(struct v4l2_async_notifier *notifier,
@@ -112,6 +124,9 @@ static irqreturn_t rkcif_isr(int irq, void *ctx)
 {
 	irqreturn_t ret = IRQ_NONE;
 
+	if (rkcif_dvp_isr(irq, ctx) == IRQ_HANDLED)
+		ret = IRQ_HANDLED;
+
 	return ret;
 }
 
diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-regs.h b/drivers/media/platform/rockchip/rkcif/rkcif-regs.h
new file mode 100644
index 000000000000..91d42d31fd10
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkcif/rkcif-regs.h
@@ -0,0 +1,131 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Rockchip Camera Interface (CIF) Driver
+ *
+ * Copyright (C) 2018 Rockchip Electronics Co., Ltd.
+ * Copyright (C) 2023 Mehdi Djait <mehdi.djait at bootlin.com>
+ * Copyright (C) 2025 Michael Riesch <michael.riesch at wolfvision.net>
+ */
+
+#ifndef _RKCIF_REGS_H
+#define _RKCIF_REGS_H
+
+#define RKCIF_REGISTER_NOTSUPPORTED		0x420000
+#define RKCIF_FETCH_Y(VAL)			((VAL) & 0x1fff)
+#define RKCIF_XY_COORD(x, y)			(((y) << 16) | (x))
+
+/* DVP register contents */
+#define RKCIF_CTRL_ENABLE_CAPTURE		BIT(0)
+#define RKCIF_CTRL_MODE_PINGPONG		BIT(1)
+#define RKCIF_CTRL_MODE_LINELOOP		BIT(2)
+#define RKCIF_CTRL_AXI_BURST_16			(0xf << 12)
+
+#define RKCIF_INTEN_FRAME_END_EN		BIT(0)
+#define RKCIF_INTEN_LINE_ERR_EN			BIT(2)
+#define RKCIF_INTEN_BUS_ERR_EN			BIT(6)
+#define RKCIF_INTEN_SCL_ERR_EN			BIT(7)
+#define RKCIF_INTEN_PST_INF_FRAME_END_EN	BIT(9)
+
+#define RKCIF_INTSTAT_CLS			0x3ff
+#define RKCIF_INTSTAT_FRAME_END			BIT(0)
+#define RKCIF_INTSTAT_LINE_END			BIT(1)
+#define RKCIF_INTSTAT_LINE_ERR			BIT(2)
+#define RKCIF_INTSTAT_PIX_ERR			BIT(3)
+#define RKCIF_INTSTAT_DFIFO_OF			BIT(5)
+#define RKCIF_INTSTAT_BUS_ERR			BIT(6)
+#define RKCIF_INTSTAT_PRE_INF_FRAME_END		BIT(8)
+#define RKCIF_INTSTAT_PST_INF_FRAME_END		BIT(9)
+#define RKCIF_INTSTAT_FRAME_END_CLR		BIT(0)
+#define RKCIF_INTSTAT_LINE_END_CLR		BIT(1)
+#define RKCIF_INTSTAT_LINE_ERR_CLR		BIT(2)
+#define RKCIF_INTSTAT_PST_INF_FRAME_END_CLR	BIT(9)
+#define RKCIF_INTSTAT_ERR			0xfc
+
+#define RKCIF_FRAME_STAT_CLS			0x00
+#define RKCIF_FRAME_FRM0_STAT_CLS		0x20
+
+#define RKCIF_FORMAT_VSY_HIGH_ACTIVE		BIT(0)
+#define RKCIF_FORMAT_HSY_LOW_ACTIVE		BIT(1)
+
+#define RKCIF_FORMAT_INPUT_MODE_YUV		(0x00 << 2)
+#define RKCIF_FORMAT_INPUT_MODE_PAL		(0x02 << 2)
+#define RKCIF_FORMAT_INPUT_MODE_NTSC		(0x03 << 2)
+#define RKCIF_FORMAT_INPUT_MODE_BT1120		(0x07 << 2)
+#define RKCIF_FORMAT_INPUT_MODE_RAW		(0x04 << 2)
+#define RKCIF_FORMAT_INPUT_MODE_JPEG		(0x05 << 2)
+#define RKCIF_FORMAT_INPUT_MODE_MIPI		(0x06 << 2)
+
+#define RKCIF_FORMAT_YUV_INPUT_ORDER_UYVY	(0x00 << 5)
+#define RKCIF_FORMAT_YUV_INPUT_ORDER_YVYU	(0x01 << 5)
+#define RKCIF_FORMAT_YUV_INPUT_ORDER_VYUY	(0x02 << 5)
+#define RKCIF_FORMAT_YUV_INPUT_ORDER_YUYV	(0x03 << 5)
+#define RKCIF_FORMAT_YUV_INPUT_422		(0x00 << 7)
+#define RKCIF_FORMAT_YUV_INPUT_420		BIT(7)
+
+#define RKCIF_FORMAT_INPUT_420_ORDER_ODD	BIT(8)
+
+#define RKCIF_FORMAT_CCIR_INPUT_ORDER_EVEN	BIT(9)
+
+#define RKCIF_FORMAT_RAW_DATA_WIDTH_8		(0x00 << 11)
+#define RKCIF_FORMAT_RAW_DATA_WIDTH_10		(0x01 << 11)
+#define RKCIF_FORMAT_RAW_DATA_WIDTH_12		(0x02 << 11)
+
+#define RKCIF_FORMAT_YUV_OUTPUT_422		(0x00 << 16)
+#define RKCIF_FORMAT_YUV_OUTPUT_420		BIT(16)
+
+#define RKCIF_FORMAT_OUTPUT_420_ORDER_EVEN	(0x00 << 17)
+#define RKCIF_FORMAT_OUTPUT_420_ORDER_ODD	BIT(17)
+
+#define RKCIF_FORMAT_RAWD_DATA_LITTLE_ENDIAN	(0x00 << 18)
+#define RKCIF_FORMAT_RAWD_DATA_BIG_ENDIAN	BIT(18)
+
+#define RKCIF_FORMAT_UV_STORAGE_ORDER_UVUV	(0x00 << 19)
+#define RKCIF_FORMAT_UV_STORAGE_ORDER_VUVU	BIT(19)
+
+#define RKCIF_FORMAT_BT1120_CLOCK_SINGLE_EDGES	(0x00 << 24)
+#define RKCIF_FORMAT_BT1120_CLOCK_DOUBLE_EDGES	BIT(24)
+#define RKCIF_FORMAT_BT1120_TRANSMIT_INTERFACE	(0x00 << 25)
+#define RKCIF_FORMAT_BT1120_TRANSMIT_PROGRESS	BIT(25)
+#define RKCIF_FORMAT_BT1120_YC_SWAP		BIT(26)
+
+#define RKCIF_SCL_CTRL_ENABLE_SCL_DOWN		BIT(0)
+#define RKCIF_SCL_CTRL_ENABLE_SCL_UP		BIT(1)
+#define RKCIF_SCL_CTRL_ENABLE_YUV_16BIT_BYPASS	BIT(4)
+#define RKCIF_SCL_CTRL_ENABLE_RAW_16BIT_BYPASS	BIT(5)
+#define RKCIF_SCL_CTRL_ENABLE_32BIT_BYPASS	BIT(6)
+#define RKCIF_SCL_CTRL_DISABLE_32BIT_BYPASS	(0x00 << 6)
+
+#define RKCIF_INTSTAT_F0_READY			BIT(0)
+#define RKCIF_INTSTAT_F1_READY			BIT(1)
+
+/* GRF register offsets and contents */
+#define RK3568_GRF_VI_CON0			0x340
+#define RK3568_GRF_VI_CON1			0x344
+#define RK3568_GRF_VI_STATUS0			0x348
+
+#define RK3568_GRF_VI_CON1_CIF_DATAPATH		BIT(9)
+#define RK3568_GRF_VI_CON1_CIF_CLK_DELAYNUM	GENMASK(6, 0)
+
+#define RK3568_GRF_WRITE_ENABLE(x)		((x) << 16)
+
+enum rkcif_dvp_register_index {
+	RKCIF_DVP_CTRL,
+	RKCIF_DVP_INTEN,
+	RKCIF_DVP_INTSTAT,
+	RKCIF_DVP_FOR,
+	RKCIF_DVP_LINE_NUM_ADDR,
+	RKCIF_DVP_FRM0_ADDR_Y,
+	RKCIF_DVP_FRM0_ADDR_UV,
+	RKCIF_DVP_FRM1_ADDR_Y,
+	RKCIF_DVP_FRM1_ADDR_UV,
+	RKCIF_DVP_VIR_LINE_WIDTH,
+	RKCIF_DVP_SET_SIZE,
+	RKCIF_DVP_SCL_CTRL,
+	RKCIF_DVP_CROP,
+	RKCIF_DVP_FRAME_STATUS,
+	RKCIF_DVP_LAST_LINE,
+	RKCIF_DVP_LAST_PIX,
+	RKCIF_DVP_REGISTER_MAX
+};
+
+#endif

-- 
2.39.5




From devnull+michael.riesch.collabora.com at kernel.org  Fri Nov 14 07:20:23 2025
From: devnull+michael.riesch.collabora.com at kernel.org (Michael Riesch via B4 Relay)
Date: Fri, 14 Nov 2025 16:20:23 +0100
Subject: [PATCH v15 12/14] arm64: dts: rockchip: add the vip node to px30
In-Reply-To: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
References: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
Message-ID: <20240220-rk3568-vicap-v15-12-8f4915ee365d@collabora.com>

From: Mehdi Djait <mehdi.djait at bootlin.com>

Add the device tree node for the PX30 Video Input Processor (VIP).

Signed-off-by: Mehdi Djait <mehdi.djait at bootlin.com>
[added cosmetic changes]
Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
Signed-off-by: Michael Riesch <michael.riesch at collabora.com>
---
 arch/arm64/boot/dts/rockchip/px30.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/px30.dtsi b/arch/arm64/boot/dts/rockchip/px30.dtsi
index 46f64cd33b9b..ef52879d6a73 100644
--- a/arch/arm64/boot/dts/rockchip/px30.dtsi
+++ b/arch/arm64/boot/dts/rockchip/px30.dtsi
@@ -1280,6 +1280,18 @@ isp_mmu: iommu at ff4a8000 {
 		#iommu-cells = <0>;
 	};
 
+	cif: video-capture at ff490000 {
+		compatible = "rockchip,px30-vip";
+		reg = <0x0 0xff490000 0x0 0x200>;
+		interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru ACLK_CIF>, <&cru HCLK_CIF>, <&cru PCLK_CIF>;
+		clock-names = "aclk", "hclk", "pclk";
+		power-domains = <&power PX30_PD_VI>;
+		resets = <&cru SRST_CIF_A>, <&cru SRST_CIF_H>, <&cru SRST_CIF_PCLKIN>;
+		reset-names = "axi", "ahb", "pclkin";
+		status = "disabled";
+	};
+
 	qos_gmac: qos at ff518000 {
 		compatible = "rockchip,px30-qos", "syscon";
 		reg = <0x0 0xff518000 0x0 0x20>;

-- 
2.39.5




From devnull+michael.riesch.collabora.com at kernel.org  Fri Nov 14 07:20:12 2025
From: devnull+michael.riesch.collabora.com at kernel.org (Michael Riesch via B4 Relay)
Date: Fri, 14 Nov 2025 16:20:12 +0100
Subject: [PATCH v15 01/14] Documentation: admin-guide: media: add rockchip
 camera interface
In-Reply-To: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
References: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
Message-ID: <20240220-rk3568-vicap-v15-1-8f4915ee365d@collabora.com>

From: Michael Riesch <michael.riesch at collabora.com>

Add a document that describes the different variants of the Rockchip
Camera Interface (CIF), their hardware layout, as well as their
representation in the media controller centric rkcif device driver,
which is located under drivers/media/platform/rockchip/rkcif.

Reviewed-by: Heiko Stuebner <heiko at sntech.de>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
Signed-off-by: Michael Riesch <michael.riesch at collabora.com>
---
 .../admin-guide/media/rkcif-rk3568-vicap.dot       |  8 +++
 Documentation/admin-guide/media/rkcif.rst          | 79 ++++++++++++++++++++++
 Documentation/admin-guide/media/v4l-drivers.rst    |  1 +
 MAINTAINERS                                        |  7 ++
 4 files changed, 95 insertions(+)

diff --git a/Documentation/admin-guide/media/rkcif-rk3568-vicap.dot b/Documentation/admin-guide/media/rkcif-rk3568-vicap.dot
new file mode 100644
index 000000000000..3fac59335459
--- /dev/null
+++ b/Documentation/admin-guide/media/rkcif-rk3568-vicap.dot
@@ -0,0 +1,8 @@
+digraph board {
+        rankdir=TB
+        n00000001 [label="{{<port0> 0} | rkcif-dvp0\n/dev/v4l-subdev0 | {<port1> 1}}", shape=Mrecord, style=filled, fillcolor=green]
+        n00000001:port1 -> n00000004
+        n00000004 [label="rkcif-dvp0-id0\n/dev/video0", shape=box, style=filled, fillcolor=yellow]
+        n00000025 [label="{{} | it6801 2-0048\n/dev/v4l-subdev1 | {<port0> 0}}", shape=Mrecord, style=filled, fillcolor=green]
+        n00000025:port0 -> n00000001:port0
+}
diff --git a/Documentation/admin-guide/media/rkcif.rst b/Documentation/admin-guide/media/rkcif.rst
new file mode 100644
index 000000000000..2558c121abc4
--- /dev/null
+++ b/Documentation/admin-guide/media/rkcif.rst
@@ -0,0 +1,79 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=========================================
+Rockchip Camera Interface (CIF)
+=========================================
+
+Introduction
+============
+
+The Rockchip Camera Interface (CIF) is featured in many Rockchip SoCs in
+different variants.
+The different variants are combinations of common building blocks, such as
+
+* INTERFACE blocks of different types, namely
+
+  * the Digital Video Port (DVP, a parallel data interface)
+  * the interface block for the MIPI CSI-2 receiver
+
+* CROP units
+
+* MIPI CSI-2 receiver (not available on all variants): This unit is referred
+  to as MIPI CSI HOST in the Rockchip documentation.
+  Technically, it is a separate hardware block, but it is strongly coupled to
+  the CIF and therefore included here.
+
+* MUX units (not available on all variants) that pass the video data to an
+  image signal processor (ISP)
+
+* SCALE units (not available on all variants)
+
+* DMA engines that transfer video data into system memory using a
+  double-buffering mechanism called ping-pong mode
+
+* Support for four streams per INTERFACE block (not available on all
+  variants), e.g., for MIPI CSI-2 Virtual Channels (VCs)
+
+This document describes the different variants of the CIF, their hardware
+layout, as well as their representation in the media controller centric rkcif
+device driver, which is located under drivers/media/platform/rockchip/rkcif.
+
+Variants
+========
+
+Rockchip PX30 Video Input Processor (VIP)
+-----------------------------------------
+
+The PX30 Video Input Processor (VIP) features a digital video port that accepts
+parallel video data or BT.656.
+Since these protocols do not feature multiple streams, the VIP has one DMA
+engine that transfers the input video data into system memory.
+
+The rkcif driver represents this hardware variant by exposing one V4L2 subdevice
+(the DVP INTERFACE/CROP block) and one V4L2 device (the DVP DMA engine).
+
+Rockchip RK3568 Video Capture (VICAP)
+-------------------------------------
+
+The RK3568 Video Capture (VICAP) unit features a digital video port and a MIPI
+CSI-2 receiver that can receive video data independently.
+The DVP accepts parallel video data, BT.656 and BT.1120.
+Since the BT.1120 protocol may feature more than one stream, the RK3568 VICAP
+DVP features four DMA engines that can capture different streams.
+Similarly, the RK3568 VICAP MIPI CSI-2 receiver features four DMA engines to
+handle different Virtual Channels (VCs).
+
+The rkcif driver represents this hardware variant by exposing up the following
+V4L2 subdevices:
+
+* rkcif-dvp0: INTERFACE/CROP block for the DVP
+
+and the following video devices:
+
+* rkcif-dvp0-id0: The support for multiple streams on the DVP is not yet
+  implemented, as it is hard to find test hardware. Thus, this video device
+  represents the first DMA engine of the RK3568 DVP.
+
+.. kernel-figure:: rkcif-rk3568-vicap.dot
+    :alt:   Topology of the RK3568 Video Capture (VICAP) unit
+    :align: center
diff --git a/Documentation/admin-guide/media/v4l-drivers.rst b/Documentation/admin-guide/media/v4l-drivers.rst
index 3bac5165b134..694fad685ff5 100644
--- a/Documentation/admin-guide/media/v4l-drivers.rst
+++ b/Documentation/admin-guide/media/v4l-drivers.rst
@@ -25,6 +25,7 @@ Video4Linux (V4L) driver-specific documentation
 	qcom_camss
 	raspberrypi-pisp-be
 	rcar-fdp1
+	rkcif
 	rkisp1
 	raspberrypi-rp1-cfe
 	saa7134
diff --git a/MAINTAINERS b/MAINTAINERS
index 42b20f33f3bb..2e1f959bb5f4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22242,6 +22242,13 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml
 F:	drivers/net/can/rockchip/
 
+ROCKCHIP CAMERA INTERFACE (RKCIF) DRIVER
+M:	Mehdi Djait <mehdi.djait at linux.intel.com>
+M:	Michael Riesch <michael.riesch at collabora.com>
+L:	linux-media at vger.kernel.org
+S:	Maintained
+F:	Documentation/admin-guide/media/rkcif*
+
 ROCKCHIP CRYPTO DRIVERS
 M:	Corentin Labbe <clabbe at baylibre.com>
 L:	linux-crypto at vger.kernel.org

-- 
2.39.5




From devnull+michael.riesch.collabora.com at kernel.org  Fri Nov 14 07:20:17 2025
From: devnull+michael.riesch.collabora.com at kernel.org (Michael Riesch via B4 Relay)
Date: Fri, 14 Nov 2025 16:20:17 +0100
Subject: [PATCH v15 06/14] media: rockchip: rkcif: add abstraction for
 interface and crop blocks
In-Reply-To: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
References: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
Message-ID: <20240220-rk3568-vicap-v15-6-8f4915ee365d@collabora.com>

From: Michael Riesch <michael.riesch at collabora.com>

Add an abstraction for the INTERFACE and CROP parts of the different
Rockchip Camera Interface (CIF) variants. These parts are represented
as V4L2 subdevice with one sink pad and one source pad. The sink pad
is connected to a subdevice: either the subdevice provided by the
driver of the companion chip connected to the DVP, or the subdevice
provided by the MIPI CSI-2 receiver. The source pad is connected to
V4l2 device(s) provided by one or many instance(s) of the DMA
abstraction.

Tested-by: Gerald Loacker <gerald.loacker at wolfvision.net>
Reviewed-by: Gerald Loacker <gerald.loacker at wolfvision.net>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
Reviewed-by: Mehdi Djait <mehdi.djait at linux.intel.com>
Signed-off-by: Michael Riesch <michael.riesch at collabora.com>
---
 drivers/media/platform/rockchip/rkcif/Makefile     |   1 +
 .../media/platform/rockchip/rkcif/rkcif-common.h   |  71 ++++
 drivers/media/platform/rockchip/rkcif/rkcif-dev.c  |  13 +
 .../platform/rockchip/rkcif/rkcif-interface.c      | 405 +++++++++++++++++++++
 .../platform/rockchip/rkcif/rkcif-interface.h      |  31 ++
 5 files changed, 521 insertions(+)

diff --git a/drivers/media/platform/rockchip/rkcif/Makefile b/drivers/media/platform/rockchip/rkcif/Makefile
index c6837ed2f65c..9d535fc27e51 100644
--- a/drivers/media/platform/rockchip/rkcif/Makefile
+++ b/drivers/media/platform/rockchip/rkcif/Makefile
@@ -2,3 +2,4 @@
 obj-$(CONFIG_VIDEO_ROCKCHIP_CIF) += rockchip-cif.o
 
 rockchip-cif-objs += rkcif-dev.o
+rockchip-cif-objs += rkcif-interface.o
diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-common.h b/drivers/media/platform/rockchip/rkcif/rkcif-common.h
index b456a56b5ac4..f01536727a5d 100644
--- a/drivers/media/platform/rockchip/rkcif/rkcif-common.h
+++ b/drivers/media/platform/rockchip/rkcif/rkcif-common.h
@@ -27,9 +27,78 @@
 #define RKCIF_DRIVER_NAME "rockchip-cif"
 #define RKCIF_CLK_MAX	  4
 
+enum rkcif_format_type {
+	RKCIF_FMT_TYPE_INVALID,
+	RKCIF_FMT_TYPE_YUV,
+	RKCIF_FMT_TYPE_RAW,
+};
+
+enum rkcif_interface_index {
+	RKCIF_DVP,
+	RKCIF_MIPI_BASE,
+	RKCIF_MIPI1 = RKCIF_MIPI_BASE,
+	RKCIF_MIPI2,
+	RKCIF_MIPI3,
+	RKCIF_MIPI4,
+	RKCIF_MIPI5,
+	RKCIF_MIPI6,
+	RKCIF_MIPI_MAX,
+	RKCIF_IF_MAX = RKCIF_MIPI_MAX
+};
+
+enum rkcif_interface_pad_index {
+	RKCIF_IF_PAD_SINK,
+	RKCIF_IF_PAD_SRC,
+	RKCIF_IF_PAD_MAX
+};
+
+enum rkcif_interface_status {
+	RKCIF_IF_INACTIVE,
+	RKCIF_IF_ACTIVE,
+};
+
+enum rkcif_interface_type {
+	RKCIF_IF_INVALID,
+	RKCIF_IF_DVP,
+	RKCIF_IF_MIPI,
+};
+
+struct rkcif_input_fmt {
+	u32 mbus_code;
+
+	enum rkcif_format_type fmt_type;
+	enum v4l2_field field;
+};
+
+struct rkcif_interface;
+
 struct rkcif_remote {
 	struct v4l2_async_connection async_conn;
 	struct v4l2_subdev *sd;
+
+	struct rkcif_interface *interface;
+};
+
+struct rkcif_dvp {
+	u32 dvp_clk_delay;
+};
+
+struct rkcif_interface {
+	enum rkcif_interface_type type;
+	enum rkcif_interface_status status;
+	enum rkcif_interface_index index;
+	struct rkcif_device *rkcif;
+	struct rkcif_remote *remote;
+	const struct rkcif_input_fmt *in_fmts;
+	unsigned int in_fmts_num;
+
+	struct media_pad pads[RKCIF_IF_PAD_MAX];
+	struct v4l2_fwnode_endpoint vep;
+	struct v4l2_subdev sd;
+
+	union {
+		struct rkcif_dvp dvp;
+	};
 };
 
 struct rkcif_match_data {
@@ -47,6 +116,8 @@ struct rkcif_device {
 	struct reset_control *reset;
 	void __iomem *base_addr;
 
+	struct rkcif_interface interfaces[RKCIF_IF_MAX];
+
 	struct media_device media_dev;
 	struct v4l2_device v4l2_dev;
 	struct v4l2_async_notifier notifier;
diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-dev.c b/drivers/media/platform/rockchip/rkcif/rkcif-dev.c
index 9215dbe90353..49e53f70715c 100644
--- a/drivers/media/platform/rockchip/rkcif/rkcif-dev.c
+++ b/drivers/media/platform/rockchip/rkcif/rkcif-dev.c
@@ -74,8 +74,21 @@ static int rkcif_notifier_bound(struct v4l2_async_notifier *notifier,
 				struct v4l2_subdev *sd,
 				struct v4l2_async_connection *asd)
 {
+	struct rkcif_device *rkcif =
+		container_of(notifier, struct rkcif_device, notifier);
 	struct rkcif_remote *remote =
 		container_of(asd, struct rkcif_remote, async_conn);
+	struct media_pad *sink_pad =
+		&remote->interface->pads[RKCIF_IF_PAD_SINK];
+	int ret;
+
+	ret = v4l2_create_fwnode_links_to_pad(sd, sink_pad,
+					      MEDIA_LNK_FL_ENABLED);
+	if (ret) {
+		dev_err(rkcif->dev, "failed to link source pad of %s\n",
+			sd->name);
+		return ret;
+	}
 
 	remote->sd = sd;
 
diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-interface.c b/drivers/media/platform/rockchip/rkcif/rkcif-interface.c
new file mode 100644
index 000000000000..0fe9410e23ed
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkcif/rkcif-interface.c
@@ -0,0 +1,405 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip Camera Interface (CIF) Driver
+ *
+ * Copyright (C) 2025 Michael Riesch <michael.riesch at wolfvision.net>
+ * Copyright (C) 2025 Collabora, Ltd.
+ */
+
+#include <media/v4l2-common.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-mc.h>
+#include <media/v4l2-subdev.h>
+
+#include "rkcif-common.h"
+#include "rkcif-interface.h"
+
+static inline struct rkcif_interface *to_rkcif_interface(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct rkcif_interface, sd);
+}
+
+static const struct media_entity_operations rkcif_interface_media_ops = {
+	.link_validate = v4l2_subdev_link_validate,
+	.has_pad_interdep = v4l2_subdev_has_pad_interdep,
+};
+
+static int rkcif_interface_set_fmt(struct v4l2_subdev *sd,
+				   struct v4l2_subdev_state *state,
+				   struct v4l2_subdev_format *format)
+{
+	struct rkcif_interface *interface = to_rkcif_interface(sd);
+	const struct rkcif_input_fmt *input;
+	struct v4l2_mbus_framefmt *sink, *src;
+	struct v4l2_rect *crop;
+	u32 other_pad, other_stream;
+	int ret;
+
+	/* the format on the source pad always matches the sink pad */
+	if (format->pad == RKCIF_IF_PAD_SRC)
+		return v4l2_subdev_get_fmt(sd, state, format);
+
+	input = rkcif_interface_find_input_fmt(interface, true,
+					       format->format.code);
+	format->format.code = input->mbus_code;
+
+	sink = v4l2_subdev_state_get_format(state, format->pad, format->stream);
+	if (!sink)
+		return -EINVAL;
+
+	*sink = format->format;
+
+	/* propagate the format to the source pad */
+	src = v4l2_subdev_state_get_opposite_stream_format(state, format->pad,
+							   format->stream);
+	if (!src)
+		return -EINVAL;
+
+	*src = *sink;
+
+	ret = v4l2_subdev_routing_find_opposite_end(&state->routing,
+						    format->pad, format->stream,
+						    &other_pad, &other_stream);
+	if (ret)
+		return -EINVAL;
+
+	crop = v4l2_subdev_state_get_crop(state, other_pad, other_stream);
+	if (!crop)
+		return -EINVAL;
+
+	/* reset crop */
+	crop->left = 0;
+	crop->top = 0;
+	crop->width = sink->width;
+	crop->height = sink->height;
+
+	return 0;
+}
+
+static int rkcif_interface_get_sel(struct v4l2_subdev *sd,
+				   struct v4l2_subdev_state *state,
+				   struct v4l2_subdev_selection *sel)
+{
+	struct v4l2_mbus_framefmt *sink;
+	struct v4l2_rect *crop;
+	int ret = 0;
+
+	if (sel->pad != RKCIF_IF_PAD_SRC)
+		return -EINVAL;
+
+	sink = v4l2_subdev_state_get_opposite_stream_format(state, sel->pad,
+							    sel->stream);
+	if (!sink)
+		return -EINVAL;
+
+	crop = v4l2_subdev_state_get_crop(state, sel->pad, sel->stream);
+	if (!crop)
+		return -EINVAL;
+
+	switch (sel->target) {
+	case V4L2_SEL_TGT_CROP_DEFAULT:
+	case V4L2_SEL_TGT_CROP_BOUNDS:
+		sel->r.left = 0;
+		sel->r.top = 0;
+		sel->r.width = sink->width;
+		sel->r.height = sink->height;
+		break;
+	case V4L2_SEL_TGT_CROP:
+		sel->r = *crop;
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static int rkcif_interface_set_sel(struct v4l2_subdev *sd,
+				   struct v4l2_subdev_state *state,
+				   struct v4l2_subdev_selection *sel)
+{
+	struct v4l2_mbus_framefmt *sink, *src;
+	struct v4l2_rect *crop;
+
+	if (sel->pad != RKCIF_IF_PAD_SRC || sel->target != V4L2_SEL_TGT_CROP)
+		return -EINVAL;
+
+	sink = v4l2_subdev_state_get_opposite_stream_format(state, sel->pad,
+							    sel->stream);
+	if (!sink)
+		return -EINVAL;
+
+	src = v4l2_subdev_state_get_format(state, sel->pad, sel->stream);
+	if (!src)
+		return -EINVAL;
+
+	crop = v4l2_subdev_state_get_crop(state, sel->pad, sel->stream);
+	if (!crop)
+		return -EINVAL;
+
+	*crop = sel->r;
+
+	src->height = sel->r.height;
+	src->width = sel->r.width;
+
+	return 0;
+}
+
+static int rkcif_interface_set_routing(struct v4l2_subdev *sd,
+				       struct v4l2_subdev_state *state,
+				       enum v4l2_subdev_format_whence which,
+				       struct v4l2_subdev_krouting *routing)
+{
+	int ret;
+
+	ret = v4l2_subdev_routing_validate(sd, routing,
+					   V4L2_SUBDEV_ROUTING_ONLY_1_TO_1);
+	if (ret)
+		return ret;
+
+	ret = v4l2_subdev_set_routing(sd, state, routing);
+
+	return ret;
+}
+
+static int rkcif_interface_enable_streams(struct v4l2_subdev *sd,
+					  struct v4l2_subdev_state *state,
+					  u32 pad, u64 streams_mask)
+{
+	struct v4l2_subdev *remote_sd;
+	struct media_pad *remote_pad;
+	u64 mask;
+
+	remote_pad =
+		media_pad_remote_pad_first(&sd->entity.pads[RKCIF_IF_PAD_SINK]);
+	remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity);
+
+	mask = v4l2_subdev_state_xlate_streams(state, RKCIF_IF_PAD_SINK,
+					       RKCIF_IF_PAD_SRC, &streams_mask);
+
+	return v4l2_subdev_enable_streams(remote_sd, remote_pad->index, mask);
+}
+
+static int rkcif_interface_disable_streams(struct v4l2_subdev *sd,
+					   struct v4l2_subdev_state *state,
+					   u32 pad, u64 streams_mask)
+{
+	struct v4l2_subdev *remote_sd;
+	struct media_pad *remote_pad;
+	u64 mask;
+
+	remote_pad =
+		media_pad_remote_pad_first(&sd->entity.pads[RKCIF_IF_PAD_SINK]);
+	remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity);
+
+	mask = v4l2_subdev_state_xlate_streams(state, RKCIF_IF_PAD_SINK,
+					       RKCIF_IF_PAD_SRC, &streams_mask);
+
+	return v4l2_subdev_disable_streams(remote_sd, remote_pad->index, mask);
+}
+
+static const struct v4l2_subdev_pad_ops rkcif_interface_pad_ops = {
+	.get_fmt = v4l2_subdev_get_fmt,
+	.set_fmt = rkcif_interface_set_fmt,
+	.get_selection = rkcif_interface_get_sel,
+	.set_selection = rkcif_interface_set_sel,
+	.set_routing = rkcif_interface_set_routing,
+	.enable_streams = rkcif_interface_enable_streams,
+	.disable_streams = rkcif_interface_disable_streams,
+};
+
+static const struct v4l2_subdev_ops rkcif_interface_ops = {
+	.pad = &rkcif_interface_pad_ops,
+};
+
+static int rkcif_interface_init_state(struct v4l2_subdev *sd,
+				      struct v4l2_subdev_state *state)
+{
+	struct rkcif_interface *interface = to_rkcif_interface(sd);
+	struct v4l2_subdev_route routes[] = {
+		{
+			.sink_pad = RKCIF_IF_PAD_SINK,
+			.sink_stream = 0,
+			.source_pad = RKCIF_IF_PAD_SRC,
+			.source_stream = 0,
+			.flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
+		},
+	};
+	struct v4l2_subdev_krouting routing = {
+		.len_routes = ARRAY_SIZE(routes),
+		.num_routes = ARRAY_SIZE(routes),
+		.routes = routes,
+	};
+	const struct v4l2_mbus_framefmt dvp_default_format = {
+		.width = 3840,
+		.height = 2160,
+		.code = MEDIA_BUS_FMT_YUYV8_1X16,
+		.field = V4L2_FIELD_NONE,
+		.colorspace = V4L2_COLORSPACE_REC709,
+		.ycbcr_enc = V4L2_YCBCR_ENC_709,
+		.quantization = V4L2_QUANTIZATION_LIM_RANGE,
+		.xfer_func = V4L2_XFER_FUNC_NONE,
+	};
+	const struct v4l2_mbus_framefmt mipi_default_format = {
+		.width = 3840,
+		.height = 2160,
+		.code = MEDIA_BUS_FMT_SRGGB10_1X10,
+		.field = V4L2_FIELD_NONE,
+		.colorspace = V4L2_COLORSPACE_RAW,
+		.ycbcr_enc = V4L2_YCBCR_ENC_601,
+		.quantization = V4L2_QUANTIZATION_FULL_RANGE,
+		.xfer_func = V4L2_XFER_FUNC_NONE,
+	};
+	const struct v4l2_mbus_framefmt *default_format;
+	int ret;
+
+	default_format = (interface->type == RKCIF_IF_DVP) ?
+				 &dvp_default_format :
+				 &mipi_default_format;
+
+	ret = v4l2_subdev_set_routing_with_fmt(sd, state, &routing,
+					       default_format);
+
+	return ret;
+}
+
+static const struct v4l2_subdev_internal_ops rkcif_interface_internal_ops = {
+	.init_state = rkcif_interface_init_state,
+};
+
+static int rkcif_interface_add(struct rkcif_interface *interface)
+{
+	struct rkcif_device *rkcif = interface->rkcif;
+	struct rkcif_remote *remote;
+	struct v4l2_async_notifier *ntf = &rkcif->notifier;
+	struct v4l2_fwnode_endpoint *vep = &interface->vep;
+	struct device *dev = rkcif->dev;
+	struct fwnode_handle *ep;
+	u32 dvp_clk_delay = 0;
+	int ret;
+
+	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), interface->index,
+					     0, 0);
+	if (!ep)
+		return -ENODEV;
+
+	vep->bus_type = V4L2_MBUS_UNKNOWN;
+	ret = v4l2_fwnode_endpoint_parse(ep, vep);
+	if (ret)
+		goto complete;
+
+	if (interface->type == RKCIF_IF_DVP) {
+		if (vep->bus_type != V4L2_MBUS_BT656 &&
+		    vep->bus_type != V4L2_MBUS_PARALLEL) {
+			ret = dev_err_probe(dev, -EINVAL,
+					    "unsupported bus type\n");
+			goto complete;
+		}
+
+		fwnode_property_read_u32(ep, "rockchip,dvp-clk-delay",
+					 &dvp_clk_delay);
+		interface->dvp.dvp_clk_delay = dvp_clk_delay;
+	}
+
+	remote = v4l2_async_nf_add_fwnode_remote(ntf, ep, struct rkcif_remote);
+	if (IS_ERR(remote)) {
+		ret = PTR_ERR(remote);
+		goto complete;
+	}
+
+	remote->interface = interface;
+	interface->remote = remote;
+	interface->status = RKCIF_IF_ACTIVE;
+	ret = 0;
+
+complete:
+	fwnode_handle_put(ep);
+
+	return ret;
+}
+
+int rkcif_interface_register(struct rkcif_device *rkcif,
+			     struct rkcif_interface *interface)
+{
+	struct media_pad *pads = interface->pads;
+	struct v4l2_subdev *sd = &interface->sd;
+	int ret;
+
+	interface->rkcif = rkcif;
+
+	v4l2_subdev_init(sd, &rkcif_interface_ops);
+	sd->dev = rkcif->dev;
+	sd->entity.ops = &rkcif_interface_media_ops;
+	sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
+	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_STREAMS;
+	sd->internal_ops = &rkcif_interface_internal_ops;
+	sd->owner = THIS_MODULE;
+
+	if (interface->type == RKCIF_IF_DVP)
+		snprintf(sd->name, sizeof(sd->name), "rkcif-dvp0");
+	else if (interface->type == RKCIF_IF_MIPI)
+		snprintf(sd->name, sizeof(sd->name), "rkcif-mipi%d",
+			 interface->index - RKCIF_MIPI_BASE);
+
+	pads[RKCIF_IF_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
+	pads[RKCIF_IF_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;
+	ret = media_entity_pads_init(&sd->entity, RKCIF_IF_PAD_MAX, pads);
+	if (ret)
+		goto err;
+
+	ret = v4l2_subdev_init_finalize(sd);
+	if (ret)
+		goto err_entity_cleanup;
+
+	ret = v4l2_device_register_subdev(&rkcif->v4l2_dev, sd);
+	if (ret) {
+		dev_err(sd->dev, "failed to register subdev\n");
+		goto err_subdev_cleanup;
+	}
+
+	ret = rkcif_interface_add(interface);
+	if (ret)
+		goto err_subdev_unregister;
+
+	return 0;
+
+err_subdev_unregister:
+	v4l2_device_unregister_subdev(sd);
+err_subdev_cleanup:
+	v4l2_subdev_cleanup(sd);
+err_entity_cleanup:
+	media_entity_cleanup(&sd->entity);
+err:
+	return ret;
+}
+
+void rkcif_interface_unregister(struct rkcif_interface *interface)
+{
+	struct v4l2_subdev *sd = &interface->sd;
+
+	if (interface->status != RKCIF_IF_ACTIVE)
+		return;
+
+	v4l2_device_unregister_subdev(sd);
+	v4l2_subdev_cleanup(sd);
+	media_entity_cleanup(&sd->entity);
+}
+
+const struct rkcif_input_fmt *
+rkcif_interface_find_input_fmt(struct rkcif_interface *interface, bool ret_def,
+			       u32 mbus_code)
+{
+	const struct rkcif_input_fmt *fmt;
+
+	WARN_ON(interface->in_fmts_num == 0);
+
+	for (unsigned int i = 0; i < interface->in_fmts_num; i++) {
+		fmt = &interface->in_fmts[i];
+		if (fmt->mbus_code == mbus_code)
+			return fmt;
+	}
+	if (ret_def)
+		return &interface->in_fmts[0];
+	else
+		return NULL;
+}
diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-interface.h b/drivers/media/platform/rockchip/rkcif/rkcif-interface.h
new file mode 100644
index 000000000000..f13aa28b6fa7
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkcif/rkcif-interface.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Rockchip Camera Interface (CIF) Driver
+ *
+ * Abstraction for the INTERFACE and CROP parts of the different CIF variants.
+ * They shall be represented as V4L2 subdevice with one sink pad and one
+ * source pad. The sink pad is connected to a subdevice: either the subdevice
+ * provided by the driver of the companion chip connected to the DVP, or the
+ * subdevice provided by the MIPI CSI-2 receiver driver. The source pad is
+ * to V4l2 device(s) provided by one or many instance(s) of the DMA
+ * abstraction.
+ *
+ * Copyright (C) 2025 Michael Riesch <michael.riesch at wolfvision.net>
+ * Copyright (C) 2025 Collabora, Ltd.
+ */
+
+#ifndef _RKCIF_INTERFACE_H
+#define _RKCIF_INTERFACE_H
+
+#include "rkcif-common.h"
+
+int rkcif_interface_register(struct rkcif_device *rkcif,
+			     struct rkcif_interface *interface);
+
+void rkcif_interface_unregister(struct rkcif_interface *interface);
+
+const struct rkcif_input_fmt *
+rkcif_interface_find_input_fmt(struct rkcif_interface *interface, bool ret_def,
+			       u32 mbus_code);
+
+#endif

-- 
2.39.5




From devnull+michael.riesch.collabora.com at kernel.org  Fri Nov 14 07:20:22 2025
From: devnull+michael.riesch.collabora.com at kernel.org (Michael Riesch via B4 Relay)
Date: Fri, 14 Nov 2025 16:20:22 +0100
Subject: [PATCH v15 11/14] arm64: defconfig: enable rockchip camera
 interface
In-Reply-To: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
References: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
Message-ID: <20240220-rk3568-vicap-v15-11-8f4915ee365d@collabora.com>

From: Michael Riesch <michael.riesch at collabora.com>

The Rockchip Camera Interface (CIF) is featured in many Rockchip SoCs
in different variations.
Enable the driver for it in the default configuration.

Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
Reviewed-by: Mehdi Djait <mehdi.djait at linux.intel.com>
Signed-off-by: Michael Riesch <michael.riesch at collabora.com>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index e3a2d37bd104..8eae6c70bfdf 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -883,6 +883,7 @@ CONFIG_VIDEO_RENESAS_FCP=m
 CONFIG_VIDEO_RENESAS_FDP1=m
 CONFIG_VIDEO_RENESAS_VSP1=m
 CONFIG_VIDEO_RCAR_DRIF=m
+CONFIG_VIDEO_ROCKCHIP_CIF=m
 CONFIG_VIDEO_ROCKCHIP_RGA=m
 CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=m
 CONFIG_VIDEO_SAMSUNG_S5P_JPEG=m

-- 
2.39.5




From devnull+michael.riesch.collabora.com at kernel.org  Fri Nov 14 07:20:20 2025
From: devnull+michael.riesch.collabora.com at kernel.org (Michael Riesch via B4 Relay)
Date: Fri, 14 Nov 2025 16:20:20 +0100
Subject: [PATCH v15 09/14] media: rockchip: rkcif: add support for rk3568
 vicap dvp capture
In-Reply-To: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
References: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
Message-ID: <20240220-rk3568-vicap-v15-9-8f4915ee365d@collabora.com>

From: Michael Riesch <michael.riesch at collabora.com>

The RK3568 Video Capture (VICAP) unit features a Digital Video Port
(DVP). Add support for it.

Tested-by: Gerald Loacker <gerald.loacker at wolfvision.net>
Reviewed-by: Gerald Loacker <gerald.loacker at wolfvision.net>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
Reviewed-by: Mehdi Djait <mehdi.djait at linux.intel.com>
Signed-off-by: Michael Riesch <michael.riesch at collabora.com>
---
 .../platform/rockchip/rkcif/rkcif-capture-dvp.c    | 276 +++++++++++++++++++++
 .../platform/rockchip/rkcif/rkcif-capture-dvp.h    |   1 +
 drivers/media/platform/rockchip/rkcif/rkcif-dev.c  |   1 +
 3 files changed, 278 insertions(+)

diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-capture-dvp.c b/drivers/media/platform/rockchip/rkcif/rkcif-capture-dvp.c
index b40135035ab8..dbaf7636aeeb 100644
--- a/drivers/media/platform/rockchip/rkcif/rkcif-capture-dvp.c
+++ b/drivers/media/platform/rockchip/rkcif/rkcif-capture-dvp.c
@@ -332,6 +332,282 @@ const struct rkcif_dvp_match_data rkcif_px30_vip_dvp_match_data = {
 	},
 };
 
+static const struct rkcif_input_fmt rk3568_dvp_in_fmts[] = {
+	{
+		.mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_INPUT_422 |
+			       RKCIF_FORMAT_YUV_INPUT_ORDER_YUYV,
+		.fmt_type = RKCIF_FMT_TYPE_YUV,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_INPUT_422 |
+			       RKCIF_FORMAT_YUV_INPUT_ORDER_YUYV,
+		.fmt_type = RKCIF_FMT_TYPE_YUV,
+		.field = V4L2_FIELD_INTERLACED,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_YVYU8_2X8,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_INPUT_422 |
+			       RKCIF_FORMAT_YUV_INPUT_ORDER_YVYU,
+		.fmt_type = RKCIF_FMT_TYPE_YUV,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_YVYU8_2X8,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_INPUT_422 |
+			       RKCIF_FORMAT_YUV_INPUT_ORDER_YVYU,
+		.fmt_type = RKCIF_FMT_TYPE_YUV,
+		.field = V4L2_FIELD_INTERLACED,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_UYVY8_2X8,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_INPUT_422 |
+			       RKCIF_FORMAT_YUV_INPUT_ORDER_UYVY,
+		.fmt_type = RKCIF_FMT_TYPE_YUV,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_UYVY8_2X8,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_INPUT_422 |
+			       RKCIF_FORMAT_YUV_INPUT_ORDER_UYVY,
+		.fmt_type = RKCIF_FMT_TYPE_YUV,
+		.field = V4L2_FIELD_INTERLACED,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_VYUY8_2X8,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_INPUT_422 |
+			       RKCIF_FORMAT_YUV_INPUT_ORDER_VYUY,
+		.fmt_type = RKCIF_FMT_TYPE_YUV,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_VYUY8_2X8,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_INPUT_422 |
+			       RKCIF_FORMAT_YUV_INPUT_ORDER_VYUY,
+		.fmt_type = RKCIF_FMT_TYPE_YUV,
+		.field = V4L2_FIELD_INTERLACED,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_YUYV8_1X16,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_INPUT_422 |
+			       RKCIF_FORMAT_YUV_INPUT_ORDER_YUYV |
+			       RKCIF_FORMAT_INPUT_MODE_BT1120 |
+			       RKCIF_FORMAT_BT1120_TRANSMIT_PROGRESS,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_YUYV8_1X16,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_INPUT_422 |
+			       RKCIF_FORMAT_YUV_INPUT_ORDER_YUYV |
+			       RKCIF_FORMAT_INPUT_MODE_BT1120,
+		.field = V4L2_FIELD_INTERLACED,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_YVYU8_1X16,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_INPUT_422 |
+			       RKCIF_FORMAT_YUV_INPUT_ORDER_YVYU |
+			       RKCIF_FORMAT_INPUT_MODE_BT1120 |
+			       RKCIF_FORMAT_BT1120_TRANSMIT_PROGRESS,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_YVYU8_1X16,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_INPUT_422 |
+			       RKCIF_FORMAT_YUV_INPUT_ORDER_YVYU |
+			       RKCIF_FORMAT_INPUT_MODE_BT1120,
+		.field = V4L2_FIELD_INTERLACED,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_UYVY8_1X16,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_INPUT_422 |
+			       RKCIF_FORMAT_YUV_INPUT_ORDER_YUYV |
+			       RKCIF_FORMAT_INPUT_MODE_BT1120 |
+			       RKCIF_FORMAT_BT1120_YC_SWAP |
+			       RKCIF_FORMAT_BT1120_TRANSMIT_PROGRESS,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_UYVY8_1X16,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_INPUT_422 |
+			       RKCIF_FORMAT_YUV_INPUT_ORDER_YUYV |
+			       RKCIF_FORMAT_BT1120_YC_SWAP |
+			       RKCIF_FORMAT_INPUT_MODE_BT1120,
+		.field = V4L2_FIELD_INTERLACED,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_VYUY8_1X16,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_INPUT_422 |
+			       RKCIF_FORMAT_YUV_INPUT_ORDER_YVYU |
+			       RKCIF_FORMAT_INPUT_MODE_BT1120 |
+			       RKCIF_FORMAT_BT1120_YC_SWAP |
+			       RKCIF_FORMAT_BT1120_TRANSMIT_PROGRESS,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_VYUY8_1X16,
+		.dvp_fmt_val = RKCIF_FORMAT_YUV_INPUT_422 |
+			       RKCIF_FORMAT_YUV_INPUT_ORDER_YVYU |
+			       RKCIF_FORMAT_BT1120_YC_SWAP |
+			       RKCIF_FORMAT_INPUT_MODE_BT1120,
+		.field = V4L2_FIELD_INTERLACED,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,
+		.dvp_fmt_val = RKCIF_FORMAT_INPUT_MODE_RAW |
+			       RKCIF_FORMAT_RAW_DATA_WIDTH_8,
+		.fmt_type = RKCIF_FMT_TYPE_RAW,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8,
+		.dvp_fmt_val = RKCIF_FORMAT_INPUT_MODE_RAW |
+			       RKCIF_FORMAT_RAW_DATA_WIDTH_8,
+		.fmt_type = RKCIF_FMT_TYPE_RAW,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8,
+		.dvp_fmt_val = RKCIF_FORMAT_INPUT_MODE_RAW |
+			       RKCIF_FORMAT_RAW_DATA_WIDTH_8,
+		.fmt_type = RKCIF_FMT_TYPE_RAW,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8,
+		.dvp_fmt_val = RKCIF_FORMAT_INPUT_MODE_RAW |
+			       RKCIF_FORMAT_RAW_DATA_WIDTH_8,
+		.fmt_type = RKCIF_FMT_TYPE_RAW,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10,
+		.dvp_fmt_val = RKCIF_FORMAT_INPUT_MODE_RAW |
+			       RKCIF_FORMAT_RAW_DATA_WIDTH_10,
+		.fmt_type = RKCIF_FMT_TYPE_RAW,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10,
+		.dvp_fmt_val = RKCIF_FORMAT_INPUT_MODE_RAW |
+			       RKCIF_FORMAT_RAW_DATA_WIDTH_10,
+		.fmt_type = RKCIF_FMT_TYPE_RAW,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10,
+		.dvp_fmt_val = RKCIF_FORMAT_INPUT_MODE_RAW |
+			       RKCIF_FORMAT_RAW_DATA_WIDTH_10,
+		.fmt_type = RKCIF_FMT_TYPE_RAW,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10,
+		.dvp_fmt_val = RKCIF_FORMAT_INPUT_MODE_RAW |
+			       RKCIF_FORMAT_RAW_DATA_WIDTH_10,
+		.fmt_type = RKCIF_FMT_TYPE_RAW,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12,
+		.dvp_fmt_val = RKCIF_FORMAT_INPUT_MODE_RAW |
+			       RKCIF_FORMAT_RAW_DATA_WIDTH_12,
+		.fmt_type = RKCIF_FMT_TYPE_RAW,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12,
+		.dvp_fmt_val = RKCIF_FORMAT_INPUT_MODE_RAW |
+			       RKCIF_FORMAT_RAW_DATA_WIDTH_12,
+		.fmt_type = RKCIF_FMT_TYPE_RAW,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12,
+		.dvp_fmt_val = RKCIF_FORMAT_INPUT_MODE_RAW |
+			       RKCIF_FORMAT_RAW_DATA_WIDTH_12,
+		.fmt_type = RKCIF_FMT_TYPE_RAW,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12,
+		.dvp_fmt_val = RKCIF_FORMAT_INPUT_MODE_RAW |
+			       RKCIF_FORMAT_RAW_DATA_WIDTH_12,
+		.fmt_type = RKCIF_FMT_TYPE_RAW,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_RGB888_1X24,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_Y8_1X8,
+		.dvp_fmt_val = RKCIF_FORMAT_INPUT_MODE_RAW |
+			       RKCIF_FORMAT_RAW_DATA_WIDTH_8,
+		.fmt_type = RKCIF_FMT_TYPE_RAW,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_Y10_1X10,
+		.dvp_fmt_val = RKCIF_FORMAT_INPUT_MODE_RAW |
+			       RKCIF_FORMAT_RAW_DATA_WIDTH_10,
+		.fmt_type = RKCIF_FMT_TYPE_RAW,
+		.field = V4L2_FIELD_NONE,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_Y12_1X12,
+		.dvp_fmt_val = RKCIF_FORMAT_INPUT_MODE_RAW |
+			       RKCIF_FORMAT_RAW_DATA_WIDTH_12,
+		.fmt_type = RKCIF_FMT_TYPE_RAW,
+		.field = V4L2_FIELD_NONE,
+	},
+};
+
+static void rk3568_dvp_grf_setup(struct rkcif_device *rkcif)
+{
+	u32 con1 = RK3568_GRF_WRITE_ENABLE(RK3568_GRF_VI_CON1_CIF_DATAPATH |
+					   RK3568_GRF_VI_CON1_CIF_CLK_DELAYNUM);
+
+	if (!rkcif->grf)
+		return;
+
+	con1 |= rkcif->interfaces[RKCIF_DVP].dvp.dvp_clk_delay &
+		RK3568_GRF_VI_CON1_CIF_CLK_DELAYNUM;
+
+	if (rkcif->interfaces[RKCIF_DVP].vep.bus.parallel.flags &
+	    V4L2_MBUS_PCLK_SAMPLE_DUALEDGE)
+		con1 |= RK3568_GRF_VI_CON1_CIF_DATAPATH;
+
+	regmap_write(rkcif->grf, RK3568_GRF_VI_CON1, con1);
+}
+
+const struct rkcif_dvp_match_data rkcif_rk3568_vicap_dvp_match_data = {
+	.in_fmts = rk3568_dvp_in_fmts,
+	.in_fmts_num = ARRAY_SIZE(rk3568_dvp_in_fmts),
+	.out_fmts = dvp_out_fmts,
+	.out_fmts_num = ARRAY_SIZE(dvp_out_fmts),
+	.setup = rk3568_dvp_grf_setup,
+	.has_scaler = false,
+	.regs = {
+		[RKCIF_DVP_CTRL] = 0x00,
+		[RKCIF_DVP_INTEN] = 0x04,
+		[RKCIF_DVP_INTSTAT] = 0x08,
+		[RKCIF_DVP_FOR] = 0x0c,
+		[RKCIF_DVP_LINE_NUM_ADDR] = 0x2c,
+		[RKCIF_DVP_FRM0_ADDR_Y] = 0x14,
+		[RKCIF_DVP_FRM0_ADDR_UV] = 0x18,
+		[RKCIF_DVP_FRM1_ADDR_Y] = 0x1c,
+		[RKCIF_DVP_FRM1_ADDR_UV] = 0x20,
+		[RKCIF_DVP_VIR_LINE_WIDTH] = 0x24,
+		[RKCIF_DVP_SET_SIZE] = 0x28,
+		[RKCIF_DVP_CROP] = 0x34,
+		[RKCIF_DVP_FRAME_STATUS] = 0x3c,
+		[RKCIF_DVP_LAST_LINE] = 0x44,
+		[RKCIF_DVP_LAST_PIX] = 0x48,
+	},
+};
+
 static inline unsigned int rkcif_dvp_get_addr(struct rkcif_device *rkcif,
 					      unsigned int index)
 {
diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-capture-dvp.h b/drivers/media/platform/rockchip/rkcif/rkcif-capture-dvp.h
index 7b2da11497c3..a4ed37833bd6 100644
--- a/drivers/media/platform/rockchip/rkcif/rkcif-capture-dvp.h
+++ b/drivers/media/platform/rockchip/rkcif/rkcif-capture-dvp.h
@@ -14,6 +14,7 @@
 #include "rkcif-common.h"
 
 extern const struct rkcif_dvp_match_data rkcif_px30_vip_dvp_match_data;
+extern const struct rkcif_dvp_match_data rkcif_rk3568_vicap_dvp_match_data;
 
 int rkcif_dvp_register(struct rkcif_device *rkcif);
 
diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-dev.c b/drivers/media/platform/rockchip/rkcif/rkcif-dev.c
index 207802073fd3..addc118ff8bf 100644
--- a/drivers/media/platform/rockchip/rkcif/rkcif-dev.c
+++ b/drivers/media/platform/rockchip/rkcif/rkcif-dev.c
@@ -48,6 +48,7 @@ static const char *const rk3568_vicap_clks[] = {
 static const struct rkcif_match_data rk3568_vicap_match_data = {
 	.clks = rk3568_vicap_clks,
 	.clks_num = ARRAY_SIZE(rk3568_vicap_clks),
+	.dvp = &rkcif_rk3568_vicap_dvp_match_data,
 };
 
 static const struct of_device_id rkcif_plat_of_match[] = {

-- 
2.39.5




From devnull+michael.riesch.collabora.com at kernel.org  Fri Nov 14 07:20:21 2025
From: devnull+michael.riesch.collabora.com at kernel.org (Michael Riesch via B4 Relay)
Date: Fri, 14 Nov 2025 16:20:21 +0100
Subject: [PATCH v15 10/14] media: rockchip: rkcif: add support for rk3568
 vicap mipi capture
In-Reply-To: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
References: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
Message-ID: <20240220-rk3568-vicap-v15-10-8f4915ee365d@collabora.com>

From: Michael Riesch <michael.riesch at collabora.com>

The RK3568 Video Capture (VICAP) unit features a MIPI CSI-2 capture
interface. Add support for the MIPI capture interface in general
and for the RK3568 VICAP MIPI capture in particular.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
Reviewed-by: Mehdi Djait <mehdi.djait at linux.intel.com>
Signed-off-by: Michael Riesch <michael.riesch at collabora.com>
---
 drivers/media/platform/rockchip/rkcif/Makefile     |   1 +
 .../platform/rockchip/rkcif/rkcif-capture-mipi.c   | 777 +++++++++++++++++++++
 .../platform/rockchip/rkcif/rkcif-capture-mipi.h   |  23 +
 .../media/platform/rockchip/rkcif/rkcif-common.h   |  29 +
 drivers/media/platform/rockchip/rkcif/rkcif-dev.c  |  12 +
 drivers/media/platform/rockchip/rkcif/rkcif-regs.h |  22 +
 6 files changed, 864 insertions(+)

diff --git a/drivers/media/platform/rockchip/rkcif/Makefile b/drivers/media/platform/rockchip/rkcif/Makefile
index a36e294d569d..dca2bf45159f 100644
--- a/drivers/media/platform/rockchip/rkcif/Makefile
+++ b/drivers/media/platform/rockchip/rkcif/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_VIDEO_ROCKCHIP_CIF) += rockchip-cif.o
 
 rockchip-cif-objs += rkcif-capture-dvp.o
+rockchip-cif-objs += rkcif-capture-mipi.o
 rockchip-cif-objs += rkcif-dev.o
 rockchip-cif-objs += rkcif-interface.o
 rockchip-cif-objs += rkcif-stream.o
diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.c b/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.c
new file mode 100644
index 000000000000..1b81bcc067ef
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.c
@@ -0,0 +1,777 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip Camera Interface (CIF) Driver
+ *
+ * Copyright (C) 2018 Rockchip Electronics Co., Ltd.
+ * Copyright (C) 2025 Michael Riesch <michael.riesch at wolfvision.net>
+ * Copyright (C) 2025 Collabora, Ltd.
+ */
+
+#include <linux/interrupt.h>
+
+#include <media/mipi-csi2.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-fh.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-mc.h>
+#include <media/v4l2-subdev.h>
+
+#include "rkcif-capture-mipi.h"
+#include "rkcif-common.h"
+#include "rkcif-interface.h"
+#include "rkcif-regs.h"
+#include "rkcif-stream.h"
+
+#define RK3568_MIPI_CTRL0_HIGH_ALIGN  BIT(31)
+#define RK3568_MIPI_CTRL0_UV_SWAP_EN  BIT(7)
+#define RK3568_MIPI_CTRL0_COMPACT_EN  BIT(6)
+#define RK3568_MIPI_CTRL0_CROP_EN     BIT(5)
+#define RK3568_MIPI_CTRL0_WRDDR(type) ((type) << 1)
+
+#define RKCIF_MIPI_CTRL0_DT_ID(id)    ((id) << 10)
+#define RKCIF_MIPI_CTRL0_VC_ID(id)    ((id) << 8)
+#define RKCIF_MIPI_CTRL0_CAP_EN	      BIT(0)
+
+#define RKCIF_MIPI_INT_FRAME0_END(id) BIT(8 + (id) * 2 + 0)
+#define RKCIF_MIPI_INT_FRAME1_END(id) BIT(8 + (id) * 2 + 1)
+
+static const struct rkcif_output_fmt mipi_out_fmts[] = {
+	/* YUV formats */
+	{
+		.fourcc = V4L2_PIX_FMT_YUYV,
+		.mbus_code = MEDIA_BUS_FMT_YUYV8_1X16,
+		.depth = 16,
+		.cplanes = 1,
+		.mipi = {
+			.dt = MIPI_CSI2_DT_YUV422_8B,
+			.type = RKCIF_MIPI_TYPE_RAW8,
+		},
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_UYVY,
+		.mbus_code = MEDIA_BUS_FMT_UYVY8_1X16,
+		.depth = 16,
+		.cplanes = 1,
+		.mipi = {
+			.dt = MIPI_CSI2_DT_YUV422_8B,
+			.type = RKCIF_MIPI_TYPE_RAW8,
+		},
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_YVYU,
+		.mbus_code = MEDIA_BUS_FMT_YVYU8_1X16,
+		.depth = 16,
+		.cplanes = 1,
+		.mipi = {
+			.dt = MIPI_CSI2_DT_YUV422_8B,
+			.type = RKCIF_MIPI_TYPE_RAW8,
+		},
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_VYUY,
+		.mbus_code = MEDIA_BUS_FMT_VYUY8_1X16,
+		.depth = 16,
+		.cplanes = 1,
+		.mipi = {
+			.dt = MIPI_CSI2_DT_YUV422_8B,
+			.type = RKCIF_MIPI_TYPE_RAW8,
+		},
+	},
+	/* RGB formats */
+	{
+		.fourcc = V4L2_PIX_FMT_RGB24,
+		.mbus_code = MEDIA_BUS_FMT_RGB888_1X24,
+		.depth = 24,
+		.cplanes = 1,
+		.mipi = {
+			.dt = MIPI_CSI2_DT_RGB888,
+			.type = RKCIF_MIPI_TYPE_RGB888,
+		},
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_BGR24,
+		.mbus_code = MEDIA_BUS_FMT_BGR888_1X24,
+		.depth = 24,
+		.cplanes = 1,
+		.mipi = {
+			.dt = MIPI_CSI2_DT_RGB888,
+			.type = RKCIF_MIPI_TYPE_RGB888,
+		},
+	},
+	/* Bayer formats */
+	{
+		.fourcc = V4L2_PIX_FMT_SBGGR8,
+		.mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,
+		.depth = 8,
+		.cplanes = 1,
+		.mipi = {
+			.dt = MIPI_CSI2_DT_RAW8,
+			.type = RKCIF_MIPI_TYPE_RAW8,
+		},
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SGBRG8,
+		.mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8,
+		.depth = 8,
+		.cplanes = 1,
+		.mipi = {
+			.dt = MIPI_CSI2_DT_RAW8,
+			.type = RKCIF_MIPI_TYPE_RAW8,
+		},
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SGRBG8,
+		.mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8,
+		.depth = 8,
+		.cplanes = 1,
+		.mipi = {
+			.dt = MIPI_CSI2_DT_RAW8,
+			.type = RKCIF_MIPI_TYPE_RAW8,
+		},
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SRGGB8,
+		.mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8,
+		.depth = 8,
+		.cplanes = 1,
+		.mipi = {
+			.dt = MIPI_CSI2_DT_RAW8,
+			.type = RKCIF_MIPI_TYPE_RAW8,
+		},
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SBGGR10,
+		.mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10,
+		.depth = 10,
+		.cplanes = 1,
+		.mipi = {
+			.dt = MIPI_CSI2_DT_RAW10,
+			.type = RKCIF_MIPI_TYPE_RAW10,
+		},
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SBGGR10P,
+		.mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10,
+		.depth = 10,
+		.cplanes = 1,
+		.mipi = {
+			.dt = MIPI_CSI2_DT_RAW10,
+			.compact = true,
+			.type = RKCIF_MIPI_TYPE_RAW10,
+		},
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SGBRG10,
+		.mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10,
+		.depth = 10,
+		.cplanes = 1,
+		.mipi = {
+			.dt = MIPI_CSI2_DT_RAW10,
+			.type = RKCIF_MIPI_TYPE_RAW10,
+		},
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SGBRG10P,
+		.mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10,
+		.depth = 10,
+		.cplanes = 1,
+		.mipi = {
+			.dt = MIPI_CSI2_DT_RAW10,
+			.compact = true,
+			.type = RKCIF_MIPI_TYPE_RAW10,
+		},
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SGRBG10,
+		.mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10,
+		.depth = 10,
+		.cplanes = 1,
+		.mipi = {
+			.dt = MIPI_CSI2_DT_RAW10,
+			.type = RKCIF_MIPI_TYPE_RAW10,
+		},
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SGRBG10P,
+		.mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10,
+		.depth = 10,
+		.cplanes = 1,
+		.mipi = {
+			.dt = MIPI_CSI2_DT_RAW10,
+			.compact = true,
+			.type = RKCIF_MIPI_TYPE_RAW10,
+		},
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SRGGB10,
+		.mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10,
+		.depth = 10,
+		.cplanes = 1,
+		.mipi = {
+			.dt = MIPI_CSI2_DT_RAW10,
+			.type = RKCIF_MIPI_TYPE_RAW10,
+		},
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SRGGB10P,
+		.mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10,
+		.depth = 10,
+		.cplanes = 1,
+		.mipi = {
+			.dt = MIPI_CSI2_DT_RAW10,
+			.compact = true,
+			.type = RKCIF_MIPI_TYPE_RAW10,
+		},
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SBGGR12,
+		.mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12,
+		.depth = 12,
+		.cplanes = 1,
+		.mipi = {
+			.dt = MIPI_CSI2_DT_RAW12,
+			.type = RKCIF_MIPI_TYPE_RAW12,
+		},
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SBGGR12P,
+		.mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12,
+		.depth = 12,
+		.cplanes = 1,
+		.mipi = {
+			.dt = MIPI_CSI2_DT_RAW12,
+			.compact = true,
+			.type = RKCIF_MIPI_TYPE_RAW12,
+		},
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SGBRG12,
+		.mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12,
+		.depth = 12,
+		.cplanes = 1,
+		.mipi = {
+			.dt = MIPI_CSI2_DT_RAW12,
+			.type = RKCIF_MIPI_TYPE_RAW12,
+		},
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SGBRG12P,
+		.mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12,
+		.depth = 12,
+		.cplanes = 1,
+		.mipi = {
+			.dt = MIPI_CSI2_DT_RAW12,
+			.compact = true,
+			.type = RKCIF_MIPI_TYPE_RAW12,
+		},
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SGRBG12,
+		.mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12,
+		.depth = 12,
+		.cplanes = 1,
+		.mipi = {
+			.dt = MIPI_CSI2_DT_RAW12,
+			.type = RKCIF_MIPI_TYPE_RAW12,
+		},
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SGRBG12P,
+		.mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12,
+		.depth = 12,
+		.cplanes = 1,
+		.mipi = {
+			.dt = MIPI_CSI2_DT_RAW12,
+			.compact = true,
+			.type = RKCIF_MIPI_TYPE_RAW12,
+		},
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SRGGB12,
+		.mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12,
+		.depth = 12,
+		.cplanes = 1,
+		.mipi = {
+			.dt = MIPI_CSI2_DT_RAW12,
+			.type = RKCIF_MIPI_TYPE_RAW12,
+		},
+	},
+	{
+		.fourcc = V4L2_PIX_FMT_SRGGB12P,
+		.mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12,
+		.depth = 12,
+		.cplanes = 1,
+		.mipi = {
+			.dt = MIPI_CSI2_DT_RAW12,
+			.compact = true,
+			.type = RKCIF_MIPI_TYPE_RAW12,
+		},
+	},
+};
+
+static const struct rkcif_input_fmt mipi_in_fmts[] = {
+	/* YUV formats */
+	{
+		.mbus_code = MEDIA_BUS_FMT_YUYV8_1X16,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_UYVY8_1X16,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_YVYU8_1X16,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_VYUY8_1X16,
+	},
+	/* RGB formats */
+	{
+		.mbus_code = MEDIA_BUS_FMT_RGB888_1X24,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_BGR888_1X24,
+	},
+	/* Bayer formats */
+	{
+		.mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12,
+	},
+	{
+		.mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12,
+	},
+};
+
+static u32
+rkcif_rk3568_mipi_ctrl0(struct rkcif_stream *stream,
+			const struct rkcif_output_fmt *active_out_fmt)
+{
+	u32 ctrl0 = 0;
+
+	ctrl0 |= RKCIF_MIPI_CTRL0_DT_ID(active_out_fmt->mipi.dt);
+	ctrl0 |= RKCIF_MIPI_CTRL0_CAP_EN;
+	ctrl0 |= RK3568_MIPI_CTRL0_CROP_EN;
+
+	if (active_out_fmt->mipi.compact)
+		ctrl0 |= RK3568_MIPI_CTRL0_COMPACT_EN;
+
+	switch (active_out_fmt->mipi.type) {
+	case RKCIF_MIPI_TYPE_RAW8:
+		break;
+	case RKCIF_MIPI_TYPE_RAW10:
+		ctrl0 |= RK3568_MIPI_CTRL0_WRDDR(0x1);
+		break;
+	case RKCIF_MIPI_TYPE_RAW12:
+		ctrl0 |= RK3568_MIPI_CTRL0_WRDDR(0x2);
+		break;
+	case RKCIF_MIPI_TYPE_RGB888:
+		ctrl0 |= RK3568_MIPI_CTRL0_WRDDR(0x3);
+		break;
+	case RKCIF_MIPI_TYPE_YUV422SP:
+		ctrl0 |= RK3568_MIPI_CTRL0_WRDDR(0x4);
+		break;
+	case RKCIF_MIPI_TYPE_YUV420SP:
+		ctrl0 |= RK3568_MIPI_CTRL0_WRDDR(0x5);
+		break;
+	case RKCIF_MIPI_TYPE_YUV400:
+		ctrl0 |= RK3568_MIPI_CTRL0_WRDDR(0x6);
+		break;
+	default:
+		break;
+	}
+
+	return ctrl0;
+}
+
+const struct rkcif_mipi_match_data rkcif_rk3568_vicap_mipi_match_data = {
+	.mipi_num = 1,
+	.mipi_ctrl0 = rkcif_rk3568_mipi_ctrl0,
+	.regs = {
+		[RKCIF_MIPI_CTRL] = 0x20,
+		[RKCIF_MIPI_INTEN] = 0xa4,
+		[RKCIF_MIPI_INTSTAT] = 0xa8,
+	},
+	.regs_id = {
+		[RKCIF_ID0] = {
+			[RKCIF_MIPI_CTRL0] = 0x00,
+			[RKCIF_MIPI_CTRL1] = 0x04,
+			[RKCIF_MIPI_FRAME0_ADDR_Y] = 0x24,
+			[RKCIF_MIPI_FRAME0_ADDR_UV] = 0x2c,
+			[RKCIF_MIPI_FRAME0_VLW_Y] = 0x34,
+			[RKCIF_MIPI_FRAME0_VLW_UV] = 0x3c,
+			[RKCIF_MIPI_FRAME1_ADDR_Y] = 0x28,
+			[RKCIF_MIPI_FRAME1_ADDR_UV] = 0x30,
+			[RKCIF_MIPI_FRAME1_VLW_Y] = 0x38,
+			[RKCIF_MIPI_FRAME1_VLW_UV] = 0x40,
+			[RKCIF_MIPI_CROP_START] = 0xbc,
+		},
+		[RKCIF_ID1] = {
+			[RKCIF_MIPI_CTRL0] = 0x08,
+			[RKCIF_MIPI_CTRL1] = 0x0c,
+			[RKCIF_MIPI_FRAME0_ADDR_Y] = 0x44,
+			[RKCIF_MIPI_FRAME0_ADDR_UV] = 0x4c,
+			[RKCIF_MIPI_FRAME0_VLW_Y] = 0x54,
+			[RKCIF_MIPI_FRAME0_VLW_UV] = 0x5c,
+			[RKCIF_MIPI_FRAME1_ADDR_Y] = 0x48,
+			[RKCIF_MIPI_FRAME1_ADDR_UV] = 0x50,
+			[RKCIF_MIPI_FRAME1_VLW_Y] = 0x58,
+			[RKCIF_MIPI_FRAME1_VLW_UV] = 0x60,
+			[RKCIF_MIPI_CROP_START] = 0xc0,
+		},
+		[RKCIF_ID2] = {
+			[RKCIF_MIPI_CTRL0] = 0x10,
+			[RKCIF_MIPI_CTRL1] = 0x14,
+			[RKCIF_MIPI_FRAME0_ADDR_Y] = 0x64,
+			[RKCIF_MIPI_FRAME0_ADDR_UV] = 0x6c,
+			[RKCIF_MIPI_FRAME0_VLW_Y] = 0x74,
+			[RKCIF_MIPI_FRAME0_VLW_UV] = 0x7c,
+			[RKCIF_MIPI_FRAME1_ADDR_Y] = 0x68,
+			[RKCIF_MIPI_FRAME1_ADDR_UV] = 0x70,
+			[RKCIF_MIPI_FRAME1_VLW_Y] = 0x78,
+			[RKCIF_MIPI_FRAME1_VLW_UV] = 0x80,
+			[RKCIF_MIPI_CROP_START] = 0xc4,
+		},
+		[RKCIF_ID3] = {
+			[RKCIF_MIPI_CTRL0] = 0x18,
+			[RKCIF_MIPI_CTRL1] = 0x1c,
+			[RKCIF_MIPI_FRAME0_ADDR_Y] = 0x84,
+			[RKCIF_MIPI_FRAME0_ADDR_UV] = 0x8c,
+			[RKCIF_MIPI_FRAME0_VLW_Y] = 0x94,
+			[RKCIF_MIPI_FRAME0_VLW_UV] = 0x9c,
+			[RKCIF_MIPI_FRAME1_ADDR_Y] = 0x88,
+			[RKCIF_MIPI_FRAME1_ADDR_UV] = 0x90,
+			[RKCIF_MIPI_FRAME1_VLW_Y] = 0x98,
+			[RKCIF_MIPI_FRAME1_VLW_UV] = 0xa0,
+			[RKCIF_MIPI_CROP_START] = 0xc8,
+		},
+	},
+	.blocks = {
+		{
+			.offset = 0x80,
+		},
+	},
+};
+
+static inline unsigned int rkcif_mipi_get_reg(struct rkcif_interface *interface,
+					      unsigned int index)
+{
+	struct rkcif_device *rkcif = interface->rkcif;
+	unsigned int block, offset, reg;
+
+	block = interface->index - RKCIF_MIPI_BASE;
+
+	if (WARN_ON_ONCE(block > RKCIF_MIPI_MAX - RKCIF_MIPI_BASE) ||
+	    WARN_ON_ONCE(index > RKCIF_MIPI_REGISTER_MAX))
+		return RKCIF_REGISTER_NOTSUPPORTED;
+
+	offset = rkcif->match_data->mipi->blocks[block].offset;
+	reg = rkcif->match_data->mipi->regs[index];
+	if (reg == RKCIF_REGISTER_NOTSUPPORTED)
+		return reg;
+
+	return offset + reg;
+}
+
+static inline unsigned int rkcif_mipi_id_get_reg(struct rkcif_stream *stream,
+						 unsigned int index)
+{
+	struct rkcif_device *rkcif = stream->rkcif;
+	unsigned int block, id, offset, reg;
+
+	block = stream->interface->index - RKCIF_MIPI_BASE;
+	id = stream->id;
+
+	if (WARN_ON_ONCE(block > RKCIF_MIPI_MAX - RKCIF_MIPI_BASE) ||
+	    WARN_ON_ONCE(id > RKCIF_ID_MAX) ||
+	    WARN_ON_ONCE(index > RKCIF_MIPI_ID_REGISTER_MAX))
+		return RKCIF_REGISTER_NOTSUPPORTED;
+
+	offset = rkcif->match_data->mipi->blocks[block].offset;
+	reg = rkcif->match_data->mipi->regs_id[id][index];
+	if (reg == RKCIF_REGISTER_NOTSUPPORTED)
+		return reg;
+
+	return offset + reg;
+}
+
+static inline __maybe_unused void
+rkcif_mipi_write(struct rkcif_interface *interface, unsigned int index, u32 val)
+{
+	unsigned int addr = rkcif_mipi_get_reg(interface, index);
+
+	if (addr == RKCIF_REGISTER_NOTSUPPORTED)
+		return;
+
+	writel(val, interface->rkcif->base_addr + addr);
+}
+
+static inline __maybe_unused void
+rkcif_mipi_stream_write(struct rkcif_stream *stream, unsigned int index,
+			u32 val)
+{
+	unsigned int addr = rkcif_mipi_id_get_reg(stream, index);
+
+	if (addr == RKCIF_REGISTER_NOTSUPPORTED)
+		return;
+
+	writel(val, stream->rkcif->base_addr + addr);
+}
+
+static inline __maybe_unused u32
+rkcif_mipi_read(struct rkcif_interface *interface, unsigned int index)
+{
+	unsigned int addr = rkcif_mipi_get_reg(interface, index);
+
+	if (addr == RKCIF_REGISTER_NOTSUPPORTED)
+		return 0;
+
+	return readl(interface->rkcif->base_addr + addr);
+}
+
+static inline __maybe_unused u32
+rkcif_mipi_stream_read(struct rkcif_stream *stream, unsigned int index)
+{
+	unsigned int addr = rkcif_mipi_id_get_reg(stream, index);
+
+	if (addr == RKCIF_REGISTER_NOTSUPPORTED)
+		return 0;
+
+	return readl(stream->rkcif->base_addr + addr);
+}
+
+static void rkcif_mipi_queue_buffer(struct rkcif_stream *stream,
+				    unsigned int index)
+{
+	struct rkcif_buffer *buffer = stream->buffers[index];
+	u32 frm_addr_y, frm_addr_uv;
+
+	frm_addr_y = index ? RKCIF_MIPI_FRAME1_ADDR_Y :
+			     RKCIF_MIPI_FRAME0_ADDR_Y;
+	frm_addr_uv = index ? RKCIF_MIPI_FRAME1_ADDR_UV :
+			      RKCIF_MIPI_FRAME0_ADDR_UV;
+
+	rkcif_mipi_stream_write(stream, frm_addr_y,
+				buffer->buff_addr[RKCIF_PLANE_Y]);
+	rkcif_mipi_stream_write(stream, frm_addr_uv,
+				buffer->buff_addr[RKCIF_PLANE_UV]);
+}
+
+static int rkcif_mipi_start_streaming(struct rkcif_stream *stream)
+{
+	struct rkcif_interface *interface = stream->interface;
+	const struct rkcif_output_fmt *active_out_fmt;
+	const struct rkcif_mipi_match_data *match_data;
+	struct v4l2_subdev_state *state;
+	u32 ctrl0 = 0, ctrl1 = 0, int_temp = 0, int_mask = 0, vlw = 0;
+	u16 height, width;
+	int ret = -EINVAL;
+
+	state = v4l2_subdev_lock_and_get_active_state(&interface->sd);
+
+	active_out_fmt = rkcif_stream_find_output_fmt(stream, false,
+						      stream->pix.pixelformat);
+	if (!active_out_fmt)
+		goto out;
+
+	height = stream->pix.height;
+	width = stream->pix.width;
+	vlw = stream->pix.plane_fmt[0].bytesperline;
+
+	match_data = stream->rkcif->match_data->mipi;
+	if (match_data->mipi_ctrl0)
+		ctrl0 = match_data->mipi_ctrl0(stream, active_out_fmt);
+
+	ctrl1 = RKCIF_XY_COORD(width, height);
+
+	int_mask |= RKCIF_MIPI_INT_FRAME0_END(stream->id);
+	int_mask |= RKCIF_MIPI_INT_FRAME1_END(stream->id);
+
+	int_temp = rkcif_mipi_read(interface, RKCIF_MIPI_INTEN);
+	int_temp |= int_mask;
+	rkcif_mipi_write(interface, RKCIF_MIPI_INTEN, int_temp);
+
+	int_temp = rkcif_mipi_read(interface, RKCIF_MIPI_INTSTAT);
+	int_temp &= ~int_mask;
+	rkcif_mipi_write(interface, RKCIF_MIPI_INTSTAT, int_temp);
+
+	rkcif_mipi_stream_write(stream, RKCIF_MIPI_FRAME0_VLW_Y, vlw);
+	rkcif_mipi_stream_write(stream, RKCIF_MIPI_FRAME1_VLW_Y, vlw);
+	rkcif_mipi_stream_write(stream, RKCIF_MIPI_FRAME0_VLW_UV, vlw);
+	rkcif_mipi_stream_write(stream, RKCIF_MIPI_FRAME1_VLW_UV, vlw);
+	rkcif_mipi_stream_write(stream, RKCIF_MIPI_CROP_START, 0x0);
+	rkcif_mipi_stream_write(stream, RKCIF_MIPI_CTRL1, ctrl1);
+	rkcif_mipi_stream_write(stream, RKCIF_MIPI_CTRL0, ctrl0);
+
+	ret = 0;
+
+out:
+	v4l2_subdev_unlock_state(state);
+	return ret;
+}
+
+static void rkcif_mipi_stop_streaming(struct rkcif_stream *stream)
+{
+	struct rkcif_interface *interface = stream->interface;
+	struct v4l2_subdev_state *state;
+	u32 int_temp = 0, int_mask = 0;
+
+	state = v4l2_subdev_lock_and_get_active_state(&interface->sd);
+
+	rkcif_mipi_stream_write(stream, RKCIF_MIPI_CTRL0, 0);
+
+	int_mask |= RKCIF_MIPI_INT_FRAME0_END(stream->id);
+	int_mask |= RKCIF_MIPI_INT_FRAME1_END(stream->id);
+
+	int_temp = rkcif_mipi_read(interface, RKCIF_MIPI_INTEN);
+	int_temp &= ~int_mask;
+	rkcif_mipi_write(interface, RKCIF_MIPI_INTEN, int_temp);
+
+	int_temp = rkcif_mipi_read(interface, RKCIF_MIPI_INTSTAT);
+	int_temp &= ~int_mask;
+	rkcif_mipi_write(interface, RKCIF_MIPI_INTSTAT, int_temp);
+
+	stream->stopping = false;
+
+	v4l2_subdev_unlock_state(state);
+}
+
+static void rkcif_mipi_set_crop(struct rkcif_stream *stream, u16 left, u16 top)
+{
+	u32 val;
+
+	val = RKCIF_XY_COORD(left, top);
+	rkcif_mipi_stream_write(stream, RKCIF_MIPI_CROP_START, val);
+}
+
+irqreturn_t rkcif_mipi_isr(int irq, void *ctx)
+{
+	struct device *dev = ctx;
+	struct rkcif_device *rkcif = dev_get_drvdata(dev);
+	irqreturn_t ret = IRQ_NONE;
+	u32 intstat;
+
+	for (unsigned int i = 0; i < rkcif->match_data->mipi->mipi_num; i++) {
+		enum rkcif_interface_index index = RKCIF_MIPI_BASE + i;
+		struct rkcif_interface *interface = &rkcif->interfaces[index];
+
+		intstat = rkcif_mipi_read(interface, RKCIF_MIPI_INTSTAT);
+		rkcif_mipi_write(interface, RKCIF_MIPI_INTSTAT, intstat);
+
+		for (unsigned int j = 0; j < interface->streams_num; j++) {
+			struct rkcif_stream *stream = &interface->streams[j];
+
+			if (intstat & RKCIF_MIPI_INT_FRAME0_END(stream->id) ||
+			    intstat & RKCIF_MIPI_INT_FRAME1_END(stream->id)) {
+				ret = IRQ_HANDLED;
+
+				if (stream->stopping) {
+					rkcif_mipi_stop_streaming(stream);
+					wake_up(&stream->wq_stopped);
+					continue;
+				}
+
+				rkcif_stream_pingpong(stream);
+			}
+		}
+	}
+
+	return ret;
+}
+
+int rkcif_mipi_register(struct rkcif_device *rkcif)
+{
+	int ret;
+
+	if (!rkcif->match_data->mipi)
+		return 0;
+
+	for (unsigned int i = 0; i < rkcif->match_data->mipi->mipi_num; i++) {
+		enum rkcif_interface_index index = RKCIF_MIPI_BASE + i;
+		struct rkcif_interface *interface = &rkcif->interfaces[index];
+
+		interface->index = index;
+		interface->type = RKCIF_IF_MIPI;
+		interface->in_fmts = mipi_in_fmts;
+		interface->in_fmts_num = ARRAY_SIZE(mipi_in_fmts);
+		interface->set_crop = rkcif_mipi_set_crop;
+		interface->streams_num = 0;
+		ret = rkcif_interface_register(rkcif, interface);
+		if (ret)
+			continue;
+
+		for (unsigned int j = 0; j < RKCIF_ID_MAX; j++) {
+			struct rkcif_stream *stream = &interface->streams[j];
+
+			stream->id = j;
+			stream->interface = interface;
+			stream->out_fmts = mipi_out_fmts;
+			stream->out_fmts_num = ARRAY_SIZE(mipi_out_fmts);
+			stream->queue_buffer = rkcif_mipi_queue_buffer;
+			stream->start_streaming = rkcif_mipi_start_streaming;
+			stream->stop_streaming = rkcif_mipi_stop_streaming;
+			ret = rkcif_stream_register(rkcif, stream);
+			if (ret)
+				goto err;
+			interface->streams_num++;
+		}
+	}
+
+	return 0;
+
+err:
+	for (unsigned int i = 0; i < rkcif->match_data->mipi->mipi_num; i++) {
+		enum rkcif_interface_index index = RKCIF_MIPI_BASE + i;
+		struct rkcif_interface *interface = &rkcif->interfaces[index];
+
+		for (unsigned int j = 0; j < interface->streams_num; j++)
+			rkcif_stream_unregister(&interface->streams[j]);
+
+		rkcif_interface_unregister(interface);
+	}
+	return ret;
+}
+
+void rkcif_mipi_unregister(struct rkcif_device *rkcif)
+{
+	if (!rkcif->match_data->mipi)
+		return;
+
+	for (unsigned int i = 0; i < rkcif->match_data->mipi->mipi_num; i++) {
+		enum rkcif_interface_index index = RKCIF_MIPI_BASE + i;
+		struct rkcif_interface *interface = &rkcif->interfaces[index];
+
+		for (unsigned int j = 0; j < interface->streams_num; j++)
+			rkcif_stream_unregister(&interface->streams[j]);
+
+		rkcif_interface_unregister(interface);
+	}
+}
diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.h b/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.h
new file mode 100644
index 000000000000..7f16eadc474c
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Rockchip Camera Interface (CIF) Driver
+ *
+ * Copyright (C) 2018 Rockchip Electronics Co., Ltd.
+ * Copyright (C) 2025 Michael Riesch <michael.riesch at wolfvision.net>
+ * Copyright (C) 2025 Collabora, Ltd.
+ */
+
+#ifndef _RKCIF_CAPTURE_MIPI_H
+#define _RKCIF_CAPTURE_MIPI_H
+
+#include "rkcif-common.h"
+
+extern const struct rkcif_mipi_match_data rkcif_rk3568_vicap_mipi_match_data;
+
+int rkcif_mipi_register(struct rkcif_device *rkcif);
+
+void rkcif_mipi_unregister(struct rkcif_device *rkcif);
+
+irqreturn_t rkcif_mipi_isr(int irq, void *ctx);
+
+#endif
diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-common.h b/drivers/media/platform/rockchip/rkcif/rkcif-common.h
index c6ec578e1049..dd92cfbc879f 100644
--- a/drivers/media/platform/rockchip/rkcif/rkcif-common.h
+++ b/drivers/media/platform/rockchip/rkcif/rkcif-common.h
@@ -73,6 +73,17 @@ enum rkcif_interface_type {
 	RKCIF_IF_MIPI,
 };
 
+enum rkcif_mipi_format_type {
+	RKCIF_MIPI_TYPE_INVALID,
+	RKCIF_MIPI_TYPE_RAW8,
+	RKCIF_MIPI_TYPE_RAW10,
+	RKCIF_MIPI_TYPE_RAW12,
+	RKCIF_MIPI_TYPE_RGB888,
+	RKCIF_MIPI_TYPE_YUV422SP,
+	RKCIF_MIPI_TYPE_YUV420SP,
+	RKCIF_MIPI_TYPE_YUV400,
+};
+
 struct rkcif_buffer {
 	struct vb2_v4l2_buffer vb;
 	struct list_head queue;
@@ -107,9 +118,15 @@ struct rkcif_output_fmt {
 	u32 fourcc;
 	u32 mbus_code;
 	u8 cplanes;
+	u8 depth;
 
 	union {
 		u32 dvp_fmt_val;
+		struct {
+			u8 dt;
+			bool compact;
+			enum rkcif_mipi_format_type type;
+		} mipi;
 	};
 };
 
@@ -184,6 +201,17 @@ struct rkcif_interface {
 	void (*set_crop)(struct rkcif_stream *stream, u16 left, u16 top);
 };
 
+struct rkcif_mipi_match_data {
+	unsigned int mipi_num;
+	unsigned int regs[RKCIF_MIPI_REGISTER_MAX];
+	unsigned int regs_id[RKCIF_ID_MAX][RKCIF_MIPI_ID_REGISTER_MAX];
+	u32 (*mipi_ctrl0)(struct rkcif_stream *stream,
+			  const struct rkcif_output_fmt *active_out_fmt);
+	struct {
+		unsigned int offset;
+	} blocks[RKCIF_MIPI_MAX - RKCIF_MIPI_BASE];
+};
+
 struct rkcif_dvp_match_data {
 	const struct rkcif_input_fmt *in_fmts;
 	unsigned int in_fmts_num;
@@ -199,6 +227,7 @@ struct rkcif_match_data {
 	const char *const *clks;
 	unsigned int clks_num;
 	const struct rkcif_dvp_match_data *dvp;
+	const struct rkcif_mipi_match_data *mipi;
 };
 
 struct rkcif_device {
diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-dev.c b/drivers/media/platform/rockchip/rkcif/rkcif-dev.c
index addc118ff8bf..b4cf1146f131 100644
--- a/drivers/media/platform/rockchip/rkcif/rkcif-dev.c
+++ b/drivers/media/platform/rockchip/rkcif/rkcif-dev.c
@@ -24,6 +24,7 @@
 #include <media/v4l2-mc.h>
 
 #include "rkcif-capture-dvp.h"
+#include "rkcif-capture-mipi.h"
 #include "rkcif-common.h"
 
 static const char *const px30_vip_clks[] = {
@@ -49,6 +50,7 @@ static const struct rkcif_match_data rk3568_vicap_match_data = {
 	.clks = rk3568_vicap_clks,
 	.clks_num = ARRAY_SIZE(rk3568_vicap_clks),
 	.dvp = &rkcif_rk3568_vicap_dvp_match_data,
+	.mipi = &rkcif_rk3568_vicap_mipi_match_data,
 };
 
 static const struct of_device_id rkcif_plat_of_match[] = {
@@ -72,14 +74,21 @@ static int rkcif_register(struct rkcif_device *rkcif)
 	if (ret && ret != -ENODEV)
 		goto err;
 
+	ret = rkcif_mipi_register(rkcif);
+	if (ret && ret != -ENODEV)
+		goto err_dvp_unregister;
+
 	return 0;
 
+err_dvp_unregister:
+	rkcif_dvp_unregister(rkcif);
 err:
 	return ret;
 }
 
 static void rkcif_unregister(struct rkcif_device *rkcif)
 {
+	rkcif_mipi_unregister(rkcif);
 	rkcif_dvp_unregister(rkcif);
 }
 
@@ -128,6 +137,9 @@ static irqreturn_t rkcif_isr(int irq, void *ctx)
 	if (rkcif_dvp_isr(irq, ctx) == IRQ_HANDLED)
 		ret = IRQ_HANDLED;
 
+	if (rkcif_mipi_isr(irq, ctx) == IRQ_HANDLED)
+		ret = IRQ_HANDLED;
+
 	return ret;
 }
 
diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-regs.h b/drivers/media/platform/rockchip/rkcif/rkcif-regs.h
index 91d42d31fd10..3cf7ee19de30 100644
--- a/drivers/media/platform/rockchip/rkcif/rkcif-regs.h
+++ b/drivers/media/platform/rockchip/rkcif/rkcif-regs.h
@@ -128,4 +128,26 @@ enum rkcif_dvp_register_index {
 	RKCIF_DVP_REGISTER_MAX
 };
 
+enum rkcif_mipi_register_index {
+	RKCIF_MIPI_CTRL,
+	RKCIF_MIPI_INTEN,
+	RKCIF_MIPI_INTSTAT,
+	RKCIF_MIPI_REGISTER_MAX
+};
+
+enum rkcif_mipi_id_register_index {
+	RKCIF_MIPI_CTRL0,
+	RKCIF_MIPI_CTRL1,
+	RKCIF_MIPI_FRAME0_ADDR_Y,
+	RKCIF_MIPI_FRAME0_ADDR_UV,
+	RKCIF_MIPI_FRAME0_VLW_Y,
+	RKCIF_MIPI_FRAME0_VLW_UV,
+	RKCIF_MIPI_FRAME1_ADDR_Y,
+	RKCIF_MIPI_FRAME1_ADDR_UV,
+	RKCIF_MIPI_FRAME1_VLW_Y,
+	RKCIF_MIPI_FRAME1_VLW_UV,
+	RKCIF_MIPI_CROP_START,
+	RKCIF_MIPI_ID_REGISTER_MAX
+};
+
 #endif

-- 
2.39.5




From devnull+michael.riesch.collabora.com at kernel.org  Fri Nov 14 07:20:25 2025
From: devnull+michael.riesch.collabora.com at kernel.org (Michael Riesch via B4 Relay)
Date: Fri, 14 Nov 2025 16:20:25 +0100
Subject: [PATCH v15 14/14] arm64: dts: rockchip: enable vicap dvp on
 wolfvision pf5 io expander
In-Reply-To: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
References: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
Message-ID: <20240220-rk3568-vicap-v15-14-8f4915ee365d@collabora.com>

From: Michael Riesch <michael.riesch at collabora.com>

The Digital Video Port (DVP, the 16-bit variant) of the RK3568 VICAP
is broken out to the PF5 mainboard expansion header.
Enable it in the device tree overlay for the WolfVision PF5 IO
Expander board.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
Reviewed-by: Gerald Loacker <gerald.loacker at wolfvision.net>
Tested-by: Gerald Loacker <gerald.loacker at wolfvision.net>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
Signed-off-by: Michael Riesch <michael.riesch at collabora.com>
---
 .../rockchip/rk3568-wolfvision-pf5-io-expander.dtso  | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5-io-expander.dtso b/arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5-io-expander.dtso
index 048933de2943..8cfce71dd318 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5-io-expander.dtso
+++ b/arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5-io-expander.dtso
@@ -11,6 +11,7 @@
 #include <dt-bindings/clock/rk3568-cru.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/media/video-interfaces.h>
 #include <dt-bindings/pinctrl/rockchip.h>
 
 &{/} {
@@ -134,3 +135,22 @@ &usb2phy0_host {
 	phy-supply = <&usb_host_vbus>;
 	status = "okay";
 };
+
+&vicap {
+	pinctrl-names = "default";
+	pinctrl-0 = <&cif_clk &cif_dvp_clk &cif_dvp_bus16>;
+	status = "okay";
+};
+
+&vicap_dvp {
+	vicap_dvp_input: endpoint {
+		bus-type = <MEDIA_BUS_TYPE_BT656>;
+		bus-width = <16>;
+		pclk-sample = <MEDIA_PCLK_SAMPLE_DUAL_EDGE>;
+		rockchip,dvp-clk-delay = <10>;
+	};
+};
+
+&vicap_mmu {
+	status = "okay";
+};

-- 
2.39.5




From michael.opdenacker at rootcommit.com  Fri Nov 14 07:46:34 2025
From: michael.opdenacker at rootcommit.com (michael.opdenacker at rootcommit.com)
Date: Fri, 14 Nov 2025 15:46:34 +0000 (UTC)
Subject: [PATCH v2 0/2] arm64: dts: rockchip: add Tinker Board 3 and 3S device tree
Message-ID: <20251114154617.69950-1-michael.opdenacker@rootcommit.com>

From: Michael Opdenacker <michael.opdenacker at rootcommit.com>

Add initial device tree support for Asus Tinker Board 3 [1] and 3S [2],
which are SBCs based on the Rockchip 3566 SoC.

The "3S" version ("S" for "storage") is just a regular Tinker Board 3
fitted with a 16 GB eMMC and a "mask ROM" DIP switch
(to mask the eMMC and enter "Mask ROM" mode for recovery).

This adds support for:
- Debug UART (/dev/ttyS2)
- SD card (/dev/mmcblk1)
- eMMC (/dev/mmcblk0, only on Tinker Board 3S)
- I2C:
  - i2c0 (internal bus with a PMIC and regulators)
  - i2c2 (internal bus with an at24 eeprom and an RTC device)
- USB 2.0 ports
- 2 GPIO LEDS

This code was tested on Tinker Board 3S using the "master"
branch of the Linux kernel.

[1] https://tinker-board.asus.com/series/tinker-board-3.html
[2] https://tinker-board.asus.com/series/tinker-board-3s.html

Changes in V2:
- Rename "Tinker board" to "Tinker Board"
  in commit messages and DT code
- Insert "-board" in DT file names
- Insert "-board" in new compatible string too
- Commit messages: change the way the references are introduced
  ("[1] https://..." instead of "Link: https://... [1]")
- Reorder alias properties and node names
- Add missing "cpu-supply" property to cpu nodes
- Use standard "eeprom at addr" node name for at24 eeprom
- DT commit message: add missing "Asus" before "Tinker"

Michael Opdenacker (2):
  dt-bindings: arm: rockchip: Add Asus Tinker Board 3 and 3S
  arm64: dts: rockchip: Add Asus Tinker Board 3 and 3S device tree

 .../devicetree/bindings/arm/rockchip.yaml     |  11 +
 arch/arm64/boot/dts/rockchip/Makefile         |   2 +
 .../dts/rockchip/rk3566-tinker-board-3.dts    |  14 +
 .../dts/rockchip/rk3566-tinker-board-3.dtsi   | 280 ++++++++++++++++++
 .../dts/rockchip/rk3566-tinker-board-3s.dts   |  30 ++
 5 files changed, 337 insertions(+)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3.dts
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3.dtsi
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3s.dts



From michael.opdenacker at rootcommit.com  Fri Nov 14 07:46:42 2025
From: michael.opdenacker at rootcommit.com (michael.opdenacker at rootcommit.com)
Date: Fri, 14 Nov 2025 15:46:42 +0000 (UTC)
Subject: [PATCH v2 1/2] dt-bindings: arm: rockchip: Add Asus Tinker Board 3 and 3S
In-Reply-To: <20251114154617.69950-1-michael.opdenacker@rootcommit.com>
References: <20251114154617.69950-1-michael.opdenacker@rootcommit.com>
Message-ID: <20251114154617.69950-2-michael.opdenacker@rootcommit.com>

From: Michael Opdenacker <michael.opdenacker at rootcommit.com>

Document the compatible strings for Asus Tinker Board 3 [1] and 3S [2],
which are SBCs based on the Rockchip 3566 SoC.

The "3S" version ("S" for "storage") just adds a 16 GB eMMC
and a "mask ROM" DIP switch to the "3" version.

[1] https://tinker-board.asus.com/series/tinker-board-3.html
[2] https://tinker-board.asus.com/series/tinker-board-3s.html

Signed-off-by: Michael Opdenacker <michael.opdenacker at rootcommit.com>
---
 Documentation/devicetree/bindings/arm/rockchip.yaml | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
index 6aceaa8acbb2..cd249325a4d9 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.yaml
+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
@@ -86,6 +86,17 @@ properties:
           - const: asus,rk3288-tinker-s
           - const: rockchip,rk3288
 
+      - description: Asus Tinker Board 3
+        items:
+          - const: asus,rk3566-tinker-board-3
+          - const: rockchip,rk3566
+
+      - description: Asus Tinker Board 3S
+        items:
+          - const: asus,rk3566-tinker-board-3s
+          - const: asus,rk3566-tinker-board-3
+          - const: rockchip,rk3566
+
       - description: Beelink A1
         items:
           - const: azw,beelink-a1


From michael.opdenacker at rootcommit.com  Fri Nov 14 07:46:56 2025
From: michael.opdenacker at rootcommit.com (michael.opdenacker at rootcommit.com)
Date: Fri, 14 Nov 2025 15:46:56 +0000 (UTC)
Subject: [PATCH v2 2/2] arm64: dts: rockchip: Add Asus Tinker Board 3 and 3S device tree
In-Reply-To: <20251114154617.69950-1-michael.opdenacker@rootcommit.com>
References: <20251114154617.69950-1-michael.opdenacker@rootcommit.com>
Message-ID: <20251114154617.69950-3-michael.opdenacker@rootcommit.com>

From: Michael Opdenacker <michael.opdenacker at rootcommit.com>

Add initial device tree support for Asus Tinker Board 3 [1] and 3S [2],
which are SBCs based on the Rockchip 3566 SoC.

The "3S" version ("S" for "storage") just adds a 16 GB eMMC
and a "mask ROM" DIP switch (to mask the eMMC and enter "Mask ROM"
mode for recovery) to the "3" version.

This adds support for:
- Debug UART (/dev/ttyS2)
- SD card (/dev/mmcblk1)
- eMMC (/dev/mmcblk0, only on Tinker Board 3S)
- I2C:
  - i2c0 (internal bus with a PMIC and regulators)
  - i2c2 (internal bus with an at24 eeprom and an RTC device)
- USB 2.0 ports
- 2 GPIO LEDS

[1] https://tinker-board.asus.com/series/tinker-board-3.html
[2] https://tinker-board.asus.com/series/tinker-board-3s.html

Signed-off-by: Michael Opdenacker <michael.opdenacker at rootcommit.com>
---
 arch/arm64/boot/dts/rockchip/Makefile         |   2 +
 .../dts/rockchip/rk3566-tinker-board-3.dts    |  14 +
 .../dts/rockchip/rk3566-tinker-board-3.dtsi   | 280 ++++++++++++++++++
 .../dts/rockchip/rk3566-tinker-board-3s.dts   |  30 ++
 4 files changed, 326 insertions(+)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3.dts
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3.dtsi
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3s.dts

diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index ad684e3831bc..e0d8b9ed176d 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -130,6 +130,8 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-lubancat-1.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-nanopi-r3s.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-bigtreetech-cb2-manta.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-bigtreetech-pi2.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-tinker-board-3.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-tinker-board-3s.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-bpi-r2-pro.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-v10.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-fastrhino-r66s.dtb
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3.dts b/arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3.dts
new file mode 100644
index 000000000000..af11faff5564
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2025 Michael Opdenacker <michael.opdenacker at rootcommit.com>
+ */
+
+/dts-v1/;
+
+#include "rk3566-tinker-board-3.dtsi"
+
+/ {
+	model = "Asus Tinker Board 3";
+	compatible = "asus,rk3566-tinker-board-3", "rockchip,rk3566";
+};
+
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3.dtsi
new file mode 100644
index 000000000000..8544d56031f2
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3.dtsi
@@ -0,0 +1,280 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2025 Michael Opdenacker <michael.opdenacker at rootcommit.com>
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
+#include "rk3566.dtsi"
+
+/ {
+	aliases {
+		i2c0 = &i2c0;
+		i2c2 = &i2c2;
+		mmc1 = &sdmmc0;
+		serial2 = &uart2;
+	};
+
+	chosen {
+		stdout-path = "serial2:1500000n8";
+	};
+
+	gpio_leds: gpio-leds {
+		compatible = "gpio-leds";
+
+		act-led {
+			gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger="mmc1";
+		};
+
+		rsv-led {
+			gpios = <&gpio0 RK_PD6 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger="none";
+		};
+	};
+
+	vcc3v3_sys: regulator-3v3-vcc-sys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+
+	vcc5v0_sys: regulator-5v0-vcc-sys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+	};
+
+	vcc5v0_usb_host: regulator-5v0-vcc-usb-host {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&usb_host_pwren_h>;
+		regulator-name = "vcc5v0_usb_host";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+};
+
+&cpu0 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu1 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu2 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu3 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&i2c0 {
+	status = "okay";
+
+	rk809: pmic at 20 {
+		compatible = "rockchip,rk809";
+		reg = <0x20>;
+		assigned-clocks = <&cru I2S1_MCLKOUT_TX>;
+		assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>;
+		#clock-cells = <1>;
+		clocks = <&cru I2S1_MCLKOUT_TX>;
+		clock-names = "mclk";
+		clock-output-names = "rk809-clkout1", "rk809-clkout2";
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_int_l>, <&i2s1m0_mclk>;
+		#sound-dai-cells = <0>;
+		system-power-controller;
+		wakeup-source;
+
+		vcc1-supply = <&vcc3v3_sys>;
+		vcc2-supply = <&vcc3v3_sys>;
+		vcc3-supply = <&vcc3v3_sys>;
+		vcc4-supply = <&vcc3v3_sys>;
+		vcc5-supply = <&vcc3v3_sys>;
+		vcc6-supply = <&vcc3v3_sys>;
+		vcc7-supply = <&vcc3v3_sys>;
+		vcc8-supply = <&vcc3v3_sys>;
+		vcc9-supply = <&vcc3v3_sys>;
+
+		regulators {
+			vcc_1v8: DCDC_REG5 {
+				regulator-name = "vcc_1v8";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_3v3: SWITCH_REG1 {
+				regulator-name = "vcc_3v3";
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc3v3_sd: SWITCH_REG2 {
+				regulator-name = "vcc3v3_sd";
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vccio_sd: LDO_REG5 {
+				regulator-name = "vccio_sd";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+		};
+	};
+
+	vdd_cpu: regulator at 40 {
+		compatible = "silergy,syr827";
+		reg = <0x40>;
+		fcs,suspend-voltage-selector = <1>;
+		regulator-name = "vdd_cpu";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <830000>;
+		regulator-max-microvolt = <1200000>;
+		regulator-ramp-delay = <2300>;
+		vin-supply = <&vcc3v3_sys>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+};
+
+&i2c2 {
+	status = "okay";
+
+	eeprom at 50 {
+		compatible = "atmel,24c08";
+		reg = <0x50>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&tb3_eeprom>;
+		status = "okay";
+	};
+
+	rtc_isl1208: rtc at 6f {
+		compatible = "isil,isl1208";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_externalrtc_reg>;
+		interrupt-names = "irq";
+		interrupts-extended = <&gpio0 RK_PD3 IRQ_TYPE_EDGE_FALLING>;
+		reg = <0x6f>;
+		status = "okay";
+	};
+};
+
+&pinctrl {
+	pmic {
+		pmic_int_l: pmic-int-l {
+			rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	usb {
+		usb_host_pwren_h: usb-host-pwren-h {
+			rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		usb_otg_pwren_h: usb-otg-pwren-h {
+			rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	rtc {
+		pinctrl_externalrtc_reg: externalrtcreggrp {
+			rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	eeprom {
+		tb3_eeprom: tb3-eeprom {
+			rockchip,pins = <3 RK_PC1 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+};
+
+&sdmmc0 {
+	bus-width = <4>;
+	cap-sd-highspeed;
+	disable-wp;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
+	vmmc-supply = <&vcc3v3_sd>;
+	vqmmc-supply = <&vccio_sd>;
+	status = "okay";
+};
+
+&uart2 {
+	status = "okay";
+};
+
+&usb_host0_ehci {
+	status = "okay";
+};
+
+&usb_host0_ohci {
+	status = "okay";
+};
+
+&usb_host1_ehci {
+	status = "okay";
+};
+
+&usb_host1_ohci {
+	status = "okay";
+};
+
+&usb2phy0 {
+	status = "okay";
+};
+
+&usb2phy0_host {
+	phy-supply = <&vcc5v0_usb_host>;
+	status = "okay";
+};
+
+&usb2phy1 {
+	status = "okay";
+};
+
+&usb2phy1_host {
+	phy-supply = <&vcc5v0_usb_host>;
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3s.dts b/arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3s.dts
new file mode 100644
index 000000000000..7bd1e31fdc57
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3s.dts
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2025 Michael Opdenacker <michael.opdenacker at rootcommit.com>
+ */
+
+/dts-v1/;
+
+#include "rk3566-tinker-board-3.dtsi"
+
+/ {
+	model = "Asus Tinker Board 3S";
+	compatible = "asus,rk3566-tinker-board-3s", "asus,rk3566-tinker-board-3", "rockchip,rk3566";
+
+	aliases {
+		mmc0 = &sdhci;
+	};
+};
+
+&sdhci {
+	bus-width = <8>;
+	cap-mmc-highspeed;
+	max-frequency = <200000000>;
+	mmc-hs200-1_8v;
+	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
+	vmmc-supply = <&vcc_3v3>;
+	vqmmc-supply = <&vcc_1v8>;
+	status = "okay";
+};


From geraldogabriel at gmail.com  Fri Nov 14 12:34:05 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Fri, 14 Nov 2025 17:34:05 -0300
Subject: [PATCH] arm64: dts: rockchip: align bindings to PCIe spec
In-Reply-To: <e8524bf8-a90c-423f-8a58-9ef05a3db1dd@rock-chips.com>
References: <aQsIXcQzeYop6a0B@geday>
 <67b605b0-7046-448a-bc9b-d3ac56333809@rock-chips.com>
 <aQ1c7ZDycxiOIy8Y@geday>
 <d9e257bd-806c-48b4-bb22-f1342e9fc15a@rock-chips.com>
 <aRLEbfsmXnGwyigS@geday>
 <AGsAmwCFJj0ZQ4vKzrqC84rs.3.1762847224180.Hmail.ye.zhang@rock-chips.com>
 <aRQ_R90S8T82th45@geday>
 <aRUvr0UggTYkkCZ_@geday>
 <aRazCssWVdAOmy7D@geday>
 <e8524bf8-a90c-423f-8a58-9ef05a3db1dd@rock-chips.com>
Message-ID: <aReSPbRxCgdNRI9y@geday>

On Fri, Nov 14, 2025 at 05:16:21PM +0800, Shawn Lin wrote:
> Don't worry, it's helpful, so I think Ye could have a look.
> May I ask if the failure only happened to one specific board?

Hi Shawn,

Yes, testing is restricted to my Radxa Rock Pi N10 board.

> 
> Another thing I noticed is about one commit:
> 114b06ee108c ("PCI: rockchip: Set Target Link Speed to 5.0 GT/s before 
> retraining")
> 
> It said: "Rockchip controllers can support up to 5.0 GT/s link speed."
> But we issued an errata long time ago to announced it doesn't, you could
> also check the PCIe part of RK3399 datasheet:
> https://opensource.rock-chips.com/images/d/d7/Rockchip_RK3399_Datasheet_V2.1-20200323.pdf

OK, I'm partly responsible for that as author of the commit in question.

First off let me say I do not intend to send any patches setting
max-link-speed to TWO for this platform.

I understand you issued an erratum, but are you absolutely sure about
that erratum? Because my testing shows otherwise:

---
With max-link-speed = <2>
pci 0000:01:00.0: 16.000 Gb/s available PCIe bandwidth, limited by 5.0 GT/s PCIe x4 link at 0000:00:00.0 (capable of 31.504 Gb/s with 8.0 GT/s PCIe x4 link)

/dev/nvme0n1:
 Timing cached reads:   3002 MB in  2.00 seconds = 1502.21 MB/sec
 Timing buffered disk reads: 2044 MB in  3.00 seconds = 680.79 MB/sec
---
With max-link-speed = <1>
pci 0000:01:00.0: 8.000 Gb/s available PCIe bandwidth, limited by 2.5 GT/s PCIe x4 link at 0000:00:00.0 (capable of 31.504 Gb/s with 8.0 GT/s PCIe x4 link)

/dev/nvme0n1:
 Timing cached reads:   2730 MB in  2.00 seconds = 1366.15 MB/sec
 Timing buffered disk reads: 2028 MB in  3.00 seconds = 675.71 MB/sec
---

As you can see, not only the kernel PCI driver recognizes 5.0 GT/s PCIe
link but there's even a marginal increase in cached reads as measured by
hdparm, the gains are of course limited by CPU performance.

> Also we set max-link-speed to ONE in rk3399-base.dtsi but seems another
> patch slip in: 755fff528b1b ("arm64: dts: rockchip: add variables for 
> pcie completion to helios64")

I can't speak for patches I haven't authored, but I believe you're
welcome to send a correction.

Thank you,
Geraldo Nascimento


From heiko at sntech.de  Fri Nov 14 15:04:08 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Sat, 15 Nov 2025 00:04:08 +0100
Subject: [PATCH v3 0/2] drm/rockchip: dw_hdmi_qp: Fixup usage of enable_gpio
In-Reply-To: <20251027222641.25066-1-laurent.pinchart@ideasonboard.com>
References: <20251027222641.25066-1-laurent.pinchart@ideasonboard.com>
Message-ID: <176316144239.624283.9548416396481211446.b4-ty@sntech.de>


On Tue, 28 Oct 2025 00:26:39 +0200, Laurent Pinchart wrote:
> The dw_hdmi_qp driver supports a "enable-gpios" DT property that is not
> documented in the corresponding DT bindings, and is not used in any
> upstream device tree sources. This patch series renames the property to
> "frl-enable-gpios" to express its purpose more clearly, and documents it
> in the bindings.
> 
> In the previous these two patches were part of "[PATCH v2 0/5] arm64:
> dts: rockchip: Add device tree for the Orange Pi CM5 Base board" ([1]).
> I have split them from the Orange Pi CM5 Base DT and rebased them on top
> of the drm-misc-next branch to ease integration.
> 
> [...]

Applied, thanks!

[1/2] dt-bindings: display: rk3588-dw-hdmi-qp: Add frl-enable-gpios property
      commit: ca408d8d93d33423cafe3046f40bcc81bc6ee5f3
[2/2] drm/rockchip: dw_hdmi_qp: Fixup usage of enable_gpio member in main struct
      commit: 53dd063bb6b342ca00d2a0c138ba58807a690417

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Fri Nov 14 15:04:07 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Sat, 15 Nov 2025 00:04:07 +0100
Subject: [PATCH v1] drm/rockchip: analogix_dp: Use dev_err_probe() instead of DRM_DEV_ERROR() during probing
In-Reply-To: <20251110075817.1159857-1-damon.ding@rock-chips.com>
References: <20251110075817.1159857-1-damon.ding@rock-chips.com>
Message-ID: <176316144241.624283.9273184537372082996.b4-ty@sntech.de>


On Mon, 10 Nov 2025 15:58:17 +0800, Damon Ding wrote:
> The DRM_DEV_ERROR() has been deprecated, and use dev_err_probe()
> can be better. The other reason is that dev_err_probe() help avoid
> unexpected repeated err logs during defered probing.
> 
> 

Applied, thanks!

[1/1] drm/rockchip: analogix_dp: Use dev_err_probe() instead of DRM_DEV_ERROR() during probing
      commit: 836b5e9c6dbd5e5ab82d0a153483048e355a79c1

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Fri Nov 14 15:04:06 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Sat, 15 Nov 2025 00:04:06 +0100
Subject: [PATCH v3 0/5] High color depth support for RK3576/RK3588 HDMI output
In-Reply-To: <20251021-rk3588-10bpc-v3-0-3d3eed00a6db@collabora.com>
References: <20251021-rk3588-10bpc-v3-0-3d3eed00a6db@collabora.com>
Message-ID: <176316144244.624283.15533493108717304321.b4-ty@sntech.de>


On Tue, 21 Oct 2025 13:19:13 +0300, Cristian Ciocaltea wrote:
> Since both Rockchip RK3576 and RK3588 SoCs are capable of handling 10
> bpc color depth HDMI output and we've already landed the required HDPTX
> PHY driver changes to support the setup, let's add the missing bits and
> pieces to VOP2, DW HDMI QP encoder and bridge library.
> 
> 

Applied, thanks!

[1/5] drm/rockchip: vop2: Check bpc before switching DCLK source
      commit: b0362c45c401c36412a1305b34a3bfeae35dbca7
[2/5] drm/bridge: dw-hdmi-qp: Handle platform supported formats and color depth
      commit: 1ff27c5929ab0f5e34d5062637369ca542a6d385
[3/5] drm/rockchip: dw_hdmi_qp: Switch to phy_configure()
      commit: ba9c2fe18c171fabe0958502e080e000671ac36f
[4/5] drm/rockchip: dw_hdmi_qp: Use bit macros for RK3576 regs
      commit: 97ffefaaf4e9ab3aeddb2273e1a9b2854c481b11
[5/5] drm/rockchip: dw_hdmi_qp: Add high color depth support
      commit: e95b9ff6bfa400d34e1cfcd8062641ba3be821a7

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Fri Nov 14 15:28:10 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Sat, 15 Nov 2025 00:28:10 +0100
Subject: [PATCH v1] drm/rockchip: Set VOP for the DRM DMA device
In-Reply-To: <20251022161948.199731-1-dmitry.osipenko@collabora.com>
References: <20251022161948.199731-1-dmitry.osipenko@collabora.com>
Message-ID: <176316288379.665693.1905072777626583730.b4-ty@sntech.de>


On Wed, 22 Oct 2025 19:19:48 +0300, Dmitry Osipenko wrote:
> Use VOP for DMA operations performed by DRM core. Rockchip DRM driver
> is backed by a virtual device that isn't IOMMU-capable, while VOP is the
> actual display controller device backed by IOMMU. Fixes "swiotlb buffer
> is full" warning messages originated from GEM prime code paths.
> 
> Note, that backporting is non-trivial as this depends on 143ec8d3f9396
> ("drm/prime: Support dedicated DMA device for dma-buf imports"), which
> landed in v6.16 and 421be3ee36a4 ("drm/rockchip: Refactor IOMMU
> initialisation"), which landed in v5.19.
> 
> [...]

Applied, thanks!

[1/1] drm/rockchip: Set VOP for the DRM DMA device
      commit: 7d7bb790aced3b1b8550b74e02fdfc001d044bee

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Fri Nov 14 15:45:27 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Sat, 15 Nov 2025 00:45:27 +0100
Subject: [PATCH] drm/rockchip: vop2: Use OVL_LAYER_SEL configuration instead of use win_mask calculate used layers
In-Reply-To: <20251112085024.2480111-1-andyshrk@163.com>
References: <20251112085024.2480111-1-andyshrk@163.com>
Message-ID: <176316391967.677170.7889906780839490279.b4-ty@sntech.de>


On Wed, 12 Nov 2025 16:50:23 +0800, Andy Yan wrote:
> When there are multiple Video Ports, and only one of them is working
> (for example, VP1 is working while VP0 is not), in this case, the
> win_mask of VP0 is 0. However, we have already set the port mux for VP0
> according to vp0->nlayers, and at the same time, in the OVL_LAYER_SEL
> register, there are windows will also be assigned to layers which will
> map to the inactive VPs. In this situation, vp0->win_mask is zero as it
> now working, it is more reliable to calculate the used layers based on
> the configuration of the OVL_LAYER_SEL register.
> 
> [...]

Applied, thanks!

[1/1] drm/rockchip: vop2: Use OVL_LAYER_SEL configuration instead of use win_mask calculate used layers
      commit: d3fe9aa495854f8d88c69c41a4b31e69424656ad

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From bmasney at redhat.com  Fri Nov 14 16:27:43 2025
From: bmasney at redhat.com (Brian Masney)
Date: Fri, 14 Nov 2025 19:27:43 -0500
Subject: [PATCH RESEND v2 0/9] phy: convert from clk round_rate() to
 determine_rate()
In-Reply-To: <20251106-phy-clk-route-rate-v2-resend-v1-0-e2058963bfb1@redhat.com>
References: <20251106-phy-clk-route-rate-v2-resend-v1-0-e2058963bfb1@redhat.com>
Message-ID: <aRfI_xT680E7Cf-o@redhat.com>

Hi Vinod,

On Thu, Nov 06, 2025 at 06:25:46PM -0500, Brian Masney wrote:
> This is a resend of my previous v2 series since I haven't receieved any
> feedback.
> 
> https://lore.kernel.org/linux-phy/20250810-phy-clk-round-rate-v2-0-9162470bb9f2 at redhat.com/T/
> 
> I'm hoping to get this merged for v6.19 so that I can remove the
> round_rate() clk op from the clk core for v6.20. The clk maintainer
> (Stephen) mentioned this work in his last pull to Linus:
> 
> https://lore.kernel.org/linux-clk/20251007051720.11386-1-sboyd at kernel.org/

Can you please take a look at this series since rc6 is this weekend? I
have almost 200 patches merged in other subsystems across the kernel
for this work since the Summer, and this series to drivers/phy is the
last one remaining that's blocking me from posting what I have to
remove the round_rate member from the clk core.

Thanks,

Brian



From dmitry.baryshkov at oss.qualcomm.com  Fri Nov 14 16:44:56 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Sat, 15 Nov 2025 02:44:56 +0200
Subject: [PATCH v1 1/2] drm/ci: uprev mesa
In-Reply-To: <20251114030056.1139570-2-vignesh.raman@collabora.com>
References: <20251114030056.1139570-1-vignesh.raman@collabora.com>
 <20251114030056.1139570-2-vignesh.raman@collabora.com>
Message-ID: <prjwrsepfc3b6ozhue5cp66khlcvdrpvpy6jkk23edncmi4l3y@oiddmamgg3mx>

On Fri, Nov 14, 2025 at 08:30:50AM +0530, Vignesh Raman wrote:
> Uprev mesa to adapt to the latest changes in Mesa CI, including support
> for firmware via LAVA overlays, removal of the python-artifacts job,
> split container and build rules, use lava-job-submitter container,
> and various misc fixes.
> 
> Co-developed-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>
> Signed-off-by: Vignesh Raman <vignesh.raman at collabora.com>
> ---
>  drivers/gpu/drm/ci/build.yml         |  22 +++---
>  drivers/gpu/drm/ci/container.yml     |  28 ++++++--
>  drivers/gpu/drm/ci/gitlab-ci.yml     |  95 ++++++++++++++++++++-----
>  drivers/gpu/drm/ci/igt_runner.sh     |   4 +-
>  drivers/gpu/drm/ci/image-tags.yml    |  22 +++---
>  drivers/gpu/drm/ci/lava-submit.sh    | 101 +++++++++++++--------------
>  drivers/gpu/drm/ci/static-checks.yml |   1 +
>  drivers/gpu/drm/ci/test.yml          |  18 +++--
>  8 files changed, 186 insertions(+), 105 deletions(-)
> 

Thanks a lot for taking care of it!


Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>



-- 
With best wishes
Dmitry


From dmitry.baryshkov at oss.qualcomm.com  Fri Nov 14 16:50:04 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Sat, 15 Nov 2025 02:50:04 +0200
Subject: [PATCH v1 2/2] drm/ci: Move qualcomm baremetal jobs to lava
In-Reply-To: <20251114030056.1139570-3-vignesh.raman@collabora.com>
References: <20251114030056.1139570-1-vignesh.raman@collabora.com>
 <20251114030056.1139570-3-vignesh.raman@collabora.com>
Message-ID: <ursdbkco5n734zhfqceztib4b6vxb2juq5jfllzcjeuctd6lvn@dbdbkbr4csws>

On Fri, Nov 14, 2025 at 08:30:51AM +0530, Vignesh Raman wrote:
> Qualcomm apq8016 and apq8096 DUTS are moved to Collabora lava
> farm. So enable these jobs to use lava and update expectation
> files.
> 
> Co-developed-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>
> Signed-off-by: Vignesh Raman <vignesh.raman at collabora.com>
> ---
>  drivers/gpu/drm/ci/arm64.config               |  1 +
>  drivers/gpu/drm/ci/test.yml                   | 62 ++++++-------------
>  .../gpu/drm/ci/xfails/msm-apq8016-fails.txt   |  4 ++
>  .../gpu/drm/ci/xfails/msm-apq8096-fails.txt   |  2 +
>  4 files changed, 27 insertions(+), 42 deletions(-)
> 

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>

I'll try picking up these patches through the drm/msm tree, if noone
objects.

-- 
With best wishes
Dmitry


From shawn.lin at rock-chips.com  Fri Nov 14 18:21:28 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Sat, 15 Nov 2025 10:21:28 +0800
Subject: [PATCH] arm64: dts: rockchip: align bindings to PCIe spec
In-Reply-To: <aReSPbRxCgdNRI9y@geday>
References: <aQsIXcQzeYop6a0B@geday>
 <67b605b0-7046-448a-bc9b-d3ac56333809@rock-chips.com>
 <aQ1c7ZDycxiOIy8Y@geday>
 <d9e257bd-806c-48b4-bb22-f1342e9fc15a@rock-chips.com>
 <aRLEbfsmXnGwyigS@geday>
 <AGsAmwCFJj0ZQ4vKzrqC84rs.3.1762847224180.Hmail.ye.zhang@rock-chips.com>
 <aRQ_R90S8T82th45@geday> <aRUvr0UggTYkkCZ_@geday> <aRazCssWVdAOmy7D@geday>
 <e8524bf8-a90c-423f-8a58-9ef05a3db1dd@rock-chips.com>
 <aReSPbRxCgdNRI9y@geday>
Message-ID: <ffd05070-9879-4468-94e3-b88968b4c21b@rock-chips.com>


? 2025/11/15 ??? 4:34, Geraldo Nascimento ??:
> On Fri, Nov 14, 2025 at 05:16:21PM +0800, Shawn Lin wrote:
>> Don't worry, it's helpful, so I think Ye could have a look.
>> May I ask if the failure only happened to one specific board?
> 
> Hi Shawn,
> 
> Yes, testing is restricted to my Radxa Rock Pi N10 board.
> 
>>
>> Another thing I noticed is about one commit:
>> 114b06ee108c ("PCI: rockchip: Set Target Link Speed to 5.0 GT/s before
>> retraining")
>>
>> It said: "Rockchip controllers can support up to 5.0 GT/s link speed."
>> But we issued an errata long time ago to announced it doesn't, you could
>> also check the PCIe part of RK3399 datasheet:
>> https://opensource.rock-chips.com/images/d/d7/Rockchip_RK3399_Datasheet_V2.1-20200323.pdf
> 
> OK, I'm partly responsible for that as author of the commit in question.
> 
> First off let me say I do not intend to send any patches setting
> max-link-speed to TWO for this platform.
> 
> I understand you issued an erratum, but are you absolutely sure about
> that erratum? Because my testing shows otherwise:

Sure.

The reason is that Gen2 is merely functional, but this does not mean it 
is 100% production-ready. It has some inherent issues that cannot be 
resolved, which may lead to failures beyond imagination. Even if the 
probability of occurrence is as low as 1 in 100,000. I cannot share 
further details. Therefore, the official documentation should be your 
primary reference, rather than relying solely on simple evaluations.

> 
> ---
> With max-link-speed = <2>
> pci 0000:01:00.0: 16.000 Gb/s available PCIe bandwidth, limited by 5.0 GT/s PCIe x4 link at 0000:00:00.0 (capable of 31.504 Gb/s with 8.0 GT/s PCIe x4 link)
> 
> /dev/nvme0n1:
>   Timing cached reads:   3002 MB in  2.00 seconds = 1502.21 MB/sec
>   Timing buffered disk reads: 2044 MB in  3.00 seconds = 680.79 MB/sec
> ---
> With max-link-speed = <1>
> pci 0000:01:00.0: 8.000 Gb/s available PCIe bandwidth, limited by 2.5 GT/s PCIe x4 link at 0000:00:00.0 (capable of 31.504 Gb/s with 8.0 GT/s PCIe x4 link)
> 
> /dev/nvme0n1:
>   Timing cached reads:   2730 MB in  2.00 seconds = 1366.15 MB/sec
>   Timing buffered disk reads: 2028 MB in  3.00 seconds = 675.71 MB/sec
> ---
> 
> As you can see, not only the kernel PCI driver recognizes 5.0 GT/s PCIe
> link but there's even a marginal increase in cached reads as measured by
> hdparm, the gains are of course limited by CPU performance.
> 
>> Also we set max-link-speed to ONE in rk3399-base.dtsi but seems another
>> patch slip in: 755fff528b1b ("arm64: dts: rockchip: add variables for
>> pcie completion to helios64")
> 
> I can't speak for patches I haven't authored, but I believe you're
> welcome to send a correction.
> 
> Thank you,
> Geraldo Nascimento
> 



From patchwork-bot+netdevbpf at kernel.org  Fri Nov 14 18:40:12 2025
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Sat, 15 Nov 2025 02:40:12 +0000
Subject: [PATCH net-next 0/4] net: stmmac: rk: use PHY_INTF_SEL_x
In-Reply-To: <aRYZaKTIvfYoV3wE@shell.armlinux.org.uk>
References: <aRYZaKTIvfYoV3wE@shell.armlinux.org.uk>
Message-ID: <176317441200.1916016.12907239609584301623.git-patchwork-notify@kernel.org>

Hello:

This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba at kernel.org>:

On Thu, 13 Nov 2025 17:46:16 +0000 you wrote:
> This series is a minimal conversion of the dwmac-rk huge driver to use
> PHY_INTF_SEL_x constants.
> 
> Patch 2 appears to reorder the output functions making diffing the
> generated code impossible.
> 
>  drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 245 +++++++++++--------------
>  1 file changed, 109 insertions(+), 136 deletions(-)

Here is the summary with links:
  - [net-next,1/4] net: stmmac: rk: replace HIWORD_UPDATE() with GRF_FIELD()
    https://git.kernel.org/netdev/net-next/c/ebb07edf9738
  - [net-next,2/4] net: stmmac: rk: convert all bitfields to GRF_FIELD*()
    https://git.kernel.org/netdev/net-next/c/764ebe423ef9
  - [net-next,3/4] net: stmmac: rk: use PHY_INTF_SEL_x constants
    https://git.kernel.org/netdev/net-next/c/5e37047f745b
  - [net-next,4/4] net: stmmac: rk: use PHY_INTF_SEL_x in functions
    https://git.kernel.org/netdev/net-next/c/1188741cb5a2

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From dmitry.baryshkov at oss.qualcomm.com  Fri Nov 14 19:55:17 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Sat, 15 Nov 2025 05:55:17 +0200
Subject: [PATCH v1 1/2] drm/ci: uprev mesa
In-Reply-To: <prjwrsepfc3b6ozhue5cp66khlcvdrpvpy6jkk23edncmi4l3y@oiddmamgg3mx>
References: <20251114030056.1139570-1-vignesh.raman@collabora.com>
 <20251114030056.1139570-2-vignesh.raman@collabora.com>
 <prjwrsepfc3b6ozhue5cp66khlcvdrpvpy6jkk23edncmi4l3y@oiddmamgg3mx>
Message-ID: <42v64xdsaqug5yy76yel4tukh6wkt2tp237vlnpteabyl5qjo5@iigtgujvecwc>

On Sat, Nov 15, 2025 at 02:44:56AM +0200, Dmitry Baryshkov wrote:
> On Fri, Nov 14, 2025 at 08:30:50AM +0530, Vignesh Raman wrote:
> > Uprev mesa to adapt to the latest changes in Mesa CI, including support
> > for firmware via LAVA overlays, removal of the python-artifacts job,
> > split container and build rules, use lava-job-submitter container,
> > and various misc fixes.
> > 
> > Co-developed-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>
> > Signed-off-by: Vignesh Raman <vignesh.raman at collabora.com>
> > ---
> >  drivers/gpu/drm/ci/build.yml         |  22 +++---
> >  drivers/gpu/drm/ci/container.yml     |  28 ++++++--
> >  drivers/gpu/drm/ci/gitlab-ci.yml     |  95 ++++++++++++++++++++-----
> >  drivers/gpu/drm/ci/igt_runner.sh     |   4 +-
> >  drivers/gpu/drm/ci/image-tags.yml    |  22 +++---
> >  drivers/gpu/drm/ci/lava-submit.sh    | 101 +++++++++++++--------------
> >  drivers/gpu/drm/ci/static-checks.yml |   1 +
> >  drivers/gpu/drm/ci/test.yml          |  18 +++--
> >  8 files changed, 186 insertions(+), 105 deletions(-)
> > 
> 
> Thanks a lot for taking care of it!
> 
> 
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>

Hmm, this causes a lot of failures, see [1] (note, the run is not
finished yet):
- On some platforms (msm, rk3399, mt8173) the
  core_setmaster at master-drop-set-root test fails. On other it seems to
  work correctly
- sm8350 seems to have some issues with this uprev, it cant' finish the
  jobs at all
- mt8173 and rockchip:rk3399 seem to have other test failures too

Could you please update fails / flakes tor all the affected platforms?
Also I'm really interested in the master-drop-set tests. Why do they
fail on some of the platforms, but not on all? This seems to be some
infrastructure-related issue, since exactly the same kernel with the
same IGT passes those tests (at least on msm hardware).

[1] https://gitlab.freedesktop.org/drm/msm/-/pipelines/1547684

-- 
With best wishes
Dmitry


From michael.opdenacker at rootcommit.com  Fri Nov 14 22:03:31 2025
From: michael.opdenacker at rootcommit.com (Michael Opdenacker)
Date: Sat, 15 Nov 2025 06:03:31 +0000 (UTC)
Subject: [PATCH v2 2/2] arm64: dts: rockchip: Add Asus Tinker Board 3 and
 3S device tree
In-Reply-To: <12d6e151-dfa0-ca0a-5888-ddffb2dbdec7@manjaro.org>
References: <12d6e151-dfa0-ca0a-5888-ddffb2dbdec7@manjaro.org>
Message-ID: <bb74679a-ce21-4373-bcc5-1214e9bf832e@rootcommit.com>

Hi Dragan,

Thanks one more time for the reviews, much appreciated :)

On 11/15/25 01:53, Dragan Simic wrote:
> Hello Michael,
>
> Thanks for the v2!  Please, see one nitpick below.
>
> On Friday, November 14, 2025 16:46 CET, michael.opdenacker at rootcommit.com wrote:
>> From: Michael Opdenacker <michael.opdenacker at rootcommit.com>
> I'm sorry for not mentioning it in my earlier responses, but this
> line is redundant, because it duplicates the From value found in
> the actual email message.


This actually comes from my Git settings. I need this when I send 
patches to the Yocto project and OpenEmbedded. That's because their 
mailing list server which alters the address of senders ("<sender> via 
lists.yoctoproject.org"), and ultimately the commit author identity in 
Git. See 
https://docs.yoctoproject.org/contributor-guide/submit-changes.html#fixing-your-from-identity

I've checked that my patches apply fine and that this "From:" line 
doesn't appear in the commits in the tree.
So, can I keep this?

:D
Thanks again
Michael.

-- 
Michael Opdenacker
Root Commit
Embedded Linux Training and Consulting
https://rootcommit.com



From geraldogabriel at gmail.com  Fri Nov 14 23:02:24 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Sat, 15 Nov 2025 04:02:24 -0300
Subject: [PATCH] arm64: dts: rockchip: align bindings to PCIe spec
In-Reply-To: <ffd05070-9879-4468-94e3-b88968b4c21b@rock-chips.com>
References: <aQ1c7ZDycxiOIy8Y@geday>
 <d9e257bd-806c-48b4-bb22-f1342e9fc15a@rock-chips.com>
 <aRLEbfsmXnGwyigS@geday>
 <AGsAmwCFJj0ZQ4vKzrqC84rs.3.1762847224180.Hmail.ye.zhang@rock-chips.com>
 <aRQ_R90S8T82th45@geday>
 <aRUvr0UggTYkkCZ_@geday>
 <aRazCssWVdAOmy7D@geday>
 <e8524bf8-a90c-423f-8a58-9ef05a3db1dd@rock-chips.com>
 <aReSPbRxCgdNRI9y@geday>
 <ffd05070-9879-4468-94e3-b88968b4c21b@rock-chips.com>
Message-ID: <aRglgNL5eumu4XbS@geday>

On Sat, Nov 15, 2025 at 10:21:28AM +0800, Shawn Lin wrote:
> 
> ? 2025/11/15 ??? 4:34, Geraldo Nascimento ??:
> >> Another thing I noticed is about one commit:
> >> 114b06ee108c ("PCI: rockchip: Set Target Link Speed to 5.0 GT/s before
> >> retraining")
> >>
> >> It said: "Rockchip controllers can support up to 5.0 GT/s link speed."
> >> But we issued an errata long time ago to announced it doesn't, you could
> >> also check the PCIe part of RK3399 datasheet:
> >> https://opensource.rock-chips.com/images/d/d7/Rockchip_RK3399_Datasheet_V2.1-20200323.pdf
> > 
> > OK, I'm partly responsible for that as author of the commit in question.
> > 
> > First off let me say I do not intend to send any patches setting
> > max-link-speed to TWO for this platform.
> > 
> > I understand you issued an erratum, but are you absolutely sure about
> > that erratum? Because my testing shows otherwise:
> 
> Sure.
> 
> The reason is that Gen2 is merely functional, but this does not mean it 
> is 100% production-ready. It has some inherent issues that cannot be 
> resolved, which may lead to failures beyond imagination. Even if the 
> probability of occurrence is as low as 1 in 100,000. I cannot share 
> further details. Therefore, the official documentation should be your 
> primary reference, rather than relying solely on simple evaluations.

Hi Shawn,

indeed, the situation is not favorable and we should strive to make
amends. I'm sorry I based the commit on outdated information, I was
none the wiser.

What I propose is to add a comment to driver core saying that path
to 5.0 GT/s shouldn't be taken and users are strongly discouraged to
mess with the maximum link speed in DT.

We deal with corner case of helios64 in another patch and make sure
there are no DTs engaging 5.0 GT/s.

This should close the loop-hole.

Regards,
Geraldo Nascimento


From dsimic at manjaro.org  Fri Nov 14 23:14:58 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Sat, 15 Nov 2025 08:14:58 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v2 2/2] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= Add Asus Tinker Board 3 and 3S device tree
In-Reply-To: <bb74679a-ce21-4373-bcc5-1214e9bf832e@rootcommit.com>
References: <12d6e151-dfa0-ca0a-5888-ddffb2dbdec7@manjaro.org> <bb74679a-ce21-4373-bcc5-1214e9bf832e@rootcommit.com>
Message-ID: <24561990-8293-0505-5837-eca416d01bb7@manjaro.org>

Hello Michael,

On Saturday, November 15, 2025 07:03 CET, Michael Opdenacker <michael.opdenacker at rootcommit.com> wrote:
> On 11/15/25 01:53, Dragan Simic wrote:
> > Thanks for the v2!  Please, see one nitpick below.
> >
> > On Friday, November 14, 2025 16:46 CET, michael.opdenacker at rootcommit.com wrote:
> >> From: Michael Opdenacker <michael.opdenacker at rootcommit.com>
> > I'm sorry for not mentioning it in my earlier responses, but this
> > line is redundant, because it duplicates the From value found in
> > the actual email message.
> 
> This actually comes from my Git settings. I need this when I send 
> patches to the Yocto project and OpenEmbedded. That's because their 
> mailing list server which alters the address of senders ("<sender> via 
> lists.yoctoproject.org"), and ultimately the commit author identity in 
> Git. See 
> https://docs.yoctoproject.org/contributor-guide/submit-changes.html#fixing-your-from-identity
> 
> I've checked that my patches apply fine and that this "From:" line 
> doesn't appear in the commits in the tree.
> So, can I keep this?

Actually, I forgot to mention that the From headers in your patch
submissions are a bit wrong by containing just the email address,
without the first and last name.  That issue should be fixed first,
regardless of the presence (or absence) of From tags.

Thanks for clarifying what's the reason for having the From tags
regardless of the actual need for having them.  Maybe setting Git's
"format.from" option to true at the repository level could solve
this nicely, while also exercising the Git-fu a bit? :)

BTW, my responses are currently jailed by the linux-rockchip mailing
list, requiring manual approval, as a result of the mail server I'm
using sometimes inserting some strange invisible UTF-8 characters
into the email subjects.  Oh well. :)



From geraldogabriel at gmail.com  Sat Nov 15 01:10:01 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Sat, 15 Nov 2025 06:10:01 -0300
Subject: [PATCH 0/3] PCI: rockchip: 5.0 GT/s speed may be dangerous
Message-ID: <cover.1763197368.git.geraldogabriel@gmail.com>

In recent interactions with Shawn Lin from Rockchip it came to my
attention there's an unknown errata regarding 5.0 GT/s operational
speed of their PCIe core. According to Shawn there's grave danger
even if the odds are low. To contain any damage, let's cover the
remaining corner-cases where the default would lead to 5.0 GT/s
operation as well as add a comment to Root Complex driver core,
documenting this danger.

Geraldo Nascimento (3):
  PCI: rockchip: warn of danger of 5.0 GT/s speeds
  PCI: rockchip-host: comment danger of 5.0 GT/s speed
  arm64: dts: rockchip: drop max-link-speed = <2> in helios64 PCIe

 arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts | 1 -
 drivers/pci/controller/pcie-rockchip-host.c            | 5 +++++
 drivers/pci/controller/pcie-rockchip.c                 | 8 ++++++--
 3 files changed, 11 insertions(+), 3 deletions(-)

-- 
2.49.0



From geraldogabriel at gmail.com  Sat Nov 15 01:10:17 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Sat, 15 Nov 2025 06:10:17 -0300
Subject: [PATCH 1/3] PCI: rockchip: warn of danger of 5.0 GT/s speeds
In-Reply-To: <cover.1763197368.git.geraldogabriel@gmail.com>
References: <cover.1763197368.git.geraldogabriel@gmail.com>
Message-ID: <d6593ae4f59468f294fdddfef83791e0db100e13.1763197368.git.geraldogabriel@gmail.com>

Shawn Lin from Rockchip has reiterated that there may be danger in using
their PCIe with 5.0 GT/s speeds. Warn the user if they make a DT change
from the default and at the same time, drive at 2.5 GT/s only, in case
the DT max-link-speed property is invalid or inexistent.

Fixes: 956cd99b35a8 ("PCI: rockchip: Separate common code from RC driver")
Link: https://lore.kernel.org/all/ffd05070-9879-4468-94e3-b88968b4c21b at rock-chips.com/
Reported-by: Shawn Lin <shawn.lin at rock-chips.com>
Signed-off-by: Geraldo Nascimento <geraldogabriel at gmail.com>
---
 drivers/pci/controller/pcie-rockchip.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/pcie-rockchip.c b/drivers/pci/controller/pcie-rockchip.c
index 0f88da378805..ed67886a6d43 100644
--- a/drivers/pci/controller/pcie-rockchip.c
+++ b/drivers/pci/controller/pcie-rockchip.c
@@ -66,8 +66,12 @@ int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip)
 	}
 
 	rockchip->link_gen = of_pci_get_max_link_speed(node);
-	if (rockchip->link_gen < 0 || rockchip->link_gen > 2)
-		rockchip->link_gen = 2;
+	if (rockchip->link_gen < 0 || rockchip->link_gen > 2) {
+		rockchip->link_gen = 1;
+		dev_warn(dev, "invalid max-link-speed, set to 2.5 GT/s\n");
+	}
+	else if (rockchip->link_gen == 2)
+		dev_warn(dev, "5.0 GT/s may lead to catastrophic failure\n");
 
 	for (i = 0; i < ROCKCHIP_NUM_PM_RSTS; i++)
 		rockchip->pm_rsts[i].id = rockchip_pci_pm_rsts[i];
-- 
2.49.0



From geraldogabriel at gmail.com  Sat Nov 15 01:10:36 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Sat, 15 Nov 2025 06:10:36 -0300
Subject: [PATCH 2/3] PCI: rockchip-host: comment danger of 5.0 GT/s speed
In-Reply-To: <cover.1763197368.git.geraldogabriel@gmail.com>
References: <cover.1763197368.git.geraldogabriel@gmail.com>
Message-ID: <b04ed0deb42c914847dd28233010f9573d6b5902.1763197368.git.geraldogabriel@gmail.com>

According to Rockchip sources, there is grave danger in enabling 5.0
GT/s speed for this core. Add a comment documenting that danger and
discouraging end-users from forcing higher speed through DT changes.

Link: https://lore.kernel.org/all/ffd05070-9879-4468-94e3-b88968b4c21b at rock-chips.com/
Reported-by: Shawn Lin <shawn.lin at rock-chips.com>
Signed-off-by: Geraldo Nascimento <geraldogabriel at gmail.com>
---
 drivers/pci/controller/pcie-rockchip-host.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c
index ee1822ca01db..7e6ff76466b7 100644
--- a/drivers/pci/controller/pcie-rockchip-host.c
+++ b/drivers/pci/controller/pcie-rockchip-host.c
@@ -332,6 +332,11 @@ static int rockchip_pcie_host_init_port(struct rockchip_pcie *rockchip)
 		/*
 		 * Enable retrain for gen2. This should be configured only after
 		 * gen1 finished.
+		 *
+		 * According to Rockchip this path is dangerous and may lead to
+		 * catastrophic failure. Even if the odds are small, users are
+		 * still discouraged to engage the corresponding DT option.
+		 *
 		 */
 		status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_CR + PCI_EXP_LNKCTL2);
 		status &= ~PCI_EXP_LNKCTL2_TLS;
-- 
2.49.0



From geraldogabriel at gmail.com  Sat Nov 15 01:10:58 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Sat, 15 Nov 2025 06:10:58 -0300
Subject: [PATCH 3/3] arm64: dts: rockchip: drop max-link-speed = <2> in
 helios64 PCIe
In-Reply-To: <cover.1763197368.git.geraldogabriel@gmail.com>
References: <cover.1763197368.git.geraldogabriel@gmail.com>
Message-ID: <53332edec449b84d8a962f2b5995667766359772.1763197368.git.geraldogabriel@gmail.com>

Shawn Lin from Rockchip strongly discourages attempts to use their
RK3399 PCIe core at 5.0 GT/s speed, citing concerns about catastrophic
failures that may happen. Even if the odds are low, drop from last user
of this property for the RK3399 platform, helios64.

Fixes: 755fff528b1b ("arm64: dts: rockchip: add variables for pcie completion to helios64")
Link: https://lore.kernel.org/all/ffd05070-9879-4468-94e3-b88968b4c21b at rock-chips.com/
Reported-by: Shawn Lin <shawn.lin at rock-chips.com>
Signed-off-by: Geraldo Nascimento <geraldogabriel at gmail.com>
---
 arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
index e7d4a2f9a95e..78a7775c3b22 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
@@ -424,7 +424,6 @@ &pcie_phy {
 
 &pcie0 {
 	ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>;
-	max-link-speed = <2>;
 	num-lanes = <2>;
 	pinctrl-names = "default";
 	status = "okay";
-- 
2.49.0



From dsimic at manjaro.org  Sat Nov 15 01:24:49 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Sat, 15 Nov 2025 10:24:49 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH 1/3] =?utf-8?q?PCI=3A?==?utf-8?q?_rockchip=3A?= 
 warn of danger of =?utf-8?q?5=2E0?= GT/s speeds
In-Reply-To: <d6593ae4f59468f294fdddfef83791e0db100e13.1763197368.git.geraldogabriel@gmail.com>
References: <cover.1763197368.git.geraldogabriel@gmail.com> <d6593ae4f59468f294fdddfef83791e0db100e13.1763197368.git.geraldogabriel@gmail.com>
Message-ID: <a214ac9a-36d9-6505-64a8-92af2da42cf1@manjaro.org>

Hello Geraldo,

On Saturday, November 15, 2025 10:10 CET, Geraldo Nascimento <geraldogabriel at gmail.com> wrote:
> Shawn Lin from Rockchip has reiterated that there may be danger in using
> their PCIe with 5.0 GT/s speeds. Warn the user if they make a DT change
> from the default and at the same time, drive at 2.5 GT/s only, in case
> the DT max-link-speed property is invalid or inexistent.
> 
> Fixes: 956cd99b35a8 ("PCI: rockchip: Separate common code from RC driver")
> Link: https://lore.kernel.org/all/ffd05070-9879-4468-94e3-b88968b4c21b at rock-chips.com/
> Reported-by: Shawn Lin <shawn.lin at rock-chips.com>
> Signed-off-by: Geraldo Nascimento <geraldogabriel at gmail.com>
> ---
>  drivers/pci/controller/pcie-rockchip.c | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/pci/controller/pcie-rockchip.c b/drivers/pci/controller/pcie-rockchip.c
> index 0f88da378805..ed67886a6d43 100644
> --- a/drivers/pci/controller/pcie-rockchip.c
> +++ b/drivers/pci/controller/pcie-rockchip.c
> @@ -66,8 +66,12 @@ int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip)
>  	}
>  
>  	rockchip->link_gen = of_pci_get_max_link_speed(node);
> -	if (rockchip->link_gen < 0 || rockchip->link_gen > 2)
> -		rockchip->link_gen = 2;
> +	if (rockchip->link_gen < 0 || rockchip->link_gen > 2) {
> +		rockchip->link_gen = 1;
> +		dev_warn(dev, "invalid max-link-speed, set to 2.5 GT/s\n");
> +	}
> +	else if (rockchip->link_gen == 2)
> +		dev_warn(dev, "5.0 GT/s may lead to catastrophic failure\n");
>  
>  	for (i = 0; i < ROCKCHIP_NUM_PM_RSTS; i++)
>  		rockchip->pm_rsts[i].id = rockchip_pci_pm_rsts[i];

Looking good to me, thanks for this patch!  People often declare
PCIe Gen2 on RK3399-based boards as "works for me", which actually
happens very often, but such simple evaluations cannot be taken
as a proof of Gen2 correctness.

Furthermore, RK3399's internal interconnects limit the effective
I/O speed of PCIe transfers already, so switching to PCIe Gen1
actually doesn't result in some large I/O performance penalties.

With all that in mind, please feel free to include

Reviewed-by: Dragan Simic <dsimic at manjaro.org>



From dsimic at manjaro.org  Sat Nov 15 01:30:49 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Sat, 15 Nov 2025 10:30:49 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH 2/3] =?utf-8?q?PCI=3A?=
 =?utf-8?q?_rockchip-host=3A?= comment danger of =?utf-8?q?5=2E0?= GT/s 
 speed
In-Reply-To: <b04ed0deb42c914847dd28233010f9573d6b5902.1763197368.git.geraldogabriel@gmail.com>
References: <cover.1763197368.git.geraldogabriel@gmail.com> <b04ed0deb42c914847dd28233010f9573d6b5902.1763197368.git.geraldogabriel@gmail.com>
Message-ID: <c8a6d165-2cdd-cd0d-4bed-95dfa5ff30d2@manjaro.org>

Hello Geraldo,

On Saturday, November 15, 2025 10:10 CET, Geraldo Nascimento <geraldogabriel at gmail.com> wrote:
> According to Rockchip sources, there is grave danger in enabling 5.0
> GT/s speed for this core. Add a comment documenting that danger and
> discouraging end-users from forcing higher speed through DT changes.
> 
> Link: https://lore.kernel.org/all/ffd05070-9879-4468-94e3-b88968b4c21b at rock-chips.com/
> Reported-by: Shawn Lin <shawn.lin at rock-chips.com>
> Signed-off-by: Geraldo Nascimento <geraldogabriel at gmail.com>
> ---
>  drivers/pci/controller/pcie-rockchip-host.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c
> index ee1822ca01db..7e6ff76466b7 100644
> --- a/drivers/pci/controller/pcie-rockchip-host.c
> +++ b/drivers/pci/controller/pcie-rockchip-host.c
> @@ -332,6 +332,11 @@ static int rockchip_pcie_host_init_port(struct rockchip_pcie *rockchip)
>  		/*
>  		 * Enable retrain for gen2. This should be configured only after
>  		 * gen1 finished.
> +		 *
> +		 * According to Rockchip this path is dangerous and may lead to
> +		 * catastrophic failure. Even if the odds are small, users are
> +		 * still discouraged to engage the corresponding DT option.
> +		 *
>  		 */
>  		status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_CR + PCI_EXP_LNKCTL2);
>  		status &= ~PCI_EXP_LNKCTL2_TLS;

Looking good to me, thanks for this patch!  There's no need
to emit warnings here, because they'd be emitted already in
the rockchip_pcie_parse_dt() function.

Please feel free to include

Reviewed-by: Dragan Simic <dsimic at manjaro.org>



From dsimic at manjaro.org  Sat Nov 15 01:36:17 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Sat, 15 Nov 2025 10:36:17 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH 3/3] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= drop max-link-speed =?utf-8?q?=3D?= <2> in 
 helios64 PCIe
In-Reply-To: <53332edec449b84d8a962f2b5995667766359772.1763197368.git.geraldogabriel@gmail.com>
References: <cover.1763197368.git.geraldogabriel@gmail.com> <53332edec449b84d8a962f2b5995667766359772.1763197368.git.geraldogabriel@gmail.com>
Message-ID: <3f13841d-030b-0202-61be-412c0ab9df6b@manjaro.org>

Hello Geraldo,

On Saturday, November 15, 2025 10:10 CET, Geraldo Nascimento <geraldogabriel at gmail.com> wrote:
> Shawn Lin from Rockchip strongly discourages attempts to use their
> RK3399 PCIe core at 5.0 GT/s speed, citing concerns about catastrophic
> failures that may happen. Even if the odds are low, drop from last user
> of this property for the RK3399 platform, helios64.
> 
> Fixes: 755fff528b1b ("arm64: dts: rockchip: add variables for pcie completion to helios64")
> Link: https://lore.kernel.org/all/ffd05070-9879-4468-94e3-b88968b4c21b at rock-chips.com/
> Reported-by: Shawn Lin <shawn.lin at rock-chips.com>
> Signed-off-by: Geraldo Nascimento <geraldogabriel at gmail.com>
> ---
>  arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
> index e7d4a2f9a95e..78a7775c3b22 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
> @@ -424,7 +424,6 @@ &pcie_phy {
>  
>  &pcie0 {
>  	ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>;
> -	max-link-speed = <2>;
>  	num-lanes = <2>;
>  	pinctrl-names = "default";
>  	status = "okay";

Looking good to me, this rounds up the prevention of issues
coming from buggy PCIe Gen2 on RK3399.

Please feel free to include

Reviewed-by: Dragan Simic <dsimic at manjaro.org>

Though, could you, please, add patch 4/3 to this series, which
would remove the redundant parameter "max-link-speed = <1>" from
rk3399-nanopi-r4s.dtsi?



From dsimic at manjaro.org  Sat Nov 15 01:42:40 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Sat, 15 Nov 2025 10:42:40 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH 3/3] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= drop max-link-speed =?utf-8?q?=3D?= <2> in 
 helios64 PCIe
In-Reply-To: <3f13841d-030b-0202-61be-412c0ab9df6b@manjaro.org>
References: <cover.1763197368.git.geraldogabriel@gmail.com> <53332edec449b84d8a962f2b5995667766359772.1763197368.git.geraldogabriel@gmail.com> <3f13841d-030b-0202-61be-412c0ab9df6b@manjaro.org>
Message-ID: <7d300769-9803-9c0c-60bb-4a724619d8e0@manjaro.org>

On Saturday, November 15, 2025 10:36 CET, "Dragan Simic" <dsimic at manjaro.org> wrote:
> On Saturday, November 15, 2025 10:10 CET, Geraldo Nascimento <geraldogabriel at gmail.com> wrote:
> > Shawn Lin from Rockchip strongly discourages attempts to use their
> > RK3399 PCIe core at 5.0 GT/s speed, citing concerns about catastrophic
> > failures that may happen. Even if the odds are low, drop from last user
> > of this property for the RK3399 platform, helios64.
> > 
> > Fixes: 755fff528b1b ("arm64: dts: rockchip: add variables for pcie completion to helios64")
> > Link: https://lore.kernel.org/all/ffd05070-9879-4468-94e3-b88968b4c21b at rock-chips.com/
> > Reported-by: Shawn Lin <shawn.lin at rock-chips.com>
> > Signed-off-by: Geraldo Nascimento <geraldogabriel at gmail.com>
> > ---
> >  arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts | 1 -
> >  1 file changed, 1 deletion(-)
> > 
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
> > index e7d4a2f9a95e..78a7775c3b22 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
> > +++ b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
> > @@ -424,7 +424,6 @@ &pcie_phy {
> >  
> >  &pcie0 {
> >  	ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>;
> > -	max-link-speed = <2>;
> >  	num-lanes = <2>;
> >  	pinctrl-names = "default";
> >  	status = "okay";
> 
> Looking good to me, this rounds up the prevention of issues
> coming from buggy PCIe Gen2 on RK3399.
> 
> Please feel free to include
> 
> Reviewed-by: Dragan Simic <dsimic at manjaro.org>
> 
> Though, could you, please, add patch 4/3 to this series, which
> would remove the redundant parameter "max-link-speed = <1>" from
> rk3399-nanopi-r4s.dtsi?

Sorry, I forgot to note that the patch summary would read a bit
better if it were reworded like this:

  arm64: dts: rockchip: Remove redundant max-link-speed from helios64 board dts



From geraldogabriel at gmail.com  Sat Nov 15 01:49:33 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Sat, 15 Nov 2025 06:49:33 -0300
Subject: [PATCH 1/3] PCI: rockchip: warn of danger of 5.0 GT/s speeds
In-Reply-To: <a214ac9a-36d9-6505-64a8-92af2da42cf1@manjaro.org>
References: <cover.1763197368.git.geraldogabriel@gmail.com>
 <d6593ae4f59468f294fdddfef83791e0db100e13.1763197368.git.geraldogabriel@gmail.com>
 <a214ac9a-36d9-6505-64a8-92af2da42cf1@manjaro.org>
Message-ID: <aRhMrXz_RlL0WErZ@geday>

On Sat, Nov 15, 2025 at 10:24:49AM +0100, Dragan Simic wrote:
> Hello Geraldo,
> 
> On Saturday, November 15, 2025 10:10 CET, Geraldo Nascimento <geraldogabriel at gmail.com> wrote:
> > Shawn Lin from Rockchip has reiterated that there may be danger in using
> > their PCIe with 5.0 GT/s speeds. Warn the user if they make a DT change
> > from the default and at the same time, drive at 2.5 GT/s only, in case
> > the DT max-link-speed property is invalid or inexistent.
> > 
> > Fixes: 956cd99b35a8 ("PCI: rockchip: Separate common code from RC driver")
> > Link: https://lore.kernel.org/all/ffd05070-9879-4468-94e3-b88968b4c21b at rock-chips.com/
> > Reported-by: Shawn Lin <shawn.lin at rock-chips.com>
> > Signed-off-by: Geraldo Nascimento <geraldogabriel at gmail.com>
> > ---
> >  drivers/pci/controller/pcie-rockchip.c | 8 ++++++--
> >  1 file changed, 6 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/pci/controller/pcie-rockchip.c b/drivers/pci/controller/pcie-rockchip.c
> > index 0f88da378805..ed67886a6d43 100644
> > --- a/drivers/pci/controller/pcie-rockchip.c
> > +++ b/drivers/pci/controller/pcie-rockchip.c
> > @@ -66,8 +66,12 @@ int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip)
> >  	}
> >  
> >  	rockchip->link_gen = of_pci_get_max_link_speed(node);
> > -	if (rockchip->link_gen < 0 || rockchip->link_gen > 2)
> > -		rockchip->link_gen = 2;
> > +	if (rockchip->link_gen < 0 || rockchip->link_gen > 2) {
> > +		rockchip->link_gen = 1;
> > +		dev_warn(dev, "invalid max-link-speed, set to 2.5 GT/s\n");
> > +	}
> > +	else if (rockchip->link_gen == 2)
> > +		dev_warn(dev, "5.0 GT/s may lead to catastrophic failure\n");
> >  
> >  	for (i = 0; i < ROCKCHIP_NUM_PM_RSTS; i++)
> >  		rockchip->pm_rsts[i].id = rockchip_pci_pm_rsts[i];
> 
> Looking good to me, thanks for this patch!  People often declare
> PCIe Gen2 on RK3399-based boards as "works for me", which actually
> happens very often, but such simple evaluations cannot be taken
> as a proof of Gen2 correctness.
> 
> Furthermore, RK3399's internal interconnects limit the effective
> I/O speed of PCIe transfers already, so switching to PCIe Gen1
> actually doesn't result in some large I/O performance penalties.
> 
> With all that in mind, please feel free to include
> 
> Reviewed-by: Dragan Simic <dsimic at manjaro.org>

Hi Dragan,

I think I'll include a Reported-By: you too, since you were the first to
warn me of unknown errata regarding Rockchip PCIe.

I told you it was a test of mine but I didn't realize the grave danger
implied by Shawn Lin declarations.

Once I realized this could end badly the only way I could retribute was
to send a few corrections :)

Thank you,
Geraldo Nascimento


From geraldogabriel at gmail.com  Sat Nov 15 01:51:29 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Sat, 15 Nov 2025 06:51:29 -0300
Subject: [PATCH 2/3] PCI: rockchip-host: comment danger of 5.0 GT/s speed
In-Reply-To: <c8a6d165-2cdd-cd0d-4bed-95dfa5ff30d2@manjaro.org>
References: <cover.1763197368.git.geraldogabriel@gmail.com>
 <b04ed0deb42c914847dd28233010f9573d6b5902.1763197368.git.geraldogabriel@gmail.com>
 <c8a6d165-2cdd-cd0d-4bed-95dfa5ff30d2@manjaro.org>
Message-ID: <aRhNIcGcQKp2ylqN@geday>

On Sat, Nov 15, 2025 at 10:30:49AM +0100, Dragan Simic wrote:
> Hello Geraldo,
> 
> On Saturday, November 15, 2025 10:10 CET, Geraldo Nascimento <geraldogabriel at gmail.com> wrote:
> > According to Rockchip sources, there is grave danger in enabling 5.0
> > GT/s speed for this core. Add a comment documenting that danger and
> > discouraging end-users from forcing higher speed through DT changes.
> > 
> > Link: https://lore.kernel.org/all/ffd05070-9879-4468-94e3-b88968b4c21b at rock-chips.com/
> > Reported-by: Shawn Lin <shawn.lin at rock-chips.com>
> > Signed-off-by: Geraldo Nascimento <geraldogabriel at gmail.com>
> > ---
> >  drivers/pci/controller/pcie-rockchip-host.c | 5 +++++
> >  1 file changed, 5 insertions(+)
> > 
> > diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c
> > index ee1822ca01db..7e6ff76466b7 100644
> > --- a/drivers/pci/controller/pcie-rockchip-host.c
> > +++ b/drivers/pci/controller/pcie-rockchip-host.c
> > @@ -332,6 +332,11 @@ static int rockchip_pcie_host_init_port(struct rockchip_pcie *rockchip)
> >  		/*
> >  		 * Enable retrain for gen2. This should be configured only after
> >  		 * gen1 finished.
> > +		 *
> > +		 * According to Rockchip this path is dangerous and may lead to
> > +		 * catastrophic failure. Even if the odds are small, users are
> > +		 * still discouraged to engage the corresponding DT option.
> > +		 *
> >  		 */
> >  		status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_CR + PCI_EXP_LNKCTL2);
> >  		status &= ~PCI_EXP_LNKCTL2_TLS;
> 
> Looking good to me, thanks for this patch!  There's no need
> to emit warnings here, because they'd be emitted already in
> the rockchip_pcie_parse_dt() function.
> 
> Please feel free to include
> 
> Reviewed-by: Dragan Simic <dsimic at manjaro.org>
>

I disagree, I think the comment stands.

Even if we reduce to one line, ex:

+ May cause damage

Regards,
Geraldo Nascimento


From geraldogabriel at gmail.com  Sat Nov 15 01:53:08 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Sat, 15 Nov 2025 06:53:08 -0300
Subject: [PATCH 3/3] arm64: dts: rockchip: drop max-link-speed = <2> in
 helios64 PCIe
In-Reply-To: <3f13841d-030b-0202-61be-412c0ab9df6b@manjaro.org>
References: <cover.1763197368.git.geraldogabriel@gmail.com>
 <53332edec449b84d8a962f2b5995667766359772.1763197368.git.geraldogabriel@gmail.com>
 <3f13841d-030b-0202-61be-412c0ab9df6b@manjaro.org>
Message-ID: <aRhNhKjneo1Ny0O6@geday>

On Sat, Nov 15, 2025 at 10:36:17AM +0100, Dragan Simic wrote:
> Hello Geraldo,
> 
> On Saturday, November 15, 2025 10:10 CET, Geraldo Nascimento <geraldogabriel at gmail.com> wrote:
> > Shawn Lin from Rockchip strongly discourages attempts to use their
> > RK3399 PCIe core at 5.0 GT/s speed, citing concerns about catastrophic
> > failures that may happen. Even if the odds are low, drop from last user
> > of this property for the RK3399 platform, helios64.
> > 
> > Fixes: 755fff528b1b ("arm64: dts: rockchip: add variables for pcie completion to helios64")
> > Link: https://lore.kernel.org/all/ffd05070-9879-4468-94e3-b88968b4c21b at rock-chips.com/
> > Reported-by: Shawn Lin <shawn.lin at rock-chips.com>
> > Signed-off-by: Geraldo Nascimento <geraldogabriel at gmail.com>
> > ---
> >  arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts | 1 -
> >  1 file changed, 1 deletion(-)
> > 
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
> > index e7d4a2f9a95e..78a7775c3b22 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
> > +++ b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
> > @@ -424,7 +424,6 @@ &pcie_phy {
> >  
> >  &pcie0 {
> >  	ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>;
> > -	max-link-speed = <2>;
> >  	num-lanes = <2>;
> >  	pinctrl-names = "default";
> >  	status = "okay";
> 
> Looking good to me, this rounds up the prevention of issues
> coming from buggy PCIe Gen2 on RK3399.
> 
> Please feel free to include
> 
> Reviewed-by: Dragan Simic <dsimic at manjaro.org>
> 
> Though, could you, please, add patch 4/3 to this series, which
> would remove the redundant parameter "max-link-speed = <1>" from
> rk3399-nanopi-r4s.dtsi?
>

Thanks for catch, will certainly be included in v2 after I get a few
more reviews.

Geraldo Nascimento


From geraldogabriel at gmail.com  Sat Nov 15 01:55:55 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Sat, 15 Nov 2025 06:55:55 -0300
Subject: [PATCH 3/3] arm64: dts: rockchip: drop max-link-speed = <2> in
 helios64 PCIe
In-Reply-To: <7d300769-9803-9c0c-60bb-4a724619d8e0@manjaro.org>
References: <cover.1763197368.git.geraldogabriel@gmail.com>
 <53332edec449b84d8a962f2b5995667766359772.1763197368.git.geraldogabriel@gmail.com>
 <3f13841d-030b-0202-61be-412c0ab9df6b@manjaro.org>
 <7d300769-9803-9c0c-60bb-4a724619d8e0@manjaro.org>
Message-ID: <aRhOK_aDoJYfgbRJ@geday>

On Sat, Nov 15, 2025 at 10:42:40AM +0100, Dragan Simic wrote:
> On Saturday, November 15, 2025 10:36 CET, "Dragan Simic" <dsimic at manjaro.org> wrote:
> > On Saturday, November 15, 2025 10:10 CET, Geraldo Nascimento <geraldogabriel at gmail.com> wrote:
> > > Shawn Lin from Rockchip strongly discourages attempts to use their
> > > RK3399 PCIe core at 5.0 GT/s speed, citing concerns about catastrophic
> > > failures that may happen. Even if the odds are low, drop from last user
> > > of this property for the RK3399 platform, helios64.
> > > 
> > > Fixes: 755fff528b1b ("arm64: dts: rockchip: add variables for pcie completion to helios64")
> > > Link: https://lore.kernel.org/all/ffd05070-9879-4468-94e3-b88968b4c21b at rock-chips.com/
> > > Reported-by: Shawn Lin <shawn.lin at rock-chips.com>
> > > Signed-off-by: Geraldo Nascimento <geraldogabriel at gmail.com>
> > > ---
> > >  arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts | 1 -
> > >  1 file changed, 1 deletion(-)
> > > 
> > > diff --git a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
> > > index e7d4a2f9a95e..78a7775c3b22 100644
> > > --- a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
> > > +++ b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
> > > @@ -424,7 +424,6 @@ &pcie_phy {
> > >  
> > >  &pcie0 {
> > >  	ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>;
> > > -	max-link-speed = <2>;
> > >  	num-lanes = <2>;
> > >  	pinctrl-names = "default";
> > >  	status = "okay";
> > 
> > Looking good to me, this rounds up the prevention of issues
> > coming from buggy PCIe Gen2 on RK3399.
> > 
> > Please feel free to include
> > 
> > Reviewed-by: Dragan Simic <dsimic at manjaro.org>
> > 
> > Though, could you, please, add patch 4/3 to this series, which
> > would remove the redundant parameter "max-link-speed = <1>" from
> > rk3399-nanopi-r4s.dtsi?
> 
> Sorry, I forgot to note that the patch summary would read a bit
> better if it were reworded like this:
> 
>   arm64: dts: rockchip: Remove redundant max-link-speed from helios64 board dts
>

No, I think:

arm64: dts: rockchip: Remove dangerous max-link-speed from helios64 board dts

Is more accurately described. With focus on the dangerous, we're not
liable.

Redudant max-link-speed only for nanopi-r4s include definitions I think!

Thanks,
Geraldo Nascimento


From dsimic at manjaro.org  Sat Nov 15 02:01:21 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Sat, 15 Nov 2025 11:01:21 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH 2/3] =?utf-8?q?PCI=3A?=
 =?utf-8?q?_rockchip-host=3A?= comment danger of =?utf-8?q?5=2E0?= GT/s 
 speed
In-Reply-To: <aRhNIcGcQKp2ylqN@geday>
References: <cover.1763197368.git.geraldogabriel@gmail.com>
 <b04ed0deb42c914847dd28233010f9573d6b5902.1763197368.git.geraldogabriel@gmail.com>
 <c8a6d165-2cdd-cd0d-4bed-95dfa5ff30d2@manjaro.org> <aRhNIcGcQKp2ylqN@geday>
Message-ID: <85d1543b-ea91-5f0f-59d6-e00fcf720938@manjaro.org>

On Saturday, November 15, 2025 10:51 CET, Geraldo Nascimento <geraldogabriel at gmail.com> wrote:
> On Sat, Nov 15, 2025 at 10:30:49AM +0100, Dragan Simic wrote:
> > On Saturday, November 15, 2025 10:10 CET, Geraldo Nascimento <geraldogabriel at gmail.com> wrote:
> > > According to Rockchip sources, there is grave danger in enabling 5.0
> > > GT/s speed for this core. Add a comment documenting that danger and
> > > discouraging end-users from forcing higher speed through DT changes.
> > > 
> > > Link: https://lore.kernel.org/all/ffd05070-9879-4468-94e3-b88968b4c21b at rock-chips.com/
> > > Reported-by: Shawn Lin <shawn.lin at rock-chips.com>
> > > Signed-off-by: Geraldo Nascimento <geraldogabriel at gmail.com>
> > > ---
> > >  drivers/pci/controller/pcie-rockchip-host.c | 5 +++++
> > >  1 file changed, 5 insertions(+)
> > > 
> > > diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c
> > > index ee1822ca01db..7e6ff76466b7 100644
> > > --- a/drivers/pci/controller/pcie-rockchip-host.c
> > > +++ b/drivers/pci/controller/pcie-rockchip-host.c
> > > @@ -332,6 +332,11 @@ static int rockchip_pcie_host_init_port(struct rockchip_pcie *rockchip)
> > >  		/*
> > >  		 * Enable retrain for gen2. This should be configured only after
> > >  		 * gen1 finished.
> > > +		 *
> > > +		 * According to Rockchip this path is dangerous and may lead to
> > > +		 * catastrophic failure. Even if the odds are small, users are
> > > +		 * still discouraged to engage the corresponding DT option.
> > > +		 *
> > >  		 */
> > >  		status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_CR + PCI_EXP_LNKCTL2);
> > >  		status &= ~PCI_EXP_LNKCTL2_TLS;
> > 
> > Looking good to me, thanks for this patch!  There's no need
> > to emit warnings here, because they'd be emitted already in
> > the rockchip_pcie_parse_dt() function.
> > 
> > Please feel free to include
> > 
> > Reviewed-by: Dragan Simic <dsimic at manjaro.org>
> >
> 
> I disagree, I think the comment stands.
> 
> Even if we reduce to one line, ex:
> 
> + May cause damage

Ah, perhaps I wasn't clear enough, so let me clarify a bit.  The
comment you added is fine, I just referred to no need for emitting
a warning at that point, because it would be emitted already.



From dsimic at manjaro.org  Sat Nov 15 02:03:19 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Sat, 15 Nov 2025 11:03:19 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH 3/3] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= drop max-link-speed =?utf-8?q?=3D?= <2> in 
 helios64 PCIe
In-Reply-To: <aRhOK_aDoJYfgbRJ@geday>
References: <cover.1763197368.git.geraldogabriel@gmail.com>
 <53332edec449b84d8a962f2b5995667766359772.1763197368.git.geraldogabriel@gmail.com>
 <3f13841d-030b-0202-61be-412c0ab9df6b@manjaro.org>
 <7d300769-9803-9c0c-60bb-4a724619d8e0@manjaro.org> <aRhOK_aDoJYfgbRJ@geday>
Message-ID: <a99f926c-e65f-8d0d-67bf-0dd4f9211970@manjaro.org>

On Saturday, November 15, 2025 10:55 CET, Geraldo Nascimento <geraldogabriel at gmail.com> wrote:
> On Sat, Nov 15, 2025 at 10:42:40AM +0100, Dragan Simic wrote:
> > On Saturday, November 15, 2025 10:36 CET, "Dragan Simic" <dsimic at manjaro.org> wrote:
> > > On Saturday, November 15, 2025 10:10 CET, Geraldo Nascimento <geraldogabriel at gmail.com> wrote:
> > > > Shawn Lin from Rockchip strongly discourages attempts to use their
> > > > RK3399 PCIe core at 5.0 GT/s speed, citing concerns about catastrophic
> > > > failures that may happen. Even if the odds are low, drop from last user
> > > > of this property for the RK3399 platform, helios64.
> > > > 
> > > > Fixes: 755fff528b1b ("arm64: dts: rockchip: add variables for pcie completion to helios64")
> > > > Link: https://lore.kernel.org/all/ffd05070-9879-4468-94e3-b88968b4c21b at rock-chips.com/
> > > > Reported-by: Shawn Lin <shawn.lin at rock-chips.com>
> > > > Signed-off-by: Geraldo Nascimento <geraldogabriel at gmail.com>
> > > > ---
> > > >  arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts | 1 -
> > > >  1 file changed, 1 deletion(-)
> > > > 
> > > > diff --git a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
> > > > index e7d4a2f9a95e..78a7775c3b22 100644
> > > > --- a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
> > > > +++ b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
> > > > @@ -424,7 +424,6 @@ &pcie_phy {
> > > >  
> > > >  &pcie0 {
> > > >  	ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>;
> > > > -	max-link-speed = <2>;
> > > >  	num-lanes = <2>;
> > > >  	pinctrl-names = "default";
> > > >  	status = "okay";
> > > 
> > > Looking good to me, this rounds up the prevention of issues
> > > coming from buggy PCIe Gen2 on RK3399.
> > > 
> > > Please feel free to include
> > > 
> > > Reviewed-by: Dragan Simic <dsimic at manjaro.org>
> > > 
> > > Though, could you, please, add patch 4/3 to this series, which
> > > would remove the redundant parameter "max-link-speed = <1>" from
> > > rk3399-nanopi-r4s.dtsi?
> > 
> > Sorry, I forgot to note that the patch summary would read a bit
> > better if it were reworded like this:
> > 
> >   arm64: dts: rockchip: Remove redundant max-link-speed from helios64 board dts
> 
> No, I think:
> 
> arm64: dts: rockchip: Remove dangerous max-link-speed from helios64 board dts
> 
> Is more accurately described. With focus on the dangerous, we're not
> liable.
> 
> Redudant max-link-speed only for nanopi-r4s include definitions I think!

Indeed, you're right.  It was obviously an -ENOCOFFEE on my part. :)



From geraldogabriel at gmail.com  Sat Nov 15 02:04:33 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Sat, 15 Nov 2025 07:04:33 -0300
Subject: [PATCH 2/3] PCI: rockchip-host: comment danger of 5.0 GT/s speed
In-Reply-To: <85d1543b-ea91-5f0f-59d6-e00fcf720938@manjaro.org>
References: <cover.1763197368.git.geraldogabriel@gmail.com>
 <b04ed0deb42c914847dd28233010f9573d6b5902.1763197368.git.geraldogabriel@gmail.com>
 <c8a6d165-2cdd-cd0d-4bed-95dfa5ff30d2@manjaro.org>
 <aRhNIcGcQKp2ylqN@geday>
 <85d1543b-ea91-5f0f-59d6-e00fcf720938@manjaro.org>
Message-ID: <aRhQMRjffbeCeArE@geday>

On Sat, Nov 15, 2025 at 11:01:21AM +0100, Dragan Simic wrote:
> On Saturday, November 15, 2025 10:51 CET, Geraldo Nascimento <geraldogabriel at gmail.com> wrote:
> > On Sat, Nov 15, 2025 at 10:30:49AM +0100, Dragan Simic wrote:
> > > Looking good to me, thanks for this patch!  There's no need
> > > to emit warnings here, because they'd be emitted already in
> > > the rockchip_pcie_parse_dt() function.
> > > 
> > > Please feel free to include
> > > 
> > > Reviewed-by: Dragan Simic <dsimic at manjaro.org>
> > >
> > 
> > I disagree, I think the comment stands.
> > 
> > Even if we reduce to one line, ex:
> > 
> > + May cause damage
> 
> Ah, perhaps I wasn't clear enough, so let me clarify a bit.  The
> comment you added is fine, I just referred to no need for emitting
> a warning at that point, because it would be emitted already.

OK, I get it now so I think it's time to send v2 with all that in mind
:)

Thanks,
Geraldo Nascimento


From dsimic at manjaro.org  Sat Nov 15 02:09:42 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Sat, 15 Nov 2025 11:09:42 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH 2/3] =?utf-8?q?PCI=3A?=
 =?utf-8?q?_rockchip-host=3A?= comment danger of =?utf-8?q?5=2E0?= GT/s 
 speed
In-Reply-To: <aRhQMRjffbeCeArE@geday>
References: <cover.1763197368.git.geraldogabriel@gmail.com>
 <b04ed0deb42c914847dd28233010f9573d6b5902.1763197368.git.geraldogabriel@gmail.com>
 <c8a6d165-2cdd-cd0d-4bed-95dfa5ff30d2@manjaro.org>
 <aRhNIcGcQKp2ylqN@geday>
 <85d1543b-ea91-5f0f-59d6-e00fcf720938@manjaro.org> <aRhQMRjffbeCeArE@geday>
Message-ID: <52931e25-0d6f-ca0a-7c26-2c65ab11432e@manjaro.org>

On Saturday, November 15, 2025 11:04 CET, Geraldo Nascimento <geraldogabriel at gmail.com> wrote:
> On Sat, Nov 15, 2025 at 11:01:21AM +0100, Dragan Simic wrote:
> > On Saturday, November 15, 2025 10:51 CET, Geraldo Nascimento <geraldogabriel at gmail.com> wrote:
> > > On Sat, Nov 15, 2025 at 10:30:49AM +0100, Dragan Simic wrote:
> > > > Looking good to me, thanks for this patch!  There's no need
> > > > to emit warnings here, because they'd be emitted already in
> > > > the rockchip_pcie_parse_dt() function.
> > > > 
> > > > Please feel free to include
> > > > 
> > > > Reviewed-by: Dragan Simic <dsimic at manjaro.org>
> > > >
> > > 
> > > I disagree, I think the comment stands.
> > > 
> > > Even if we reduce to one line, ex:
> > > 
> > > + May cause damage
> > 
> > Ah, perhaps I wasn't clear enough, so let me clarify a bit.  The
> > comment you added is fine, I just referred to no need for emitting
> > a warning at that point, because it would be emitted already.
> 
> OK, I get it now so I think it's time to send v2 with all that in mind
> :)

Please, wait a day or two before sending the v2, because that's
standard procedure.  Sending more than one version in the same day
is highly discouraged, because it doesn't give enough time to people
for reviewing, and may cause people to look at a wrong version.



From geraldogabriel at gmail.com  Sat Nov 15 02:11:59 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Sat, 15 Nov 2025 07:11:59 -0300
Subject: [PATCH 2/3] PCI: rockchip-host: comment danger of 5.0 GT/s speed
In-Reply-To: <52931e25-0d6f-ca0a-7c26-2c65ab11432e@manjaro.org>
References: <cover.1763197368.git.geraldogabriel@gmail.com>
 <b04ed0deb42c914847dd28233010f9573d6b5902.1763197368.git.geraldogabriel@gmail.com>
 <c8a6d165-2cdd-cd0d-4bed-95dfa5ff30d2@manjaro.org>
 <aRhNIcGcQKp2ylqN@geday>
 <85d1543b-ea91-5f0f-59d6-e00fcf720938@manjaro.org>
 <aRhQMRjffbeCeArE@geday>
 <52931e25-0d6f-ca0a-7c26-2c65ab11432e@manjaro.org>
Message-ID: <aRhR79u5BPtRRFw3@geday>

On Sat, Nov 15, 2025 at 11:09:42AM +0100, Dragan Simic wrote:
> Please, wait a day or two before sending the v2, because that's
> standard procedure.  Sending more than one version in the same day
> is highly discouraged, because it doesn't give enough time to people
> for reviewing, and may cause people to look at a wrong version.

Yeah, you're right, sorry.


From krzk at kernel.org  Sat Nov 15 03:37:55 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sat, 15 Nov 2025 12:37:55 +0100
Subject: [PATCH v2 1/2] dt-bindings: arm: rockchip: Add Asus Tinker Board
 3 and 3S
In-Reply-To: <20251114154617.69950-2-michael.opdenacker@rootcommit.com>
References: <20251114154617.69950-1-michael.opdenacker@rootcommit.com>
 <20251114154617.69950-2-michael.opdenacker@rootcommit.com>
Message-ID: <20251115-dragonfly-of-fantastic-innovation-9e7f7d@kuoka>

On Fri, Nov 14, 2025 at 03:46:42PM +0000, michael.opdenacker at rootcommit.com wrote:
> From: Michael Opdenacker <michael.opdenacker at rootcommit.com>
> 
> Document the compatible strings for Asus Tinker Board 3 [1] and 3S [2],
> which are SBCs based on the Rockchip 3566 SoC.
> 
> The "3S" version ("S" for "storage") just adds a 16 GB eMMC
> and a "mask ROM" DIP switch to the "3" version.
> 
> [1] https://tinker-board.asus.com/series/tinker-board-3.html
> [2] https://tinker-board.asus.com/series/tinker-board-3s.htm

<form letter>
This is a friendly reminder during the review process.

It looks like you received a tag and forgot to add it.

If you do not know the process, here is a short explanation:
Please add Acked-by/Reviewed-by/Tested-by tags when posting new
versions of patchset, under or above your Signed-off-by tag, unless
patch changed significantly (e.g. new properties added to the DT
bindings). Tag is "received", when provided in a message replied to you
on the mailing list. Tools like b4 can help here. However, there's no
need to repost patches *only* to add the tags. The upstream maintainer
will do that for tags received on the version they apply.

Please read:
https://elixir.bootlin.com/linux/v6.12-rc3/source/Documentation/process/submitting-patches.rst#L577

If a tag was not added on purpose, please state why and what changed.
</form letter>

Best regards,
Krzysztof



From amadeus at jmu.edu.cn  Sat Nov 15 07:00:10 2025
From: amadeus at jmu.edu.cn (Chukun Pan)
Date: Sat, 15 Nov 2025 23:00:10 +0800
Subject: (subset) [PATCH 1/6] arm64: dts: rockchip: add mmc aliases for 100ASK DshanPi A1
In-Reply-To: <176307502906.495066.9339764118786240746.b4-ty@sntech.de>
References: <176307502906.495066.9339764118786240746.b4-ty@sntech.de>
Message-ID: <20251115150010.1052575-1-amadeus@jmu.edu.cn>

Hi,

> Applied, thanks!

> [4/6] arm64: dts: rockchip: fixes supply for 100ASK DshanPi A1
>       commit: 621bb09a76fa12a9e61c9d745ae524db86abf781

Sorry, I don't know if this is a problem:

The commit message started with an extra ">".

>From the schematic, the supply of ES8388 chip and the vmmc-supply
of SD card both originate from the VCC3V3_S0 regulator, fix it.

https://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git/commit/?id=621bb09a76fa12a9e61c9d745ae524db86abf781

Thanks,
Chukun


From heiko at sntech.de  Sat Nov 15 09:59:36 2025
From: heiko at sntech.de (Heiko =?UTF-8?B?U3TDvGJuZXI=?=)
Date: Sat, 15 Nov 2025 18:59:36 +0100
Subject: [PATCH v15 00/14] media: rockchip: add a driver for the rockchip camera
 interface
In-Reply-To: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
References: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
Message-ID: <2678569.Lt9SDvczpP@diego>

Am Freitag, 14. November 2025, 16:20:11 Mitteleurop?ische Normalzeit schrieb Michael Riesch via B4 Relay:
> This series introduces support for the Rockchip Camera Interface (CIF),
> which is featured in many Rockchip SoCs in different variations.
> The series has now been around for a while and has received many comments
> and reviews. Thus, it should be ready for mainline by now.
> 
> The last issue we discussed (see thread to v14, link below) was the
> necessary integration of a mux subdevice, as the MIPI CSI-2 data can
> be passed to the ISP and/or to the VICAP on RK3568. In order to avoid
> any uAPI breakage, the MIPI CSI-2 receiver support has been removed in v15
> (following an off-list discussion with Sakari).
> 
> Therefore, the v15 of the series adds a media controller centric V4L2
> device driver for the Rockchip CIF with
>  - support for the PX30 VIP (not tested, though, due to the lack of HW)
>  - support for the RK3568 VICAP, including
>     - capturing frames from the DVP
>     - capturing frames from the MIPI CSI-2 receiver
>  - abstraction for the ping-pong scheme to allow for future extensions
>  - abstraction for the INTERFACE and CROP parts to allow for future
>    extensions
>  - initial support for different virtual channels (not tested, though,
>    due to the lack of HW)
> 
> Apart from that, there are no changes compared to v14.
> 
> Looking forward to your comments!

[...]

> Michael Riesch (12):
>       Documentation: admin-guide: media: add rockchip camera interface
>       media: dt-bindings: video-interfaces: add defines for sampling modes
>       media: dt-bindings: add rockchip rk3568 vicap
>       media: rockchip: add driver for the rockchip camera interface
>       media: rockchip: rkcif: add abstraction for interface and crop blocks
>       media: rockchip: rkcif: add abstraction for dma blocks
>       media: rockchip: rkcif: add support for px30 vip dvp capture
>       media: rockchip: rkcif: add support for rk3568 vicap dvp capture
>       media: rockchip: rkcif: add support for rk3568 vicap mipi capture

for people playing along at home, patches 1-10 seems to have been merged
into the media-committers tree [0]


[0] https://gitlab.freedesktop.org/linux-media/media-committers/-/commit/1f2353f5a1af995efbf7bea44341aa0d03460b28
    that commit and backwards in the history



>       arm64: defconfig: enable rockchip camera interface
>       arm64: dts: rockchip: add vicap node to rk356x
>       arm64: dts: rockchip: enable vicap dvp on wolfvision pf5 io expander





From heiko at sntech.de  Sat Nov 15 11:53:12 2025
From: heiko at sntech.de (Heiko =?UTF-8?B?U3TDvGJuZXI=?=)
Date: Sat, 15 Nov 2025 20:53:12 +0100
Subject: (subset) [PATCH 1/6] arm64: dts: rockchip: add mmc aliases for 100ASK
 DshanPi A1
In-Reply-To: <20251115150010.1052575-1-amadeus@jmu.edu.cn>
References: <176307502906.495066.9339764118786240746.b4-ty@sntech.de>
 <20251115150010.1052575-1-amadeus@jmu.edu.cn>
Message-ID: <2251982.Mh6RI2rZIc@diego>

Hi,

Am Samstag, 15. November 2025, 16:00:10 Mitteleurop?ische Normalzeit schrieb Chukun Pan:
> > Applied, thanks!
> 
> > [4/6] arm64: dts: rockchip: fixes supply for 100ASK DshanPi A1
> >       commit: 621bb09a76fa12a9e61c9d745ae524db86abf781
> 
> Sorry, I don't know if this is a problem:
> 
> The commit message started with an extra ">".
> 
> >From the schematic, the supply of ES8388 chip and the vmmc-supply
> of SD card both originate from the VCC3V3_S0 regulator, fix it.
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git/commit/?id=621bb09a76fa12a9e61c9d745ae524db86abf781

thanks for noticing this. I've now edited the commit message in place
to fix that.

Heiko




From heiko at sntech.de  Sat Nov 15 15:27:47 2025
From: heiko at sntech.de (Heiko =?UTF-8?B?U3TDvGJuZXI=?=)
Date: Sun, 16 Nov 2025 00:27:47 +0100
Subject: [PATCH v2 2/2] arm64: dts: rockchip: Add Asus Tinker Board 3 and 3S
 device tree
In-Reply-To: <24561990-8293-0505-5837-eca416d01bb7@manjaro.org>
References: <12d6e151-dfa0-ca0a-5888-ddffb2dbdec7@manjaro.org>
 <bb74679a-ce21-4373-bcc5-1214e9bf832e@rootcommit.com>
 <24561990-8293-0505-5837-eca416d01bb7@manjaro.org>
Message-ID: <2455319.NG923GbCHz@diego>

Am Samstag, 15. November 2025, 08:14:58 Mitteleurop?ische Normalzeit schrieb Dragan Simic:
> Hello Michael,
> 
> On Saturday, November 15, 2025 07:03 CET, Michael Opdenacker <michael.opdenacker at rootcommit.com> wrote:
> > On 11/15/25 01:53, Dragan Simic wrote:
> > > Thanks for the v2!  Please, see one nitpick below.
> > >
> > > On Friday, November 14, 2025 16:46 CET, michael.opdenacker at rootcommit.com wrote:
> > >> From: Michael Opdenacker <michael.opdenacker at rootcommit.com>
> > > I'm sorry for not mentioning it in my earlier responses, but this
> > > line is redundant, because it duplicates the From value found in
> > > the actual email message.
> > 
> > This actually comes from my Git settings. I need this when I send 
> > patches to the Yocto project and OpenEmbedded. That's because their 
> > mailing list server which alters the address of senders ("<sender> via 
> > lists.yoctoproject.org"), and ultimately the commit author identity in 
> > Git. See 
> > https://docs.yoctoproject.org/contributor-guide/submit-changes.html#fixing-your-from-identity
> > 
> > I've checked that my patches apply fine and that this "From:" line 
> > doesn't appear in the commits in the tree.
> > So, can I keep this?

Yes you can keep that, I don't see a problem with that additional
From header.

> Actually, I forgot to mention that the From headers in your patch
> submissions are a bit wrong by containing just the email address,
> without the first and last name.  That issue should be fixed first,
> regardless of the presence (or absence) of From tags.
> 
> Thanks for clarifying what's the reason for having the From tags
> regardless of the actual need for having them.  Maybe setting Git's
> "format.from" option to true at the repository level could solve
> this nicely, while also exercising the Git-fu a bit? :)
> 
> BTW, my responses are currently jailed by the linux-rockchip mailing
> list, requiring manual approval, as a result of the mail server I'm
> using sometimes inserting some strange invisible UTF-8 characters
> into the email subjects.  Oh well. :)

I guess that mailserver needs a fix :-)


Heiko




From brgl at bgdev.pl  Fri Nov  7 02:29:50 2025
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 07 Nov 2025 11:29:50 +0100
Subject: [PATCH v5 0/8] net: stmmac: qcom-ethqos: add support for SCMI
 power domains
Message-ID: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>

Add support for the firmware-managed variant of the DesignWare MAC on
the sa8255p platform. This series contains new DT bindings and driver
changes required to support the MAC in the STMMAC driver.

It also reorganizes the ethqos code quite a bit to make the introduction
of power domains into the driver a bit easier on the eye.

The DTS changes will go in separately.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
Changes in v5:
- Name the DT binding document after the new compatbile
- Add missing space
- Make the power-domains limits stricter
- Link to v4: https://lore.kernel.org/r/20251104-qcom-sa8255p-emac-v4-0-f76660087cea at linaro.org

Changes in v4:
- Remove the phys property from the SCMI bindings
- Mark the power-domain-names property as required
- Set maxItems for power-domains to 1 for all existing bindings to
  maintain the current requirements after modifying the value in the
  top-level document
- Link to v3: https://lore.kernel.org/r/20251027-qcom-sa8255p-emac-v3-0-75767b9230ab at linaro.org

Changes in v3:
- Drop 'power' and 'perf' prefixes from power domain names
- Rebase on top of Russell's changes to dwmac
- Rebase on top of even more changes from Russell that are not yet
  in next (E1vB6ld-0000000BIPy-2Qi4 at rmk-PC.armlinux.org.uk)
- Link to v2: https://lore.kernel.org/all/20251008-qcom-sa8255p-emac-v2-0-92bc29309fce at linaro.org/

Changes in v2:
- Fix the power-domains property in DT bindings
- Rework the DT bindings example
- Drop the DTS patch, it will go upstream separately
- Link to v1: https://lore.kernel.org/r/20250910-qcom-sa8255p-emac-v1-0-32a79cf1e668 at linaro.org

---
Bartosz Golaszewski (8):
      dt-bindings: net: qcom: document the ethqos device for SCMI-based systems
      net: stmmac: qcom-ethqos: use generic device properties
      net: stmmac: qcom-ethqos: improve typing in devres callback
      net: stmmac: qcom-ethqos: wrap emac driver data in additional structure
      net: stmmac: qcom-ethqos: split power management fields into a separate structure
      net: stmmac: qcom-ethqos: split power management context into a separate struct
      net: stmmac: qcom-ethqos: define a callback for setting the serdes speed
      net: stmmac: qcom-ethqos: add support for sa8255p

 .../bindings/net/allwinner,sun7i-a20-gmac.yaml     |   3 +
 .../bindings/net/altr,socfpga-stmmac.yaml          |   3 +
 .../bindings/net/amlogic,meson-dwmac.yaml          |   3 +
 .../devicetree/bindings/net/eswin,eic7700-eth.yaml |   3 +
 .../devicetree/bindings/net/intel,dwmac-plat.yaml  |   3 +
 .../bindings/net/loongson,ls1b-gmac.yaml           |   3 +
 .../bindings/net/loongson,ls1c-emac.yaml           |   3 +
 .../devicetree/bindings/net/nxp,dwmac-imx.yaml     |   3 +
 .../devicetree/bindings/net/nxp,lpc1850-dwmac.yaml |   3 +
 .../devicetree/bindings/net/nxp,s32-dwmac.yaml     |   3 +
 .../devicetree/bindings/net/qcom,ethqos.yaml       |   3 +
 .../bindings/net/qcom,sa8255p-ethqos.yaml          |  98 ++++++
 .../devicetree/bindings/net/renesas,rzn1-gmac.yaml |   3 +
 .../bindings/net/renesas,rzv2h-gbeth.yaml          |   3 +
 .../devicetree/bindings/net/rockchip-dwmac.yaml    |   3 +
 .../devicetree/bindings/net/snps,dwmac.yaml        |   5 +-
 .../bindings/net/sophgo,cv1800b-dwmac.yaml         |   3 +
 .../bindings/net/sophgo,sg2044-dwmac.yaml          |   3 +
 .../bindings/net/starfive,jh7110-dwmac.yaml        |   3 +
 .../devicetree/bindings/net/stm32-dwmac.yaml       |   3 +
 .../devicetree/bindings/net/tesla,fsd-ethqos.yaml  |   3 +
 .../devicetree/bindings/net/thead,th1520-gmac.yaml |   3 +
 .../bindings/net/toshiba,visconti-dwmac.yaml       |   3 +
 MAINTAINERS                                        |   1 +
 drivers/net/ethernet/stmicro/stmmac/Kconfig        |   2 +-
 .../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c    | 342 +++++++++++++++++----
 26 files changed, 448 insertions(+), 63 deletions(-)
---
base-commit: 9c0826a5d9aa4d52206dd89976858457a2a8a7ed
change-id: 20250704-qcom-sa8255p-emac-8460235ac512

Best regards,
-- 
Bartosz Golaszewski <bartosz.golaszewski at linaro.org>



From brgl at bgdev.pl  Fri Nov  7 02:29:51 2025
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 07 Nov 2025 11:29:51 +0100
Subject: [PATCH v5 1/8] dt-bindings: net: qcom: document the ethqos device
 for SCMI-based systems
In-Reply-To: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>
References: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>
Message-ID: <20251107-qcom-sa8255p-emac-v5-1-01d3e3aaf388@linaro.org>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

Describe the firmware-managed variant of the QCom DesignWare MAC. As the
properties here differ a lot from the HLOS-managed variant, lets put it
in a separate file. Since we need to update the maximum number of power
domains, let's update existing bindings referencing the top-level
snps,dwmac.yaml and limit their maxItems for power-domains to 1.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 .../bindings/net/allwinner,sun7i-a20-gmac.yaml     |  3 +
 .../bindings/net/altr,socfpga-stmmac.yaml          |  3 +
 .../bindings/net/amlogic,meson-dwmac.yaml          |  3 +
 .../devicetree/bindings/net/eswin,eic7700-eth.yaml |  3 +
 .../devicetree/bindings/net/intel,dwmac-plat.yaml  |  3 +
 .../bindings/net/loongson,ls1b-gmac.yaml           |  3 +
 .../bindings/net/loongson,ls1c-emac.yaml           |  3 +
 .../devicetree/bindings/net/nxp,dwmac-imx.yaml     |  3 +
 .../devicetree/bindings/net/nxp,lpc1850-dwmac.yaml |  3 +
 .../devicetree/bindings/net/nxp,s32-dwmac.yaml     |  3 +
 .../devicetree/bindings/net/qcom,ethqos.yaml       |  3 +
 .../bindings/net/qcom,sa8255p-ethqos.yaml          | 98 ++++++++++++++++++++++
 .../devicetree/bindings/net/renesas,rzn1-gmac.yaml |  3 +
 .../bindings/net/renesas,rzv2h-gbeth.yaml          |  3 +
 .../devicetree/bindings/net/rockchip-dwmac.yaml    |  3 +
 .../devicetree/bindings/net/snps,dwmac.yaml        |  5 +-
 .../bindings/net/sophgo,cv1800b-dwmac.yaml         |  3 +
 .../bindings/net/sophgo,sg2044-dwmac.yaml          |  3 +
 .../bindings/net/starfive,jh7110-dwmac.yaml        |  3 +
 .../devicetree/bindings/net/stm32-dwmac.yaml       |  3 +
 .../devicetree/bindings/net/tesla,fsd-ethqos.yaml  |  3 +
 .../devicetree/bindings/net/thead,th1520-gmac.yaml |  3 +
 .../bindings/net/toshiba,visconti-dwmac.yaml       |  3 +
 MAINTAINERS                                        |  1 +
 24 files changed, 166 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/net/allwinner,sun7i-a20-gmac.yaml b/Documentation/devicetree/bindings/net/allwinner,sun7i-a20-gmac.yaml
index 23e92be33ac8609a16db530782989caed22a5730..b12632545673b2ad0148a677f45a7447309a43cd 100644
--- a/Documentation/devicetree/bindings/net/allwinner,sun7i-a20-gmac.yaml
+++ b/Documentation/devicetree/bindings/net/allwinner,sun7i-a20-gmac.yaml
@@ -40,6 +40,9 @@ properties:
     description:
       PHY regulator
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
diff --git a/Documentation/devicetree/bindings/net/altr,socfpga-stmmac.yaml b/Documentation/devicetree/bindings/net/altr,socfpga-stmmac.yaml
index fc445ad5a1f1ac490e921696d6f7ca83d15de459..448e617cddc4cda8dbc77e83324495ffd5dfb9be 100644
--- a/Documentation/devicetree/bindings/net/altr,socfpga-stmmac.yaml
+++ b/Documentation/devicetree/bindings/net/altr,socfpga-stmmac.yaml
@@ -140,6 +140,9 @@ properties:
           - description: offset of the control register
           - description: shift within the control register
 
+  power-domains:
+    maxItems: 1
+
 patternProperties:
   "^mdio[0-9]$":
     type: object
diff --git a/Documentation/devicetree/bindings/net/amlogic,meson-dwmac.yaml b/Documentation/devicetree/bindings/net/amlogic,meson-dwmac.yaml
index 5c91716d1f21e617543b03c5a90b993f8aee053c..9c9cc3ef384da0270489c21b3426572ea46d9499 100644
--- a/Documentation/devicetree/bindings/net/amlogic,meson-dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/amlogic,meson-dwmac.yaml
@@ -158,6 +158,9 @@ properties:
   interrupt-names:
     const: macirq
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
diff --git a/Documentation/devicetree/bindings/net/eswin,eic7700-eth.yaml b/Documentation/devicetree/bindings/net/eswin,eic7700-eth.yaml
index 91e8cd1db67b8e14961497a7254e6b01dc4e582a..c1b67cfa76d070d5e8349d5e92ce6bc4bf2ab67c 100644
--- a/Documentation/devicetree/bindings/net/eswin,eic7700-eth.yaml
+++ b/Documentation/devicetree/bindings/net/eswin,eic7700-eth.yaml
@@ -83,6 +83,9 @@ properties:
                          register
           - description: Offset of register controlling TX/RX clock delay
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
diff --git a/Documentation/devicetree/bindings/net/intel,dwmac-plat.yaml b/Documentation/devicetree/bindings/net/intel,dwmac-plat.yaml
index 62c1da36a2b5a29290e5e01be87c48158c4adf89..e41851931b947559c89b0cd6f4756f71046f9594 100644
--- a/Documentation/devicetree/bindings/net/intel,dwmac-plat.yaml
+++ b/Documentation/devicetree/bindings/net/intel,dwmac-plat.yaml
@@ -47,6 +47,9 @@ properties:
   interrupt-names:
     const: macirq
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - clocks
diff --git a/Documentation/devicetree/bindings/net/loongson,ls1b-gmac.yaml b/Documentation/devicetree/bindings/net/loongson,ls1b-gmac.yaml
index c4f3224bad387b87a5b4a3049dabd75f2c4bd42f..c9a131b8d8304c41559a416b324df749c0a87d14 100644
--- a/Documentation/devicetree/bindings/net/loongson,ls1b-gmac.yaml
+++ b/Documentation/devicetree/bindings/net/loongson,ls1b-gmac.yaml
@@ -66,6 +66,9 @@ properties:
       - mii
       - rgmii-id
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
diff --git a/Documentation/devicetree/bindings/net/loongson,ls1c-emac.yaml b/Documentation/devicetree/bindings/net/loongson,ls1c-emac.yaml
index 99001b940b8361f69bb917617f857ee99f4b3fa5..49db18423dd807683b9bb297978f5da8ea6cee3d 100644
--- a/Documentation/devicetree/bindings/net/loongson,ls1c-emac.yaml
+++ b/Documentation/devicetree/bindings/net/loongson,ls1c-emac.yaml
@@ -65,6 +65,9 @@ properties:
       - mii
       - rmii
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
diff --git a/Documentation/devicetree/bindings/net/nxp,dwmac-imx.yaml b/Documentation/devicetree/bindings/net/nxp,dwmac-imx.yaml
index e5db346beca9649be4f97727b78fda8973095912..b240c76e7dd5254d0c3752610c4aa848a3c3d65b 100644
--- a/Documentation/devicetree/bindings/net/nxp,dwmac-imx.yaml
+++ b/Documentation/devicetree/bindings/net/nxp,dwmac-imx.yaml
@@ -83,6 +83,9 @@ properties:
     description:
       To select RMII reference clock from external.
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - clocks
diff --git a/Documentation/devicetree/bindings/net/nxp,lpc1850-dwmac.yaml b/Documentation/devicetree/bindings/net/nxp,lpc1850-dwmac.yaml
index 05acd9bc7616356e68090ebdd4df20e42f70dd7e..f61188ab0dbe3c0cec5b10f7a65dfaff4dc3898f 100644
--- a/Documentation/devicetree/bindings/net/nxp,lpc1850-dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/nxp,lpc1850-dwmac.yaml
@@ -51,6 +51,9 @@ properties:
     items:
       - const: stmmaceth
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
diff --git a/Documentation/devicetree/bindings/net/nxp,s32-dwmac.yaml b/Documentation/devicetree/bindings/net/nxp,s32-dwmac.yaml
index 2b8b74c5feec8378750358e1b9335cc2c2762bb6..716407a750796ff27e8fbcdb75267f3922ef64f5 100644
--- a/Documentation/devicetree/bindings/net/nxp,s32-dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/nxp,s32-dwmac.yaml
@@ -52,6 +52,9 @@ properties:
       - const: rx
       - const: ptp_ref
 
+  power-domains:
+    maxItems: 1
+
 required:
   - clocks
   - clock-names
diff --git a/Documentation/devicetree/bindings/net/qcom,ethqos.yaml b/Documentation/devicetree/bindings/net/qcom,ethqos.yaml
index 423959cb928d945aa3e758a3c803d12bd61ec42b..ef520f8105773e22c0536ff419dad55fe316e1bd 100644
--- a/Documentation/devicetree/bindings/net/qcom,ethqos.yaml
+++ b/Documentation/devicetree/bindings/net/qcom,ethqos.yaml
@@ -86,6 +86,9 @@ properties:
   phy-names:
     const: serdes
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - clocks
diff --git a/Documentation/devicetree/bindings/net/qcom,sa8255p-ethqos.yaml b/Documentation/devicetree/bindings/net/qcom,sa8255p-ethqos.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..23a7b2a210e20c947498e1a0dc6b0e773af6e988
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/qcom,sa8255p-ethqos.yaml
@@ -0,0 +1,98 @@
+# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/qcom,ethqos-scmi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Ethernet ETHQOS device (firmware managed)
+
+maintainers:
+  - Bjorn Andersson <andersson at kernel.org>
+  - Konrad Dybcio <konradybcio at kernel.org>
+  - Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
+
+description:
+  dwmmac based Qualcomm ethernet devices which support Gigabit
+  ethernet (version v2.3.0 and onwards) with clocks, interconnects, etc.
+  managed by firmware
+
+allOf:
+  - $ref: snps,dwmac.yaml#
+
+properties:
+  compatible:
+    const: qcom,sa8255p-ethqos
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: stmmaceth
+      - const: rgmii
+
+  interrupts:
+    items:
+      - description: Combined signal for various interrupt events
+      - description: The interrupt that occurs when HW safety error triggered
+
+  interrupt-names:
+    items:
+      - const: macirq
+      - const: sfty
+
+  power-domains:
+    minItems: 3
+    maxItems: 3
+
+  power-domain-names:
+    items:
+      - const: core
+      - const: mdio
+      - const: serdes
+
+  iommus:
+    maxItems: 1
+
+  dma-coherent: true
+
+required:
+  - compatible
+  - reg-names
+  - power-domains
+  - power-domain-names
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    ethernet: ethernet at 7a80000 {
+        compatible = "qcom,sa8255p-ethqos";
+        reg = <0x23040000 0x10000>,
+              <0x23056000 0x100>;
+        reg-names = "stmmaceth", "rgmii";
+
+        iommus = <&apps_smmu 0x120 0x7>;
+
+        interrupts = <GIC_SPI 946 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 782 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-names = "macirq", "sfty";
+
+        dma-coherent;
+
+        snps,tso;
+        snps,pbl = <32>;
+        rx-fifo-depth = <16384>;
+        tx-fifo-depth = <16384>;
+
+        phy-handle = <&ethernet_phy>;
+        phy-mode = "2500base-x";
+
+        snps,mtl-rx-config = <&mtl_rx_setup1>;
+        snps,mtl-tx-config = <&mtl_tx_setup1>;
+
+        power-domains = <&scmi8_pd 0>, <&scmi8_pd 1>, <&scmi8_dvfs 0>;
+        power-domain-names = "core", "mdio", "serdes";
+    };
diff --git a/Documentation/devicetree/bindings/net/renesas,rzn1-gmac.yaml b/Documentation/devicetree/bindings/net/renesas,rzn1-gmac.yaml
index 16dd7a2631abf6fb7dc8e0c90755ab1e81915b38..ed0d10a19ca4c47c05f6873c64b0537b90acd15a 100644
--- a/Documentation/devicetree/bindings/net/renesas,rzn1-gmac.yaml
+++ b/Documentation/devicetree/bindings/net/renesas,rzn1-gmac.yaml
@@ -44,6 +44,9 @@ properties:
       phandle pointing to a PCS sub-node compatible with
       renesas,rzn1-miic.yaml#
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
 
diff --git a/Documentation/devicetree/bindings/net/renesas,rzv2h-gbeth.yaml b/Documentation/devicetree/bindings/net/renesas,rzv2h-gbeth.yaml
index bd53ab300f5003ea1f951d3957cefc702301217a..bc5054b05f6d7f1bcd5cd8640deb89293d9f69a6 100644
--- a/Documentation/devicetree/bindings/net/renesas,rzv2h-gbeth.yaml
+++ b/Documentation/devicetree/bindings/net/renesas,rzv2h-gbeth.yaml
@@ -123,6 +123,9 @@ properties:
       Documentation/devicetree/bindings/net/pcs/renesas,rzn1-miic.yaml#
       (Refer RZ/T2H portion in the DT-binding file)
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
diff --git a/Documentation/devicetree/bindings/net/rockchip-dwmac.yaml b/Documentation/devicetree/bindings/net/rockchip-dwmac.yaml
index d17112527dab0a5104ffaf2627fdcb73603d5db7..ef82ff2a2884d994c5ae6c98e0b3483b56dda653 100644
--- a/Documentation/devicetree/bindings/net/rockchip-dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/rockchip-dwmac.yaml
@@ -121,6 +121,9 @@ properties:
   phy-supply:
     description: PHY regulator
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - clocks
diff --git a/Documentation/devicetree/bindings/net/snps,dwmac.yaml b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
index dd3c72e8363e70d101ed2702e2ea3235ee38e2a0..312d1bbc2ad1051520355039f5587381cbd1e01c 100644
--- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
@@ -71,6 +71,7 @@ properties:
         - loongson,ls7a-dwmac
         - nxp,s32g2-dwmac
         - qcom,qcs404-ethqos
+        - qcom,sa8255p-ethqos
         - qcom,sa8775p-ethqos
         - qcom,sc8280xp-ethqos
         - qcom,sm8150-ethqos
@@ -180,7 +181,8 @@ properties:
           - const: ahb
 
   power-domains:
-    maxItems: 1
+    minItems: 1
+    maxItems: 3
 
   mac-mode:
     $ref: ethernet-controller.yaml#/properties/phy-connection-type
@@ -643,6 +645,7 @@ allOf:
                 - ingenic,x1830-mac
                 - ingenic,x2000-mac
                 - qcom,qcs404-ethqos
+                - qcom,sa8255p-ethqos
                 - qcom,sa8775p-ethqos
                 - qcom,sc8280xp-ethqos
                 - qcom,sm8150-ethqos
diff --git a/Documentation/devicetree/bindings/net/sophgo,cv1800b-dwmac.yaml b/Documentation/devicetree/bindings/net/sophgo,cv1800b-dwmac.yaml
index b89456f0ef830991135bd17626da98661429596c..e78cbf594c695204040a53ab1e367daa9e12246b 100644
--- a/Documentation/devicetree/bindings/net/sophgo,cv1800b-dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/sophgo,cv1800b-dwmac.yaml
@@ -49,6 +49,9 @@ properties:
   reset-names:
     const: stmmaceth
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
diff --git a/Documentation/devicetree/bindings/net/sophgo,sg2044-dwmac.yaml b/Documentation/devicetree/bindings/net/sophgo,sg2044-dwmac.yaml
index ce21979a2d9a438adb1e59d1a479bc6c1961bdca..e124cfc9bd90e37cf950e3576fc8030361ce6a11 100644
--- a/Documentation/devicetree/bindings/net/sophgo,sg2044-dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/sophgo,sg2044-dwmac.yaml
@@ -52,6 +52,9 @@ properties:
   interrupt-names:
     maxItems: 1
 
+  power-domains:
+    maxItems: 1
+
   resets:
     maxItems: 1
 
diff --git a/Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml b/Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml
index 313a15331661208a1fa64386739d87a4f11b7e20..8a68c6d7b5c6d6629a780d002299d767088def77 100644
--- a/Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/starfive,jh7110-dwmac.yaml
@@ -71,6 +71,9 @@ properties:
       The argument one is the offset of phy mode selection, the
       argument two is the shift of phy mode selection.
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
diff --git a/Documentation/devicetree/bindings/net/stm32-dwmac.yaml b/Documentation/devicetree/bindings/net/stm32-dwmac.yaml
index 987254900d0da7aab81237f20b1540ad8a17bd21..29b878079ff0c1a0ef95fc63f2035f478ee039b2 100644
--- a/Documentation/devicetree/bindings/net/stm32-dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/stm32-dwmac.yaml
@@ -121,6 +121,9 @@ properties:
     minItems: 1
     maxItems: 2
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - clocks
diff --git a/Documentation/devicetree/bindings/net/tesla,fsd-ethqos.yaml b/Documentation/devicetree/bindings/net/tesla,fsd-ethqos.yaml
index dd7481bb16e59982c26c1a54ae82b8cff85fdfe0..ad635529d676ed6b752ab3bde5152d5cbddcb519 100644
--- a/Documentation/devicetree/bindings/net/tesla,fsd-ethqos.yaml
+++ b/Documentation/devicetree/bindings/net/tesla,fsd-ethqos.yaml
@@ -67,6 +67,9 @@ properties:
       - rgmii-rxid
       - rgmii-txid
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
diff --git a/Documentation/devicetree/bindings/net/thead,th1520-gmac.yaml b/Documentation/devicetree/bindings/net/thead,th1520-gmac.yaml
index b3492a9aa4effa73fadf92a63a76ba8bb65a8769..c859f8bb5d582af8b8782f2f89ab5e6ee3d7a46c 100644
--- a/Documentation/devicetree/bindings/net/thead,th1520-gmac.yaml
+++ b/Documentation/devicetree/bindings/net/thead,th1520-gmac.yaml
@@ -78,6 +78,9 @@ properties:
     items:
       - const: macirq
 
+  power-domains:
+    maxItems: 1
+
 required:
   - clocks
   - clock-names
diff --git a/Documentation/devicetree/bindings/net/toshiba,visconti-dwmac.yaml b/Documentation/devicetree/bindings/net/toshiba,visconti-dwmac.yaml
index f0f32e18fc8550e6f63b87b60a095972453836c9..efa39eab0256a1102b01872bd848749788c9b4e8 100644
--- a/Documentation/devicetree/bindings/net/toshiba,visconti-dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/toshiba,visconti-dwmac.yaml
@@ -48,6 +48,9 @@ properties:
   interrupt-names:
     const: macirq
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
diff --git a/MAINTAINERS b/MAINTAINERS
index 58c7e3f678d8d4efe8a711c6fba0b01d9f2acdd4..09d47aa727964c04f2fa723dcf643e5a6356f70b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -21266,6 +21266,7 @@ L:	netdev at vger.kernel.org
 L:	linux-arm-msm at vger.kernel.org
 S:	Maintained
 F:	Documentation/devicetree/bindings/net/qcom,ethqos.yaml
+F:	Documentation/devicetree/bindings/net/qcom,sa8255p-ethqos.yaml
 F:	drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
 
 QUALCOMM FASTRPC DRIVER

-- 
2.51.0



From brgl at bgdev.pl  Fri Nov  7 02:29:54 2025
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 07 Nov 2025 11:29:54 +0100
Subject: [PATCH v5 4/8] net: stmmac: qcom-ethqos: wrap emac driver data in
 additional structure
In-Reply-To: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>
References: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>
Message-ID: <20251107-qcom-sa8255p-emac-v5-4-01d3e3aaf388@linaro.org>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

As the first step in enabling power domain support in the driver, we'll
split the device match data and runtime data structures into their
general and power-management-specific parts. To allow that: first wrap
the emac driver data in another layer which will later be expanded.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 .../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c    | 51 ++++++++++++++++------
 1 file changed, 37 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 8493131ca32f5c6ca7e1654da0bbf4ffa1eefa4e..9cafe101049d5412d649b3beaca350c497ffc981 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -97,6 +97,10 @@ struct ethqos_emac_driver_data {
 	bool needs_sgmii_loopback;
 };
 
+struct ethqos_emac_match_data {
+	const struct ethqos_emac_driver_data *drv_data;
+};
+
 struct qcom_ethqos {
 	struct platform_device *pdev;
 	void __iomem *rgmii_base;
@@ -214,6 +218,10 @@ static const struct ethqos_emac_driver_data emac_v2_3_0_data = {
 	.has_emac_ge_3 = false,
 };
 
+static const struct ethqos_emac_match_data emac_qcs404_data = {
+	.drv_data = &emac_v2_3_0_data,
+};
+
 static const struct ethqos_emac_por emac_v2_1_0_por[] = {
 	{ .offset = RGMII_IO_MACRO_CONFIG,	.value = 0x40C01343 },
 	{ .offset = SDCC_HC_REG_DLL_CONFIG,	.value = 0x2004642C },
@@ -230,6 +238,10 @@ static const struct ethqos_emac_driver_data emac_v2_1_0_data = {
 	.has_emac_ge_3 = false,
 };
 
+static const struct ethqos_emac_match_data emac_sm8150_data = {
+	.drv_data = &emac_v2_1_0_data,
+};
+
 static const struct ethqos_emac_por emac_v3_0_0_por[] = {
 	{ .offset = RGMII_IO_MACRO_CONFIG,	.value = 0x40c01343 },
 	{ .offset = SDCC_HC_REG_DLL_CONFIG,	.value = 0x2004642c },
@@ -262,6 +274,10 @@ static const struct ethqos_emac_driver_data emac_v3_0_0_data = {
 	},
 };
 
+static const struct ethqos_emac_match_data emac_sc8280xp_data = {
+	.drv_data = &emac_v3_0_0_data,
+};
+
 static const struct ethqos_emac_por emac_v4_0_0_por[] = {
 	{ .offset = RGMII_IO_MACRO_CONFIG,	.value = 0x40c01343 },
 	{ .offset = SDCC_HC_REG_DLL_CONFIG,	.value = 0x2004642c },
@@ -297,6 +313,10 @@ static const struct ethqos_emac_driver_data emac_v4_0_0_data = {
 	},
 };
 
+static const struct ethqos_emac_match_data emac_sa8775p_data = {
+	.drv_data = &emac_v4_0_0_data,
+};
+
 static int ethqos_dll_configure(struct qcom_ethqos *ethqos)
 {
 	struct device *dev = &ethqos->pdev->dev;
@@ -750,7 +770,8 @@ static void ethqos_ptp_clk_freq_config(struct stmmac_priv *priv)
 
 static int qcom_ethqos_probe(struct platform_device *pdev)
 {
-	const struct ethqos_emac_driver_data *data;
+	const struct ethqos_emac_driver_data *drv_data;
+	const struct ethqos_emac_match_data *data;
 	struct plat_stmmacenet_data *plat_dat;
 	struct stmmac_resources stmmac_res;
 	struct device *dev = &pdev->dev;
@@ -801,13 +822,15 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 	ethqos->mac_base = stmmac_res.addr;
 
 	data = device_get_match_data(dev);
-	ethqos->por = data->por;
-	ethqos->num_por = data->num_por;
-	ethqos->rgmii_config_loopback_en = data->rgmii_config_loopback_en;
-	ethqos->has_emac_ge_3 = data->has_emac_ge_3;
-	ethqos->needs_sgmii_loopback = data->needs_sgmii_loopback;
+	drv_data = data->drv_data;
 
-	ethqos->link_clk = devm_clk_get(dev, data->link_clk_name ?: "rgmii");
+	ethqos->por = drv_data->por;
+	ethqos->num_por = drv_data->num_por;
+	ethqos->rgmii_config_loopback_en = drv_data->rgmii_config_loopback_en;
+	ethqos->has_emac_ge_3 = drv_data->has_emac_ge_3;
+	ethqos->needs_sgmii_loopback = drv_data->needs_sgmii_loopback;
+
+	ethqos->link_clk = devm_clk_get(dev, drv_data->link_clk_name ?: "rgmii");
 	if (IS_ERR(ethqos->link_clk))
 		return dev_err_probe(dev, PTR_ERR(ethqos->link_clk),
 				     "Failed to get link_clk\n");
@@ -835,14 +858,14 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 	plat_dat->ptp_clk_freq_config = ethqos_ptp_clk_freq_config;
 	plat_dat->core_type = DWMAC_CORE_GMAC4;
 	if (ethqos->has_emac_ge_3)
-		plat_dat->dwmac4_addrs = &data->dwmac4_addrs;
+		plat_dat->dwmac4_addrs = &drv_data->dwmac4_addrs;
 	plat_dat->pmt = 1;
 	if (device_property_present(dev, "snps,tso"))
 		plat_dat->flags |= STMMAC_FLAG_TSO_EN;
 	if (device_is_compatible(dev, "qcom,qcs404-ethqos"))
 		plat_dat->flags |= STMMAC_FLAG_RX_CLK_RUNS_IN_LPI;
-	if (data->dma_addr_width)
-		plat_dat->host_dma_width = data->dma_addr_width;
+	if (drv_data->dma_addr_width)
+		plat_dat->host_dma_width = drv_data->dma_addr_width;
 
 	if (ethqos->serdes_phy) {
 		plat_dat->serdes_powerup = qcom_ethqos_serdes_powerup;
@@ -857,10 +880,10 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 }
 
 static const struct of_device_id qcom_ethqos_match[] = {
-	{ .compatible = "qcom,qcs404-ethqos", .data = &emac_v2_3_0_data},
-	{ .compatible = "qcom,sa8775p-ethqos", .data = &emac_v4_0_0_data},
-	{ .compatible = "qcom,sc8280xp-ethqos", .data = &emac_v3_0_0_data},
-	{ .compatible = "qcom,sm8150-ethqos", .data = &emac_v2_1_0_data},
+	{ .compatible = "qcom,qcs404-ethqos", .data = &emac_qcs404_data},
+	{ .compatible = "qcom,sa8775p-ethqos", .data = &emac_sa8775p_data},
+	{ .compatible = "qcom,sc8280xp-ethqos", .data = &emac_sc8280xp_data},
+	{ .compatible = "qcom,sm8150-ethqos", .data = &emac_sm8150_data},
 	{ }
 };
 MODULE_DEVICE_TABLE(of, qcom_ethqos_match);

-- 
2.51.0



From brgl at bgdev.pl  Fri Nov  7 02:29:55 2025
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 07 Nov 2025 11:29:55 +0100
Subject: [PATCH v5 5/8] net: stmmac: qcom-ethqos: split power management
 fields into a separate structure
In-Reply-To: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>
References: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>
Message-ID: <20251107-qcom-sa8255p-emac-v5-5-01d3e3aaf388@linaro.org>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

Now that we have a separate wrapper for device match data, let's extend
this structure with a pointer to the structure containing fields related
to power-management only. This is done because a device may have the
same device settings but different power management mode (e.g.: firmware
vs manual).

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 .../net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c   | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 9cafe101049d5412d649b3beaca350c497ffc981..1f00556bbad997e2ec76b521cffe2eb14fabb79e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -91,14 +91,18 @@ struct ethqos_emac_driver_data {
 	unsigned int num_por;
 	bool rgmii_config_loopback_en;
 	bool has_emac_ge_3;
-	const char *link_clk_name;
 	u32 dma_addr_width;
 	struct dwmac4_addrs dwmac4_addrs;
 	bool needs_sgmii_loopback;
 };
 
+struct ethqos_emac_pm_data {
+	const char *link_clk_name;
+};
+
 struct ethqos_emac_match_data {
 	const struct ethqos_emac_driver_data *drv_data;
+	const struct ethqos_emac_pm_data *pm_data;
 };
 
 struct qcom_ethqos {
@@ -292,7 +296,6 @@ static const struct ethqos_emac_driver_data emac_v4_0_0_data = {
 	.num_por = ARRAY_SIZE(emac_v4_0_0_por),
 	.rgmii_config_loopback_en = false,
 	.has_emac_ge_3 = true,
-	.link_clk_name = "phyaux",
 	.needs_sgmii_loopback = true,
 	.dma_addr_width = 36,
 	.dwmac4_addrs = {
@@ -313,8 +316,13 @@ static const struct ethqos_emac_driver_data emac_v4_0_0_data = {
 	},
 };
 
+static const struct ethqos_emac_pm_data emac_sa8775p_pm_data = {
+	.link_clk_name = "phyaux",
+};
+
 static const struct ethqos_emac_match_data emac_sa8775p_data = {
 	.drv_data = &emac_v4_0_0_data,
+	.pm_data = &emac_sa8775p_pm_data,
 };
 
 static int ethqos_dll_configure(struct qcom_ethqos *ethqos)
@@ -771,11 +779,13 @@ static void ethqos_ptp_clk_freq_config(struct stmmac_priv *priv)
 static int qcom_ethqos_probe(struct platform_device *pdev)
 {
 	const struct ethqos_emac_driver_data *drv_data;
+	const struct ethqos_emac_pm_data *pm_data;
 	const struct ethqos_emac_match_data *data;
 	struct plat_stmmacenet_data *plat_dat;
 	struct stmmac_resources stmmac_res;
 	struct device *dev = &pdev->dev;
 	struct qcom_ethqos *ethqos;
+	const char *clk_name;
 	int ret, i;
 
 	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
@@ -823,6 +833,9 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 
 	data = device_get_match_data(dev);
 	drv_data = data->drv_data;
+	pm_data = data->pm_data;
+	clk_name = pm_data && pm_data->link_clk_name ?
+				pm_data->link_clk_name : "rgmii";
 
 	ethqos->por = drv_data->por;
 	ethqos->num_por = drv_data->num_por;
@@ -830,7 +843,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 	ethqos->has_emac_ge_3 = drv_data->has_emac_ge_3;
 	ethqos->needs_sgmii_loopback = drv_data->needs_sgmii_loopback;
 
-	ethqos->link_clk = devm_clk_get(dev, drv_data->link_clk_name ?: "rgmii");
+	ethqos->link_clk = devm_clk_get(dev, clk_name);
 	if (IS_ERR(ethqos->link_clk))
 		return dev_err_probe(dev, PTR_ERR(ethqos->link_clk),
 				     "Failed to get link_clk\n");

-- 
2.51.0



From brgl at bgdev.pl  Fri Nov  7 02:29:56 2025
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 07 Nov 2025 11:29:56 +0100
Subject: [PATCH v5 6/8] net: stmmac: qcom-ethqos: split power management
 context into a separate struct
In-Reply-To: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>
References: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>
Message-ID: <20251107-qcom-sa8255p-emac-v5-6-01d3e3aaf388@linaro.org>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

With match data split into general and power-management sections, let's
now do the same with runtime device data.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 .../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c    | 46 ++++++++++++----------
 1 file changed, 25 insertions(+), 21 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 1f00556bbad997e2ec76b521cffe2eb14fabb79e..09f122062dec87aa11804af2769ddff4964e6596 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -105,17 +105,21 @@ struct ethqos_emac_match_data {
 	const struct ethqos_emac_pm_data *pm_data;
 };
 
+struct ethqos_emac_pm_ctx {
+	struct clk *link_clk;
+	unsigned int link_clk_rate;
+	struct phy *serdes_phy;
+};
+
 struct qcom_ethqos {
 	struct platform_device *pdev;
 	void __iomem *rgmii_base;
 	void __iomem *mac_base;
 	int (*configure_func)(struct qcom_ethqos *ethqos, int speed);
 
-	unsigned int link_clk_rate;
-	struct clk *link_clk;
-	struct phy *serdes_phy;
-	int serdes_speed;
+	struct ethqos_emac_pm_ctx pm;
 	phy_interface_t phy_mode;
+	int serdes_speed;
 
 	const struct ethqos_emac_por *por;
 	unsigned int num_por;
@@ -181,9 +185,9 @@ ethqos_update_link_clk(struct qcom_ethqos *ethqos, int speed)
 
 	rate = rgmii_clock(speed);
 	if (rate > 0)
-		ethqos->link_clk_rate = rate * 2;
+		ethqos->pm.link_clk_rate = rate * 2;
 
-	clk_set_rate(ethqos->link_clk, ethqos->link_clk_rate);
+	clk_set_rate(ethqos->pm.link_clk, ethqos->pm.link_clk_rate);
 }
 
 static void
@@ -639,7 +643,7 @@ static int ethqos_configure_rgmii(struct qcom_ethqos *ethqos, int speed)
 static void ethqos_set_serdes_speed(struct qcom_ethqos *ethqos, int speed)
 {
 	if (ethqos->serdes_speed != speed) {
-		phy_set_speed(ethqos->serdes_phy, speed);
+		phy_set_speed(ethqos->pm.serdes_phy, speed);
 		ethqos->serdes_speed = speed;
 	}
 }
@@ -708,23 +712,23 @@ static int qcom_ethqos_serdes_powerup(struct net_device *ndev, void *priv)
 	struct qcom_ethqos *ethqos = priv;
 	int ret;
 
-	ret = phy_init(ethqos->serdes_phy);
+	ret = phy_init(ethqos->pm.serdes_phy);
 	if (ret)
 		return ret;
 
-	ret = phy_power_on(ethqos->serdes_phy);
+	ret = phy_power_on(ethqos->pm.serdes_phy);
 	if (ret)
 		return ret;
 
-	return phy_set_speed(ethqos->serdes_phy, ethqos->serdes_speed);
+	return phy_set_speed(ethqos->pm.serdes_phy, ethqos->serdes_speed);
 }
 
 static void qcom_ethqos_serdes_powerdown(struct net_device *ndev, void *priv)
 {
 	struct qcom_ethqos *ethqos = priv;
 
-	phy_power_off(ethqos->serdes_phy);
-	phy_exit(ethqos->serdes_phy);
+	phy_power_off(ethqos->pm.serdes_phy);
+	phy_exit(ethqos->pm.serdes_phy);
 }
 
 static int ethqos_clks_config(void *priv, bool enabled)
@@ -733,7 +737,7 @@ static int ethqos_clks_config(void *priv, bool enabled)
 	int ret = 0;
 
 	if (enabled) {
-		ret = clk_prepare_enable(ethqos->link_clk);
+		ret = clk_prepare_enable(ethqos->pm.link_clk);
 		if (ret) {
 			dev_err(&ethqos->pdev->dev, "link_clk enable failed\n");
 			return ret;
@@ -746,7 +750,7 @@ static int ethqos_clks_config(void *priv, bool enabled)
 		 */
 		ethqos_set_func_clk_en(ethqos);
 	} else {
-		clk_disable_unprepare(ethqos->link_clk);
+		clk_disable_unprepare(ethqos->pm.link_clk);
 	}
 
 	return ret;
@@ -843,9 +847,9 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 	ethqos->has_emac_ge_3 = drv_data->has_emac_ge_3;
 	ethqos->needs_sgmii_loopback = drv_data->needs_sgmii_loopback;
 
-	ethqos->link_clk = devm_clk_get(dev, clk_name);
-	if (IS_ERR(ethqos->link_clk))
-		return dev_err_probe(dev, PTR_ERR(ethqos->link_clk),
+	ethqos->pm.link_clk = devm_clk_get(dev, clk_name);
+	if (IS_ERR(ethqos->pm.link_clk))
+		return dev_err_probe(dev, PTR_ERR(ethqos->pm.link_clk),
 				     "Failed to get link_clk\n");
 
 	ret = ethqos_clks_config(ethqos, true);
@@ -856,9 +860,9 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	ethqos->serdes_phy = devm_phy_optional_get(dev, "serdes");
-	if (IS_ERR(ethqos->serdes_phy))
-		return dev_err_probe(dev, PTR_ERR(ethqos->serdes_phy),
+	ethqos->pm.serdes_phy = devm_phy_optional_get(dev, "serdes");
+	if (IS_ERR(ethqos->pm.serdes_phy))
+		return dev_err_probe(dev, PTR_ERR(ethqos->pm.serdes_phy),
 				     "Failed to get serdes phy\n");
 
 	ethqos->serdes_speed = SPEED_1000;
@@ -880,7 +884,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 	if (drv_data->dma_addr_width)
 		plat_dat->host_dma_width = drv_data->dma_addr_width;
 
-	if (ethqos->serdes_phy) {
+	if (ethqos->pm.serdes_phy) {
 		plat_dat->serdes_powerup = qcom_ethqos_serdes_powerup;
 		plat_dat->serdes_powerdown  = qcom_ethqos_serdes_powerdown;
 	}

-- 
2.51.0



From brgl at bgdev.pl  Fri Nov  7 02:29:58 2025
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 07 Nov 2025 11:29:58 +0100
Subject: [PATCH v5 8/8] net: stmmac: qcom-ethqos: add support for sa8255p
In-Reply-To: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>
References: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>
Message-ID: <20251107-qcom-sa8255p-emac-v5-8-01d3e3aaf388@linaro.org>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

Extend the driver to support a new model - sa8255p. Unlike the
previously supported variants, this one's power management is done in
the firmware using SCMI. This is modeled in linux using power domains so
add support for them.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 .../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c    | 230 ++++++++++++++++++---
 1 file changed, 201 insertions(+), 29 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 446f06b591a0b70992c7a431b56cf88c1b6718fd..d2922b4fb4bad1bb8dd77f1feaa7a260b97f0ae8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -7,6 +7,8 @@
 #include <linux/platform_device.h>
 #include <linux/phy.h>
 #include <linux/phy/phy.h>
+#include <linux/pm_opp.h>
+#include <linux/pm_domain.h>
 
 #include "stmmac.h"
 #include "stmmac_platform.h"
@@ -81,6 +83,13 @@
 
 #define SGMII_10M_RX_CLK_DVDR			0x31
 
+enum ethqos_pd_selector {
+	ETHQOS_PD_CORE = 0,
+	ETHQOS_PD_MDIO,
+	ETHQOS_PD_SERDES,
+	ETHQOS_NUM_PDS,
+};
+
 struct ethqos_emac_por {
 	unsigned int offset;
 	unsigned int value;
@@ -98,6 +107,9 @@ struct ethqos_emac_driver_data {
 
 struct ethqos_emac_pm_data {
 	const char *link_clk_name;
+	bool use_domains;
+	struct dev_pm_domain_attach_data pd;
+	unsigned int clk_ptp_rate;
 };
 
 struct ethqos_emac_match_data {
@@ -111,13 +123,20 @@ struct ethqos_emac_pm_ctx {
 	struct phy *serdes_phy;
 };
 
+struct ethqos_emac_pd_ctx {
+	struct dev_pm_domain_list *pd_list;
+};
+
 struct qcom_ethqos {
 	struct platform_device *pdev;
 	void __iomem *rgmii_base;
 	void __iomem *mac_base;
 	int (*configure_func)(struct qcom_ethqos *ethqos, int speed);
 
-	struct ethqos_emac_pm_ctx pm;
+	union {
+		struct ethqos_emac_pm_ctx pm;
+		struct ethqos_emac_pd_ctx pd;
+	};
 	phy_interface_t phy_mode;
 	int serdes_speed;
 	int (*set_serdes_speed)(struct qcom_ethqos *ethqos);
@@ -330,6 +349,25 @@ static const struct ethqos_emac_match_data emac_sa8775p_data = {
 	.pm_data = &emac_sa8775p_pm_data,
 };
 
+static const char * const emac_sa8255p_pd_names[] = {
+	"core", "mdio", "serdes"
+};
+
+static const struct ethqos_emac_pm_data emac_sa8255p_pm_data = {
+	.pd = {
+		.pd_flags = PD_FLAG_NO_DEV_LINK,
+		.pd_names = emac_sa8255p_pd_names,
+		.num_pd_names = ETHQOS_NUM_PDS,
+	},
+	.use_domains = true,
+	.clk_ptp_rate = 230400000,
+};
+
+static const struct ethqos_emac_match_data emac_sa8255p_data = {
+	.drv_data = &emac_v4_0_0_data,
+	.pm_data = &emac_sa8255p_pm_data,
+};
+
 static int ethqos_dll_configure(struct qcom_ethqos *ethqos)
 {
 	struct device *dev = &ethqos->pdev->dev;
@@ -411,6 +449,28 @@ static int ethqos_dll_configure(struct qcom_ethqos *ethqos)
 	return 0;
 }
 
+static int qcom_ethqos_domain_on(struct qcom_ethqos *ethqos,
+				 enum ethqos_pd_selector sel)
+{
+	struct device *dev = ethqos->pd.pd_list->pd_devs[sel];
+	int ret;
+
+	ret = pm_runtime_resume_and_get(dev);
+	if (ret < 0)
+		dev_err(&ethqos->pdev->dev,
+			"Failed to enable the power domain for %s\n",
+			dev_name(dev));
+	return ret;
+}
+
+static void qcom_ethqos_domain_off(struct qcom_ethqos *ethqos,
+				   enum ethqos_pd_selector sel)
+{
+	struct device *dev = ethqos->pd.pd_list->pd_devs[sel];
+
+	pm_runtime_put_sync(dev);
+}
+
 static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos, int speed)
 {
 	struct device *dev = &ethqos->pdev->dev;
@@ -646,6 +706,13 @@ static int ethqos_set_serdes_speed_phy(struct qcom_ethqos *ethqos)
 	return phy_set_speed(ethqos->pm.serdes_phy, ethqos->serdes_speed);
 }
 
+static int ethqos_set_serdes_speed_pd(struct qcom_ethqos *ethqos)
+{
+	struct device *dev = ethqos->pd.pd_list->pd_devs[ETHQOS_PD_SERDES];
+
+	return dev_pm_opp_set_level(dev, ethqos->serdes_speed);
+}
+
 static void ethqos_set_serdes_speed(struct qcom_ethqos *ethqos, int speed)
 {
 	if (ethqos->serdes_speed != speed) {
@@ -737,6 +804,27 @@ static void qcom_ethqos_serdes_powerdown(struct net_device *ndev, void *priv)
 	phy_exit(ethqos->pm.serdes_phy);
 }
 
+static int qcom_ethqos_pd_serdes_powerup(struct net_device *ndev, void *priv)
+{
+	struct qcom_ethqos *ethqos = priv;
+	struct device *dev = ethqos->pd.pd_list->pd_devs[ETHQOS_PD_SERDES];
+	int ret;
+
+	ret = qcom_ethqos_domain_on(ethqos, ETHQOS_PD_SERDES);
+	if (ret < 0)
+		return ret;
+
+	return dev_pm_opp_set_level(dev, ethqos->serdes_speed);
+}
+
+static void qcom_ethqos_pd_serdes_powerdown(struct net_device *ndev, void *priv)
+{
+	struct qcom_ethqos *ethqos = priv;
+
+	/* TODO set level */
+	qcom_ethqos_domain_off(ethqos, ETHQOS_PD_SERDES);
+}
+
 static int ethqos_clks_config(void *priv, bool enabled)
 {
 	struct qcom_ethqos *ethqos = priv;
@@ -769,6 +857,61 @@ static void ethqos_clks_disable(void *data)
 	ethqos_clks_config(ethqos, false);
 }
 
+static int ethqos_pd_clks_config(void *priv, bool enabled)
+{
+	struct qcom_ethqos *ethqos = priv;
+	int ret = 0;
+
+	if (enabled) {
+		ret = qcom_ethqos_domain_on(ethqos, ETHQOS_PD_MDIO);
+		if (ret < 0) {
+			dev_err(&ethqos->pdev->dev,
+				"Failed to enable the MDIO power domain\n");
+			return ret;
+		}
+
+		ethqos_set_func_clk_en(ethqos);
+	} else {
+		qcom_ethqos_domain_off(ethqos, ETHQOS_PD_MDIO);
+	}
+
+	return ret;
+}
+
+static int qcom_ethqos_pd_init(struct platform_device *pdev, void *priv)
+{
+	struct qcom_ethqos *ethqos = priv;
+	int ret;
+
+	/*
+	 * Enable functional clock to prevent DMA reset after timeout due
+	 * to no PHY clock being enabled after the hardware block has been
+	 * power cycled. The actual configuration will be adjusted once
+	 * ethqos_fix_mac_speed() is called.
+	 */
+	ethqos_set_func_clk_en(ethqos);
+
+	ret = qcom_ethqos_domain_on(ethqos, ETHQOS_PD_CORE);
+	if (ret)
+		return ret;
+
+	ret = qcom_ethqos_domain_on(ethqos, ETHQOS_PD_MDIO);
+	if (ret) {
+		qcom_ethqos_domain_off(ethqos, ETHQOS_PD_CORE);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void qcom_ethqos_pd_exit(struct platform_device *pdev, void *data)
+{
+	struct qcom_ethqos *ethqos = data;
+
+	qcom_ethqos_domain_off(ethqos, ETHQOS_PD_MDIO);
+	qcom_ethqos_domain_off(ethqos, ETHQOS_PD_CORE);
+}
+
 static void ethqos_ptp_clk_freq_config(struct stmmac_priv *priv)
 {
 	struct plat_stmmacenet_data *plat_dat = priv->plat;
@@ -809,8 +952,6 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 				     "dt configuration failed\n");
 	}
 
-	plat_dat->clks_config = ethqos_clks_config;
-
 	ethqos = devm_kzalloc(dev, sizeof(*ethqos), GFP_KERNEL);
 	if (!ethqos)
 		return -ENOMEM;
@@ -852,28 +993,63 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 	ethqos->rgmii_config_loopback_en = drv_data->rgmii_config_loopback_en;
 	ethqos->has_emac_ge_3 = drv_data->has_emac_ge_3;
 	ethqos->needs_sgmii_loopback = drv_data->needs_sgmii_loopback;
-
-	ethqos->pm.link_clk = devm_clk_get(dev, clk_name);
-	if (IS_ERR(ethqos->pm.link_clk))
-		return dev_err_probe(dev, PTR_ERR(ethqos->pm.link_clk),
-				     "Failed to get link_clk\n");
-
-	ret = ethqos_clks_config(ethqos, true);
-	if (ret)
-		return ret;
-
-	ret = devm_add_action_or_reset(dev, ethqos_clks_disable, ethqos);
-	if (ret)
-		return ret;
-
-	ethqos->pm.serdes_phy = devm_phy_optional_get(dev, "serdes");
-	if (IS_ERR(ethqos->pm.serdes_phy))
-		return dev_err_probe(dev, PTR_ERR(ethqos->pm.serdes_phy),
-				     "Failed to get serdes phy\n");
-
-	ethqos->set_serdes_speed = ethqos_set_serdes_speed_phy;
 	ethqos->serdes_speed = SPEED_1000;
-	ethqos_update_link_clk(ethqos, SPEED_1000);
+
+	if (pm_data && pm_data->use_domains) {
+		ethqos->set_serdes_speed = ethqos_set_serdes_speed_pd;
+
+		ret = devm_pm_domain_attach_list(dev, &pm_data->pd,
+						 &ethqos->pd.pd_list);
+		if (ret < 0)
+			return dev_err_probe(dev, ret, "Failed to attach power domains\n");
+
+		plat_dat->clks_config = ethqos_pd_clks_config;
+		plat_dat->serdes_powerup = qcom_ethqos_pd_serdes_powerup;
+		plat_dat->serdes_powerdown = qcom_ethqos_pd_serdes_powerdown;
+		plat_dat->exit = qcom_ethqos_pd_exit;
+		plat_dat->init = qcom_ethqos_pd_init;
+		plat_dat->clk_ptp_rate = pm_data->clk_ptp_rate;
+
+		ret = qcom_ethqos_pd_init(pdev, ethqos);
+		if (ret)
+			return ret;
+
+		ret = qcom_ethqos_domain_on(ethqos, ETHQOS_PD_SERDES);
+		if (ret)
+			return dev_err_probe(dev, ret,
+					     "Failed to enable the serdes power domain\n");
+	} else {
+		ethqos->set_serdes_speed = ethqos_set_serdes_speed_phy;
+
+		ethqos->pm.link_clk = devm_clk_get(dev, clk_name);
+		if (IS_ERR(ethqos->pm.link_clk))
+			return dev_err_probe(dev, PTR_ERR(ethqos->pm.link_clk),
+					     "Failed to get link_clk\n");
+
+		ret = ethqos_clks_config(ethqos, true);
+		if (ret)
+			return ret;
+
+		ret = devm_add_action_or_reset(dev, ethqos_clks_disable, ethqos);
+		if (ret)
+			return ret;
+
+		ethqos->pm.serdes_phy = devm_phy_optional_get(dev, "serdes");
+		if (IS_ERR(ethqos->pm.serdes_phy))
+			return dev_err_probe(dev, PTR_ERR(ethqos->pm.serdes_phy),
+					     "Failed to get serdes phy\n");
+
+		ethqos_update_link_clk(ethqos, SPEED_1000);
+
+		plat_dat->clks_config = ethqos_clks_config;
+		plat_dat->ptp_clk_freq_config = ethqos_ptp_clk_freq_config;
+
+		if (ethqos->pm.serdes_phy) {
+			plat_dat->serdes_powerup = qcom_ethqos_serdes_powerup;
+			plat_dat->serdes_powerdown  = qcom_ethqos_serdes_powerdown;
+		}
+	}
+
 	ethqos_set_func_clk_en(ethqos);
 
 	plat_dat->bsp_priv = ethqos;
@@ -891,11 +1067,6 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 	if (drv_data->dma_addr_width)
 		plat_dat->host_dma_width = drv_data->dma_addr_width;
 
-	if (ethqos->pm.serdes_phy) {
-		plat_dat->serdes_powerup = qcom_ethqos_serdes_powerup;
-		plat_dat->serdes_powerdown  = qcom_ethqos_serdes_powerdown;
-	}
-
 	/* Enable TSO on queue0 and enable TBS on rest of the queues */
 	for (i = 1; i < plat_dat->tx_queues_to_use; i++)
 		plat_dat->tx_queues_cfg[i].tbs_en = 1;
@@ -905,6 +1076,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 
 static const struct of_device_id qcom_ethqos_match[] = {
 	{ .compatible = "qcom,qcs404-ethqos", .data = &emac_qcs404_data},
+	{ .compatible = "qcom,sa8255p-ethqos", .data = &emac_sa8255p_data},
 	{ .compatible = "qcom,sa8775p-ethqos", .data = &emac_sa8775p_data},
 	{ .compatible = "qcom,sc8280xp-ethqos", .data = &emac_sc8280xp_data},
 	{ .compatible = "qcom,sm8150-ethqos", .data = &emac_sm8150_data},

-- 
2.51.0



From brgl at bgdev.pl  Fri Nov  7 02:29:52 2025
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 07 Nov 2025 11:29:52 +0100
Subject: [PATCH v5 2/8] net: stmmac: qcom-ethqos: use generic device
 properties
In-Reply-To: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>
References: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>
Message-ID: <20251107-qcom-sa8255p-emac-v5-2-01d3e3aaf388@linaro.org>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

In order to drop the dependency on CONFIG_OF, convert all device property
getters from OF-specific to generic device properties and stop pulling
in any linux/of.h symbols.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 drivers/net/ethernet/stmicro/stmmac/Kconfig             | 2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 9 ++++-----
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
index 87c5bea6c2a243f3be998b2c3935bc1dc23bfe22..22d0eaab35eaffac0bca58f8625ecc5c955b6631 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -135,7 +135,7 @@ config DWMAC_MESON
 config DWMAC_QCOM_ETHQOS
 	tristate "Qualcomm ETHQOS support"
 	default ARCH_QCOM
-	depends on OF && (ARCH_QCOM || COMPILE_TEST)
+	depends on ARCH_QCOM || COMPILE_TEST
 	help
 	  Support for the Qualcomm ETHQOS core.
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 1a616a71c36ace29a74a0aa23fc8173443aa49a5..8578a2df8cf0d1d8808bcf7e7b57c93eb14c87db 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -1,8 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0
 // Copyright (c) 2018-19, Linaro Limited
 
+#include <linux/mod_devicetable.h>
 #include <linux/module.h>
-#include <linux/of.h>
 #include <linux/of_net.h>
 #include <linux/platform_device.h>
 #include <linux/phy.h>
@@ -748,7 +748,6 @@ static void ethqos_ptp_clk_freq_config(struct stmmac_priv *priv)
 
 static int qcom_ethqos_probe(struct platform_device *pdev)
 {
-	struct device_node *np = pdev->dev.of_node;
 	const struct ethqos_emac_driver_data *data;
 	struct plat_stmmacenet_data *plat_dat;
 	struct stmmac_resources stmmac_res;
@@ -799,7 +798,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 
 	ethqos->mac_base = stmmac_res.addr;
 
-	data = of_device_get_match_data(dev);
+	data = device_get_match_data(dev);
 	ethqos->por = data->por;
 	ethqos->num_por = data->num_por;
 	ethqos->rgmii_config_loopback_en = data->rgmii_config_loopback_en;
@@ -836,9 +835,9 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 	if (ethqos->has_emac_ge_3)
 		plat_dat->dwmac4_addrs = &data->dwmac4_addrs;
 	plat_dat->pmt = 1;
-	if (of_property_read_bool(np, "snps,tso"))
+	if (device_property_present(dev, "snps,tso"))
 		plat_dat->flags |= STMMAC_FLAG_TSO_EN;
-	if (of_device_is_compatible(np, "qcom,qcs404-ethqos"))
+	if (device_is_compatible(dev, "qcom,qcs404-ethqos"))
 		plat_dat->flags |= STMMAC_FLAG_RX_CLK_RUNS_IN_LPI;
 	if (data->dma_addr_width)
 		plat_dat->host_dma_width = data->dma_addr_width;

-- 
2.51.0



From brgl at bgdev.pl  Fri Nov  7 02:29:53 2025
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 07 Nov 2025 11:29:53 +0100
Subject: [PATCH v5 3/8] net: stmmac: qcom-ethqos: improve typing in devres
 callback
In-Reply-To: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>
References: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>
Message-ID: <20251107-qcom-sa8255p-emac-v5-3-01d3e3aaf388@linaro.org>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

It's bad practice to just directly pass void pointers to functions which
expect concrete types. Make it more clear what type ethqos_clks_config()
expects.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 8578a2df8cf0d1d8808bcf7e7b57c93eb14c87db..8493131ca32f5c6ca7e1654da0bbf4ffa1eefa4e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -726,7 +726,9 @@ static int ethqos_clks_config(void *priv, bool enabled)
 
 static void ethqos_clks_disable(void *data)
 {
-	ethqos_clks_config(data, false);
+	struct qcom_ethqos *ethqos = data;
+
+	ethqos_clks_config(ethqos, false);
 }
 
 static void ethqos_ptp_clk_freq_config(struct stmmac_priv *priv)

-- 
2.51.0



From brgl at bgdev.pl  Fri Nov  7 02:29:57 2025
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 07 Nov 2025 11:29:57 +0100
Subject: [PATCH v5 7/8] net: stmmac: qcom-ethqos: define a callback for
 setting the serdes speed
In-Reply-To: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>
References: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>
Message-ID: <20251107-qcom-sa8255p-emac-v5-7-01d3e3aaf388@linaro.org>

From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

Ahead of adding support for firmware driven power management, let's
allow different ways of setting the PHY speed. To that end create a
callback with a single implementation for now, that will be extended
later.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
index 09f122062dec87aa11804af2769ddff4964e6596..446f06b591a0b70992c7a431b56cf88c1b6718fd 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -120,6 +120,7 @@ struct qcom_ethqos {
 	struct ethqos_emac_pm_ctx pm;
 	phy_interface_t phy_mode;
 	int serdes_speed;
+	int (*set_serdes_speed)(struct qcom_ethqos *ethqos);
 
 	const struct ethqos_emac_por *por;
 	unsigned int num_por;
@@ -640,11 +641,16 @@ static int ethqos_configure_rgmii(struct qcom_ethqos *ethqos, int speed)
 	return 0;
 }
 
+static int ethqos_set_serdes_speed_phy(struct qcom_ethqos *ethqos)
+{
+	return phy_set_speed(ethqos->pm.serdes_phy, ethqos->serdes_speed);
+}
+
 static void ethqos_set_serdes_speed(struct qcom_ethqos *ethqos, int speed)
 {
 	if (ethqos->serdes_speed != speed) {
-		phy_set_speed(ethqos->pm.serdes_phy, speed);
 		ethqos->serdes_speed = speed;
+		ethqos->set_serdes_speed(ethqos);
 	}
 }
 
@@ -865,6 +871,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
 		return dev_err_probe(dev, PTR_ERR(ethqos->pm.serdes_phy),
 				     "Failed to get serdes phy\n");
 
+	ethqos->set_serdes_speed = ethqos_set_serdes_speed_phy;
 	ethqos->serdes_speed = SPEED_1000;
 	ethqos_update_link_clk(ethqos, SPEED_1000);
 	ethqos_set_func_clk_en(ethqos);

-- 
2.51.0



From konrad.dybcio at oss.qualcomm.com  Fri Nov  7 02:49:48 2025
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Fri, 7 Nov 2025 11:49:48 +0100
Subject: [PATCH v5 2/8] net: stmmac: qcom-ethqos: use generic device
 properties
In-Reply-To: <20251107-qcom-sa8255p-emac-v5-2-01d3e3aaf388@linaro.org>
References: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>
 <20251107-qcom-sa8255p-emac-v5-2-01d3e3aaf388@linaro.org>
Message-ID: <21a3d269-76e6-4da9-aa25-bfd1fb6dfb07@oss.qualcomm.com>

On 11/7/25 11:29 AM, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> 
> In order to drop the dependency on CONFIG_OF, convert all device property
> getters from OF-specific to generic device properties and stop pulling
> in any linux/of.h symbols.
> 
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> ---

[...]

> -	if (of_property_read_bool(np, "snps,tso"))
> +	if (device_property_present(dev, "snps,tso"))

This is a change in behavior - "snps,tso = <0>" would have previously
returned false, it now returns true

although it seems like it's the plat driver clunkily working around
not including the common compatible and inlining parts of the common
probe functions..

Konrad



From konrad.dybcio at oss.qualcomm.com  Fri Nov  7 02:50:29 2025
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Fri, 7 Nov 2025 11:50:29 +0100
Subject: [PATCH v5 3/8] net: stmmac: qcom-ethqos: improve typing in devres
 callback
In-Reply-To: <20251107-qcom-sa8255p-emac-v5-3-01d3e3aaf388@linaro.org>
References: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>
 <20251107-qcom-sa8255p-emac-v5-3-01d3e3aaf388@linaro.org>
Message-ID: <9805b902-95bb-4b18-b65f-f6efdfb6807a@oss.qualcomm.com>

On 11/7/25 11:29 AM, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> 
> It's bad practice to just directly pass void pointers to functions which
> expect concrete types. Make it more clear what type ethqos_clks_config()
> expects.
> 
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> ---
>  drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
> index 8578a2df8cf0d1d8808bcf7e7b57c93eb14c87db..8493131ca32f5c6ca7e1654da0bbf4ffa1eefa4e 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
> @@ -726,7 +726,9 @@ static int ethqos_clks_config(void *priv, bool enabled)
>  
>  static void ethqos_clks_disable(void *data)
>  {
> -	ethqos_clks_config(data, false);
> +	struct qcom_ethqos *ethqos = data;
> +
> +	ethqos_clks_config(ethqos, false);

ethqos_clks_config() takes a voidptr too

Konrad


From konrad.dybcio at oss.qualcomm.com  Fri Nov  7 02:54:33 2025
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Fri, 7 Nov 2025 11:54:33 +0100
Subject: [PATCH v5 4/8] net: stmmac: qcom-ethqos: wrap emac driver data in
 additional structure
In-Reply-To: <20251107-qcom-sa8255p-emac-v5-4-01d3e3aaf388@linaro.org>
References: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>
 <20251107-qcom-sa8255p-emac-v5-4-01d3e3aaf388@linaro.org>
Message-ID: <86df9697-af58-4486-93de-b01df5ba13a6@oss.qualcomm.com>

On 11/7/25 11:29 AM, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> 
> As the first step in enabling power domain support in the driver, we'll
> split the device match data and runtime data structures into their
> general and power-management-specific parts. To allow that: first wrap
> the emac driver data in another layer which will later be expanded.
> 
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> ---

[...]

>  static int qcom_ethqos_probe(struct platform_device *pdev)
>  {
> -	const struct ethqos_emac_driver_data *data;
> +	const struct ethqos_emac_driver_data *drv_data;
> +	const struct ethqos_emac_match_data *data;>  	struct plat_stmmacenet_data *plat_dat;
>  	struct stmmac_resources stmmac_res;
>  	struct device *dev = &pdev->dev;
> @@ -801,13 +822,15 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
>  	ethqos->mac_base = stmmac_res.addr;
>  
>  	data = device_get_match_data(dev);

This change could be made much smaller if you kept a drv_data
pointer named 'data' and called the new one match_data

but I don't really care either way

Reviewed-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>

Konrad


From konrad.dybcio at oss.qualcomm.com  Fri Nov  7 03:00:12 2025
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Fri, 7 Nov 2025 12:00:12 +0100
Subject: [PATCH v5 6/8] net: stmmac: qcom-ethqos: split power management
 context into a separate struct
In-Reply-To: <20251107-qcom-sa8255p-emac-v5-6-01d3e3aaf388@linaro.org>
References: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>
 <20251107-qcom-sa8255p-emac-v5-6-01d3e3aaf388@linaro.org>
Message-ID: <14f95efb-0eb0-48ee-9132-df35abddfcc7@oss.qualcomm.com>

On 11/7/25 11:29 AM, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> 
> With match data split into general and power-management sections, let's
> now do the same with runtime device data.
> 
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> ---
>  .../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c    | 46 ++++++++++++----------
>  1 file changed, 25 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
> index 1f00556bbad997e2ec76b521cffe2eb14fabb79e..09f122062dec87aa11804af2769ddff4964e6596 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
> @@ -105,17 +105,21 @@ struct ethqos_emac_match_data {
>  	const struct ethqos_emac_pm_data *pm_data;
>  };
>  
> +struct ethqos_emac_pm_ctx {
> +	struct clk *link_clk;
> +	unsigned int link_clk_rate;
> +	struct phy *serdes_phy;

What is the benefit of doing this? PHY APIs happily consume a nullptr
and NOP out, and the PHY is already retrieved with _optional(),
similarly with clk

Konrad


From konrad.dybcio at oss.qualcomm.com  Fri Nov  7 03:10:02 2025
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Fri, 7 Nov 2025 12:10:02 +0100
Subject: [PATCH v5 8/8] net: stmmac: qcom-ethqos: add support for sa8255p
In-Reply-To: <20251107-qcom-sa8255p-emac-v5-8-01d3e3aaf388@linaro.org>
References: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>
 <20251107-qcom-sa8255p-emac-v5-8-01d3e3aaf388@linaro.org>
Message-ID: <5fea976c-a047-43a4-a062-fee1d40447b4@oss.qualcomm.com>

On 11/7/25 11:29 AM, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> 
> Extend the driver to support a new model - sa8255p. Unlike the
> previously supported variants, this one's power management is done in
> the firmware using SCMI. This is modeled in linux using power domains so
> add support for them.
> 
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> ---

[...]
> +static void qcom_ethqos_pd_serdes_powerdown(struct net_device *ndev, void *priv)
> +{
> +	struct qcom_ethqos *ethqos = priv;
> +
> +	/* TODO set level */
> +	qcom_ethqos_domain_off(ethqos, ETHQOS_PD_SERDES);

dev_pm_opp_set_level(dev, 0);?

perhaps with _index?

Konrad


From robh at kernel.org  Fri Nov  7 03:22:18 2025
From: robh at kernel.org (Rob Herring (Arm))
Date: Fri, 07 Nov 2025 05:22:18 -0600
Subject: [PATCH v5 1/8] dt-bindings: net: qcom: document the ethqos
 device for SCMI-based systems
In-Reply-To: <20251107-qcom-sa8255p-emac-v5-1-01d3e3aaf388@linaro.org>
References: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>
 <20251107-qcom-sa8255p-emac-v5-1-01d3e3aaf388@linaro.org>
Message-ID: <176251453854.1709481.17350672291824662534.robh@kernel.org>


On Fri, 07 Nov 2025 11:29:51 +0100, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> 
> Describe the firmware-managed variant of the QCom DesignWare MAC. As the
> properties here differ a lot from the HLOS-managed variant, lets put it
> in a separate file. Since we need to update the maximum number of power
> domains, let's update existing bindings referencing the top-level
> snps,dwmac.yaml and limit their maxItems for power-domains to 1.
> 
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> ---
>  .../bindings/net/allwinner,sun7i-a20-gmac.yaml     |  3 +
>  .../bindings/net/altr,socfpga-stmmac.yaml          |  3 +
>  .../bindings/net/amlogic,meson-dwmac.yaml          |  3 +
>  .../devicetree/bindings/net/eswin,eic7700-eth.yaml |  3 +
>  .../devicetree/bindings/net/intel,dwmac-plat.yaml  |  3 +
>  .../bindings/net/loongson,ls1b-gmac.yaml           |  3 +
>  .../bindings/net/loongson,ls1c-emac.yaml           |  3 +
>  .../devicetree/bindings/net/nxp,dwmac-imx.yaml     |  3 +
>  .../devicetree/bindings/net/nxp,lpc1850-dwmac.yaml |  3 +
>  .../devicetree/bindings/net/nxp,s32-dwmac.yaml     |  3 +
>  .../devicetree/bindings/net/qcom,ethqos.yaml       |  3 +
>  .../bindings/net/qcom,sa8255p-ethqos.yaml          | 98 ++++++++++++++++++++++
>  .../devicetree/bindings/net/renesas,rzn1-gmac.yaml |  3 +
>  .../bindings/net/renesas,rzv2h-gbeth.yaml          |  3 +
>  .../devicetree/bindings/net/rockchip-dwmac.yaml    |  3 +
>  .../devicetree/bindings/net/snps,dwmac.yaml        |  5 +-
>  .../bindings/net/sophgo,cv1800b-dwmac.yaml         |  3 +
>  .../bindings/net/sophgo,sg2044-dwmac.yaml          |  3 +
>  .../bindings/net/starfive,jh7110-dwmac.yaml        |  3 +
>  .../devicetree/bindings/net/stm32-dwmac.yaml       |  3 +
>  .../devicetree/bindings/net/tesla,fsd-ethqos.yaml  |  3 +
>  .../devicetree/bindings/net/thead,th1520-gmac.yaml |  3 +
>  .../bindings/net/toshiba,visconti-dwmac.yaml       |  3 +
>  MAINTAINERS                                        |  1 +
>  24 files changed, 166 insertions(+), 1 deletion(-)
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/net/qcom,sa8255p-ethqos.yaml: $id: Cannot determine base path from $id, relative path/filename doesn't match actual path or filename
 	 $id: http://devicetree.org/schemas/net/qcom,ethqos-scmi.yaml
 	file: /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/net/qcom,sa8255p-ethqos.yaml

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20251107-qcom-sa8255p-emac-v5-1-01d3e3aaf388 at linaro.org

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.



From horms at kernel.org  Tue Nov 11 03:47:53 2025
From: horms at kernel.org (Simon Horman)
Date: Tue, 11 Nov 2025 11:47:53 +0000
Subject: [PATCH v5 8/8] net: stmmac: qcom-ethqos: add support for sa8255p
In-Reply-To: <20251107-qcom-sa8255p-emac-v5-8-01d3e3aaf388@linaro.org>
References: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>
 <20251107-qcom-sa8255p-emac-v5-8-01d3e3aaf388@linaro.org>
Message-ID: <aRMiafCQNPVDOljU@horms.kernel.org>

On Fri, Nov 07, 2025 at 11:29:58AM +0100, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>

...

> +static int qcom_ethqos_pd_init(struct platform_device *pdev, void *priv)
> +{
> +	struct qcom_ethqos *ethqos = priv;
> +	int ret;
> +
> +	/*
> +	 * Enable functional clock to prevent DMA reset after timeout due
> +	 * to no PHY clock being enabled after the hardware block has been
> +	 * power cycled. The actual configuration will be adjusted once
> +	 * ethqos_fix_mac_speed() is called.
> +	 */
> +	ethqos_set_func_clk_en(ethqos);
> +
> +	ret = qcom_ethqos_domain_on(ethqos, ETHQOS_PD_CORE);
> +	if (ret)
> +		return ret;
> +
> +	ret = qcom_ethqos_domain_on(ethqos, ETHQOS_PD_MDIO);
> +	if (ret) {
> +		qcom_ethqos_domain_off(ethqos, ETHQOS_PD_CORE);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static void qcom_ethqos_pd_exit(struct platform_device *pdev, void *data)
> +{
> +	struct qcom_ethqos *ethqos = data;
> +
> +	qcom_ethqos_domain_off(ethqos, ETHQOS_PD_MDIO);
> +	qcom_ethqos_domain_off(ethqos, ETHQOS_PD_CORE);
> +}
> +
>  static void ethqos_ptp_clk_freq_config(struct stmmac_priv *priv)
>  {
>  	struct plat_stmmacenet_data *plat_dat = priv->plat;

...

> @@ -852,28 +993,63 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
>  	ethqos->rgmii_config_loopback_en = drv_data->rgmii_config_loopback_en;
>  	ethqos->has_emac_ge_3 = drv_data->has_emac_ge_3;
>  	ethqos->needs_sgmii_loopback = drv_data->needs_sgmii_loopback;
> -
> -	ethqos->pm.link_clk = devm_clk_get(dev, clk_name);
> -	if (IS_ERR(ethqos->pm.link_clk))
> -		return dev_err_probe(dev, PTR_ERR(ethqos->pm.link_clk),
> -				     "Failed to get link_clk\n");
> -
> -	ret = ethqos_clks_config(ethqos, true);
> -	if (ret)
> -		return ret;
> -
> -	ret = devm_add_action_or_reset(dev, ethqos_clks_disable, ethqos);
> -	if (ret)
> -		return ret;
> -
> -	ethqos->pm.serdes_phy = devm_phy_optional_get(dev, "serdes");
> -	if (IS_ERR(ethqos->pm.serdes_phy))
> -		return dev_err_probe(dev, PTR_ERR(ethqos->pm.serdes_phy),
> -				     "Failed to get serdes phy\n");
> -
> -	ethqos->set_serdes_speed = ethqos_set_serdes_speed_phy;
>  	ethqos->serdes_speed = SPEED_1000;
> -	ethqos_update_link_clk(ethqos, SPEED_1000);
> +
> +	if (pm_data && pm_data->use_domains) {
> +		ethqos->set_serdes_speed = ethqos_set_serdes_speed_pd;
> +
> +		ret = devm_pm_domain_attach_list(dev, &pm_data->pd,
> +						 &ethqos->pd.pd_list);
> +		if (ret < 0)
> +			return dev_err_probe(dev, ret, "Failed to attach power domains\n");
> +
> +		plat_dat->clks_config = ethqos_pd_clks_config;
> +		plat_dat->serdes_powerup = qcom_ethqos_pd_serdes_powerup;
> +		plat_dat->serdes_powerdown = qcom_ethqos_pd_serdes_powerdown;
> +		plat_dat->exit = qcom_ethqos_pd_exit;

Hi Bartosz,

It seems that the intention of this is to ensure
that domains turned on by qcom_ethqos_pd_init()
are turned off again on exit or clean-up in error paths.

> +		plat_dat->init = qcom_ethqos_pd_init;
> +		plat_dat->clk_ptp_rate = pm_data->clk_ptp_rate;
> +
> +		ret = qcom_ethqos_pd_init(pdev, ethqos);
> +		if (ret)
> +			return ret;

And here those domains are turned on.

> +
> +		ret = qcom_ethqos_domain_on(ethqos, ETHQOS_PD_SERDES);
> +		if (ret)

But it seems that if we reach this error path then the cleanup is not
performed. This is because plat_dat and thus it's exit callback are
registered until the call to devm_stmmac_pltfr_probe() towards the end of
this function.

Sorry if I'm on the wrong track here. I did dig into it.
But this was flagged by Claude Code running
https://github.com/masoncl/review-prompts/

> +			return dev_err_probe(dev, ret,
> +					     "Failed to enable the serdes power domain\n");

...


From brgl at bgdev.pl  Thu Nov 13 05:18:48 2025
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Thu, 13 Nov 2025 14:18:48 +0100
Subject: [PATCH v5 2/8] net: stmmac: qcom-ethqos: use generic device properties
In-Reply-To: <21a3d269-76e6-4da9-aa25-bfd1fb6dfb07@oss.qualcomm.com>
References: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>
 <20251107-qcom-sa8255p-emac-v5-2-01d3e3aaf388@linaro.org> <21a3d269-76e6-4da9-aa25-bfd1fb6dfb07@oss.qualcomm.com>
Message-ID: <CAMRc=MexMn_GSC2EtMek5hDRLjGYA5HKM8ge9vrxw1pYDqPJgw@mail.gmail.com>

On Fri, Nov 7, 2025 at 11:49?AM Konrad Dybcio
<konrad.dybcio at oss.qualcomm.com> wrote:
>
> On 11/7/25 11:29 AM, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> >
> > In order to drop the dependency on CONFIG_OF, convert all device property
> > getters from OF-specific to generic device properties and stop pulling
> > in any linux/of.h symbols.
> >
> > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> > ---
>
> [...]
>
> > -     if (of_property_read_bool(np, "snps,tso"))
> > +     if (device_property_present(dev, "snps,tso"))
>
> This is a change in behavior - "snps,tso = <0>" would have previously
> returned false, it now returns true
>

This property is a boolean flag, it cannot have a value.

Bartosz

> although it seems like it's the plat driver clunkily working around
> not including the common compatible and inlining parts of the common
> probe functions..
>
> Konrad
>


From brgl at bgdev.pl  Thu Nov 13 05:31:22 2025
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Thu, 13 Nov 2025 14:31:22 +0100
Subject: [PATCH v5 3/8] net: stmmac: qcom-ethqos: improve typing in devres callback
In-Reply-To: <9805b902-95bb-4b18-b65f-f6efdfb6807a@oss.qualcomm.com>
References: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>
 <20251107-qcom-sa8255p-emac-v5-3-01d3e3aaf388@linaro.org> <9805b902-95bb-4b18-b65f-f6efdfb6807a@oss.qualcomm.com>
Message-ID: <CAMRc=MdWu5x5bgh4CfPsowJnF0Qh1W770KTDtTFMkGkQf4_LKg@mail.gmail.com>

On Fri, Nov 7, 2025 at 11:50?AM Konrad Dybcio
<konrad.dybcio at oss.qualcomm.com> wrote:
>
> On 11/7/25 11:29 AM, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> >
> > It's bad practice to just directly pass void pointers to functions which
> > expect concrete types. Make it more clear what type ethqos_clks_config()
> > expects.
> >
> > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> > ---
> >  drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 4 +++-
> >  1 file changed, 3 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
> > index 8578a2df8cf0d1d8808bcf7e7b57c93eb14c87db..8493131ca32f5c6ca7e1654da0bbf4ffa1eefa4e 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
> > +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
> > @@ -726,7 +726,9 @@ static int ethqos_clks_config(void *priv, bool enabled)
> >
> >  static void ethqos_clks_disable(void *data)
> >  {
> > -     ethqos_clks_config(data, false);
> > +     struct qcom_ethqos *ethqos = data;
> > +
> > +     ethqos_clks_config(ethqos, false);
>
> ethqos_clks_config() takes a voidptr too
>
> Konrad

Right. I think I had something in mind when I wrote it but I'm not
sure what anymore. Best drop this.

Bart


From konrad.dybcio at oss.qualcomm.com  Thu Nov 13 05:32:53 2025
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Thu, 13 Nov 2025 14:32:53 +0100
Subject: [PATCH v5 2/8] net: stmmac: qcom-ethqos: use generic device
 properties
In-Reply-To: <CAMRc=MexMn_GSC2EtMek5hDRLjGYA5HKM8ge9vrxw1pYDqPJgw@mail.gmail.com>
References: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>
 <20251107-qcom-sa8255p-emac-v5-2-01d3e3aaf388@linaro.org>
 <21a3d269-76e6-4da9-aa25-bfd1fb6dfb07@oss.qualcomm.com>
 <CAMRc=MexMn_GSC2EtMek5hDRLjGYA5HKM8ge9vrxw1pYDqPJgw@mail.gmail.com>
Message-ID: <cd7c0490-a2d6-4885-aa36-ee1492f107b8@oss.qualcomm.com>

On 11/13/25 2:18 PM, Bartosz Golaszewski wrote:
> On Fri, Nov 7, 2025 at 11:49?AM Konrad Dybcio
> <konrad.dybcio at oss.qualcomm.com> wrote:
>>
>> On 11/7/25 11:29 AM, Bartosz Golaszewski wrote:
>>> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
>>>
>>> In order to drop the dependency on CONFIG_OF, convert all device property
>>> getters from OF-specific to generic device properties and stop pulling
>>> in any linux/of.h symbols.
>>>
>>> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
>>> ---
>>
>> [...]
>>
>>> -     if (of_property_read_bool(np, "snps,tso"))
>>> +     if (device_property_present(dev, "snps,tso"))
>>
>> This is a change in behavior - "snps,tso = <0>" would have previously
>> returned false, it now returns true
>>
> 
> This property is a boolean flag, it cannot have a value.

Every DT property may have a value, so this is not as obvious as we'd
like it to be (IIUC - unless that changed recently)

Konrad


From brgl at bgdev.pl  Thu Nov 13 05:33:48 2025
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Thu, 13 Nov 2025 14:33:48 +0100
Subject: [PATCH v5 4/8] net: stmmac: qcom-ethqos: wrap emac driver data in
 additional structure
In-Reply-To: <86df9697-af58-4486-93de-b01df5ba13a6@oss.qualcomm.com>
References: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>
 <20251107-qcom-sa8255p-emac-v5-4-01d3e3aaf388@linaro.org> <86df9697-af58-4486-93de-b01df5ba13a6@oss.qualcomm.com>
Message-ID: <CAMRc=MfMQ3P-BK239953S9sTAe1_qSc_miWEFDNu83frE3aSqA@mail.gmail.com>

On Fri, Nov 7, 2025 at 11:54?AM Konrad Dybcio
<konrad.dybcio at oss.qualcomm.com> wrote:
>
> On 11/7/25 11:29 AM, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> >
> > As the first step in enabling power domain support in the driver, we'll
> > split the device match data and runtime data structures into their
> > general and power-management-specific parts. To allow that: first wrap
> > the emac driver data in another layer which will later be expanded.
> >
> > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> > ---
>
> [...]
>
> >  static int qcom_ethqos_probe(struct platform_device *pdev)
> >  {
> > -     const struct ethqos_emac_driver_data *data;
> > +     const struct ethqos_emac_driver_data *drv_data;
> > +     const struct ethqos_emac_match_data *data;>     struct plat_stmmacenet_data *plat_dat;
> >       struct stmmac_resources stmmac_res;
> >       struct device *dev = &pdev->dev;
> > @@ -801,13 +822,15 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
> >       ethqos->mac_base = stmmac_res.addr;
> >
> >       data = device_get_match_data(dev);
>
> This change could be made much smaller if you kept a drv_data
> pointer named 'data' and called the new one match_data
>

I prefer to make a clear distinction between the two.

Bart

> but I don't really care either way
>
> Reviewed-by: Konrad Dybcio <konrad.dybcio at oss.qualcomm.com>
>
> Konrad


From brgl at bgdev.pl  Thu Nov 13 05:41:44 2025
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Thu, 13 Nov 2025 14:41:44 +0100
Subject: [PATCH v5 2/8] net: stmmac: qcom-ethqos: use generic device properties
In-Reply-To: <cd7c0490-a2d6-4885-aa36-ee1492f107b8@oss.qualcomm.com>
References: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>
 <20251107-qcom-sa8255p-emac-v5-2-01d3e3aaf388@linaro.org> <21a3d269-76e6-4da9-aa25-bfd1fb6dfb07@oss.qualcomm.com>
 <CAMRc=MexMn_GSC2EtMek5hDRLjGYA5HKM8ge9vrxw1pYDqPJgw@mail.gmail.com> <cd7c0490-a2d6-4885-aa36-ee1492f107b8@oss.qualcomm.com>
Message-ID: <CAMRc=MeuByh=N_-F2+zPiqnh+Qp9u97kiMheLJ-xxcSZSy+_tw@mail.gmail.com>

On Thu, Nov 13, 2025 at 2:33?PM Konrad Dybcio
<konrad.dybcio at oss.qualcomm.com> wrote:
>
> On 11/13/25 2:18 PM, Bartosz Golaszewski wrote:
> > On Fri, Nov 7, 2025 at 11:49?AM Konrad Dybcio
> > <konrad.dybcio at oss.qualcomm.com> wrote:
> >>
> >> On 11/7/25 11:29 AM, Bartosz Golaszewski wrote:
> >>> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> >>>
> >>> In order to drop the dependency on CONFIG_OF, convert all device property
> >>> getters from OF-specific to generic device properties and stop pulling
> >>> in any linux/of.h symbols.
> >>>
> >>> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> >>> ---
> >>
> >> [...]
> >>
> >>> -     if (of_property_read_bool(np, "snps,tso"))
> >>> +     if (device_property_present(dev, "snps,tso"))
> >>
> >> This is a change in behavior - "snps,tso = <0>" would have previously
> >> returned false, it now returns true
> >>
> >
> > This property is a boolean flag, it cannot have a value.
>
> Every DT property may have a value, so this is not as obvious as we'd
> like it to be (IIUC - unless that changed recently)
>

That's new to me. I thought that if a property is a
/schemas/types.yaml#/definitions/flag then only its boolean form is
allowed. The fact that the dtc can compile it with a value doesn't
matter as the bindings are the higher authority for DT sources?

I don't mind changing it to device_property_read_bool() but I'm not
sure if we really should.

Bartosz


From brgl at bgdev.pl  Thu Nov 13 05:44:12 2025
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Thu, 13 Nov 2025 14:44:12 +0100
Subject: [PATCH v5 6/8] net: stmmac: qcom-ethqos: split power management
 context into a separate struct
In-Reply-To: <14f95efb-0eb0-48ee-9132-df35abddfcc7@oss.qualcomm.com>
References: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>
 <20251107-qcom-sa8255p-emac-v5-6-01d3e3aaf388@linaro.org> <14f95efb-0eb0-48ee-9132-df35abddfcc7@oss.qualcomm.com>
Message-ID: <CAMRc=Mf03rYoi-C+kMic9RYZdk2vtAW5LDMYNMqg-H5vJccUhA@mail.gmail.com>

On Fri, Nov 7, 2025 at 12:00?PM Konrad Dybcio
<konrad.dybcio at oss.qualcomm.com> wrote:
>
> On 11/7/25 11:29 AM, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> >
> > With match data split into general and power-management sections, let's
> > now do the same with runtime device data.
> >
> > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
> > ---
> >  .../ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c    | 46 ++++++++++++----------
> >  1 file changed, 25 insertions(+), 21 deletions(-)
> >
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
> > index 1f00556bbad997e2ec76b521cffe2eb14fabb79e..09f122062dec87aa11804af2769ddff4964e6596 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
> > +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
> > @@ -105,17 +105,21 @@ struct ethqos_emac_match_data {
> >       const struct ethqos_emac_pm_data *pm_data;
> >  };
> >
> > +struct ethqos_emac_pm_ctx {
> > +     struct clk *link_clk;
> > +     unsigned int link_clk_rate;
> > +     struct phy *serdes_phy;
>
> What is the benefit of doing this? PHY APIs happily consume a nullptr
> and NOP out, and the PHY is already retrieved with _optional(),
> similarly with clk
>
> Konrad

Because it clearly divides the driver's logic into the manual and
firmware-driven variants. Just because we could, doesn't necessarily
mean we should just call PHY APIs with a nullptr if readability is
better when we don't.

Bartosz


From brgl at bgdev.pl  Thu Nov 13 06:39:45 2025
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Thu, 13 Nov 2025 15:39:45 +0100
Subject: [PATCH v5 8/8] net: stmmac: qcom-ethqos: add support for sa8255p
In-Reply-To: <aRMiafCQNPVDOljU@horms.kernel.org>
References: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>
 <20251107-qcom-sa8255p-emac-v5-8-01d3e3aaf388@linaro.org> <aRMiafCQNPVDOljU@horms.kernel.org>
Message-ID: <CAMRc=MfEuAhichw-tPJkj_BKxy7AzvfmVJJyXzHsqa2wf=2EKw@mail.gmail.com>

On Tue, Nov 11, 2025 at 12:48?PM Simon Horman <horms at kernel.org> wrote:
>
> On Fri, Nov 07, 2025 at 11:29:58AM +0100, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
>
> ...
>
> > +static int qcom_ethqos_pd_init(struct platform_device *pdev, void *priv)
> > +{
> > +     struct qcom_ethqos *ethqos = priv;
> > +     int ret;
> > +
> > +     /*
> > +      * Enable functional clock to prevent DMA reset after timeout due
> > +      * to no PHY clock being enabled after the hardware block has been
> > +      * power cycled. The actual configuration will be adjusted once
> > +      * ethqos_fix_mac_speed() is called.
> > +      */
> > +     ethqos_set_func_clk_en(ethqos);
> > +
> > +     ret = qcom_ethqos_domain_on(ethqos, ETHQOS_PD_CORE);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = qcom_ethqos_domain_on(ethqos, ETHQOS_PD_MDIO);
> > +     if (ret) {
> > +             qcom_ethqos_domain_off(ethqos, ETHQOS_PD_CORE);
> > +             return ret;
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static void qcom_ethqos_pd_exit(struct platform_device *pdev, void *data)
> > +{
> > +     struct qcom_ethqos *ethqos = data;
> > +
> > +     qcom_ethqos_domain_off(ethqos, ETHQOS_PD_MDIO);
> > +     qcom_ethqos_domain_off(ethqos, ETHQOS_PD_CORE);
> > +}
> > +
> >  static void ethqos_ptp_clk_freq_config(struct stmmac_priv *priv)
> >  {
> >       struct plat_stmmacenet_data *plat_dat = priv->plat;
>
> ...
>
> > @@ -852,28 +993,63 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
> >       ethqos->rgmii_config_loopback_en = drv_data->rgmii_config_loopback_en;
> >       ethqos->has_emac_ge_3 = drv_data->has_emac_ge_3;
> >       ethqos->needs_sgmii_loopback = drv_data->needs_sgmii_loopback;
> > -
> > -     ethqos->pm.link_clk = devm_clk_get(dev, clk_name);
> > -     if (IS_ERR(ethqos->pm.link_clk))
> > -             return dev_err_probe(dev, PTR_ERR(ethqos->pm.link_clk),
> > -                                  "Failed to get link_clk\n");
> > -
> > -     ret = ethqos_clks_config(ethqos, true);
> > -     if (ret)
> > -             return ret;
> > -
> > -     ret = devm_add_action_or_reset(dev, ethqos_clks_disable, ethqos);
> > -     if (ret)
> > -             return ret;
> > -
> > -     ethqos->pm.serdes_phy = devm_phy_optional_get(dev, "serdes");
> > -     if (IS_ERR(ethqos->pm.serdes_phy))
> > -             return dev_err_probe(dev, PTR_ERR(ethqos->pm.serdes_phy),
> > -                                  "Failed to get serdes phy\n");
> > -
> > -     ethqos->set_serdes_speed = ethqos_set_serdes_speed_phy;
> >       ethqos->serdes_speed = SPEED_1000;
> > -     ethqos_update_link_clk(ethqos, SPEED_1000);
> > +
> > +     if (pm_data && pm_data->use_domains) {
> > +             ethqos->set_serdes_speed = ethqos_set_serdes_speed_pd;
> > +
> > +             ret = devm_pm_domain_attach_list(dev, &pm_data->pd,
> > +                                              &ethqos->pd.pd_list);
> > +             if (ret < 0)
> > +                     return dev_err_probe(dev, ret, "Failed to attach power domains\n");
> > +
> > +             plat_dat->clks_config = ethqos_pd_clks_config;
> > +             plat_dat->serdes_powerup = qcom_ethqos_pd_serdes_powerup;
> > +             plat_dat->serdes_powerdown = qcom_ethqos_pd_serdes_powerdown;
> > +             plat_dat->exit = qcom_ethqos_pd_exit;
>
> Hi Bartosz,
>
> It seems that the intention of this is to ensure
> that domains turned on by qcom_ethqos_pd_init()
> are turned off again on exit or clean-up in error paths.
>
> > +             plat_dat->init = qcom_ethqos_pd_init;
> > +             plat_dat->clk_ptp_rate = pm_data->clk_ptp_rate;
> > +
> > +             ret = qcom_ethqos_pd_init(pdev, ethqos);
> > +             if (ret)
> > +                     return ret;
>
> And here those domains are turned on.
>
> > +
> > +             ret = qcom_ethqos_domain_on(ethqos, ETHQOS_PD_SERDES);
> > +             if (ret)
>
> But it seems that if we reach this error path then the cleanup is not
> performed. This is because plat_dat and thus it's exit callback are
> registered until the call to devm_stmmac_pltfr_probe() towards the end of
> this function.

We can only reach this if devm_stmmac_pltfr_probe() fails. Yeah it
probably warrants a devres action.

Bartosz


From konrad.dybcio at oss.qualcomm.com  Thu Nov 13 06:47:09 2025
From: konrad.dybcio at oss.qualcomm.com (Konrad Dybcio)
Date: Thu, 13 Nov 2025 15:47:09 +0100
Subject: [PATCH v5 2/8] net: stmmac: qcom-ethqos: use generic device
 properties
In-Reply-To: <CAMRc=MeuByh=N_-F2+zPiqnh+Qp9u97kiMheLJ-xxcSZSy+_tw@mail.gmail.com>
References: <20251107-qcom-sa8255p-emac-v5-0-01d3e3aaf388@linaro.org>
 <20251107-qcom-sa8255p-emac-v5-2-01d3e3aaf388@linaro.org>
 <21a3d269-76e6-4da9-aa25-bfd1fb6dfb07@oss.qualcomm.com>
 <CAMRc=MexMn_GSC2EtMek5hDRLjGYA5HKM8ge9vrxw1pYDqPJgw@mail.gmail.com>
 <cd7c0490-a2d6-4885-aa36-ee1492f107b8@oss.qualcomm.com>
 <CAMRc=MeuByh=N_-F2+zPiqnh+Qp9u97kiMheLJ-xxcSZSy+_tw@mail.gmail.com>
Message-ID: <45915f40-caa1-417b-95bb-deb7363a2ffc@oss.qualcomm.com>

On 11/13/25 2:41 PM, Bartosz Golaszewski wrote:
> On Thu, Nov 13, 2025 at 2:33?PM Konrad Dybcio
> <konrad.dybcio at oss.qualcomm.com> wrote:
>>
>> On 11/13/25 2:18 PM, Bartosz Golaszewski wrote:
>>> On Fri, Nov 7, 2025 at 11:49?AM Konrad Dybcio
>>> <konrad.dybcio at oss.qualcomm.com> wrote:
>>>>
>>>> On 11/7/25 11:29 AM, Bartosz Golaszewski wrote:
>>>>> From: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
>>>>>
>>>>> In order to drop the dependency on CONFIG_OF, convert all device property
>>>>> getters from OF-specific to generic device properties and stop pulling
>>>>> in any linux/of.h symbols.
>>>>>
>>>>> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski at linaro.org>
>>>>> ---
>>>>
>>>> [...]
>>>>
>>>>> -     if (of_property_read_bool(np, "snps,tso"))
>>>>> +     if (device_property_present(dev, "snps,tso"))
>>>>
>>>> This is a change in behavior - "snps,tso = <0>" would have previously
>>>> returned false, it now returns true
>>>>
>>>
>>> This property is a boolean flag, it cannot have a value.
>>
>> Every DT property may have a value, so this is not as obvious as we'd
>> like it to be (IIUC - unless that changed recently)
>>
> 
> That's new to me. I thought that if a property is a
> /schemas/types.yaml#/definitions/flag then only its boolean form is
> allowed. The fact that the dtc can compile it with a value doesn't
> matter as the bindings are the higher authority for DT sources?

You're right, I misrepresented the issue. read_bool() was historically
used for making sure a property is present and this was a problem
when the type was != flag.

Please discard my comment

Konrad


From dsimic at manjaro.org  Fri Nov 14 16:52:43 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Sat, 15 Nov 2025 01:52:43 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v2 1/2] =?utf-8?q?dt-bindings=3A?=
 =?utf-8?q?_arm=3A?==?utf-8?q?_rockchip=3A?= Add Asus Tinker Board 3 and 3S
Message-ID: <e4cd11d0-463c-e707-5110-6b92899b1ba3@manjaro.org>

Hello Michael,

Thanks for the v2!  Please, see some remarks below.

On Friday, November 14, 2025 16:46 CET, michael.opdenacker at rootcommit.com wrote:
> From: Michael Opdenacker <michael.opdenacker at rootcommit.com>

I'm sorry for not mentioning it in my earlier responses, but this
line is redundant, because it duplicates the From value found in
the actual email message.

> Document the compatible strings for Asus Tinker Board 3 [1] and 3S [2],
> which are SBCs based on the Rockchip 3566 SoC.
> 
> The "3S" version ("S" for "storage") just adds a 16 GB eMMC
> and a "mask ROM" DIP switch to the "3" version.
> 
> [1] https://tinker-board.asus.com/series/tinker-board-3.html
> [2] https://tinker-board.asus.com/series/tinker-board-3s.html
> 
> Signed-off-by: Michael Opdenacker <michael.opdenacker at rootcommit.com>
> ---
>  Documentation/devicetree/bindings/arm/rockchip.yaml | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
> index 6aceaa8acbb2..cd249325a4d9 100644
> --- a/Documentation/devicetree/bindings/arm/rockchip.yaml
> +++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
> @@ -86,6 +86,17 @@ properties:
>            - const: asus,rk3288-tinker-s
>            - const: rockchip,rk3288
>  
> +      - description: Asus Tinker Board 3
> +        items:
> +          - const: asus,rk3566-tinker-board-3
> +          - const: rockchip,rk3566
> +
> +      - description: Asus Tinker Board 3S
> +        items:
> +          - const: asus,rk3566-tinker-board-3s
> +          - const: asus,rk3566-tinker-board-3
> +          - const: rockchip,rk3566
> +
>        - description: Beelink A1
>          items:
>            - const: azw,beelink-a1

I'm sorry again for not mentioning it in my earlier responses, 
but shouldn't this addition be specified like below:

     - description: Asus Tinker Board 3/3S
       items:
         - enum:
	   - asus,rk3566-tinker-board-3
           - asus,rk3566-tinker-board-3s
         - const: rockchip,rk3566

... because the introduced .dts files define the actual board DTs,
by descending from the common .dtsi file, while they're compatible
in the sense of the 3S board variant extending the 3 variant.



From dsimic at manjaro.org  Fri Nov 14 16:53:19 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Sat, 15 Nov 2025 01:53:19 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v2 2/2] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= Add Asus Tinker Board 3 and 3S device tree
Message-ID: <12d6e151-dfa0-ca0a-5888-ddffb2dbdec7@manjaro.org>

Hello Michael,

Thanks for the v2!  Please, see one nitpick below.

On Friday, November 14, 2025 16:46 CET, michael.opdenacker at rootcommit.com wrote:
> From: Michael Opdenacker <michael.opdenacker at rootcommit.com>

I'm sorry for not mentioning it in my earlier responses, but this
line is redundant, because it duplicates the From value found in
the actual email message.

> Add initial device tree support for Asus Tinker Board 3 [1] and 3S [2],
> which are SBCs based on the Rockchip 3566 SoC.
> 
> The "3S" version ("S" for "storage") just adds a 16 GB eMMC
> and a "mask ROM" DIP switch (to mask the eMMC and enter "Mask ROM"
> mode for recovery) to the "3" version.
> 
> This adds support for:
> - Debug UART (/dev/ttyS2)
> - SD card (/dev/mmcblk1)
> - eMMC (/dev/mmcblk0, only on Tinker Board 3S)
> - I2C:
>   - i2c0 (internal bus with a PMIC and regulators)
>   - i2c2 (internal bus with an at24 eeprom and an RTC device)
> - USB 2.0 ports
> - 2 GPIO LEDS
> 
> [1] https://tinker-board.asus.com/series/tinker-board-3.html
> [2] https://tinker-board.asus.com/series/tinker-board-3s.html
> 
> Signed-off-by: Michael Opdenacker <michael.opdenacker at rootcommit.com>
> ---
>  arch/arm64/boot/dts/rockchip/Makefile         |   2 +
>  .../dts/rockchip/rk3566-tinker-board-3.dts    |  14 +
>  .../dts/rockchip/rk3566-tinker-board-3.dtsi   | 280 ++++++++++++++++++
>  .../dts/rockchip/rk3566-tinker-board-3s.dts   |  30 ++
>  4 files changed, 326 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3.dts
>  create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3.dtsi
>  create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3s.dts

[snip]




From heiko at sntech.de  Sat Nov 15 15:43:19 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Sun, 16 Nov 2025 00:43:19 +0100
Subject: (subset) [PATCH v15 00/14] media: rockchip: add a driver for the rockchip camera interface
In-Reply-To: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
References: <20240220-rk3568-vicap-v15-0-8f4915ee365d@collabora.com>
Message-ID: <176325011672.721648.2323929668705434904.b4-ty@sntech.de>


On Fri, 14 Nov 2025 16:20:11 +0100, Michael Riesch wrote:
> Habidere,
> 
> This series introduces support for the Rockchip Camera Interface (CIF),
> which is featured in many Rockchip SoCs in different variations.
> The series has now been around for a while and has received many comments
> and reviews. Thus, it should be ready for mainline by now.
> 
> [...]

Applied, thanks!

[11/14] arm64: defconfig: enable rockchip camera interface
        commit: 60705b039f960378bb2a0a844f9378646bc0c6c8
[12/14] arm64: dts: rockchip: add the vip node to px30
        commit: d2da7e98c0bf7f75433809ad875c6e1ae57f0cea
[13/14] arm64: dts: rockchip: add vicap node to rk356x
        commit: 78f316e90906d54c8aa6029e5c19ae83e420e56a


Not applied 
    arm64: dts: rockchip: enable vicap dvp on wolfvision pf5 io expander

because of
Lexical error: ../arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5-io-expander.dtso:149.18-45 Unexpected 'MEDIA_PCLK_SAMPLE_DUAL_EDGE'
FATAL ERROR: Syntax error parsing input tree

This likely will only work after the next merge window.

So if you can live with that please resubmit that last patch individually.


Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From dmitry.baryshkov at oss.qualcomm.com  Sun Nov 16 07:32:03 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Sun, 16 Nov 2025 17:32:03 +0200
Subject: [PATCH v1 1/2] drm/ci: uprev mesa
In-Reply-To: <42v64xdsaqug5yy76yel4tukh6wkt2tp237vlnpteabyl5qjo5@iigtgujvecwc>
References: <20251114030056.1139570-1-vignesh.raman@collabora.com>
 <20251114030056.1139570-2-vignesh.raman@collabora.com>
 <prjwrsepfc3b6ozhue5cp66khlcvdrpvpy6jkk23edncmi4l3y@oiddmamgg3mx>
 <42v64xdsaqug5yy76yel4tukh6wkt2tp237vlnpteabyl5qjo5@iigtgujvecwc>
Message-ID: <2obhppq6a4ercfnhvm42tbbgh3xut4lz66fc4j7mpev5oxxno7@dydu2wysmgvi>

On Sat, Nov 15, 2025 at 05:55:17AM +0200, Dmitry Baryshkov wrote:
> On Sat, Nov 15, 2025 at 02:44:56AM +0200, Dmitry Baryshkov wrote:
> > On Fri, Nov 14, 2025 at 08:30:50AM +0530, Vignesh Raman wrote:
> > > Uprev mesa to adapt to the latest changes in Mesa CI, including support
> > > for firmware via LAVA overlays, removal of the python-artifacts job,
> > > split container and build rules, use lava-job-submitter container,
> > > and various misc fixes.
> > > 
> > > Co-developed-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>
> > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>
> > > Signed-off-by: Vignesh Raman <vignesh.raman at collabora.com>
> > > ---
> > >  drivers/gpu/drm/ci/build.yml         |  22 +++---
> > >  drivers/gpu/drm/ci/container.yml     |  28 ++++++--
> > >  drivers/gpu/drm/ci/gitlab-ci.yml     |  95 ++++++++++++++++++++-----
> > >  drivers/gpu/drm/ci/igt_runner.sh     |   4 +-
> > >  drivers/gpu/drm/ci/image-tags.yml    |  22 +++---
> > >  drivers/gpu/drm/ci/lava-submit.sh    | 101 +++++++++++++--------------
> > >  drivers/gpu/drm/ci/static-checks.yml |   1 +
> > >  drivers/gpu/drm/ci/test.yml          |  18 +++--
> > >  8 files changed, 186 insertions(+), 105 deletions(-)
> > > 
> > 
> > Thanks a lot for taking care of it!
> > 
> > 
> > Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>
> 
> Hmm, this causes a lot of failures, see [1] (note, the run is not
> finished yet):
> - On some platforms (msm, rk3399, mt8173) the
>   core_setmaster at master-drop-set-root test fails. On other it seems to
>   work correctly
> - sm8350 seems to have some issues with this uprev, it cant' finish the
>   jobs at all
> - mt8173 and rockchip:rk3399 seem to have other test failures too

I have fixed most of the fallouts, see [2]. But ideally this should be
split into two parts: fix before mesa uprev (I think some of them are
already there), uprev mesa, applying necessary fixes and then enable apq
jobs.

At this point I have no idea what's wrong with MT8183. Most likely it
needs either a DT fix or a driver fix. The driver fails to probe because
it can't build a sensible component chain.

On i915 several tests kill the hardware, making it timeout all remaining
tests in a bad way.

BTW: I see that for some of the drivers we skip the absolute majority of
the tests. What are we actually testing on those?

> 
> Could you please update fails / flakes tor all the affected platforms?
> Also I'm really interested in the master-drop-set tests. Why do they
> fail on some of the platforms, but not on all? This seems to be some
> infrastructure-related issue, since exactly the same kernel with the
> same IGT passes those tests (at least on msm hardware).
> 
> [1] https://gitlab.freedesktop.org/drm/msm/-/pipelines/1547684

[2] https://gitlab.freedesktop.org/lumag/msm/-/commits/msm-next-lumag-db820c


-- 
With best wishes
Dmitry


From dsimic at manjaro.org  Sun Nov 16 17:17:12 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Mon, 17 Nov 2025 02:17:12 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v2 2/2] =?utf-8?q?arm64=3A?==?utf-8?q?_dts=3A?=
 =?utf-8?q?_rockchip=3A?= Add Asus Tinker Board 3 and 3S device tree
In-Reply-To: <2455319.NG923GbCHz@diego>
References: <12d6e151-dfa0-ca0a-5888-ddffb2dbdec7@manjaro.org>
 <bb74679a-ce21-4373-bcc5-1214e9bf832e@rootcommit.com>
 <24561990-8293-0505-5837-eca416d01bb7@manjaro.org> <2455319.NG923GbCHz@diego>
Message-ID: <a5e7824d-03c7-fa0a-473f-193e172420d2@manjaro.org>

Hello Heiko,

On Sunday, November 16, 2025 00:27 CET, Heiko St?bner <heiko at sntech.de> wrote:
> Am Samstag, 15. November 2025, 08:14:58 Mitteleurop?ische Normalzeit schrieb Dragan Simic:
> > BTW, my responses are currently jailed by the linux-rockchip mailing
> > list, requiring manual approval, as a result of the mail server I'm
> > using sometimes inserting some strange invisible UTF-8 characters
> > into the email subjects.  Oh well. :)
> 
> I guess that mailserver needs a fix :-)

Indeed, something is, unfortunately, really messed up there, :/
to the point that even one of my "unjailed" responses in this
thread ended up in a separate lore thread. [1]

[1] https://lore.kernel.org/linux-rockchip/e4cd11d0-463c-e707-5110-6b92899b1ba3 at manjaro.org/T/#u



From chaoyi.chen at rock-chips.com  Sun Nov 16 17:33:55 2025
From: chaoyi.chen at rock-chips.com (Chaoyi Chen)
Date: Mon, 17 Nov 2025 09:33:55 +0800
Subject: [PATCH v9 08/10] drm/rockchip: cdn-dp: Add multiple bridges to
 support PHY port selection
In-Reply-To: <b1a339e7-a011-4b4b-8988-2e3768753c85@rock-chips.com>
References: <20251111105040.94-1-kernel@airkyi.com>
 <20251111105040.94-9-kernel@airkyi.com>
 <DE5YP3AVGOG3.OHP68Z0F6KBU@bootlin.com>
 <b1a339e7-a011-4b4b-8988-2e3768753c85@rock-chips.com>
Message-ID: <2ebace6f-d3c4-4516-b6cb-4951de06b6c8@rock-chips.com>

Hi Luca,

On 11/12/2025 9:37 AM, Chaoyi Chen wrote:
> Hello Luca,
>
> On 11/11/2025 11:14 PM, Luca Ceresoli wrote:
>> Hello Chaoyi,
>>
>> On Tue Nov 11, 2025 at 11:50 AM CET, Chaoyi Chen wrote:
>>> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
>>>
>>> The RK3399 has two USB/DP combo PHY and one CDN-DP controller. And
>>> the CDN-DP can be switched to output to one of the PHYs. If both ports
>>> are plugged into DP, DP will select the first port for output.
>>>
>>> This patch adds support for multiple bridges, enabling users to flexibly
>>> select the output port. For each PHY port, a separate encoder and bridge
>>> are registered.
>>>
>>> The change is based on the DRM AUX HPD bridge, rather than the
>>> extcon approach. This requires the DT to correctly describe the
>>> connections between the first bridge in bridge chain and DP
>>> controller. For example, the bridge chain may be like this:
>>>
>>> PHY aux birdge -> fsa4480 analog audio switch bridge ->
>>> onnn,nb7vpq904m USB reminder bridge -> USB-C controller AUX HPD bridge
>>>
>>> In this case, the connection relationships among the PHY aux bridge
>>> and the DP contorller need to be described in DT.
>>>
>>> In addition, the cdn_dp_parse_next_bridge_dt() will parses it and
>>> determines whether to register one or two bridges.
>>>
>>> Since there is only one DP controller, only one of the PHY ports can
>>> output at a time. The key is how to switch between different PHYs,
>>> which is handled by cdn_dp_switch_port() and cdn_dp_enable().
>>>
>>> There are two cases:
>>>
>>> 1. Neither bridge is enabled. In this case, both bridges can
>>> independently read the EDID, and the PHY port may switch before
>>> reading the EDID.
>>>
>>> 2. One bridge is already enabled. In this case, other bridges are not
>>> allowed to read the EDID. So we will try to return the cached EDID.
>>>
>>> Since the scenario of two ports plug in at the same time is rare,
>>> I don't have a board which support two TypeC connector to test this.
>>> Therefore, I tested forced switching on a single PHY port, as well as
>>> output using a fake PHY port alongside a real PHY port.
>>>
>>> Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
>> [...]
>>
>>> @@ -966,28 +1084,16 @@ static int cdn_dp_pd_event(struct notifier_block *nb,
>>> ????? return NOTIFY_DONE;
>>> ? }
>>>
>>> -static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
>>> +static int cdn_bridge_add(struct device *dev,
>>> +????????????? struct drm_bridge *bridge,
>>> +????????????? struct drm_bridge *next_bridge,
>>> +????????????? struct drm_encoder *encoder)
>>> ? {
>>> ????? struct cdn_dp_device *dp = dev_get_drvdata(dev);
>>> -??? struct drm_encoder *encoder;
>>> +??? struct drm_device *drm_dev = dp->drm_dev;
>>> +??? struct drm_bridge *last_bridge = NULL;
>>> ????? struct drm_connector *connector;
>>> -??? struct cdn_dp_port *port;
>>> -??? struct drm_device *drm_dev = data;
>>> -??? int ret, i;
>> [...]
>>
>>> +??? if (next_bridge) {
>>> +??????? ret = drm_bridge_attach(encoder, next_bridge, bridge,
>>> +??????????????????? DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>>> +??????? if (ret)
>>> +??????????? return ret;
>>> +
>>> +??????? last_bridge = next_bridge;
>>> +??????? while (drm_bridge_get_next_bridge(last_bridge))
>>> +??????????? last_bridge = drm_bridge_get_next_bridge(last_bridge);
>> DRM bridges are now refcounted, and you are not calling drm_bridge_get()
>> and drm_bridge_put() here. But here you can use
>> drm_bridge_chain_get_last_bridge() which will simplify your job.
>>
>> Don't forget to call drm_bridge_put() on the returned bridge when the
>> bridge is not referenced anymore. This should be as easy as adding a
>> cleanup action on the variable declaration above:
>>
>> -??? struct drm_bridge *last_bridge = NULL;
>> +??? struct drm_bridge *last_bridge __free(drm_bridge_put) = NULL;
>
> Ah, I have seen your patch about this. Thank you for the reminder, I will fix this in v10.
>
>>
>>> @@ -1029,8 +1147,102 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
>>> ????????? return ret;
>>> ????? }
>>>
>>> +??? if (last_bridge)
>>> +??????? connector->fwnode = fwnode_handle_get(of_fwnode_handle(last_bridge->of_node));
>>> +
>>> ????? drm_connector_attach_encoder(connector, encoder);
>>>
>>> +??? return 0;
>>> +}
>>> +
>>> +static int cdn_dp_parse_next_bridge_dt(struct cdn_dp_device *dp)
>>> +{
>>> +??? struct device_node *np = dp->dev->of_node;
>>> +??? struct device_node *port __free(device_node) = of_graph_get_port_by_id(np, 1);
>>> +??? struct drm_bridge *bridge;
>>> +??? int count = 0;
>>> +??? int ret = 0;
>>> +??? int i;
>>> +
>>> +??? /* If device use extcon, do not use hpd bridge */
>>> +??? for (i = 0; i < dp->ports; i++) {
>>> +??????? if (dp->port[i]->extcon) {
>>> +??????????? dp->bridge_count = 1;
>>> +??????????? return 0;
>>> +??????? }
>>> +??? }
>>> +
>>> +
>>> +??? /* One endpoint may correspond to one next bridge. */
>>> +??? for_each_of_graph_port_endpoint(port, dp_ep) {
>>> +??????? struct device_node *next_bridge_node __free(device_node) =
>>> +??????????? of_graph_get_remote_port_parent(dp_ep);
>>> +
>>> +??????? bridge = of_drm_find_bridge(next_bridge_node);
>>> +??????? if (!bridge) {
>>> +??????????? ret = -EPROBE_DEFER;
>>> +??????????? goto out;
>>> +??????? }
>>> +
>>> +??????? dp->next_bridge_valid = true;
>>> +??????? dp->next_bridge_list[count].bridge = bridge;
>> You are storing a reference to a drm_bridge, so have to increment the
>> refcount:
>>
>> ??????? dp->next_bridge_list[count].bridge = drm_bridge_get(bridge);
>> ???????????????????????????????????????????? ^^^^^^^^^^^^^^
>>
>> FYI there is a plan to replace of_drm_find_bridge() with a function that
>> increases the bridge refcount before returning the bridge, but it's not
>> there yet. When that will happen, the explicit drm_bridge_get() won't be
>> needed anymore and this code can be updated accordingly.

Out of curiosity, I checked the callers of of_drm_find_bridge(), and it seems that the vast majority of them do not pay attention to the increase or decrease of reference counts. Does this mean that even if we add reference counting in of_drm_find_bridge(), we still need to modify the corresponding functions of their callers and decrease the reference count at the appropriate time? Thank you.


>>
>> Also you have to call drm_bridge_put() to release that reference when the
>> pointer goes away. I guess that should happen in cdn_dp_unbind().
>
> You're right, this is indeed a pitfall. I will fix it in v10.
>
>
-- 
Best,
Chaoyi



From shawn.lin at rock-chips.com  Sun Nov 16 19:42:59 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Mon, 17 Nov 2025 11:42:59 +0800
Subject: [PATCH 0/3] PCI: rockchip: 5.0 GT/s speed may be dangerous
In-Reply-To: <cover.1763197368.git.geraldogabriel@gmail.com>
References: <cover.1763197368.git.geraldogabriel@gmail.com>
Message-ID: <8f3cc1c1-7bf7-4610-b7ce-79ebd6f05a6e@rock-chips.com>

Hi Geraldo,

? 2025/11/15 ??? 17:10, Geraldo Nascimento ??:
> In recent interactions with Shawn Lin from Rockchip it came to my
> attention there's an unknown errata regarding 5.0 GT/s operational
> speed of their PCIe core. According to Shawn there's grave danger
> even if the odds are low. To contain any damage, let's cover the
> remaining corner-cases where the default would lead to 5.0 GT/s
> operation as well as add a comment to Root Complex driver core,
> documenting this danger.
> 

I'm not sure just adding a warn would be a good choice. Could we totally
force to use gen1 and add a warn if trying to use Gen2.

Meanwhile amend the commit message to add a reference
of RK3399 official datesheet[1] which says PCIe on RK3399 should only
support 2.5GT/s?


[1]https://opensource.rock-chips.com/images/d/d7/Rockchip_RK3399_Datasheet_V2.1-20200323.pdf

> Geraldo Nascimento (3):
>    PCI: rockchip: warn of danger of 5.0 GT/s speeds
>    PCI: rockchip-host: comment danger of 5.0 GT/s speed
>    arm64: dts: rockchip: drop max-link-speed = <2> in helios64 PCIe
> 
>   arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts | 1 -
>   drivers/pci/controller/pcie-rockchip-host.c            | 5 +++++
>   drivers/pci/controller/pcie-rockchip.c                 | 8 ++++++--
>   3 files changed, 11 insertions(+), 3 deletions(-)
> 



From dsimic at manjaro.org  Sun Nov 16 19:57:11 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Mon, 17 Nov 2025 04:57:11 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH 0/3] =?utf-8?q?PCI=3A?==?utf-8?q?_rockchip=3A?=
 =?utf-8?q?_5=2E0?= GT/s speed may be dangerous
In-Reply-To: <8f3cc1c1-7bf7-4610-b7ce-79ebd6f05a6e@rock-chips.com>
References: <cover.1763197368.git.geraldogabriel@gmail.com> <8f3cc1c1-7bf7-4610-b7ce-79ebd6f05a6e@rock-chips.com>
Message-ID: <257951b7-c22e-9707-6aba-3dc5794306bb@manjaro.org>

Hello Shawn and Geraldo,

On Monday, November 17, 2025 04:42 CET, Shawn Lin <shawn.lin at rock-chips.com> wrote:
> ? 2025/11/15 ??? 17:10, Geraldo Nascimento ??:
> > In recent interactions with Shawn Lin from Rockchip it came to my
> > attention there's an unknown errata regarding 5.0 GT/s operational
> > speed of their PCIe core. According to Shawn there's grave danger
> > even if the odds are low. To contain any damage, let's cover the
> > remaining corner-cases where the default would lead to 5.0 GT/s
> > operation as well as add a comment to Root Complex driver core,
> > documenting this danger.
> 
> I'm not sure just adding a warn would be a good choice. Could we totally
> force to use gen1 and add a warn if trying to use Gen2.

I think that forcing 2.5 GT/s with an appropriate warning message
is a good idea.  That would be like some quirk that gets applied
automatically, to prevent data corruption, while warning people
who attempt to "overclock" the PCIe interface.

> Meanwhile amend the commit message to add a reference
> of RK3399 official datesheet[1] which says PCIe on RK3399 should only
> support 2.5GT/s?
> 
> [1]https://opensource.rock-chips.com/images/d/d7/Rockchip_RK3399_Datasheet_V2.1-20200323.pdf

Also, rewording the patch summary as follows below may be good,
because that would provide more details:

  PCI: rockchip: Warn about Gen2 5.0 GT/s on RK3399 being unsafe

Or, if we'll go with the automatic downgrading, like this:

  PCI: rockchip: Limit RK3399 to Gen1 2.5 GT/s to prevent breakage



From kevin.tian at intel.com  Sun Nov 16 22:37:37 2025
From: kevin.tian at intel.com (Tian, Kevin)
Date: Mon, 17 Nov 2025 06:37:37 +0000
Subject: [PATCH v2 1/3] RDMA/usnic: Remove iommu_set_fault_handler()
In-Reply-To: <1-v2-25fc75484cab+ab-iommu_set_fault_jgg@nvidia.com>
References: <0-v2-25fc75484cab+ab-iommu_set_fault_jgg@nvidia.com>
 <1-v2-25fc75484cab+ab-iommu_set_fault_jgg@nvidia.com>
Message-ID: <BN9PR11MB52768F201F306F13023AFE718CC9A@BN9PR11MB5276.namprd11.prod.outlook.com>

> From: Jason Gunthorpe <jgg at nvidia.com>
> Sent: Friday, November 7, 2025 4:35 AM
> 
> The handler in usnic just prints a fault report message, the iommu drivers
> all do a better job of that these days. Just remove the use of this old
> API.
> 
> Acked-by: Jason Gunthorpe <jgg at nvidia.com>
> Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
> Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>

Reviewed-by: Kevin Tian <kevin.tian at intel.com>


From kevin.tian at intel.com  Sun Nov 16 22:38:51 2025
From: kevin.tian at intel.com (Tian, Kevin)
Date: Mon, 17 Nov 2025 06:38:51 +0000
Subject: [PATCH v2 2/3] iommu/amd: Don't call report_iommu_fault()
In-Reply-To: <2-v2-25fc75484cab+ab-iommu_set_fault_jgg@nvidia.com>
References: <0-v2-25fc75484cab+ab-iommu_set_fault_jgg@nvidia.com>
 <2-v2-25fc75484cab+ab-iommu_set_fault_jgg@nvidia.com>
Message-ID: <BN9PR11MB5276EFE7D236FF918A79263C8CC9A@BN9PR11MB5276.namprd11.prod.outlook.com>

> From: Jason Gunthorpe <jgg at nvidia.com>
> Sent: Friday, November 7, 2025 4:35 AM
> 
> This old style API is only used by drivers/gpu/drm/msm,
> drivers/remoteproc/omap_remoteproc.c, and
> drivers/remoteproc/qcom_q6v5_adsp.c none are used on x86 HW.
> 
> Remove the dead code to discourage new users.
> 
> Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> ---
>  drivers/iommu/amd/iommu.c | 7 -------
>  1 file changed, 7 deletions(-)
> 
> diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
> index 2e1865daa1cee8..d4d9a5dbfa6333 100644
> --- a/drivers/iommu/amd/iommu.c
> +++ b/drivers/iommu/amd/iommu.c
> @@ -854,13 +854,6 @@ static void amd_iommu_report_page_fault(struct
> amd_iommu *iommu,
>  						   PCI_FUNC(devid),
> domain_id);
>  				goto out;
>  			}
> -
> -			if (!report_iommu_fault(&dev_data->domain-
> >domain,
> -						&pdev->dev, address,
> -						IS_WRITE_REQUEST(flags) ?
> -
> 	IOMMU_FAULT_WRITE :
> -
> 	IOMMU_FAULT_READ))
> -				goto out;
>  		}
> 
>  		if (__ratelimit(&dev_data->rs)) {
> --
> 2.43.0
> 

Remove amd_iommu_report_page_fault() too?


From kevin.tian at intel.com  Sun Nov 16 22:43:13 2025
From: kevin.tian at intel.com (Tian, Kevin)
Date: Mon, 17 Nov 2025 06:43:13 +0000
Subject: [PATCH v2 3/3] iommu: Allow drivers to say if they use
 report_iommu_fault()
In-Reply-To: <3-v2-25fc75484cab+ab-iommu_set_fault_jgg@nvidia.com>
References: <0-v2-25fc75484cab+ab-iommu_set_fault_jgg@nvidia.com>
 <3-v2-25fc75484cab+ab-iommu_set_fault_jgg@nvidia.com>
Message-ID: <BN9PR11MB527652DC5E566D67AD54FEA98CC9A@BN9PR11MB5276.namprd11.prod.outlook.com>

> From: Jason Gunthorpe <jgg at nvidia.com>
> Sent: Friday, November 7, 2025 4:35 AM
> 
> @@ -1643,6 +1643,7 @@ static const struct iommu_ops arm_smmu_ops = {
>  	.get_resv_regions	= arm_smmu_get_resv_regions,
>  	.def_domain_type	= arm_smmu_def_domain_type,
>  	.owner			= THIS_MODULE,
> +	.report_iommu_fault_supported = true,

'_supported' could be removed.

Reviewed-by: Kevin Tian <kevin.tian at intel.com>


From geraldogabriel at gmail.com  Sun Nov 16 23:02:28 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Mon, 17 Nov 2025 04:02:28 -0300
Subject: [PATCH 0/3] PCI: rockchip: 5.0 GT/s speed may be dangerous
In-Reply-To: <257951b7-c22e-9707-6aba-3dc5794306bb@manjaro.org>
References: <cover.1763197368.git.geraldogabriel@gmail.com>
 <8f3cc1c1-7bf7-4610-b7ce-79ebd6f05a6e@rock-chips.com>
 <257951b7-c22e-9707-6aba-3dc5794306bb@manjaro.org>
Message-ID: <aRrIhA1uv_aIneOc@geday>

On Mon, Nov 17, 2025 at 04:57:11AM +0100, Dragan Simic wrote:
> Hello Shawn and Geraldo,
> 
> On Monday, November 17, 2025 04:42 CET, Shawn Lin <shawn.lin at rock-chips.com> wrote:
> > ? 2025/11/15 ??? 17:10, Geraldo Nascimento ??:
> > > In recent interactions with Shawn Lin from Rockchip it came to my
> > > attention there's an unknown errata regarding 5.0 GT/s operational
> > > speed of their PCIe core. According to Shawn there's grave danger
> > > even if the odds are low. To contain any damage, let's cover the
> > > remaining corner-cases where the default would lead to 5.0 GT/s
> > > operation as well as add a comment to Root Complex driver core,
> > > documenting this danger.
> > 
> > I'm not sure just adding a warn would be a good choice. Could we totally
> > force to use gen1 and add a warn if trying to use Gen2.
> 
> I think that forcing 2.5 GT/s with an appropriate warning message
> is a good idea.  That would be like some quirk that gets applied
> automatically, to prevent data corruption, while warning people
> who attempt to "overclock" the PCIe interface.

Hi Shawn and Dragan,

Alright, I'll send v2 with this suggestion in mind. So that driving the
core at 5.0 GT/s will require patching and compiling own kernel.

> 
> > Meanwhile amend the commit message to add a reference
> > of RK3399 official datesheet[1] which says PCIe on RK3399 should only
> > support 2.5GT/s?
> > 
> > [1]https://opensource.rock-chips.com/images/d/d7/Rockchip_RK3399_Datasheet_V2.1-20200323.pdf
> 

Shawn, URLs have the bad habit of changing or simply disappearing, so I
don't think it's a good idea to put URL in the commit message.

Also, the datasheet just mentions that RK3399 supports only 2.5 GT/s,
it does not mention possible damage from driving the core at 5.0 GT/s.

> Also, rewording the patch summary as follows below may be good,
> because that would provide more details:
> 
>   PCI: rockchip: Warn about Gen2 5.0 GT/s on RK3399 being unsafe
> 
> Or, if we'll go with the automatic downgrading, like this:
> 
>   PCI: rockchip: Limit RK3399 to Gen1 2.5 GT/s to prevent breakage
> 

Dragan, these are good ones, thanks. Though I think I'll omit Gen1/Gen2
wording since I know how much Bjorn dislikes those terms.

Thanks,
Geraldo Nascimento


From heikki.krogerus at linux.intel.com  Mon Nov 17 00:33:39 2025
From: heikki.krogerus at linux.intel.com (Heikki Krogerus)
Date: Mon, 17 Nov 2025 10:33:39 +0200
Subject: [PATCH v9 01/10] usb: typec: Add notifier functions
In-Reply-To: <20251111105040.94-2-kernel@airkyi.com>
References: <20251111105040.94-1-kernel@airkyi.com>
 <20251111105040.94-2-kernel@airkyi.com>
Message-ID: <aRrd48unDVdtKYH3@kuha.fi.intel.com>

Tue, Nov 11, 2025 at 06:50:31PM +0800, Chaoyi Chen kirjoitti:
> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> 
> Some other part of kernel may want to know the event of typec bus.
> 
> This patch add common notifier function to notify these event.
> 
> Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> ---
> 
> Changes in v9:
> - Remove redundant header files.
> 
> Changes in v8:
> - Fix coding style.
> 
>  drivers/usb/typec/Makefile        |  2 +-
>  drivers/usb/typec/bus.h           |  2 ++
>  drivers/usb/typec/class.c         |  2 ++
>  drivers/usb/typec/notify.c        | 23 +++++++++++++++++++++++
>  include/linux/usb/typec_altmode.h |  9 +++++++++
>  5 files changed, 37 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/usb/typec/notify.c
> 
> diff --git a/drivers/usb/typec/Makefile b/drivers/usb/typec/Makefile
> index 7a368fea61bc..20d09c5314d7 100644
> --- a/drivers/usb/typec/Makefile
> +++ b/drivers/usb/typec/Makefile
> @@ -1,6 +1,6 @@
>  # SPDX-License-Identifier: GPL-2.0
>  obj-$(CONFIG_TYPEC)		+= typec.o
> -typec-y				:= class.o mux.o bus.o pd.o retimer.o
> +typec-y				:= class.o mux.o notify.o bus.o pd.o retimer.o
>  typec-$(CONFIG_ACPI)		+= port-mapper.o
>  obj-$(CONFIG_TYPEC)		+= altmodes/
>  obj-$(CONFIG_TYPEC_TCPM)	+= tcpm/
> diff --git a/drivers/usb/typec/bus.h b/drivers/usb/typec/bus.h
> index 643b8c81786d..820b59b6d434 100644
> --- a/drivers/usb/typec/bus.h
> +++ b/drivers/usb/typec/bus.h
> @@ -26,6 +26,8 @@ struct altmode {
>  	struct altmode			*plug[2];
>  };
>  
> +void typec_notify_event(unsigned long event, void *data);
> +
>  #define to_altmode(d) container_of(d, struct altmode, adev)
>  
>  extern const struct bus_type typec_bus;
> diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
> index 9b2647cb199b..9d2aa3dd3f56 100644
> --- a/drivers/usb/typec/class.c
> +++ b/drivers/usb/typec/class.c
> @@ -600,6 +600,8 @@ typec_register_altmode(struct device *parent,
>  		return ERR_PTR(ret);
>  	}
>  
> +	typec_notify_event(TYPEC_ALTMODE_REGISTERED, &alt->adev);
> +
>  	return &alt->adev;
>  }

You need to also send TYPEC_ALTMODE_UNREGISTERED notification in
typec_unregister_altmode().

thanks,

> diff --git a/drivers/usb/typec/notify.c b/drivers/usb/typec/notify.c
> new file mode 100644
> index 000000000000..9e50b54da359
> --- /dev/null
> +++ b/drivers/usb/typec/notify.c
> @@ -0,0 +1,23 @@
> +// SPDX-License-Identifier: GPL-2.0
> +#include <linux/notifier.h>
> +
> +#include "bus.h"
> +
> +static BLOCKING_NOTIFIER_HEAD(typec_notifier_list);
> +
> +int typec_altmode_register_notify(struct notifier_block *nb)
> +{
> +	return blocking_notifier_chain_register(&typec_notifier_list, nb);
> +}
> +EXPORT_SYMBOL_GPL(typec_altmode_register_notify);
> +
> +int typec_altmode_unregister_notify(struct notifier_block *nb)
> +{
> +	return blocking_notifier_chain_unregister(&typec_notifier_list, nb);
> +}
> +EXPORT_SYMBOL_GPL(typec_altmode_unregister_notify);
> +
> +void typec_notify_event(unsigned long event, void *data)
> +{
> +	blocking_notifier_call_chain(&typec_notifier_list, event, data);
> +}
> diff --git a/include/linux/usb/typec_altmode.h b/include/linux/usb/typec_altmode.h
> index f7db3bd4c90e..59e20702504b 100644
> --- a/include/linux/usb/typec_altmode.h
> +++ b/include/linux/usb/typec_altmode.h
> @@ -10,6 +10,7 @@
>  #define MODE_DISCOVERY_MAX	6
>  
>  struct typec_altmode_ops;
> +struct notifier_block;
>  
>  /**
>   * struct typec_altmode - USB Type-C alternate mode device
> @@ -77,6 +78,14 @@ int typec_altmode_notify(struct typec_altmode *altmode, unsigned long conf,
>  const struct typec_altmode *
>  typec_altmode_get_partner(struct typec_altmode *altmode);
>  
> +enum usb_typec_event {
> +	TYPEC_ALTMODE_REGISTERED,
> +	TYPEC_ALTMODE_UNREGISTERED,
> +};
> +
> +int typec_altmode_register_notify(struct notifier_block *nb);
> +int typec_altmode_unregister_notify(struct notifier_block *nb);
> +
>  /**
>   * struct typec_cable_ops - Cable alternate mode operations vector
>   * @enter: Operations to be executed with Enter Mode Command
> -- 
> 2.51.1

-- 
heikki


From heikki.krogerus at linux.intel.com  Mon Nov 17 00:40:30 2025
From: heikki.krogerus at linux.intel.com (Heikki Krogerus)
Date: Mon, 17 Nov 2025 10:40:30 +0200
Subject: [PATCH v9 03/10] drm/bridge: Implement generic USB Type-C DP HPD
 bridge
In-Reply-To: <20251111105040.94-4-kernel@airkyi.com>
References: <20251111105040.94-1-kernel@airkyi.com>
 <20251111105040.94-4-kernel@airkyi.com>
Message-ID: <aRrffpTP5KyAFVnx@kuha.fi.intel.com>

Tue, Nov 11, 2025 at 06:50:33PM +0800, Chaoyi Chen kirjoitti:
> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> 
> The HPD function of Type-C DP is implemented through
> drm_connector_oob_hotplug_event(). For embedded DP, it is required
> that the DRM connector fwnode corresponds to the Type-C port fwnode.
> 
> To describe the relationship between the DP controller and the Type-C
> port device, we usually using drm_bridge to build a bridge chain.
> 
> Now several USB-C controller drivers have already implemented the DP
> HPD bridge function provided by aux-hpd-bridge.c, it will build a DP
> HPD bridge on USB-C connector port device.
> 
> But this requires the USB-C controller driver to manually register the
> HPD bridge. If the driver does not implement this feature, the bridge
> will not be create.
> 
> So this patch implements a generic DP HPD bridge based on
> aux-hpd-bridge.c. It will monitor Type-C bus events, and when a
> Type-C port device containing the DP svid is registered, it will
> create an HPD bridge for it without the need for the USB-C controller
> driver to implement it.
> 
> Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>

Normally there is no "help" section for hidden config options. I
guess it can not cause any harm? It is a bit confusing, though. But
FWIW:

Reviewed-by: Heikki Krogerus <heikki.krogerus at linux.intel.com>

> ---
> 
> Changes in v9:
> - Remove the exposed DRM_AUX_HPD_BRIDGE option, and select
> DRM_AUX_HPD_TYPEC_BRIDGE when it is available.
> - Add more commit comment about problem background.
> 
> Changes in v8:
> - Merge generic DP HPD bridge into one module.
> 
>  drivers/gpu/drm/bridge/Kconfig                | 10 ++++
>  drivers/gpu/drm/bridge/Makefile               |  1 +
>  .../gpu/drm/bridge/aux-hpd-typec-dp-bridge.c  | 50 +++++++++++++++++++
>  3 files changed, 61 insertions(+)
>  create mode 100644 drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
> 
> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
> index a250afd8d662..559487aa09a9 100644
> --- a/drivers/gpu/drm/bridge/Kconfig
> +++ b/drivers/gpu/drm/bridge/Kconfig
> @@ -30,6 +30,16 @@ config DRM_AUX_HPD_BRIDGE
>  	  Simple bridge that terminates the bridge chain and provides HPD
>  	  support.
>  
> +if DRM_AUX_HPD_BRIDGE
> +config DRM_AUX_HPD_TYPEC_BRIDGE
> +	tristate
> +	depends on TYPEC || !TYPEC
> +	default TYPEC
> +	help
> +	  Simple bridge that terminates the bridge chain and provides HPD
> +	  support. It build bridge on each USB-C connector device node.
> +endif
> +
>  menu "Display Interface Bridges"
>  	depends on DRM && DRM_BRIDGE
>  
> diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
> index c7dc03182e59..a3a0393d2e72 100644
> --- a/drivers/gpu/drm/bridge/Makefile
> +++ b/drivers/gpu/drm/bridge/Makefile
> @@ -1,6 +1,7 @@
>  # SPDX-License-Identifier: GPL-2.0
>  obj-$(CONFIG_DRM_AUX_BRIDGE) += aux-bridge.o
>  obj-$(CONFIG_DRM_AUX_HPD_BRIDGE) += aux-hpd-bridge.o
> +obj-$(CONFIG_DRM_AUX_HPD_TYPEC_BRIDGE) += aux-hpd-typec-dp-bridge.o
>  obj-$(CONFIG_DRM_CHIPONE_ICN6211) += chipone-icn6211.o
>  obj-$(CONFIG_DRM_CHRONTEL_CH7033) += chrontel-ch7033.o
>  obj-$(CONFIG_DRM_CROS_EC_ANX7688) += cros-ec-anx7688.o
> diff --git a/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c b/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
> new file mode 100644
> index 000000000000..9cb6a0cb0f0a
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
> @@ -0,0 +1,50 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +#include <linux/of.h>
> +#include <linux/usb/typec_altmode.h>
> +#include <linux/usb/typec_dp.h>
> +
> +#include <drm/bridge/aux-bridge.h>
> +
> +static int drm_typec_bus_event(struct notifier_block *nb,
> +			       unsigned long action, void *data)
> +{
> +	struct typec_altmode *alt = (struct typec_altmode *)data;
> +
> +	if (action != TYPEC_ALTMODE_REGISTERED)
> +		goto done;
> +
> +	if (is_typec_partner(&alt->dev) || alt->svid != USB_TYPEC_DP_SID)
> +		goto done;
> +
> +	/*
> +	 * alt->dev.parent->parent : USB-C controller device
> +	 * alt->dev.parent         : USB-C connector device
> +	 */
> +	drm_dp_hpd_bridge_register(alt->dev.parent->parent,
> +				   to_of_node(alt->dev.parent->fwnode));
> +
> +done:
> +	return NOTIFY_OK;
> +}
> +
> +static struct notifier_block drm_typec_event_nb = {
> +	.notifier_call = drm_typec_bus_event,
> +};
> +
> +static void drm_aux_hpd_typec_dp_bridge_module_exit(void)
> +{
> +	typec_altmode_unregister_notify(&drm_typec_event_nb);
> +}
> +
> +static int __init drm_aux_hpd_typec_dp_bridge_module_init(void)
> +{
> +	typec_altmode_register_notify(&drm_typec_event_nb);
> +
> +	return 0;
> +}
> +
> +module_init(drm_aux_hpd_typec_dp_bridge_module_init);
> +module_exit(drm_aux_hpd_typec_dp_bridge_module_exit);
> +
> +MODULE_DESCRIPTION("DRM TYPEC DP HPD BRIDGE");
> +MODULE_LICENSE("GPL");
> -- 
> 2.51.1

-- 
heikki


From chaoyi.chen at rock-chips.com  Mon Nov 17 00:41:07 2025
From: chaoyi.chen at rock-chips.com (Chaoyi Chen)
Date: Mon, 17 Nov 2025 16:41:07 +0800
Subject: [PATCH v9 01/10] usb: typec: Add notifier functions
In-Reply-To: <aRrd48unDVdtKYH3@kuha.fi.intel.com>
References: <20251111105040.94-1-kernel@airkyi.com>
 <20251111105040.94-2-kernel@airkyi.com> <aRrd48unDVdtKYH3@kuha.fi.intel.com>
Message-ID: <a3d80b63-761c-4a15-b7fb-c8a3bba8a5bd@rock-chips.com>

On 11/17/2025 4:33 PM, Heikki Krogerus wrote:

> Tue, Nov 11, 2025 at 06:50:31PM +0800, Chaoyi Chen kirjoitti:
>> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
>>
>> Some other part of kernel may want to know the event of typec bus.
>>
>> This patch add common notifier function to notify these event.
>>
>> Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
>> ---
>>
>> Changes in v9:
>> - Remove redundant header files.
>>
>> Changes in v8:
>> - Fix coding style.
>>
>>   drivers/usb/typec/Makefile        |  2 +-
>>   drivers/usb/typec/bus.h           |  2 ++
>>   drivers/usb/typec/class.c         |  2 ++
>>   drivers/usb/typec/notify.c        | 23 +++++++++++++++++++++++
>>   include/linux/usb/typec_altmode.h |  9 +++++++++
>>   5 files changed, 37 insertions(+), 1 deletion(-)
>>   create mode 100644 drivers/usb/typec/notify.c
>>
>> diff --git a/drivers/usb/typec/Makefile b/drivers/usb/typec/Makefile
>> index 7a368fea61bc..20d09c5314d7 100644
>> --- a/drivers/usb/typec/Makefile
>> +++ b/drivers/usb/typec/Makefile
>> @@ -1,6 +1,6 @@
>>   # SPDX-License-Identifier: GPL-2.0
>>   obj-$(CONFIG_TYPEC)		+= typec.o
>> -typec-y				:= class.o mux.o bus.o pd.o retimer.o
>> +typec-y				:= class.o mux.o notify.o bus.o pd.o retimer.o
>>   typec-$(CONFIG_ACPI)		+= port-mapper.o
>>   obj-$(CONFIG_TYPEC)		+= altmodes/
>>   obj-$(CONFIG_TYPEC_TCPM)	+= tcpm/
>> diff --git a/drivers/usb/typec/bus.h b/drivers/usb/typec/bus.h
>> index 643b8c81786d..820b59b6d434 100644
>> --- a/drivers/usb/typec/bus.h
>> +++ b/drivers/usb/typec/bus.h
>> @@ -26,6 +26,8 @@ struct altmode {
>>   	struct altmode			*plug[2];
>>   };
>>   
>> +void typec_notify_event(unsigned long event, void *data);
>> +
>>   #define to_altmode(d) container_of(d, struct altmode, adev)
>>   
>>   extern const struct bus_type typec_bus;
>> diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
>> index 9b2647cb199b..9d2aa3dd3f56 100644
>> --- a/drivers/usb/typec/class.c
>> +++ b/drivers/usb/typec/class.c
>> @@ -600,6 +600,8 @@ typec_register_altmode(struct device *parent,
>>   		return ERR_PTR(ret);
>>   	}
>>   
>> +	typec_notify_event(TYPEC_ALTMODE_REGISTERED, &alt->adev);
>> +
>>   	return &alt->adev;
>>   }
> You need to also send TYPEC_ALTMODE_UNREGISTERED notification in
> typec_unregister_altmode().
>
Sorry, I left that out. I will fix this in v10. Thank you.

-- 
Best,
Chaoyi



From chaoyi.chen at rock-chips.com  Mon Nov 17 00:47:25 2025
From: chaoyi.chen at rock-chips.com (Chaoyi Chen)
Date: Mon, 17 Nov 2025 16:47:25 +0800
Subject: [PATCH v9 03/10] drm/bridge: Implement generic USB Type-C DP HPD
 bridge
In-Reply-To: <aRrffpTP5KyAFVnx@kuha.fi.intel.com>
References: <20251111105040.94-1-kernel@airkyi.com>
 <20251111105040.94-4-kernel@airkyi.com> <aRrffpTP5KyAFVnx@kuha.fi.intel.com>
Message-ID: <140cd555-d512-4712-9d71-2d7f188a74fb@rock-chips.com>

On 11/17/2025 4:40 PM, Heikki Krogerus wrote:

> Tue, Nov 11, 2025 at 06:50:33PM +0800, Chaoyi Chen kirjoitti:
>> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
>>
>> The HPD function of Type-C DP is implemented through
>> drm_connector_oob_hotplug_event(). For embedded DP, it is required
>> that the DRM connector fwnode corresponds to the Type-C port fwnode.
>>
>> To describe the relationship between the DP controller and the Type-C
>> port device, we usually using drm_bridge to build a bridge chain.
>>
>> Now several USB-C controller drivers have already implemented the DP
>> HPD bridge function provided by aux-hpd-bridge.c, it will build a DP
>> HPD bridge on USB-C connector port device.
>>
>> But this requires the USB-C controller driver to manually register the
>> HPD bridge. If the driver does not implement this feature, the bridge
>> will not be create.
>>
>> So this patch implements a generic DP HPD bridge based on
>> aux-hpd-bridge.c. It will monitor Type-C bus events, and when a
>> Type-C port device containing the DP svid is registered, it will
>> create an HPD bridge for it without the need for the USB-C controller
>> driver to implement it.
>>
>> Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> Normally there is no "help" section for hidden config options. I
> guess it can not cause any harm? It is a bit confusing, though. But
> FWIW:

The hidden options "DRM_AUX_BRIDGE" and "DRM_AUX_HPD_BRIDGE" also have a help section.

I think this is just for comment purposes :)


>
> Reviewed-by: Heikki Krogerus <heikki.krogerus at linux.intel.com>
>
>> ---
>>
>> Changes in v9:
>> - Remove the exposed DRM_AUX_HPD_BRIDGE option, and select
>> DRM_AUX_HPD_TYPEC_BRIDGE when it is available.
>> - Add more commit comment about problem background.
>>
>> Changes in v8:
>> - Merge generic DP HPD bridge into one module.
>>
>>   drivers/gpu/drm/bridge/Kconfig                | 10 ++++
>>   drivers/gpu/drm/bridge/Makefile               |  1 +
>>   .../gpu/drm/bridge/aux-hpd-typec-dp-bridge.c  | 50 +++++++++++++++++++
>>   3 files changed, 61 insertions(+)
>>   create mode 100644 drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
>>
>> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
>> index a250afd8d662..559487aa09a9 100644
>> --- a/drivers/gpu/drm/bridge/Kconfig
>> +++ b/drivers/gpu/drm/bridge/Kconfig
>> @@ -30,6 +30,16 @@ config DRM_AUX_HPD_BRIDGE
>>   	  Simple bridge that terminates the bridge chain and provides HPD
>>   	  support.
>>   
>> +if DRM_AUX_HPD_BRIDGE
>> +config DRM_AUX_HPD_TYPEC_BRIDGE
>> +	tristate
>> +	depends on TYPEC || !TYPEC
>> +	default TYPEC
>> +	help
>> +	  Simple bridge that terminates the bridge chain and provides HPD
>> +	  support. It build bridge on each USB-C connector device node.
>> +endif
>> +
>>   menu "Display Interface Bridges"
>>   	depends on DRM && DRM_BRIDGE
>>   
>> diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
>> index c7dc03182e59..a3a0393d2e72 100644
>> --- a/drivers/gpu/drm/bridge/Makefile
>> +++ b/drivers/gpu/drm/bridge/Makefile
>> @@ -1,6 +1,7 @@
>>   # SPDX-License-Identifier: GPL-2.0
>>   obj-$(CONFIG_DRM_AUX_BRIDGE) += aux-bridge.o
>>   obj-$(CONFIG_DRM_AUX_HPD_BRIDGE) += aux-hpd-bridge.o
>> +obj-$(CONFIG_DRM_AUX_HPD_TYPEC_BRIDGE) += aux-hpd-typec-dp-bridge.o
>>   obj-$(CONFIG_DRM_CHIPONE_ICN6211) += chipone-icn6211.o
>>   obj-$(CONFIG_DRM_CHRONTEL_CH7033) += chrontel-ch7033.o
>>   obj-$(CONFIG_DRM_CROS_EC_ANX7688) += cros-ec-anx7688.o
>> diff --git a/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c b/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
>> new file mode 100644
>> index 000000000000..9cb6a0cb0f0a
>> --- /dev/null
>> +++ b/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
>> @@ -0,0 +1,50 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +#include <linux/of.h>
>> +#include <linux/usb/typec_altmode.h>
>> +#include <linux/usb/typec_dp.h>
>> +
>> +#include <drm/bridge/aux-bridge.h>
>> +
>> +static int drm_typec_bus_event(struct notifier_block *nb,
>> +			       unsigned long action, void *data)
>> +{
>> +	struct typec_altmode *alt = (struct typec_altmode *)data;
>> +
>> +	if (action != TYPEC_ALTMODE_REGISTERED)
>> +		goto done;
>> +
>> +	if (is_typec_partner(&alt->dev) || alt->svid != USB_TYPEC_DP_SID)
>> +		goto done;
>> +
>> +	/*
>> +	 * alt->dev.parent->parent : USB-C controller device
>> +	 * alt->dev.parent         : USB-C connector device
>> +	 */
>> +	drm_dp_hpd_bridge_register(alt->dev.parent->parent,
>> +				   to_of_node(alt->dev.parent->fwnode));
>> +
>> +done:
>> +	return NOTIFY_OK;
>> +}
>> +
>> +static struct notifier_block drm_typec_event_nb = {
>> +	.notifier_call = drm_typec_bus_event,
>> +};
>> +
>> +static void drm_aux_hpd_typec_dp_bridge_module_exit(void)
>> +{
>> +	typec_altmode_unregister_notify(&drm_typec_event_nb);
>> +}
>> +
>> +static int __init drm_aux_hpd_typec_dp_bridge_module_init(void)
>> +{
>> +	typec_altmode_register_notify(&drm_typec_event_nb);
>> +
>> +	return 0;
>> +}
>> +
>> +module_init(drm_aux_hpd_typec_dp_bridge_module_init);
>> +module_exit(drm_aux_hpd_typec_dp_bridge_module_exit);
>> +
>> +MODULE_DESCRIPTION("DRM TYPEC DP HPD BRIDGE");
>> +MODULE_LICENSE("GPL");
>> -- 
>> 2.51.1

-- 
Best,
Chaoyi



From devnull+michael.riesch.collabora.com at kernel.org  Mon Nov 17 02:01:08 2025
From: devnull+michael.riesch.collabora.com at kernel.org (Michael Riesch via B4 Relay)
Date: Mon, 17 Nov 2025 11:01:08 +0100
Subject: [PATCH 0/3] media: rockchip: add driver for the rockchip mipi
 csi-2 receiver
Message-ID: <20251114-rockchip-mipi-receiver-v1-0-d13086e810dd@collabora.com>

Habidere,

This series adds support for the Rockchip MIPI CSI-2 Receiver that is
integrated into recent Rockchip SoCs, such as the RK3568 and the RK3588.

These changes have been discussed and reviewed thoroughly (see [0] and
predecessors). As has been discussed in [0], it would be beneficial to
add support for the split mode (a feature of the Rockchip CSI-2 DPHY)
before integrating the MIPI CSI-2 Receiver into the respective SoC
device tree includes. However, we can readily add the DT binding and
the driver as I am positive they will not need to be changed when this
feature is introduced.

This constitutes a small step towards mainline video capture and camera
support on the Rockchip RK3588.

Looking forward to your comments!

Signed-off-by: Michael Riesch <michael.riesch at collabora.com>

[0] https://lore.kernel.org/r/20240220-rk3568-vicap-v14-0-b38b6da0fc80 at collabora.com

---
Michael Riesch (3):
      media: dt-bindings: add rockchip mipi csi-2 receiver
      media: rockchip: add driver for the rockchip mipi csi-2 receiver
      arm64: defconfig: enable rockchip mipi csi-2 receiver

 .../bindings/media/rockchip,rk3568-mipi-csi.yaml   | 146 ++++
 MAINTAINERS                                        |   7 +
 arch/arm64/configs/defconfig                       |   1 +
 drivers/media/platform/rockchip/Kconfig            |   1 +
 drivers/media/platform/rockchip/Makefile           |   1 +
 drivers/media/platform/rockchip/rkcsi/Kconfig      |  16 +
 drivers/media/platform/rockchip/rkcsi/Makefile     |   3 +
 drivers/media/platform/rockchip/rkcsi/rkcsi.c      | 742 +++++++++++++++++++++
 8 files changed, 917 insertions(+)
---
base-commit: 1f2353f5a1af995efbf7bea44341aa0d03460b28
change-id: 20251114-rockchip-mipi-receiver-0baf244c9c8e

Best regards,
-- 
Michael Riesch <michael.riesch at collabora.com>




From devnull+michael.riesch.collabora.com at kernel.org  Mon Nov 17 02:01:09 2025
From: devnull+michael.riesch.collabora.com at kernel.org (Michael Riesch via B4 Relay)
Date: Mon, 17 Nov 2025 11:01:09 +0100
Subject: [PATCH 1/3] media: dt-bindings: add rockchip mipi csi-2 receiver
In-Reply-To: <20251114-rockchip-mipi-receiver-v1-0-d13086e810dd@collabora.com>
References: <20251114-rockchip-mipi-receiver-v1-0-d13086e810dd@collabora.com>
Message-ID: <20251114-rockchip-mipi-receiver-v1-1-d13086e810dd@collabora.com>

From: Michael Riesch <michael.riesch at collabora.com>

Add documentation for the Rockchip MIPI CSI-2 Receiver.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
Reviewed-by: Bryan O'Donoghue <bod at kernel.org>
Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
Signed-off-by: Michael Riesch <michael.riesch at collabora.com>
---
 .../bindings/media/rockchip,rk3568-mipi-csi.yaml   | 146 +++++++++++++++++++++
 MAINTAINERS                                        |   6 +
 2 files changed, 152 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/rockchip,rk3568-mipi-csi.yaml b/Documentation/devicetree/bindings/media/rockchip,rk3568-mipi-csi.yaml
new file mode 100644
index 000000000000..52fe959af8f9
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/rockchip,rk3568-mipi-csi.yaml
@@ -0,0 +1,146 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/rockchip,rk3568-mipi-csi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip MIPI CSI-2 Receiver
+
+maintainers:
+  - Michael Riesch <michael.riesch at collabora.com>
+
+description:
+  The Rockchip MIPI CSI-2 Receiver is a CSI-2 bridge with one input port and
+  one output port. It receives the data with the help of an external MIPI PHY
+  (C-PHY or D-PHY) and passes it to the Rockchip RK3568 Video Capture (VICAP)
+  block.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - rockchip,rk3588-mipi-csi
+          - const: rockchip,rk3568-mipi-csi
+      - const: rockchip,rk3568-mipi-csi
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    items:
+      - description: Interrupt that signals changes in CSI2HOST_ERR1.
+      - description: Interrupt that signals changes in CSI2HOST_ERR2.
+
+  interrupt-names:
+    items:
+      - const: err1
+      - const: err2
+
+  clocks:
+    maxItems: 1
+
+  phys:
+    maxItems: 1
+    description: MIPI C-PHY or D-PHY.
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port at 0:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description: Input port node. Connect to e.g., a MIPI CSI-2 image sensor.
+
+        properties:
+          endpoint:
+            $ref: video-interfaces.yaml#
+            unevaluatedProperties: false
+
+            properties:
+              bus-type:
+                enum:
+                  - 1 # MEDIA_BUS_TYPE_CSI2_CPHY
+                  - 4 # MEDIA_BUS_TYPE_CSI2_DPHY
+
+              data-lanes:
+                minItems: 1
+                maxItems: 4
+
+            required:
+              - bus-type
+              - data-lanes
+
+      port at 1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: Output port connected to a RK3568 VICAP port.
+
+    required:
+      - port at 0
+      - port at 1
+
+  power-domains:
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - phys
+  - ports
+  - power-domains
+  - resets
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/rk3568-cru.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/media/video-interfaces.h>
+    #include <dt-bindings/power/rk3568-power.h>
+
+    soc {
+        interrupt-parent = <&gic>;
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        csi: csi at fdfb0000 {
+            compatible = "rockchip,rk3568-mipi-csi";
+            reg = <0x0 0xfdfb0000 0x0 0x10000>;
+            interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+                         <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+            interrupt-names = "err1", "err2";
+            clocks = <&cru PCLK_CSI2HOST1>;
+            phys = <&csi_dphy>;
+            power-domains = <&power RK3568_PD_VI>;
+            resets = <&cru SRST_P_CSI2HOST1>;
+
+            ports {
+                #address-cells = <1>;
+                #size-cells = <0>;
+
+                csi_in: port at 0 {
+                    reg = <0>;
+
+                    csi_input: endpoint {
+                        bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>;
+                        data-lanes = <1 2 3 4>;
+                        remote-endpoint = <&imx415_output>;
+                    };
+                };
+
+                csi_out: port at 1 {
+                    reg = <1>;
+
+                    csi_output: endpoint {
+                        remote-endpoint = <&vicap_mipi_input>;
+                    };
+                };
+            };
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 4205ca007e07..145473671a4a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22299,6 +22299,12 @@ F:	Documentation/userspace-api/media/v4l/metafmt-rkisp1.rst
 F:	drivers/media/platform/rockchip/rkisp1
 F:	include/uapi/linux/rkisp1-config.h
 
+ROCKCHIP MIPI CSI-2 RECEIVER DRIVER
+M:	Michael Riesch <michael.riesch at collabora.com>
+L:	linux-media at vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/media/rockchip,rk3568-mipi-csi.yaml
+
 ROCKCHIP RK3568 RANDOM NUMBER GENERATOR SUPPORT
 M:	Daniel Golle <daniel at makrotopia.org>
 M:	Aurelien Jarno <aurelien at aurel32.net>

-- 
2.39.5




From devnull+michael.riesch.collabora.com at kernel.org  Mon Nov 17 02:01:10 2025
From: devnull+michael.riesch.collabora.com at kernel.org (Michael Riesch via B4 Relay)
Date: Mon, 17 Nov 2025 11:01:10 +0100
Subject: [PATCH 2/3] media: rockchip: add driver for the rockchip mipi
 csi-2 receiver
In-Reply-To: <20251114-rockchip-mipi-receiver-v1-0-d13086e810dd@collabora.com>
References: <20251114-rockchip-mipi-receiver-v1-0-d13086e810dd@collabora.com>
Message-ID: <20251114-rockchip-mipi-receiver-v1-2-d13086e810dd@collabora.com>

From: Michael Riesch <michael.riesch at collabora.com>

The Rockchip MIPI CSI-2 Receiver is a CSI-2 bridge with one input
port and one output port. It receives the data with the help of an
external MIPI PHY (C-PHY or D-PHY) and passes it to the Rockchip
Video Capture (VICAP) block.

Add a V4L2 subdevice driver for this unit.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
Reviewed-by: Mehdi Djait <mehdi.djait at linux.intel.com>
Signed-off-by: Michael Riesch <michael.riesch at collabora.com>
---
 MAINTAINERS                                    |   1 +
 drivers/media/platform/rockchip/Kconfig        |   1 +
 drivers/media/platform/rockchip/Makefile       |   1 +
 drivers/media/platform/rockchip/rkcsi/Kconfig  |  16 +
 drivers/media/platform/rockchip/rkcsi/Makefile |   3 +
 drivers/media/platform/rockchip/rkcsi/rkcsi.c  | 742 +++++++++++++++++++++++++
 6 files changed, 764 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 145473671a4a..b389f2e631ce 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22304,6 +22304,7 @@ M:	Michael Riesch <michael.riesch at collabora.com>
 L:	linux-media at vger.kernel.org
 S:	Maintained
 F:	Documentation/devicetree/bindings/media/rockchip,rk3568-mipi-csi.yaml
+F:	drivers/media/platform/rockchip/rkcsi/
 
 ROCKCHIP RK3568 RANDOM NUMBER GENERATOR SUPPORT
 M:	Daniel Golle <daniel at makrotopia.org>
diff --git a/drivers/media/platform/rockchip/Kconfig b/drivers/media/platform/rockchip/Kconfig
index ba401d32f01b..54b698c4cd2c 100644
--- a/drivers/media/platform/rockchip/Kconfig
+++ b/drivers/media/platform/rockchip/Kconfig
@@ -4,5 +4,6 @@ comment "Rockchip media platform drivers"
 
 source "drivers/media/platform/rockchip/rga/Kconfig"
 source "drivers/media/platform/rockchip/rkcif/Kconfig"
+source "drivers/media/platform/rockchip/rkcsi/Kconfig"
 source "drivers/media/platform/rockchip/rkisp1/Kconfig"
 source "drivers/media/platform/rockchip/rkvdec/Kconfig"
diff --git a/drivers/media/platform/rockchip/Makefile b/drivers/media/platform/rockchip/Makefile
index 0e0b2cbbd4bd..522a7d3e30b0 100644
--- a/drivers/media/platform/rockchip/Makefile
+++ b/drivers/media/platform/rockchip/Makefile
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-y += rga/
 obj-y += rkcif/
+obj-y += rkcsi/
 obj-y += rkisp1/
 obj-y += rkvdec/
diff --git a/drivers/media/platform/rockchip/rkcsi/Kconfig b/drivers/media/platform/rockchip/rkcsi/Kconfig
new file mode 100644
index 000000000000..d8004198c386
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkcsi/Kconfig
@@ -0,0 +1,16 @@
+config VIDEO_ROCKCHIP_CSI
+	tristate "Rockchip MIPI CSI-2 Receiver"
+	depends on VIDEO_DEV
+	depends on ARCH_ROCKCHIP || COMPILE_TEST
+	depends on V4L_PLATFORM_DRIVERS
+	depends on PM && COMMON_CLK
+	select MEDIA_CONTROLLER
+	select V4L2_FWNODE
+	select VIDEO_V4L2_SUBDEV_API
+	help
+	  This is a driver for Rockchip MIPI CSI-2 Receiver. It is featured
+	  in various Rockchips SoCs, usually in combination with a Video
+	  Capture (VICAP) unit (see Rockchip Camera Interface (CIF) driver).
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called rockchip-mipi-csi.
diff --git a/drivers/media/platform/rockchip/rkcsi/Makefile b/drivers/media/platform/rockchip/rkcsi/Makefile
new file mode 100644
index 000000000000..147712cbb68a
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkcsi/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_VIDEO_ROCKCHIP_CSI) += rockchip-mipi-csi.o
+rockchip-mipi-csi-objs += rkcsi.o
diff --git a/drivers/media/platform/rockchip/rkcsi/rkcsi.c b/drivers/media/platform/rockchip/rkcsi/rkcsi.c
new file mode 100644
index 000000000000..d4108ce5bbf9
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkcsi/rkcsi.c
@@ -0,0 +1,742 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip MIPI CSI-2 Receiver Driver
+ *
+ * Copyright (C) 2019 Rockchip Electronics Co., Ltd.
+ * Copyright (C) 2025 Michael Riesch <michael.riesch at wolfvision.net>
+ * Copyright (C) 2025 Collabora, Ltd.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
+#include <linux/of_platform.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+
+#include <media/mipi-csi2.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-subdev.h>
+
+#define CSI2HOST_N_LANES     0x04
+#define CSI2HOST_CSI2_RESETN 0x10
+#define CSI2HOST_PHY_STATE   0x14
+#define CSI2HOST_ERR1	     0x20
+#define CSI2HOST_ERR2	     0x24
+#define CSI2HOST_MSK1	     0x28
+#define CSI2HOST_MSK2	     0x2c
+#define CSI2HOST_CONTROL     0x40
+
+#define SW_CPHY_EN(x)	     ((x) << 0)
+#define SW_DSI_EN(x)	     ((x) << 4)
+#define SW_DATATYPE_FS(x)    ((x) << 8)
+#define SW_DATATYPE_FE(x)    ((x) << 14)
+#define SW_DATATYPE_LS(x)    ((x) << 20)
+#define SW_DATATYPE_LE(x)    ((x) << 26)
+
+#define RKCSI_CLKS_MAX	     1
+
+enum {
+	RKCSI_PAD_SINK,
+	RKCSI_PAD_SRC,
+	RKCSI_PAD_MAX,
+};
+
+struct rkcsi_format {
+	u32 code;
+	u8 depth;
+	u8 csi_dt;
+};
+
+struct rkcsi_device {
+	struct device *dev;
+
+	void __iomem *base_addr;
+	struct clk_bulk_data *clks;
+	unsigned int clks_num;
+	struct phy *phy;
+	struct reset_control *reset;
+
+	const struct rkcsi_format *formats;
+	unsigned int formats_num;
+
+	struct media_pad pads[RKCSI_PAD_MAX];
+	struct v4l2_async_notifier notifier;
+	struct v4l2_fwnode_endpoint vep;
+	struct v4l2_subdev sd;
+
+	struct v4l2_subdev *source_sd;
+	u32 source_pad;
+};
+
+static const struct v4l2_mbus_framefmt default_format = {
+	.width = 3840,
+	.height = 2160,
+	.code = MEDIA_BUS_FMT_SRGGB10_1X10,
+	.field = V4L2_FIELD_NONE,
+	.colorspace = V4L2_COLORSPACE_RAW,
+	.ycbcr_enc = V4L2_YCBCR_ENC_601,
+	.quantization = V4L2_QUANTIZATION_FULL_RANGE,
+	.xfer_func = V4L2_XFER_FUNC_NONE,
+};
+
+static const struct rkcsi_format formats[] = {
+	/* YUV formats */
+	{
+		.code = MEDIA_BUS_FMT_YUYV8_1X16,
+		.depth = 16,
+		.csi_dt = MIPI_CSI2_DT_YUV422_8B,
+	},
+	{
+		.code = MEDIA_BUS_FMT_UYVY8_1X16,
+		.depth = 16,
+		.csi_dt = MIPI_CSI2_DT_YUV422_8B,
+	},
+	{
+		.code = MEDIA_BUS_FMT_YVYU8_1X16,
+		.depth = 16,
+		.csi_dt = MIPI_CSI2_DT_YUV422_8B,
+	},
+	{
+		.code = MEDIA_BUS_FMT_VYUY8_1X16,
+		.depth = 16,
+		.csi_dt = MIPI_CSI2_DT_YUV422_8B,
+	},
+	/* RGB formats */
+	{
+		.code = MEDIA_BUS_FMT_RGB888_1X24,
+		.depth = 24,
+		.csi_dt = MIPI_CSI2_DT_RGB888,
+	},
+	{
+		.code = MEDIA_BUS_FMT_BGR888_1X24,
+		.depth = 24,
+		.csi_dt = MIPI_CSI2_DT_RGB888,
+	},
+	/* Bayer formats */
+	{
+		.code = MEDIA_BUS_FMT_SBGGR8_1X8,
+		.depth = 8,
+		.csi_dt = MIPI_CSI2_DT_RAW8,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGBRG8_1X8,
+		.depth = 8,
+		.csi_dt = MIPI_CSI2_DT_RAW8,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGRBG8_1X8,
+		.depth = 8,
+		.csi_dt = MIPI_CSI2_DT_RAW8,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SRGGB8_1X8,
+		.depth = 8,
+		.csi_dt = MIPI_CSI2_DT_RAW8,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SBGGR10_1X10,
+		.depth = 10,
+		.csi_dt = MIPI_CSI2_DT_RAW10,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGBRG10_1X10,
+		.depth = 10,
+		.csi_dt = MIPI_CSI2_DT_RAW10,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGRBG10_1X10,
+		.depth = 10,
+		.csi_dt = MIPI_CSI2_DT_RAW10,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SRGGB10_1X10,
+		.depth = 10,
+		.csi_dt = MIPI_CSI2_DT_RAW10,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SBGGR12_1X12,
+		.depth = 12,
+		.csi_dt = MIPI_CSI2_DT_RAW12,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGBRG12_1X12,
+		.depth = 12,
+		.csi_dt = MIPI_CSI2_DT_RAW12,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGRBG12_1X12,
+		.depth = 12,
+		.csi_dt = MIPI_CSI2_DT_RAW12,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SRGGB12_1X12,
+		.depth = 12,
+		.csi_dt = MIPI_CSI2_DT_RAW12,
+	},
+};
+
+static inline struct rkcsi_device *to_rkcsi(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct rkcsi_device, sd);
+}
+
+static inline __maybe_unused void rkcsi_write(struct rkcsi_device *csi_dev,
+					      unsigned int addr, u32 val)
+{
+	writel(val, csi_dev->base_addr + addr);
+}
+
+static inline __maybe_unused u32 rkcsi_read(struct rkcsi_device *csi_dev,
+					    unsigned int addr)
+{
+	return readl(csi_dev->base_addr + addr);
+}
+
+static const struct rkcsi_format *
+rkcsi_find_format(struct rkcsi_device *csi_dev, u32 mbus_code)
+{
+	const struct rkcsi_format *format;
+
+	WARN_ON(csi_dev->formats_num == 0);
+
+	for (int i = 0; i < csi_dev->formats_num; i++) {
+		format = &csi_dev->formats[i];
+		if (format->code == mbus_code)
+			return format;
+	}
+
+	return NULL;
+}
+
+static int rkcsi_start(struct rkcsi_device *csi_dev)
+{
+	struct media_pad *source_pad =
+		&csi_dev->source_sd->entity.pads[csi_dev->source_pad];
+	enum v4l2_mbus_type bus_type = csi_dev->vep.bus_type;
+	union phy_configure_opts opts;
+	s64 link_freq;
+	u32 lanes = csi_dev->vep.bus.mipi_csi2.num_data_lanes;
+	u32 control = 0;
+	int ret;
+
+	if (lanes < 1 || lanes > 4)
+		return -EINVAL;
+
+	/* set mult and div to 0, thus completely rely on V4L2_CID_LINK_FREQ */
+	link_freq = v4l2_get_link_freq(source_pad, 0, 0);
+	if (link_freq <= 0)
+		return -EINVAL;
+
+	if (bus_type == V4L2_MBUS_CSI2_DPHY) {
+		struct phy_configure_opts_mipi_dphy *cfg = &opts.mipi_dphy;
+
+		ret = phy_mipi_dphy_get_default_config_for_hsclk(link_freq * 2,
+								 lanes, cfg);
+		if (ret)
+			return ret;
+
+		ret = phy_set_mode(csi_dev->phy, PHY_MODE_MIPI_DPHY);
+		if (ret)
+			return ret;
+
+		ret = phy_configure(csi_dev->phy, &opts);
+		if (ret)
+			return ret;
+
+		control |= SW_CPHY_EN(0);
+
+	} else if (bus_type == V4L2_MBUS_CSI2_CPHY) {
+		/* TODO: implement CPHY configuration */
+		return -EOPNOTSUPP;
+	} else {
+		return -EINVAL;
+	}
+
+	control |= SW_DATATYPE_FS(0x00) | SW_DATATYPE_FE(0x01) |
+		   SW_DATATYPE_LS(0x02) | SW_DATATYPE_LE(0x03);
+
+	rkcsi_write(csi_dev, CSI2HOST_N_LANES, lanes - 1);
+	rkcsi_write(csi_dev, CSI2HOST_CONTROL, control);
+	rkcsi_write(csi_dev, CSI2HOST_CSI2_RESETN, 1);
+
+	ret = phy_power_on(csi_dev->phy);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void rkcsi_stop(struct rkcsi_device *csi_dev)
+{
+	phy_power_off(csi_dev->phy);
+
+	rkcsi_write(csi_dev, CSI2HOST_CSI2_RESETN, 0);
+	rkcsi_write(csi_dev, CSI2HOST_MSK1, ~0);
+	rkcsi_write(csi_dev, CSI2HOST_MSK2, ~0);
+}
+
+static const struct media_entity_operations rkcsi_media_ops = {
+	.link_validate = v4l2_subdev_link_validate,
+};
+
+static int rkcsi_enum_mbus_code(struct v4l2_subdev *sd,
+				struct v4l2_subdev_state *sd_state,
+				struct v4l2_subdev_mbus_code_enum *code)
+{
+	struct rkcsi_device *csi_dev = to_rkcsi(sd);
+
+	if (code->pad == RKCSI_PAD_SRC) {
+		const struct v4l2_mbus_framefmt *sink_fmt;
+
+		if (code->index)
+			return -EINVAL;
+
+		sink_fmt = v4l2_subdev_state_get_format(sd_state,
+							RKCSI_PAD_SINK);
+		code->code = sink_fmt->code;
+
+		return 0;
+	} else if (code->pad == RKCSI_PAD_SINK) {
+		if (code->index > csi_dev->formats_num)
+			return -EINVAL;
+
+		code->code = csi_dev->formats[code->index].code;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static int rkcsi_set_fmt(struct v4l2_subdev *sd,
+			 struct v4l2_subdev_state *state,
+			 struct v4l2_subdev_format *format)
+{
+	struct rkcsi_device *csi_dev = to_rkcsi(sd);
+	const struct rkcsi_format *fmt;
+	struct v4l2_mbus_framefmt *sink, *src;
+
+	/* the format on the source pad always matches the sink pad */
+	if (format->pad == RKCSI_PAD_SRC)
+		return v4l2_subdev_get_fmt(sd, state, format);
+
+	sink = v4l2_subdev_state_get_format(state, format->pad, format->stream);
+	if (!sink)
+		return -EINVAL;
+
+	fmt = rkcsi_find_format(csi_dev, format->format.code);
+	if (!fmt)
+		format->format = default_format;
+
+	*sink = format->format;
+
+	/* propagate the format to the source pad */
+	src = v4l2_subdev_state_get_opposite_stream_format(state, format->pad,
+							   format->stream);
+	if (!src)
+		return -EINVAL;
+
+	*src = *sink;
+
+	return 0;
+}
+
+static int rkcsi_set_routing(struct v4l2_subdev *sd,
+			     struct v4l2_subdev_state *state,
+			     enum v4l2_subdev_format_whence which,
+			     struct v4l2_subdev_krouting *routing)
+{
+	int ret;
+
+	ret = v4l2_subdev_routing_validate(sd, routing,
+					   V4L2_SUBDEV_ROUTING_ONLY_1_TO_1);
+	if (ret)
+		return ret;
+
+	ret = v4l2_subdev_set_routing_with_fmt(sd, state, routing,
+					       &default_format);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int rkcsi_enable_streams(struct v4l2_subdev *sd,
+				struct v4l2_subdev_state *state, u32 pad,
+				u64 streams_mask)
+{
+	struct rkcsi_device *csi_dev = to_rkcsi(sd);
+	struct v4l2_subdev *remote_sd;
+	struct media_pad *sink_pad, *remote_pad;
+	struct device *dev = csi_dev->dev;
+	u64 mask;
+	int ret;
+
+	sink_pad = &sd->entity.pads[RKCSI_PAD_SINK];
+	remote_pad = media_pad_remote_pad_first(sink_pad);
+	remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity);
+
+	mask = v4l2_subdev_state_xlate_streams(state, RKCSI_PAD_SINK,
+					       RKCSI_PAD_SRC, &streams_mask);
+
+	ret = pm_runtime_resume_and_get(dev);
+	if (ret)
+		goto err;
+
+	ret = rkcsi_start(csi_dev);
+	if (ret) {
+		dev_err(dev, "failed to enable CSI hardware\n");
+		goto err_pm_runtime_put;
+	}
+
+	ret = v4l2_subdev_enable_streams(remote_sd, remote_pad->index, mask);
+	if (ret)
+		goto err_csi_stop;
+
+	return 0;
+
+err_csi_stop:
+	rkcsi_stop(csi_dev);
+err_pm_runtime_put:
+	pm_runtime_put_sync(dev);
+err:
+	return ret;
+}
+
+static int rkcsi_disable_streams(struct v4l2_subdev *sd,
+				 struct v4l2_subdev_state *state, u32 pad,
+				 u64 streams_mask)
+{
+	struct rkcsi_device *csi_dev = to_rkcsi(sd);
+	struct v4l2_subdev *remote_sd;
+	struct media_pad *sink_pad, *remote_pad;
+	struct device *dev = csi_dev->dev;
+	u64 mask;
+	int ret;
+
+	sink_pad = &sd->entity.pads[RKCSI_PAD_SINK];
+	remote_pad = media_pad_remote_pad_first(sink_pad);
+	remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity);
+
+	mask = v4l2_subdev_state_xlate_streams(state, RKCSI_PAD_SINK,
+					       RKCSI_PAD_SRC, &streams_mask);
+
+	ret = v4l2_subdev_disable_streams(remote_sd, remote_pad->index, mask);
+
+	rkcsi_stop(csi_dev);
+
+	pm_runtime_mark_last_busy(dev);
+	pm_runtime_put_autosuspend(dev);
+
+	return ret;
+}
+
+static const struct v4l2_subdev_pad_ops rkcsi_pad_ops = {
+	.enum_mbus_code = rkcsi_enum_mbus_code,
+	.get_fmt = v4l2_subdev_get_fmt,
+	.set_fmt = rkcsi_set_fmt,
+	.set_routing = rkcsi_set_routing,
+	.enable_streams = rkcsi_enable_streams,
+	.disable_streams = rkcsi_disable_streams,
+};
+
+static const struct v4l2_subdev_ops rkcsi_ops = {
+	.pad = &rkcsi_pad_ops,
+};
+
+static int rkcsi_init_state(struct v4l2_subdev *sd,
+			    struct v4l2_subdev_state *state)
+{
+	struct v4l2_subdev_route routes[] = {
+		{
+			.sink_pad = RKCSI_PAD_SINK,
+			.sink_stream = 0,
+			.source_pad = RKCSI_PAD_SRC,
+			.source_stream = 0,
+			.flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
+		},
+	};
+	struct v4l2_subdev_krouting routing = {
+		.len_routes = ARRAY_SIZE(routes),
+		.num_routes = ARRAY_SIZE(routes),
+		.routes = routes,
+	};
+	int ret;
+
+	ret = v4l2_subdev_set_routing_with_fmt(sd, state, &routing,
+					       &default_format);
+
+	return ret;
+}
+
+static const struct v4l2_subdev_internal_ops rkcsi_internal_ops = {
+	.init_state = rkcsi_init_state,
+};
+
+static int rkcsi_notifier_bound(struct v4l2_async_notifier *notifier,
+				struct v4l2_subdev *sd,
+				struct v4l2_async_connection *asd)
+{
+	struct rkcsi_device *csi_dev =
+		container_of(notifier, struct rkcsi_device, notifier);
+	int source_pad;
+
+	source_pad = media_entity_get_fwnode_pad(&sd->entity, sd->fwnode,
+						 MEDIA_PAD_FL_SOURCE);
+	if (source_pad < 0) {
+		dev_err(csi_dev->dev, "failed to find source pad for %s\n",
+			sd->name);
+		return source_pad;
+	}
+
+	csi_dev->source_sd = sd;
+	csi_dev->source_pad = source_pad;
+
+	return media_create_pad_link(&sd->entity, source_pad,
+				     &csi_dev->sd.entity, RKCSI_PAD_SINK,
+				     MEDIA_LNK_FL_ENABLED);
+}
+
+static const struct v4l2_async_notifier_operations rkcsi_notifier_ops = {
+	.bound = rkcsi_notifier_bound,
+};
+
+static int rkcsi_register_notifier(struct rkcsi_device *csi_dev)
+{
+	struct v4l2_async_connection *asd;
+	struct v4l2_async_notifier *ntf = &csi_dev->notifier;
+	struct v4l2_fwnode_endpoint *vep = &csi_dev->vep;
+	struct v4l2_subdev *sd = &csi_dev->sd;
+	struct device *dev = csi_dev->dev;
+	struct fwnode_handle *ep;
+	int ret = 0;
+
+	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0, 0);
+	if (!ep)
+		return dev_err_probe(dev, -ENODEV, "failed to get endpoint\n");
+
+	vep->bus_type = V4L2_MBUS_UNKNOWN;
+	ret = v4l2_fwnode_endpoint_parse(ep, vep);
+	if (ret) {
+		ret = dev_err_probe(dev, ret, "failed to parse endpoint\n");
+		goto out;
+	}
+
+	if (vep->bus_type != V4L2_MBUS_CSI2_DPHY &&
+	    vep->bus_type != V4L2_MBUS_CSI2_CPHY) {
+		ret = dev_err_probe(dev, -EINVAL,
+				    "invalid bus type of endpoint\n");
+		goto out;
+	}
+
+	v4l2_async_subdev_nf_init(ntf, sd);
+	ntf->ops = &rkcsi_notifier_ops;
+
+	asd = v4l2_async_nf_add_fwnode_remote(ntf, ep,
+					      struct v4l2_async_connection);
+	if (IS_ERR(asd)) {
+		ret = PTR_ERR(asd);
+		goto err_nf_cleanup;
+	}
+
+	ret = v4l2_async_nf_register(ntf);
+	if (ret) {
+		ret = dev_err_probe(dev, ret, "failed to register notifier\n");
+		goto err_nf_cleanup;
+	}
+
+	goto out;
+
+err_nf_cleanup:
+	v4l2_async_nf_cleanup(ntf);
+out:
+	fwnode_handle_put(ep);
+	return ret;
+}
+
+static int rkcsi_register(struct rkcsi_device *csi_dev)
+{
+	struct media_pad *pads = csi_dev->pads;
+	struct v4l2_subdev *sd = &csi_dev->sd;
+	int ret;
+
+	ret = rkcsi_register_notifier(csi_dev);
+	if (ret)
+		goto err;
+
+	v4l2_subdev_init(sd, &rkcsi_ops);
+	sd->dev = csi_dev->dev;
+	sd->entity.ops = &rkcsi_media_ops;
+	sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
+	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_STREAMS;
+	sd->internal_ops = &rkcsi_internal_ops;
+	sd->owner = THIS_MODULE;
+	snprintf(sd->name, sizeof(sd->name), "rockchip-mipi-csi %s",
+		 dev_name(csi_dev->dev));
+
+	pads[RKCSI_PAD_SINK].flags = MEDIA_PAD_FL_SINK |
+				     MEDIA_PAD_FL_MUST_CONNECT;
+	pads[RKCSI_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;
+	ret = media_entity_pads_init(&sd->entity, RKCSI_PAD_MAX, pads);
+	if (ret)
+		goto err_notifier_unregister;
+
+	ret = v4l2_subdev_init_finalize(sd);
+	if (ret)
+		goto err_entity_cleanup;
+
+	ret = v4l2_async_register_subdev(sd);
+	if (ret) {
+		dev_err(sd->dev, "failed to register CSI subdev\n");
+		goto err_subdev_cleanup;
+	}
+
+	return 0;
+
+err_subdev_cleanup:
+	v4l2_subdev_cleanup(sd);
+err_entity_cleanup:
+	media_entity_cleanup(&sd->entity);
+err_notifier_unregister:
+	v4l2_async_nf_unregister(&csi_dev->notifier);
+	v4l2_async_nf_cleanup(&csi_dev->notifier);
+err:
+	return ret;
+}
+
+static void rkcsi_unregister(struct rkcsi_device *csi_dev)
+{
+	struct v4l2_subdev *sd = &csi_dev->sd;
+
+	v4l2_async_unregister_subdev(sd);
+	v4l2_subdev_cleanup(sd);
+	media_entity_cleanup(&sd->entity);
+	v4l2_async_nf_unregister(&csi_dev->notifier);
+	v4l2_async_nf_cleanup(&csi_dev->notifier);
+}
+
+static const struct of_device_id rkcsi_of_match[] = {
+	{
+		.compatible = "rockchip,rk3568-mipi-csi",
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(of, rkcsi_of_match);
+
+static int rkcsi_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct rkcsi_device *csi_dev;
+	int ret;
+
+	csi_dev = devm_kzalloc(dev, sizeof(*csi_dev), GFP_KERNEL);
+	if (!csi_dev)
+		return -ENOMEM;
+	csi_dev->dev = dev;
+	dev_set_drvdata(dev, csi_dev);
+
+	csi_dev->base_addr = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(csi_dev->base_addr))
+		return PTR_ERR(csi_dev->base_addr);
+
+	ret = devm_clk_bulk_get_all(dev, &csi_dev->clks);
+	if (ret != RKCSI_CLKS_MAX)
+		return dev_err_probe(dev, -ENODEV, "failed to get clocks\n");
+	csi_dev->clks_num = ret;
+
+	csi_dev->phy = devm_phy_get(dev, NULL);
+	if (IS_ERR(csi_dev->phy))
+		return dev_err_probe(dev, PTR_ERR(csi_dev->phy),
+				     "failed to get MIPI CSI PHY\n");
+
+	csi_dev->reset = devm_reset_control_get_exclusive(dev, NULL);
+	if (IS_ERR(csi_dev->reset))
+		return dev_err_probe(dev, PTR_ERR(csi_dev->reset),
+				     "failed to get reset\n");
+
+	csi_dev->formats = formats;
+	csi_dev->formats_num = ARRAY_SIZE(formats);
+
+	pm_runtime_enable(dev);
+
+	ret = phy_init(csi_dev->phy);
+	if (ret) {
+		ret = dev_err_probe(dev, ret,
+				    "failed to initialize MIPI CSI PHY\n");
+		goto err_pm_runtime_disable;
+	}
+
+	ret = rkcsi_register(csi_dev);
+	if (ret)
+		goto err_phy_exit;
+
+	return 0;
+
+err_phy_exit:
+	phy_exit(csi_dev->phy);
+err_pm_runtime_disable:
+	pm_runtime_disable(dev);
+	return ret;
+}
+
+static void rkcsi_remove(struct platform_device *pdev)
+{
+	struct rkcsi_device *csi_dev = platform_get_drvdata(pdev);
+	struct device *dev = &pdev->dev;
+
+	rkcsi_unregister(csi_dev);
+	phy_exit(csi_dev->phy);
+	pm_runtime_disable(dev);
+}
+
+static int rkcsi_runtime_suspend(struct device *dev)
+{
+	struct rkcsi_device *csi_dev = dev_get_drvdata(dev);
+
+	clk_bulk_disable_unprepare(csi_dev->clks_num, csi_dev->clks);
+
+	return 0;
+}
+
+static int rkcsi_runtime_resume(struct device *dev)
+{
+	struct rkcsi_device *csi_dev = dev_get_drvdata(dev);
+	int ret;
+
+	reset_control_assert(csi_dev->reset);
+	udelay(5);
+	reset_control_deassert(csi_dev->reset);
+
+	ret = clk_bulk_prepare_enable(csi_dev->clks_num, csi_dev->clks);
+	if (ret) {
+		dev_err(dev, "failed to enable clocks\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct dev_pm_ops rkcsi_pm_ops = {
+	.runtime_suspend = rkcsi_runtime_suspend,
+	.runtime_resume = rkcsi_runtime_resume,
+};
+
+static struct platform_driver rkcsi_drv = {
+	.driver = {
+		   .name = "rockchip-mipi-csi",
+		   .of_match_table = rkcsi_of_match,
+		   .pm = &rkcsi_pm_ops,
+	},
+	.probe = rkcsi_probe,
+	.remove = rkcsi_remove,
+};
+module_platform_driver(rkcsi_drv);
+
+MODULE_DESCRIPTION("Rockchip MIPI CSI-2 Receiver platform driver");
+MODULE_LICENSE("GPL");

-- 
2.39.5




From devnull+michael.riesch.collabora.com at kernel.org  Mon Nov 17 02:01:11 2025
From: devnull+michael.riesch.collabora.com at kernel.org (Michael Riesch via B4 Relay)
Date: Mon, 17 Nov 2025 11:01:11 +0100
Subject: [PATCH 3/3] arm64: defconfig: enable rockchip mipi csi-2 receiver
In-Reply-To: <20251114-rockchip-mipi-receiver-v1-0-d13086e810dd@collabora.com>
References: <20251114-rockchip-mipi-receiver-v1-0-d13086e810dd@collabora.com>
Message-ID: <20251114-rockchip-mipi-receiver-v1-3-d13086e810dd@collabora.com>

From: Michael Riesch <michael.riesch at collabora.com>

The Rockchip MIPI CSI-2 Receiver is integrated into recent Rockchip
SoCs, such as the RK3568 and the RK3588.
Enable the driver for it in the default configuration.

Signed-off-by: Michael Riesch <michael.riesch at collabora.com>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index e3a2d37bd104..a161666f2894 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -883,6 +883,7 @@ CONFIG_VIDEO_RENESAS_FCP=m
 CONFIG_VIDEO_RENESAS_FDP1=m
 CONFIG_VIDEO_RENESAS_VSP1=m
 CONFIG_VIDEO_RCAR_DRIF=m
+CONFIG_VIDEO_ROCKCHIP_CSI=m
 CONFIG_VIDEO_ROCKCHIP_RGA=m
 CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=m
 CONFIG_VIDEO_SAMSUNG_S5P_JPEG=m

-- 
2.39.5




From krzk at kernel.org  Mon Nov 17 02:06:23 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 17 Nov 2025 11:06:23 +0100
Subject: [PATCH 1/3] media: dt-bindings: add rockchip mipi csi-2 receiver
In-Reply-To: <20251114-rockchip-mipi-receiver-v1-1-d13086e810dd@collabora.com>
References: <20251114-rockchip-mipi-receiver-v1-0-d13086e810dd@collabora.com>
 <20251114-rockchip-mipi-receiver-v1-1-d13086e810dd@collabora.com>
Message-ID: <7c37017a-0769-4db3-be7f-af5837d4d102@kernel.org>

On 17/11/2025 11:01, Michael Riesch via B4 Relay wrote:
> From: Michael Riesch <michael.riesch at collabora.com>
> 
> Add documentation for the Rockchip MIPI CSI-2 Receiver.
> 
> Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
> Reviewed-by: Bryan O'Donoghue <bod at kernel.org>
> Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>


Please keep only one tag per person.

That's a v1 so I don't get how could you get these above and I could not
find answer in the cover letter either.

Best regards,
Krzysztof


From michael.opdenacker at rootcommit.com  Mon Nov 17 02:09:04 2025
From: michael.opdenacker at rootcommit.com (Michael Opdenacker)
Date: Mon, 17 Nov 2025 10:09:04 +0000 (UTC)
Subject: [PATCH v2 1/2] dt-bindings: arm: rockchip: Add Asus Tinker Board
 3 and 3S
In-Reply-To: <e4cd11d0-463c-e707-5110-6b92899b1ba3@manjaro.org>
References: <e4cd11d0-463c-e707-5110-6b92899b1ba3@manjaro.org>
Message-ID: <ae5c3bab-69fa-42c0-8beb-e5fdf0c95251@rootcommit.com>

Hi Dragan

Oops, indeed I overlooked this message!

On 11/15/25 01:52, Dragan Simic wrote:
> Hello Michael,
>
> Thanks for the v2!  Please, see some remarks below.
>
> On Friday, November 14, 2025 16:46 CET, michael.opdenacker at rootcommit.com wrote:
>> From: Michael Opdenacker <michael.opdenacker at rootcommit.com>
> I'm sorry for not mentioning it in my earlier responses, but this
> line is redundant, because it duplicates the From value found in
> the actual email message.
>
>> Document the compatible strings for Asus Tinker Board 3 [1] and 3S [2],
>> which are SBCs based on the Rockchip 3566 SoC.
>>
>> The "3S" version ("S" for "storage") just adds a 16 GB eMMC
>> and a "mask ROM" DIP switch to the "3" version.
>>
>> [1] https://tinker-board.asus.com/series/tinker-board-3.html
>> [2] https://tinker-board.asus.com/series/tinker-board-3s.html
>>
>> Signed-off-by: Michael Opdenacker <michael.opdenacker at rootcommit.com>
>> ---
>>   Documentation/devicetree/bindings/arm/rockchip.yaml | 11 +++++++++++
>>   1 file changed, 11 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
>> index 6aceaa8acbb2..cd249325a4d9 100644
>> --- a/Documentation/devicetree/bindings/arm/rockchip.yaml
>> +++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
>> @@ -86,6 +86,17 @@ properties:
>>             - const: asus,rk3288-tinker-s
>>             - const: rockchip,rk3288
>>   
>> +      - description: Asus Tinker Board 3
>> +        items:
>> +          - const: asus,rk3566-tinker-board-3
>> +          - const: rockchip,rk3566
>> +
>> +      - description: Asus Tinker Board 3S
>> +        items:
>> +          - const: asus,rk3566-tinker-board-3s
>> +          - const: asus,rk3566-tinker-board-3
>> +          - const: rockchip,rk3566
>> +
>>         - description: Beelink A1
>>           items:
>>             - const: azw,beelink-a1
> I'm sorry again for not mentioning it in my earlier responses,
> but shouldn't this addition be specified like below:
>
>       - description: Asus Tinker Board 3/3S
>         items:
>           - enum:
> 	   - asus,rk3566-tinker-board-3
>             - asus,rk3566-tinker-board-3s
>           - const: rockchip,rk3566
>
> ... because the introduced .dts files define the actual board DTs,
> by descending from the common .dtsi file, while they're compatible
> in the sense of the 3S board variant extending the 3 variant.

Indeed, that's the way it should be, looking at the rest of the 
rockchip.yaml file.

I was too hypnotized by the section for the original Tinkerboard, which 
doesn't follow this either (I'll send a separate patch).
Thanks a lot!
Cheers
Michael.

-- 
Michael Opdenacker
Root Commit
Yocto Project and OpenEmbedded Training course - Learn by doing:
https://rootcommit.com/training/yocto/



From adrian.hunter at intel.com  Mon Nov 17 02:22:23 2025
From: adrian.hunter at intel.com (Adrian Hunter)
Date: Mon, 17 Nov 2025 12:22:23 +0200
Subject: [PATCH 2/2] mmc: sdhci-of-dwcmshc: reduce CIT for better
 performance
In-Reply-To: <CAPDyKFqAwP=SDrQ_umkYk0qA50rVt=WJ5giDt8mt+RyBSCQDpQ@mail.gmail.com>
References: <1762933460-204066-1-git-send-email-shawn.lin@rock-chips.com>
 <1762933460-204066-2-git-send-email-shawn.lin@rock-chips.com>
 <CAPDyKFqAwP=SDrQ_umkYk0qA50rVt=WJ5giDt8mt+RyBSCQDpQ@mail.gmail.com>
Message-ID: <89415639-96a6-4d85-bdee-f7364e4d3354@intel.com>

On 12/11/2025 14:03, Ulf Hansson wrote:
> + cqhci maintainers (Adrian, Asutosh, Ritesh)
> 
> On Wed, 12 Nov 2025 at 08:44, Shawn Lin <shawn.lin at rock-chips.com> wrote:
>>
>> CQHCI_SSC1.CIT indicates to the CQE the polling period to use for
>> periodic SEND_QUEUE_STATUS (CMD13) polling. Some eMMCs have only one
>> hardware queue, and CMD13 can only query one slot at a time for data
>> transmission, which cannot be processed in parallel. Modifying the
>> CMD13 query interval can increase the query frequency and improve
>> random write performance.
>>
>> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
> 
> No strong opinion on this, but I looped in the cqhci maintainers to
> allow them to chime in.

cqhci-core leaves CQHCI_SSC1 configuration to the default values
or for drivers to set for themselves.  When it comes to timing
values, eMMC has not really been one-size-fits-all, so that seems
appropriate.

So for both patches:

Acked-by: Adrian Hunter <adrian.hunter at intel.com>

> 
> Kind regards
> Uffe
> 
>> ---
>>
>>  drivers/mmc/host/cqhci.h            | 1 +
>>  drivers/mmc/host/sdhci-of-dwcmshc.c | 5 +++++
>>  2 files changed, 6 insertions(+)
>>
>> diff --git a/drivers/mmc/host/cqhci.h b/drivers/mmc/host/cqhci.h
>> index ce189a1..3668856 100644
>> --- a/drivers/mmc/host/cqhci.h
>> +++ b/drivers/mmc/host/cqhci.h
>> @@ -93,6 +93,7 @@
>>  /* send status config 1 */
>>  #define CQHCI_SSC1                     0x40
>>  #define CQHCI_SSC1_CBC_MASK            GENMASK(19, 16)
>> +#define CQHCI_SSC1_CIT_MASK            GENMASK(15, 0)
>>
>>  /* send status config 2 */
>>  #define CQHCI_SSC2                     0x44
>> diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c
>> index e276a4e..cad5165 100644
>> --- a/drivers/mmc/host/sdhci-of-dwcmshc.c
>> +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c
>> @@ -631,6 +631,11 @@ static void rk35xx_sdhci_cqe_pre_enable(struct mmc_host *mmc)
>>         struct dwcmshc_priv *dwc_priv = sdhci_pltfm_priv(pltfm_host);
>>         u32 reg;
>>
>> +       /* Set Send Status Command Idle Timer to 10.66us (256 * 1 / 24) */
>> +       reg = sdhci_readl(host, dwc_priv->vendor_specific_area2 + CQHCI_SSC1);
>> +       reg = (reg & ~CQHCI_SSC1_CIT_MASK) | 0x0100;
>> +       sdhci_writel(host, reg, dwc_priv->vendor_specific_area2 + CQHCI_SSC1);
>> +
>>         reg = sdhci_readl(host, dwc_priv->vendor_specific_area2 + CQHCI_CFG);
>>         reg |= CQHCI_ENABLE;
>>         sdhci_writel(host, reg, dwc_priv->vendor_specific_area2 + CQHCI_CFG);
>> --
>> 2.7.4
>>



From michael.riesch at collabora.com  Mon Nov 17 02:33:34 2025
From: michael.riesch at collabora.com (Michael Riesch)
Date: Mon, 17 Nov 2025 11:33:34 +0100
Subject: [PATCH 1/3] media: dt-bindings: add rockchip mipi csi-2 receiver
In-Reply-To: <7c37017a-0769-4db3-be7f-af5837d4d102@kernel.org>
References: <20251114-rockchip-mipi-receiver-v1-0-d13086e810dd@collabora.com>
 <20251114-rockchip-mipi-receiver-v1-1-d13086e810dd@collabora.com>
 <7c37017a-0769-4db3-be7f-af5837d4d102@kernel.org>
Message-ID: <2a7a0978-0e7c-4c2b-a51e-8056f9ed1d3f@collabora.com>

Hi Krzysztof,

On 11/17/25 11:06, Krzysztof Kozlowski wrote:
> On 17/11/2025 11:01, Michael Riesch via B4 Relay wrote:
>> From: Michael Riesch <michael.riesch at collabora.com>
>>
>> Add documentation for the Rockchip MIPI CSI-2 Receiver.
>>
>> Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
>> Reviewed-by: Bryan O'Donoghue <bod at kernel.org>
>> Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
>> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
> 
> 
> Please keep only one tag per person.

Oops, OK.

> That's a v1 so I don't get how could you get these above and I could not
> find answer in the cover letter either.

Quote cover letter:

    "These changes have been discussed and reviewed thoroughly (see [0]
    and predecessors).

    [...]

    [0]
https://lore.kernel.org/r/20240220-rk3568-vicap-v14-0-b38b6da0fc80 at collabora.com"

That's how I got them.

> 
> Best regards,
> Krzysztof

Thanks and best regards,
Michael



From dsimic at manjaro.org  Mon Nov 17 07:59:05 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Mon, 17 Nov 2025 16:59:05 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH 0/3] =?utf-8?q?PCI=3A?==?utf-8?q?_rockchip=3A?=
 =?utf-8?q?_5=2E0?= GT/s speed may be dangerous
In-Reply-To: <aRrIhA1uv_aIneOc@geday>
References: <cover.1763197368.git.geraldogabriel@gmail.com>
 <8f3cc1c1-7bf7-4610-b7ce-79ebd6f05a6e@rock-chips.com>
 <257951b7-c22e-9707-6aba-3dc5794306bb@manjaro.org> <aRrIhA1uv_aIneOc@geday>
Message-ID: <4afa0534-5458-ac0c-6c92-38ed52aea00b@manjaro.org>

Hello Geraldo,

On Monday, November 17, 2025 08:02 CET, Geraldo Nascimento <geraldogabriel at gmail.com> wrote:
> On Mon, Nov 17, 2025 at 04:57:11AM +0100, Dragan Simic wrote:
> > On Monday, November 17, 2025 04:42 CET, Shawn Lin <shawn.lin at rock-chips.com> wrote:
> > > ? 2025/11/15 ??? 17:10, Geraldo Nascimento ??:
> > > > In recent interactions with Shawn Lin from Rockchip it came to my
> > > > attention there's an unknown errata regarding 5.0 GT/s operational
> > > > speed of their PCIe core. According to Shawn there's grave danger
> > > > even if the odds are low. To contain any damage, let's cover the
> > > > remaining corner-cases where the default would lead to 5.0 GT/s
> > > > operation as well as add a comment to Root Complex driver core,
> > > > documenting this danger.
> > > 
> > > I'm not sure just adding a warn would be a good choice. Could we totally
> > > force to use gen1 and add a warn if trying to use Gen2.
> > 
> > I think that forcing 2.5 GT/s with an appropriate warning message
> > is a good idea.  That would be like some quirk that gets applied
> > automatically, to prevent data corruption, while warning people
> > who attempt to "overclock" the PCIe interface.
> 
> Alright, I'll send v2 with this suggestion in mind. So that driving the
> core at 5.0 GT/s will require patching and compiling own kernel.
> 
> > > Meanwhile amend the commit message to add a reference
> > > of RK3399 official datesheet[1] which says PCIe on RK3399 should only
> > > support 2.5GT/s?
> > > 
> > > [1]https://opensource.rock-chips.com/images/d/d7/Rockchip_RK3399_Datasheet_V2.1-20200323.pdf
> > 
> 
> Shawn, URLs have the bad habit of changing or simply disappearing, so I
> don't think it's a good idea to put URL in the commit message.

Ah, it's actually perfectly fine, there's always Wayback Machibe
to rescue references/URLs that may disappear over time.  Wikipedia
relies heavily on exactly that mechanism, for example.

[2] https://web.archive.org/

> Also, the datasheet just mentions that RK3399 supports only 2.5 GT/s,
> it does not mention possible damage from driving the core at 5.0 GT/s.

True, but having an additional reference doesn't hurt, especially
because the revision history mentions, albeit vaguely, an update
to the PCIe specification in version 1.1.of the datasheet.  Though,
if we had the version 1.0 publicly available for comparison, that
would've been much better. :)

> > Also, rewording the patch summary as follows below may be good,
> > because that would provide more details:
> > 
> >   PCI: rockchip: Warn about Gen2 5.0 GT/s on RK3399 being unsafe
> > 
> > Or, if we'll go with the automatic downgrading, like this:
> > 
> >   PCI: rockchip: Limit RK3399 to Gen1 2.5 GT/s to prevent breakage
> 
> Dragan, these are good ones, thanks. Though I think I'll omit Gen1/Gen2
> wording since I know how much Bjorn dislikes those terms.

I'm glad that you like those, and I also thought about not including
the GenX parts, because they're basically a bit redundant. :)



From linux.amoon at gmail.com  Mon Nov 17 10:10:08 2025
From: linux.amoon at gmail.com (Anand Moon)
Date: Mon, 17 Nov 2025 23:40:08 +0530
Subject: [RFC v1 0/5] Fix some register offset as per RK3399 TRM part 2
Message-ID: <20251117181023.482138-1-linux.amoon@gmail.com>

In order to enable ASPM we need to fix the register offset as
RK3399 TRM part 2 - PCIe Controller.

Tested on Radxa Rock Pi 4b.

Thanks
-Anand

Anand Moon (5):
  PCI: rockchip: Fix Link Control register offset and enable ASPM/CLKREQ
  PCI: rockchip: Fix Device Control register offset for Max payload size
  PCI: rockchip: Fix Slot Capability Register offset for slot power
    limit
  PCI: rockchip: Fix Link Control and Status Register 2 for target link
    speed
  PCI: rockchip: Fix Linkwidth Control Register offset for Retrain Link

 drivers/pci/controller/pcie-rockchip-host.c | 31 +++++++++++----------
 drivers/pci/controller/pcie-rockchip.h      |  5 ++++
 2 files changed, 21 insertions(+), 15 deletions(-)


base-commit: e7c375b181600caf135cfd03eadbc45eb530f2cb
-- 
2.50.1



From linux.amoon at gmail.com  Mon Nov 17 10:10:09 2025
From: linux.amoon at gmail.com (Anand Moon)
Date: Mon, 17 Nov 2025 23:40:09 +0530
Subject: [RFC v1 1/5] PCI: rockchip: Fix Link Control register offset and enable ASPM/CLKREQ
In-Reply-To: <20251117181023.482138-1-linux.amoon@gmail.com>
References: <20251117181023.482138-1-linux.amoon@gmail.com>
Message-ID: <20251117181023.482138-2-linux.amoon@gmail.com>

As per the RK3399 TRM (Part 2, 17.6.6.1.31), the Link Control register
(RC_CONFIG_LC) resides at an offset of 0xd0 within the Root Complex (RC)
configuration space, not at the offset of the PCI Express Capability List
(0xc0). Following changes correct the register offset to use
PCIE_RC_CONFIG_LC (0xd0) to configure link control.

Additionally, this commit explicitly enables ASPM (Active State Power
Management) control and the CLKREQ# (Clock Request) mechanism as part of
the Link Control register programming when enabling bandwidth
notifications.

Signed-off-by: Anand Moon <linux.amoon at gmail.com>
---
 drivers/pci/controller/pcie-rockchip-host.c | 15 ++++++++-------
 drivers/pci/controller/pcie-rockchip.h      |  1 +
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c
index ee1822ca01db..f0de5b2590c4 100644
--- a/drivers/pci/controller/pcie-rockchip-host.c
+++ b/drivers/pci/controller/pcie-rockchip-host.c
@@ -32,18 +32,19 @@ static void rockchip_pcie_enable_bw_int(struct rockchip_pcie *rockchip)
 {
 	u32 status;
 
-	status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_CR + PCI_EXP_LNKCTL);
-	status |= (PCI_EXP_LNKCTL_LBMIE | PCI_EXP_LNKCTL_LABIE);
-	rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_CR + PCI_EXP_LNKCTL);
+	status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LC + PCI_EXP_LNKCTL);
+	status |= (PCI_EXP_LNKCTL_LBMIE | PCI_EXP_LNKCTL_LABIE |
+		   PCI_EXP_LNKCTL_ASPMC | PCI_EXP_LNKCTL_CLKREQ_EN);
+	rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LC + PCI_EXP_LNKCTL);
 }
 
 static void rockchip_pcie_clr_bw_int(struct rockchip_pcie *rockchip)
 {
 	u32 status;
 
-	status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_CR + PCI_EXP_LNKCTL);
+	status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LC + PCI_EXP_LNKCTL);
 	status |= (PCI_EXP_LNKSTA_LBMS | PCI_EXP_LNKSTA_LABS) << 16;
-	rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_CR + PCI_EXP_LNKCTL);
+	rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LC + PCI_EXP_LNKCTL);
 }
 
 static void rockchip_pcie_update_txcredit_mui(struct rockchip_pcie *rockchip)
@@ -306,9 +307,9 @@ static int rockchip_pcie_host_init_port(struct rockchip_pcie *rockchip)
 	rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_CR + PCI_EXP_LNKCTL);
 
 	/* Set RC's RCB to 128 */
-	status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_CR + PCI_EXP_LNKCTL);
+	status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LC + PCI_EXP_LNKCTL);
 	status |= PCI_EXP_LNKCTL_RCB;
-	rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_CR + PCI_EXP_LNKCTL);
+	rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LC + PCI_EXP_LNKCTL);
 
 	/* Enable Gen1 training */
 	rockchip_pcie_write(rockchip, PCIE_CLIENT_LINK_TRAIN_ENABLE,
diff --git a/drivers/pci/controller/pcie-rockchip.h b/drivers/pci/controller/pcie-rockchip.h
index 3e82a69b9c00..5d8a3ae38599 100644
--- a/drivers/pci/controller/pcie-rockchip.h
+++ b/drivers/pci/controller/pcie-rockchip.h
@@ -157,6 +157,7 @@
 #define PCIE_EP_CONFIG_LCS		(PCIE_EP_CONFIG_BASE + 0xd0)
 #define PCIE_RC_CONFIG_RID_CCR		(PCIE_RC_CONFIG_BASE + 0x08)
 #define PCIE_RC_CONFIG_CR		(PCIE_RC_CONFIG_BASE + 0xc0)
+#define PCIE_RC_CONFIG_LC		(PCIE_RC_CONFIG_BASE + 0xd0)
 #define PCIE_RC_CONFIG_L1_SUBSTATE_CTRL2 (PCIE_RC_CONFIG_BASE + 0x90c)
 #define PCIE_RC_CONFIG_THP_CAP		(PCIE_RC_CONFIG_BASE + 0x274)
 #define   PCIE_RC_CONFIG_THP_CAP_NEXT_MASK	GENMASK(31, 20)
-- 
2.50.1



From linux.amoon at gmail.com  Mon Nov 17 10:10:10 2025
From: linux.amoon at gmail.com (Anand Moon)
Date: Mon, 17 Nov 2025 23:40:10 +0530
Subject: [RFC v1 2/5] PCI: rockchip: Fix Device Control register offset for Max payload size
In-Reply-To: <20251117181023.482138-1-linux.amoon@gmail.com>
References: <20251117181023.482138-1-linux.amoon@gmail.com>
Message-ID: <20251117181023.482138-3-linux.amoon@gmail.com>

As per 17.6.6.1.29 PCI Express Device Capabilities Register
(PCIE_RC_CONFIG_DC) reside at offset 0xc8 within the Root Complex (RC)
configuration space, not at the offset of the PCI Express Capability
List (0xc0). Following changes corrects the register offset to use
PCIE_RC_CONFIG_DC (0xc8) to configure Max Payload Size.

Signed-off-by: Anand Moon <linux.amoon at gmail.com>
---
 drivers/pci/controller/pcie-rockchip-host.c | 4 ++--
 drivers/pci/controller/pcie-rockchip.h      | 1 +
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c
index f0de5b2590c4..d51780f4a254 100644
--- a/drivers/pci/controller/pcie-rockchip-host.c
+++ b/drivers/pci/controller/pcie-rockchip-host.c
@@ -382,10 +382,10 @@ static int rockchip_pcie_host_init_port(struct rockchip_pcie *rockchip)
 		rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_CR + PCI_EXP_LNKCAP);
 	}
 
-	status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_CR + PCI_EXP_DEVCTL);
+	status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_DC + PCI_EXP_DEVCTL);
 	status &= ~PCI_EXP_DEVCTL_PAYLOAD;
 	status |= PCI_EXP_DEVCTL_PAYLOAD_256B;
-	rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_CR + PCI_EXP_DEVCTL);
+	rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_DC + PCI_EXP_DEVCTL);
 
 	return 0;
 err_power_off_phy:
diff --git a/drivers/pci/controller/pcie-rockchip.h b/drivers/pci/controller/pcie-rockchip.h
index 5d8a3ae38599..c0ec6c32ea16 100644
--- a/drivers/pci/controller/pcie-rockchip.h
+++ b/drivers/pci/controller/pcie-rockchip.h
@@ -157,6 +157,7 @@
 #define PCIE_EP_CONFIG_LCS		(PCIE_EP_CONFIG_BASE + 0xd0)
 #define PCIE_RC_CONFIG_RID_CCR		(PCIE_RC_CONFIG_BASE + 0x08)
 #define PCIE_RC_CONFIG_CR		(PCIE_RC_CONFIG_BASE + 0xc0)
+#define PCIE_RC_CONFIG_DC		(PCIE_RC_CONFIG_BASE + 0xc8)
 #define PCIE_RC_CONFIG_LC		(PCIE_RC_CONFIG_BASE + 0xd0)
 #define PCIE_RC_CONFIG_L1_SUBSTATE_CTRL2 (PCIE_RC_CONFIG_BASE + 0x90c)
 #define PCIE_RC_CONFIG_THP_CAP		(PCIE_RC_CONFIG_BASE + 0x274)
-- 
2.50.1



From linux.amoon at gmail.com  Mon Nov 17 10:10:11 2025
From: linux.amoon at gmail.com (Anand Moon)
Date: Mon, 17 Nov 2025 23:40:11 +0530
Subject: [RFC v1 3/5] PCI: rockchip: Fix Slot Capability Register offset for slot power limit
In-Reply-To: <20251117181023.482138-1-linux.amoon@gmail.com>
References: <20251117181023.482138-1-linux.amoon@gmail.com>
Message-ID: <20251117181023.482138-4-linux.amoon@gmail.com>

As per 17.6.6.1.32 Slot Capability Register (PCIE_RC_CONFIG_SR) reside
at offset 0xd4 within the Root Complex (RC) configuration space, not at
the offset of the PCI Express Capability List (0xc0). Following changes
corrects the register offset to use PCIE_RC_CONFIG_SR (0xd4) to configure
Slot Power Limit value.

Signed-off-by: Anand Moon <linux.amoon at gmail.com>
---
 drivers/pci/controller/pcie-rockchip-host.c | 4 ++--
 drivers/pci/controller/pcie-rockchip.h      | 1 +
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c
index d51780f4a254..d77403bbb81d 100644
--- a/drivers/pci/controller/pcie-rockchip-host.c
+++ b/drivers/pci/controller/pcie-rockchip-host.c
@@ -271,10 +271,10 @@ static void rockchip_pcie_set_power_limit(struct rockchip_pcie *rockchip)
 		power = power / 10;
 	}
 
-	status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_CR + PCI_EXP_DEVCAP);
+	status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_SR + PCI_EXP_DEVCAP);
 	status |= FIELD_PREP(PCI_EXP_DEVCAP_PWR_VAL, power);
 	status |= FIELD_PREP(PCI_EXP_DEVCAP_PWR_SCL, scale);
-	rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_CR + PCI_EXP_DEVCAP);
+	rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_SR + PCI_EXP_DEVCAP);
 }
 
 /**
diff --git a/drivers/pci/controller/pcie-rockchip.h b/drivers/pci/controller/pcie-rockchip.h
index c0ec6c32ea16..4ba07ff3a3cf 100644
--- a/drivers/pci/controller/pcie-rockchip.h
+++ b/drivers/pci/controller/pcie-rockchip.h
@@ -159,6 +159,7 @@
 #define PCIE_RC_CONFIG_CR		(PCIE_RC_CONFIG_BASE + 0xc0)
 #define PCIE_RC_CONFIG_DC		(PCIE_RC_CONFIG_BASE + 0xc8)
 #define PCIE_RC_CONFIG_LC		(PCIE_RC_CONFIG_BASE + 0xd0)
+#define PCIE_RC_CONFIG_SR		(PCIE_RC_CONFIG_BASE + 0xd4)
 #define PCIE_RC_CONFIG_L1_SUBSTATE_CTRL2 (PCIE_RC_CONFIG_BASE + 0x90c)
 #define PCIE_RC_CONFIG_THP_CAP		(PCIE_RC_CONFIG_BASE + 0x274)
 #define   PCIE_RC_CONFIG_THP_CAP_NEXT_MASK	GENMASK(31, 20)
-- 
2.50.1



From linux.amoon at gmail.com  Mon Nov 17 10:10:12 2025
From: linux.amoon at gmail.com (Anand Moon)
Date: Mon, 17 Nov 2025 23:40:12 +0530
Subject: [RFC v1 4/5] PCI: rockchip: Fix Link Control and Status Register 2 for target link speed
In-Reply-To: <20251117181023.482138-1-linux.amoon@gmail.com>
References: <20251117181023.482138-1-linux.amoon@gmail.com>
Message-ID: <20251117181023.482138-5-linux.amoon@gmail.com>

As per 17.6.4.5.11 Link Control and Status Register 2 (PCIE_RC_CONFIG_LC2)
reside at offset 0xf0 within the Root Complex (RC) configuration space, not
at the offset of the PCI Express Capability List (0xc0). Following changes
corrects the register offset to use PCIE_RC_CONFIG_LC2 (0xf0) to configure
target like speed.

Signed-off-by: Anand Moon <linux.amoon at gmail.com>
---
 drivers/pci/controller/pcie-rockchip-host.c | 4 ++--
 drivers/pci/controller/pcie-rockchip.h      | 1 +
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c
index d77403bbb81d..b3c9b9cbeb8d 100644
--- a/drivers/pci/controller/pcie-rockchip-host.c
+++ b/drivers/pci/controller/pcie-rockchip-host.c
@@ -334,10 +334,10 @@ static int rockchip_pcie_host_init_port(struct rockchip_pcie *rockchip)
 		 * Enable retrain for gen2. This should be configured only after
 		 * gen1 finished.
 		 */
-		status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_CR + PCI_EXP_LNKCTL2);
+		status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LC2 + PCI_EXP_LNKCTL2);
 		status &= ~PCI_EXP_LNKCTL2_TLS;
 		status |= PCI_EXP_LNKCTL2_TLS_5_0GT;
-		rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_CR + PCI_EXP_LNKCTL2);
+		rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LC2 + PCI_EXP_LNKCTL2);
 		status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_CR + PCI_EXP_LNKCTL);
 		status |= PCI_EXP_LNKCTL_RL;
 		rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_CR + PCI_EXP_LNKCTL);
diff --git a/drivers/pci/controller/pcie-rockchip.h b/drivers/pci/controller/pcie-rockchip.h
index 4ba07ff3a3cf..a83ce7787466 100644
--- a/drivers/pci/controller/pcie-rockchip.h
+++ b/drivers/pci/controller/pcie-rockchip.h
@@ -160,6 +160,7 @@
 #define PCIE_RC_CONFIG_DC		(PCIE_RC_CONFIG_BASE + 0xc8)
 #define PCIE_RC_CONFIG_LC		(PCIE_RC_CONFIG_BASE + 0xd0)
 #define PCIE_RC_CONFIG_SR		(PCIE_RC_CONFIG_BASE + 0xd4)
+#define PCIE_RC_CONFIG_LC2		(PCIE_RC_CONFIG_BASE + 0xf0)
 #define PCIE_RC_CONFIG_L1_SUBSTATE_CTRL2 (PCIE_RC_CONFIG_BASE + 0x90c)
 #define PCIE_RC_CONFIG_THP_CAP		(PCIE_RC_CONFIG_BASE + 0x274)
 #define   PCIE_RC_CONFIG_THP_CAP_NEXT_MASK	GENMASK(31, 20)
-- 
2.50.1



From linux.amoon at gmail.com  Mon Nov 17 10:10:13 2025
From: linux.amoon at gmail.com (Anand Moon)
Date: Mon, 17 Nov 2025 23:40:13 +0530
Subject: [RFC v1 5/5] PCI: rockchip: Fix Linkwidth Control Register offset for Retrain Link
In-Reply-To: <20251117181023.482138-1-linux.amoon@gmail.com>
References: <20251117181023.482138-1-linux.amoon@gmail.com>
Message-ID: <20251117181023.482138-6-linux.amoon@gmail.com>

As per 17.6.7.1.21 Linkwidth Control Register (PCIE_RC_CONFIG_LWC) reside
at offset 0x50 within the Root Complex (RC) configuration space, not at
the offset of the PCI Express Capability List (0xc0). Following changes
corrects the register offset to use PCIE_RC_CONFIG_LWC (0x50) to configure
Retrain link.

Signed-off-by: Anand Moon <linux.amoon at gmail.com>
---
 drivers/pci/controller/pcie-rockchip-host.c | 4 ++--
 drivers/pci/controller/pcie-rockchip.h      | 1 +
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c
index b3c9b9cbeb8d..aae3def64bf0 100644
--- a/drivers/pci/controller/pcie-rockchip-host.c
+++ b/drivers/pci/controller/pcie-rockchip-host.c
@@ -338,9 +338,9 @@ static int rockchip_pcie_host_init_port(struct rockchip_pcie *rockchip)
 		status &= ~PCI_EXP_LNKCTL2_TLS;
 		status |= PCI_EXP_LNKCTL2_TLS_5_0GT;
 		rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LC2 + PCI_EXP_LNKCTL2);
-		status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_CR + PCI_EXP_LNKCTL);
+		status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LWC + PCI_EXP_LNKCTL);
 		status |= PCI_EXP_LNKCTL_RL;
-		rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_CR + PCI_EXP_LNKCTL);
+		rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LWC + PCI_EXP_LNKCTL);
 
 		err = readl_poll_timeout(rockchip->apb_base + PCIE_CORE_CTRL,
 					 status, PCIE_LINK_IS_GEN2(status), 20,
diff --git a/drivers/pci/controller/pcie-rockchip.h b/drivers/pci/controller/pcie-rockchip.h
index a83ce7787466..5bcaef7bba4c 100644
--- a/drivers/pci/controller/pcie-rockchip.h
+++ b/drivers/pci/controller/pcie-rockchip.h
@@ -160,6 +160,7 @@
 #define PCIE_RC_CONFIG_DC		(PCIE_RC_CONFIG_BASE + 0xc8)
 #define PCIE_RC_CONFIG_LC		(PCIE_RC_CONFIG_BASE + 0xd0)
 #define PCIE_RC_CONFIG_SR		(PCIE_RC_CONFIG_BASE + 0xd4)
+#define PCIE_RC_CONFIG_LWC		(PCIE_RC_CONFIG_BASE + 0x50)
 #define PCIE_RC_CONFIG_LC2		(PCIE_RC_CONFIG_BASE + 0xf0)
 #define PCIE_RC_CONFIG_L1_SUBSTATE_CTRL2 (PCIE_RC_CONFIG_BASE + 0x90c)
 #define PCIE_RC_CONFIG_THP_CAP		(PCIE_RC_CONFIG_BASE + 0x274)
-- 
2.50.1



From nicolas.frattaroli at collabora.com  Mon Nov 17 11:11:47 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 17 Nov 2025 20:11:47 +0100
Subject: [PATCH v4 03/10] drm: Add enum conversion from/to HDMI_COLORSPACE
 to DRM_COLOR_FORMAT
In-Reply-To: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
References: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
Message-ID: <20251117-color-format-v4-3-0ded72bd1b00@collabora.com>

From: Marius Vlad <marius.vlad at collabora.com>

This would please the compiler to have a enum transformation from one to
another even though the values are the same. It should also make things
obvious that we use different enums.

Signed-off-by: Marius Vlad <marius.vlad at collabora.com>
---
 drivers/gpu/drm/drm_connector.c | 18 ++++++++++++++++++
 include/drm/drm_connector.h     |  3 +++
 2 files changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 0ad7be0a2d09..61c077b67ac3 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1384,6 +1384,24 @@ drm_color_format_enum_to_color_format(enum drm_color_format_enum fmt_enum)
 	}
 }
 
+enum hdmi_colorspace
+color_format_to_hdmi_colorspace(enum drm_color_format fmt)
+{
+	switch (fmt) {
+	default:
+	case DRM_COLOR_FORMAT_AUTO:
+	case DRM_COLOR_FORMAT_RGB444:
+		return HDMI_COLORSPACE_RGB;
+	case DRM_COLOR_FORMAT_YCBCR444:
+		return HDMI_COLORSPACE_YUV444;
+	case DRM_COLOR_FORMAT_YCBCR422:
+		return HDMI_COLORSPACE_YUV422;
+	case DRM_COLOR_FORMAT_YCBCR420:
+		return HDMI_COLORSPACE_YUV420;
+	}
+}
+EXPORT_SYMBOL(color_format_to_hdmi_colorspace);
+
 /**
  * drm_get_color_format_name - return a string for color format
  * @colorspace: color format to compute name of
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index a071079fd3ad..e044976c8d76 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -2586,6 +2586,9 @@ drm_color_format_to_color_format_enum(enum drm_color_format fmt);
 u32
 drm_color_format_enum_to_color_format(enum drm_color_format_enum fmt_enum);
 
+enum hdmi_colorspace
+color_format_to_hdmi_colorspace(enum drm_color_format fmt);
+
 /**
  * drm_for_each_connector_iter - connector_list iterator macro
  * @connector: &struct drm_connector pointer used as cursor

-- 
2.51.2



From nicolas.frattaroli at collabora.com  Mon Nov 17 11:11:44 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 17 Nov 2025 20:11:44 +0100
Subject: [PATCH v4 00/10] Add new general DRM property "color format"
Message-ID: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>

Hello,

this is a follow-up to
https://lore.kernel.org/all/20250911130739.4936-1-marius.vlad at collabora.com/
which in of itself is a follow-up to
https://lore.kernel.org/dri-devel/20240115160554.720247-1-andri at yngvason.is/ where
a new DRM connector property has been added allowing users to
force a particular color format.

That in turn was actually also a follow-up from Werner Sembach's posted at
https://lore.kernel.org/dri-devel/20210630151018.330354-1-wse at tuxedocomputers.com/

As the number of cooks have reached critical mass, I'm hoping I'll be
the last person to touch this particular series.

We have an implementation in Weston at
https://gitlab.freedesktop.org/wayland/weston/-/merge_requests/1825 that
adds support for this property. This patch series has been tested
against that MR on i915 (HDMI, DP), amdgpu (HDMI, DP) and on rockchip
(HDMI).

You can also manually test this with modetest like so, but beware that
this is a non-atomic invocation, so testing YUV420 like this will result
in weird outcomes if only some of the modes support YUV420:

  $ modetest -s 115:1920x1080-60 at NV12 -w 115:'color format':4

where 115 is the connector ID and '4' is the enum value for a particular
color format.

General notes on the approach taken by me: instead of silently switching
to a different format than was explicitly requested, or even worse,
outputting something to the sink the sink doesn't support, bubble up an
error to userspace instead. "color format" is a "I want this" type
property, not a "force this" type property, i.e. the kernel will respect
the limits imposed by the hardware.

I'm not sure if my drm_bridge change actually achieves what I want in a
more complex bridge setup. I'd need to either come up with a virtual
bridge to test these scenarios, or spend some time making a flat flex
cable adapter for the DSI-HDMI bridge board I have here. Before I invest
too much time into either of those, I'd like to get some feedback on
this approach however.

Things I've tested:
- HDMI (YCbCr 4:4:4 + RGB + Auto) on RK3588
- HDMI + DP (YCbCr 4:4:4, YCbCr 4:2:0, RGB, Auto) on Intel N97 (i915)
  DP-MST is untested, but I expect it to work the same.
- HDMI (YCbCr 4:4:4, YCbCr 4:2:2, YCbCr 4:2:0, RGB, Auto) + DP (YCbCr
  4:4:4, RGB, Auto) on an AMD Radeon RX 550 (amdgpu). DP-MST is
  untested.

Changes in v4:
- Rebase onto next-20251117
- Get rid of HDMI_COLORSPACE_AUTO
- Split hdmi_compute_config change into separate patch
- Add missing symbol export for color_format_to_hdmi_colorspace to fix
  builds in certain configurations
- Drop "drm: Pass supported color formats straight onto drm_bridge"
- Make dw-hdmi-qp set the platform data's supported color formats as
  the bridge's supported HDMI color formats
- drm_hdmi_state_helper: pass requested color format to
  hdmi_compute_format_bpc if set.
- drm_bridge: limit the bus formats to those explicitly requested with
  the color format property during the atomic bridge check call,
  specifically in drm_atomic_bridge_chain_select_bus_fmts.
- i915: Remove INTEL_OUTPUT_FORMAT_AUTO, as automatic format selection
  does not need to involve the hardware state
- i915: Deduplicate ntel_output_format_to_drm_color_format code by
  moving it as a static inline __pure function into a shared header
- i915: rework logic in HDMI, DP and DP-MST output config functions to
  remove redundant locals, simplify execution flow, and return an error
  to userspace if an explicit color_format request can't be satisfied.
- i915: assign myself as the author and make the others Co-developers,
  so that they don't get the blame for any of my bugs.
- amdgpu: refactor fill_stream_properties_from_drm_display_mode to
  improve readability and ensure that impossible color format requests
  get bubbled up to userspace as errors
- amdgpu: don't pick YUV444 over RGB.
- amdgpu: assign authorship to myself, with others as Co-developers, as
  logic was modified and the blame should fall on me
- dw_hdmi_qp-rockchip: set the supported color formats platform data
  member
- rockchip: remove drm property registration for rk3066_hdmi and
  inno_hdmi. None of the platforms that use these use vop2 as the
  video output processor.
- Link to v3: https://lore.kernel.org/all/20250911130739.4936-1-marius.vlad at collabora.com/

Changes in v3 by mvlad compared to Andri's v2 series:
- renamed the property to just 'color format'
- the property is added dynamically similar to the Colorspace property
- a key point from previous comments was that drivers should advertise
  the color formats they support and userspace would query EDID and
  perform an intersection from those color formats which users can
  further use. With this patch set each driver that adds this property
  has such list of hard-coded color formats, but fundamentally the idea
  is that driver can query the HW and do that on its own. The
  infrastructure is now in place to allow to do that
- by default the 'AUTO' color format is set. With this patch series that
  has been introduced as a fallback to RGB. Drivers could further
  customize this behavour and could perform additional checks on the sink
  to pick another suitable color format they'd like for AUTO
- drm_bridge bridge code has been improved to allow initialization with
  the same color formats list as the DRM connector property. Similarly, bpc
  pick-up now takes the color format into consideration when deciding
  which bpc to choose from
- The new DRM color format re-uses HDMI_COLORPSACE enum and provides an
  enum translations between the two to avoid touching all other drivers that
  use HDMI_COLORPSACE enum. I believe at this point that this allows the
  least amount of disruption and avoids a massive bike shedding around
  that part
- a rockchip implementation has been by my colleague Derek Foreman
- YUV444 color format has been added in i915
- address comment about "Remove unnecessary SIGNAL_TYPE_HDMI_TYPE_A
  check" where aconnector might be invalid
- Link to v2: https://lore.kernel.org/dri-devel/20240115160554.720247-1-andri at yngvason.is/

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
Andri Yngvason (1):
      drm: Add new general DRM property "color format"

Derek Foreman (1):
      drm/rockchip: Implement "color format" DRM property

Marius Vlad (1):
      drm: Add enum conversion from/to HDMI_COLORSPACE to DRM_COLOR_FORMAT

Nicolas Frattaroli (6):
      drm/bridge: Act on the DRM color format property
      drm/bridge: dw-hdmi-qp: Set bridge supported_formats
      drm/rockchip: dw_hdmi_qp: Set supported_formats platdata
      drm/display: hdmi-state-helper: Act on color format DRM property
      drm/i915: Implement the "color format" DRM property
      drm/amdgpu: Implement "color format" DRM property

Werner Sembach (1):
      drm/amd/display: Remove unnecessary SIGNAL_TYPE_HDMI_TYPE_A check

 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  |  93 ++++++++--
 .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c    |  14 ++
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c       |   5 +
 drivers/gpu/drm/display/drm_hdmi_state_helper.c    |   8 +-
 drivers/gpu/drm/drm_atomic_helper.c                |   5 +
 drivers/gpu/drm/drm_atomic_uapi.c                  |   4 +
 drivers/gpu/drm/drm_bridge.c                       |  57 ++++++
 drivers/gpu/drm/drm_connector.c                    | 198 +++++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_connector.c     |  19 ++
 drivers/gpu/drm/i915/display/intel_connector.h     |   2 +
 drivers/gpu/drm/i915/display/intel_display_types.h |  15 ++
 drivers/gpu/drm/i915/display/intel_dp.c            |  42 ++++-
 drivers/gpu/drm/i915/display/intel_dp.h            |   4 +
 drivers/gpu/drm/i915/display/intel_dp_mst.c        |  37 +++-
 drivers/gpu/drm/i915/display/intel_hdmi.c          |  40 ++++-
 drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c     |  27 +++
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c       |  46 +++++
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h       |   2 +
 include/drm/drm_connector.h                        |  57 +++++-
 19 files changed, 637 insertions(+), 38 deletions(-)
---
base-commit: d1d18879e01e4c9efcb85a96d188a8e4326136dd
change-id: 20251028-color-format-49fd202b7183

Best regards,
-- 
Nicolas Frattaroli <nicolas.frattaroli at collabora.com>



From nicolas.frattaroli at collabora.com  Mon Nov 17 11:11:45 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 17 Nov 2025 20:11:45 +0100
Subject: [PATCH v4 01/10] drm/amd/display: Remove unnecessary
 SIGNAL_TYPE_HDMI_TYPE_A check
In-Reply-To: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
References: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
Message-ID: <20251117-color-format-v4-1-0ded72bd1b00@collabora.com>

From: Werner Sembach <wse at tuxedocomputers.com>

Remove unnecessary SIGNAL_TYPE_HDMI_TYPE_A check that was performed in the
drm_mode_is_420_only() case, but not in the drm_mode_is_420_also() &&
force_yuv420_output case.

Without further knowledge if YCbCr 4:2:0 is supported outside of HDMI,
there is no reason to use RGB when the display
reports drm_mode_is_420_only() even on a non HDMI connection.

This patch also moves both checks in the same if-case. This  eliminates an
extra else-if-case.

Signed-off-by: Werner Sembach <wse at tuxedocomputers.com>
Signed-off-by: Andri Yngvason <andri at yngvason.is>
Tested-by: Andri Yngvason <andri at yngvason.is>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index e6728fd12eeb..598dc3ce993c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -6522,12 +6522,8 @@ static void fill_stream_properties_from_drm_display_mode(
 	timing_out->v_border_top = 0;
 	timing_out->v_border_bottom = 0;
 	/* TODO: un-hardcode */
-	if (drm_mode_is_420_only(info, mode_in)
-			&& stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
-		timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
-	else if (drm_mode_is_420_also(info, mode_in)
-			&& aconnector
-			&& aconnector->force_yuv420_output)
+	if (drm_mode_is_420_only(info, mode_in) || (drm_mode_is_420_also(info, mode_in) &&
+	    aconnector && aconnector->force_yuv420_output))
 		timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
 	else if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCBCR422)
 			&& aconnector

-- 
2.51.2



From nicolas.frattaroli at collabora.com  Mon Nov 17 11:11:46 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 17 Nov 2025 20:11:46 +0100
Subject: [PATCH v4 02/10] drm: Add new general DRM property "color format"
In-Reply-To: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
References: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
Message-ID: <20251117-color-format-v4-2-0ded72bd1b00@collabora.com>

From: Andri Yngvason <andri at yngvason.is>

Adds a new general DRM property named "color format" which can be used by
userspace to force the display driver output a particular color format.

Possible options are:
    - auto (setup by default, driver internally picks the color format)
    - rgb
    - ycbcr444
    - ycbcr422
    - ycbcr420

Drivers should advertise from this list the formats which they support.
Together with this list and EDID data from the sink we should be able
to relay a list of usable color formats to users to pick from.

Signed-off-by: Werner Sembach <wse at tuxedocomputers.com>
Signed-off-by: Andri Yngvason <andri at yngvason.is>
Signed-off-by: Marius Vlad <marius.vlad at collabora.com>
---
 drivers/gpu/drm/drm_atomic_helper.c |   5 +
 drivers/gpu/drm/drm_atomic_uapi.c   |   4 +
 drivers/gpu/drm/drm_connector.c     | 180 ++++++++++++++++++++++++++++++++++++
 include/drm/drm_connector.h         |  54 ++++++++++-
 4 files changed, 238 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index e641fcf8c568..25f354b2cc0d 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -736,6 +736,11 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
 			if (old_connector_state->max_requested_bpc !=
 			    new_connector_state->max_requested_bpc)
 				new_crtc_state->connectors_changed = true;
+
+			if (old_connector_state->color_format !=
+			    new_connector_state->color_format)
+				new_crtc_state->connectors_changed = true;
+
 		}
 
 		if (funcs->atomic_check)
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index b2cb5ae5a139..2f093b0d1628 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -784,6 +784,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
 		state->privacy_screen_sw_state = val;
 	} else if (property == connector->broadcast_rgb_property) {
 		state->hdmi.broadcast_rgb = val;
+	} else if (property == connector->color_format_property) {
+		state->color_format = drm_color_format_enum_to_color_format(val);
 	} else if (connector->funcs->atomic_set_property) {
 		return connector->funcs->atomic_set_property(connector,
 				state, property, val);
@@ -869,6 +871,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
 		*val = state->privacy_screen_sw_state;
 	} else if (property == connector->broadcast_rgb_property) {
 		*val = state->hdmi.broadcast_rgb;
+	} else if (property == connector->color_format_property) {
+		*val = drm_color_format_to_color_format_enum(state->color_format);
 	} else if (connector->funcs->atomic_get_property) {
 		return connector->funcs->atomic_get_property(connector,
 				state, property, val);
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 272d6254ea47..0ad7be0a2d09 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1348,6 +1348,55 @@ static const char * const colorspace_names[] = {
 	[DRM_MODE_COLORIMETRY_BT601_YCC] = "BT601_YCC",
 };
 
+u32
+drm_color_format_to_color_format_enum(enum drm_color_format fmt)
+{
+	switch (fmt) {
+	default:
+	case DRM_COLOR_FORMAT_AUTO:
+		return DRM_MODE_COLOR_FORMAT_AUTO;
+	case DRM_COLOR_FORMAT_RGB444:
+		return DRM_MODE_COLOR_FORMAT_RGB444;
+	case DRM_COLOR_FORMAT_YCBCR444:
+		return DRM_MODE_COLOR_FORMAT_YCBCR444;
+	case DRM_COLOR_FORMAT_YCBCR422:
+		return DRM_MODE_COLOR_FORMAT_YCBCR422;
+	case DRM_COLOR_FORMAT_YCBCR420:
+		return DRM_MODE_COLOR_FORMAT_YCBCR420;
+	}
+}
+
+u32
+drm_color_format_enum_to_color_format(enum drm_color_format_enum fmt_enum)
+{
+	switch (fmt_enum) {
+	default:
+	case DRM_MODE_COLOR_FORMAT_RGB444:
+		return DRM_COLOR_FORMAT_RGB444;
+	case DRM_MODE_COLOR_FORMAT_AUTO:
+		return DRM_COLOR_FORMAT_AUTO;
+	case DRM_MODE_COLOR_FORMAT_YCBCR444:
+		return DRM_COLOR_FORMAT_YCBCR444;
+	case DRM_MODE_COLOR_FORMAT_YCBCR422:
+		return DRM_COLOR_FORMAT_YCBCR422;
+	case DRM_MODE_COLOR_FORMAT_YCBCR420:
+		return DRM_COLOR_FORMAT_YCBCR420;
+	}
+}
+
+/**
+ * drm_get_color_format_name - return a string for color format
+ * @colorspace: color format to compute name of
+ *
+ */
+const char *drm_get_color_format_name(enum drm_color_format color_fmt)
+{
+	u32 conv_color_fmt = drm_color_format_to_color_format_enum(color_fmt);
+
+	return drm_hdmi_connector_get_output_format_name(conv_color_fmt);
+}
+EXPORT_SYMBOL(drm_get_color_format_name);
+
 /**
  * drm_get_colorspace_name - return a string for color encoding
  * @colorspace: color space to compute name of
@@ -1377,6 +1426,22 @@ static const u32 hdmi_colorspaces =
 	BIT(DRM_MODE_COLORIMETRY_DCI_P3_RGB_D65) |
 	BIT(DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER);
 
+/* already bit-shifted */
+static const u32 hdmi_colorformats =
+	DRM_COLOR_FORMAT_AUTO |
+	DRM_COLOR_FORMAT_RGB444 |
+	DRM_COLOR_FORMAT_YCBCR444 |
+	DRM_COLOR_FORMAT_YCBCR422 |
+	DRM_COLOR_FORMAT_YCBCR420;
+
+/* already bit-shifted */
+static const u32 dp_colorformats =
+	DRM_COLOR_FORMAT_AUTO |
+	DRM_COLOR_FORMAT_RGB444 |
+	DRM_COLOR_FORMAT_YCBCR444 |
+	DRM_COLOR_FORMAT_YCBCR422 |
+	DRM_COLOR_FORMAT_YCBCR420;
+
 /*
  * As per DP 1.4a spec, 2.2.5.7.5 VSC SDP Payload for Pixel Encoding/Colorimetry
  * Format Table 2-120
@@ -2628,6 +2693,101 @@ int drm_mode_create_hdmi_colorspace_property(struct drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_mode_create_hdmi_colorspace_property);
 
+static int drm_mode_create_color_format_property(struct drm_connector *connector,
+						 u32 supported_color_formats)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_prop_enum_list enum_list[DRM_MODE_COLOR_FORMAT_COUNT];
+	int i, len;
+
+	if (connector->color_format_property)
+		return 0;
+
+	if (!supported_color_formats) {
+		drm_err(dev, "No supported color formats provded on [CONNECTOR:%d:%s]\n",
+			    connector->base.id, connector->name);
+		return -EINVAL;
+	}
+
+	if ((supported_color_formats & -BIT(DRM_MODE_COLOR_FORMAT_COUNT)) != 0) {
+		drm_err(dev, "Unknown colorspace provded on [CONNECTOR:%d:%s]\n",
+			    connector->base.id, connector->name);
+		return -EINVAL;
+	}
+
+	len = 0;
+	for (i = 0; i < DRM_MODE_COLOR_FORMAT_COUNT; i++) {
+		if (!(supported_color_formats & BIT(i)))
+			continue;
+
+		enum_list[len].type = i;
+		if (i != DRM_MODE_COLOR_FORMAT_AUTO)
+			enum_list[len].name = output_format_str[i];
+		else
+			enum_list[len].name = "AUTO";
+		len++;
+	}
+
+	connector->color_format_property =
+		drm_property_create_enum(dev, DRM_MODE_PROP_ENUM, "color format",
+					enum_list, len);
+
+	if (!connector->color_format_property)
+		return -ENOMEM;
+
+	return 0;
+}
+
+/**
+ * drm_mode_create_hdmi_color_format_property - create hdmi color format property
+ * @connector: connector to create the color format property on.
+ * @supported_color_formats: bitmap of supported color formats
+ *
+ * Called by a driver the first time it's needed, must be attached to desired
+ * HDMI connectors.
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_mode_create_hdmi_color_format_property(struct drm_connector *connector,
+					       u32 supported_color_formats)
+{
+	u32 color_formats;
+
+	if (supported_color_formats)
+		color_formats = supported_color_formats & hdmi_colorformats;
+	else
+		color_formats = hdmi_colorformats;
+
+	return drm_mode_create_color_format_property(connector, color_formats);
+}
+EXPORT_SYMBOL(drm_mode_create_hdmi_color_format_property);
+
+/**
+ * drm_mode_create_dp_color_format_property - create dp color format property
+ * @connector: connector to create the Colorspace property on.
+ * @supported_color_formats: bitmap of supported color formats
+ *
+ * Called by a driver the first time it's needed, must be attached to desired
+ * DP connectors.
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_mode_create_dp_color_format_property(struct drm_connector *connector,
+					     u32 supported_color_formats)
+{
+	u32 color_formats;
+
+	if (supported_color_formats)
+		color_formats = supported_color_formats & dp_colorformats;
+	else
+		color_formats = dp_colorformats;
+
+	return drm_mode_create_color_format_property(connector, color_formats);
+}
+EXPORT_SYMBOL(drm_mode_create_dp_color_format_property);
+
 /**
  * drm_mode_create_dp_colorspace_property - create dp colorspace property
  * @connector: connector to create the Colorspace property on.
@@ -2845,6 +3005,26 @@ int drm_connector_attach_max_bpc_property(struct drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_connector_attach_max_bpc_property);
 
+/**
+ * drm_connector_attach_color_format_property - attach "force color format" property
+ * @connector: connector to attach force color format property on.
+ *
+ * This is used to add support for selecting a color format on a connector.
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_connector_attach_color_format_property(struct drm_connector *connector)
+{
+	struct drm_property *prop = connector->color_format_property;
+
+	drm_object_attach_property(&connector->base, prop, DRM_COLOR_FORMAT_AUTO);
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_connector_attach_color_format_property);
+
+
 /**
  * drm_connector_attach_hdr_output_metadata_property - attach "HDR_OUTPUT_METADA" property
  * @connector: connector to attach the property on.
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 8f34f4b8183d..a071079fd3ad 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -556,6 +556,26 @@ enum drm_colorspace {
 	DRM_MODE_COLORIMETRY_COUNT
 };
 
+enum drm_color_format_enum {
+	DRM_MODE_COLOR_FORMAT_RGB444		= HDMI_COLORSPACE_RGB,
+	DRM_MODE_COLOR_FORMAT_YCBCR422		= HDMI_COLORSPACE_YUV422,
+	DRM_MODE_COLOR_FORMAT_YCBCR444		= HDMI_COLORSPACE_YUV444,
+	DRM_MODE_COLOR_FORMAT_YCBCR420		= HDMI_COLORSPACE_YUV420,
+	/* auto case, driver will set the color_format */
+	DRM_MODE_COLOR_FORMAT_AUTO,
+	DRM_MODE_COLOR_FORMAT_COUNT
+};
+
+enum drm_color_format {
+	DRM_COLOR_FORMAT_NONE			= 0,
+	DRM_COLOR_FORMAT_RGB444			= (1 << 0),
+	DRM_COLOR_FORMAT_YCBCR422		= (1 << 1),
+	DRM_COLOR_FORMAT_YCBCR444		= (1 << 2),
+	DRM_COLOR_FORMAT_YCBCR420		= (1 << 3),
+	/* auto case, driver will set the color_format */
+	DRM_COLOR_FORMAT_AUTO			= (1 << 4),
+};
+
 /**
  * enum drm_bus_flags - bus_flags info for &drm_display_info
  *
@@ -699,11 +719,6 @@ struct drm_display_info {
 	 */
 	enum subpixel_order subpixel_order;
 
-#define DRM_COLOR_FORMAT_RGB444		(1<<0)
-#define DRM_COLOR_FORMAT_YCBCR444	(1<<1)
-#define DRM_COLOR_FORMAT_YCBCR422	(1<<2)
-#define DRM_COLOR_FORMAT_YCBCR420	(1<<3)
-
 	/**
 	 * @panel_orientation: Read only connector property for built-in panels,
 	 * indicating the orientation of the panel vs the device's casing.
@@ -1107,6 +1122,13 @@ struct drm_connector_state {
 	 */
 	enum drm_colorspace colorspace;
 
+	/**
+	 * @color_format: State variable for Connector property to request
+	 * color format change on Sink. This is most commonly used to switch
+	 * between RGB to YUV and vice-versa.
+	 */
+	enum drm_color_format color_format;
+
 	/**
 	 * @writeback_job: Writeback job for writeback connectors
 	 *
@@ -2060,6 +2082,12 @@ struct drm_connector {
 	 */
 	struct drm_property *colorspace_property;
 
+	/**
+	 * @color_format_property: Connector property to set the suitable
+	 * color format supported by the sink.
+	 */
+	struct drm_property *color_format_property;
+
 	/**
 	 * @path_blob_ptr:
 	 *
@@ -2461,6 +2489,12 @@ int drm_mode_create_dp_colorspace_property(struct drm_connector *connector,
 int drm_mode_create_content_type_property(struct drm_device *dev);
 int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
 
+int drm_mode_create_hdmi_color_format_property(struct drm_connector *connector,
+					       u32 supported_color_formats);
+
+int drm_mode_create_dp_color_format_property(struct drm_connector *connector,
+					     u32 supported_color_formats);
+
 int drm_connector_set_path_property(struct drm_connector *connector,
 				    const char *path);
 int drm_connector_set_tile_property(struct drm_connector *connector);
@@ -2542,6 +2576,16 @@ bool drm_connector_has_possible_encoder(struct drm_connector *connector,
 					struct drm_encoder *encoder);
 const char *drm_get_colorspace_name(enum drm_colorspace colorspace);
 
+int drm_connector_attach_color_format_property(struct drm_connector *connector);
+
+const char *drm_get_color_format_name(enum drm_color_format color_fmt);
+
+u32
+drm_color_format_to_color_format_enum(enum drm_color_format fmt);
+
+u32
+drm_color_format_enum_to_color_format(enum drm_color_format_enum fmt_enum);
+
 /**
  * drm_for_each_connector_iter - connector_list iterator macro
  * @connector: &struct drm_connector pointer used as cursor

-- 
2.51.2



From nicolas.frattaroli at collabora.com  Mon Nov 17 11:11:48 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 17 Nov 2025 20:11:48 +0100
Subject: [PATCH v4 04/10] drm/bridge: Act on the DRM color format property
In-Reply-To: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
References: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
Message-ID: <20251117-color-format-v4-4-0ded72bd1b00@collabora.com>

The new DRM color format property allows userspace to request a specific
color format on a connector. In turn, this fills the connector state's
color_format member to switch color formats.

Make drm_bridges consider the color_format set in the connector state
during the atomic bridge check. Specifically, reject any output bus
formats that do not correspond to the requested color format.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/gpu/drm/drm_bridge.c | 57 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index 8f355df883d8..b7df5cbad832 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -1052,6 +1052,59 @@ static int select_bus_fmt_recursive(struct drm_bridge *first_bridge,
 	return ret;
 }
 
+static bool __pure bus_format_is_color_fmt(u32 bus_fmt, enum drm_color_format fmt)
+{
+	if (bus_fmt == MEDIA_BUS_FMT_FIXED)
+		return true;
+
+	switch (fmt) {
+	case DRM_COLOR_FORMAT_NONE:
+	case DRM_COLOR_FORMAT_AUTO:
+		return true;
+	case DRM_COLOR_FORMAT_RGB444:
+		switch (bus_fmt) {
+		case MEDIA_BUS_FMT_RGB888_1X24:
+		case MEDIA_BUS_FMT_RGB101010_1X30:
+		case MEDIA_BUS_FMT_RGB121212_1X36:
+		case MEDIA_BUS_FMT_RGB161616_1X48:
+			return true;
+		default:
+			return false;
+		}
+	case DRM_COLOR_FORMAT_YCBCR444:
+		switch (bus_fmt) {
+		case MEDIA_BUS_FMT_YUV8_1X24:
+		case MEDIA_BUS_FMT_YUV10_1X30:
+		case MEDIA_BUS_FMT_YUV12_1X36:
+		case MEDIA_BUS_FMT_YUV16_1X48:
+			return true;
+		default:
+			return false;
+		}
+	case DRM_COLOR_FORMAT_YCBCR422:
+		switch (bus_fmt) {
+		case MEDIA_BUS_FMT_UYVY8_1X16:
+		case MEDIA_BUS_FMT_UYVY10_1X20:
+		case MEDIA_BUS_FMT_UYVY12_1X24:
+			return true;
+		default:
+			return false;
+		}
+	case DRM_COLOR_FORMAT_YCBCR420:
+		switch (bus_fmt) {
+		case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
+		case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
+		case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
+		case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
+			return true;
+		default:
+			return false;
+		}
+	}
+
+	return false;
+}
+
 /*
  * This function is called by &drm_atomic_bridge_chain_check() just before
  * calling &drm_bridge_funcs.atomic_check() on all elements of the chain.
@@ -1137,6 +1190,10 @@ drm_atomic_bridge_chain_select_bus_fmts(struct drm_bridge *bridge,
 	}
 
 	for (i = 0; i < num_out_bus_fmts; i++) {
+		if (!bus_format_is_color_fmt(out_bus_fmts[i], conn_state->color_format)) {
+			ret = -ENOTSUPP;
+			continue;
+		}
 		ret = select_bus_fmt_recursive(bridge, last_bridge, crtc_state,
 					       conn_state, out_bus_fmts[i]);
 		if (ret != -ENOTSUPP)

-- 
2.51.2



From nicolas.frattaroli at collabora.com  Mon Nov 17 11:11:49 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 17 Nov 2025 20:11:49 +0100
Subject: [PATCH v4 05/10] drm/bridge: dw-hdmi-qp: Set bridge
 supported_formats
In-Reply-To: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
References: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
Message-ID: <20251117-color-format-v4-5-0ded72bd1b00@collabora.com>

The drm_bridge "supported_formats" member stores a bitmask of supported
HDMI output formats if the bridge is in fact an HDMI bridge.

However, until now, the synopsys dw-hdmi-qp driver did not set this
member in the bridge it creates.

Set it based on the platform data's supported_formats member, and
default to BIT(HDMI_COLORSPACE_RGB) if it's absent, which preserves the
previous behaviour.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
index fe4c026280f0..cf888236bd65 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
@@ -1269,6 +1269,11 @@ struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev,
 		dev_warn(dev, "Set ref_clk_rate to vendor default\n");
 	}
 
+	if (plat_data->supported_formats)
+		hdmi->bridge.supported_formats = plat_data->supported_formats;
+	else
+		hdmi->bridge.supported_formats = BIT(HDMI_COLORSPACE_RGB);
+
 	dw_hdmi_qp_init_hw(hdmi);
 
 	ret = devm_request_threaded_irq(dev, plat_data->main_irq,

-- 
2.51.2



From nicolas.frattaroli at collabora.com  Mon Nov 17 11:11:50 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 17 Nov 2025 20:11:50 +0100
Subject: [PATCH v4 06/10] drm/rockchip: dw_hdmi_qp: Set supported_formats
 platdata
In-Reply-To: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
References: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
Message-ID: <20251117-color-format-v4-6-0ded72bd1b00@collabora.com>

With the introduction of the supported_formats member in the
dw-hdmi-qp platform data struct, drivers that have access to this
information should now set it.

Set it in the rockchip dw_hdmi_qp glue driver, where such a bitmask of
supported color formats already exists. It just needs to be converted to
the appropriate HDMI_COLORSPACE_ mask.

This allows this information to be passed down to the dw-hdmi-qp core,
which sets it in the bridge it creates, and consequently will allow the
common HDMI bridge code to act on it.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
index c9fe6aa3e3e3..7c294751de19 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
@@ -468,6 +468,28 @@ static const struct of_device_id dw_hdmi_qp_rockchip_dt_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, dw_hdmi_qp_rockchip_dt_ids);
 
+static const u32 supported_colorformats = DRM_COLOR_FORMAT_AUTO |
+					  DRM_COLOR_FORMAT_RGB444 |
+					  DRM_COLOR_FORMAT_YCBCR444;
+
+static unsigned int __pure drm_to_hdmi_fmts(const u32 fmt)
+{
+	unsigned int res = 0;
+
+	if (fmt & DRM_COLOR_FORMAT_AUTO)
+		res |= BIT(HDMI_COLORSPACE_RGB);
+	if (fmt & DRM_COLOR_FORMAT_RGB444)
+		res |= BIT(HDMI_COLORSPACE_RGB);
+	if (fmt & DRM_COLOR_FORMAT_YCBCR444)
+		res |= BIT(HDMI_COLORSPACE_YUV444);
+	if (fmt & DRM_COLOR_FORMAT_YCBCR422)
+		res |= BIT(HDMI_COLORSPACE_YUV422);
+	if (fmt & DRM_COLOR_FORMAT_YCBCR420)
+		res |= BIT(HDMI_COLORSPACE_YUV420);
+
+	return res;
+}
+
 static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
 				    void *data)
 {
@@ -521,6 +543,8 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
 	plat_data.phy_data = hdmi;
 	plat_data.max_bpc = 10;
 
+	plat_data.supported_formats = drm_to_hdmi_fmts(supported_colorformats);
+
 	encoder = &hdmi->encoder.encoder;
 	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
 

-- 
2.51.2



From nicolas.frattaroli at collabora.com  Mon Nov 17 11:11:51 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 17 Nov 2025 20:11:51 +0100
Subject: [PATCH v4 07/10] drm/display: hdmi-state-helper: Act on color
 format DRM property
In-Reply-To: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
References: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
Message-ID: <20251117-color-format-v4-7-0ded72bd1b00@collabora.com>

With the introduction of the "color format" DRM property, which allows
userspace to request a specific color format, the HDMI state helper
should implement this.

Implement it by checking whether the property is set and set to
something other than auto. If so, pass the requested color format, and
otherwise set RGB.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/gpu/drm/display/drm_hdmi_state_helper.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
index a561f124be99..add0d51fce33 100644
--- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c
+++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
@@ -650,9 +650,15 @@ hdmi_compute_config(const struct drm_connector *connector,
 				       conn_state->max_bpc,
 				       8, connector->max_bpc);
 	int ret;
+	enum hdmi_colorspace hdmi_colorspace;
+
+	if (conn_state->color_format && conn_state->color_format != DRM_COLOR_FORMAT_AUTO)
+		hdmi_colorspace = color_format_to_hdmi_colorspace(conn_state->color_format);
+	else
+		hdmi_colorspace = HDMI_COLORSPACE_RGB;
 
 	ret = hdmi_compute_format_bpc(connector, conn_state, mode, max_bpc,
-				      HDMI_COLORSPACE_RGB);
+				      hdmi_colorspace);
 	if (ret) {
 		if (connector->ycbcr_420_allowed) {
 			ret = hdmi_compute_format_bpc(connector, conn_state,

-- 
2.51.2



From nicolas.frattaroli at collabora.com  Mon Nov 17 11:11:52 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 17 Nov 2025 20:11:52 +0100
Subject: [PATCH v4 08/10] drm/i915: Implement the "color format" DRM
 property
In-Reply-To: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
References: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
Message-ID: <20251117-color-format-v4-8-0ded72bd1b00@collabora.com>

This includes RGB, YUV420, YUV444 and Auto. Auto will pick RGB, unless
the mode being asked for is YUV420-only, in which case it picks YUV420,
with a fallback for RGB in place just as a last-ditch attempt.

Should the explicitly requested color format not be supported by the
sink, then an error is returned to userspace, so that it can make a
better choice.

Co-developed-by: Werner Sembach <wse at tuxedocomputers.com>
Signed-off-by: Werner Sembach <wse at tuxedocomputers.com>
Co-developed-by: Andri Yngvason <andri at yngvason.is>
Signed-off-by: Andri Yngvason <andri at yngvason.is>
Co-developed-by: Marius Vlad <marius.vlad at collabora.com>
Signed-off-by: Marius Vlad <marius.vlad at collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/gpu/drm/i915/display/intel_connector.c     | 19 ++++++++++
 drivers/gpu/drm/i915/display/intel_connector.h     |  2 ++
 drivers/gpu/drm/i915/display/intel_display_types.h | 15 ++++++++
 drivers/gpu/drm/i915/display/intel_dp.c            | 42 +++++++++++++++++-----
 drivers/gpu/drm/i915/display/intel_dp.h            |  4 +++
 drivers/gpu/drm/i915/display/intel_dp_mst.c        | 37 +++++++++++++++++--
 drivers/gpu/drm/i915/display/intel_hdmi.c          | 40 ++++++++++++++++-----
 7 files changed, 140 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_connector.c b/drivers/gpu/drm/i915/display/intel_connector.c
index 913d90a7a508..3d563e12d3aa 100644
--- a/drivers/gpu/drm/i915/display/intel_connector.c
+++ b/drivers/gpu/drm/i915/display/intel_connector.c
@@ -40,6 +40,11 @@
 #include "intel_hdcp.h"
 #include "intel_panel.h"
 
+static const u32 supported_colorformats = DRM_COLOR_FORMAT_AUTO |
+					  DRM_COLOR_FORMAT_RGB444 |
+					  DRM_COLOR_FORMAT_YCBCR444 |
+					  DRM_COLOR_FORMAT_YCBCR420;
+
 static void intel_connector_modeset_retry_work_fn(struct work_struct *work)
 {
 	struct intel_connector *connector = container_of(work, typeof(*connector),
@@ -326,6 +331,13 @@ intel_attach_hdmi_colorspace_property(struct drm_connector *connector)
 		drm_connector_attach_colorspace_property(connector);
 }
 
+void
+intel_attach_hdmi_colorformat_property(struct drm_connector *connector)
+{
+	if (!drm_mode_create_hdmi_color_format_property(connector, supported_colorformats))
+		drm_connector_attach_color_format_property(connector);
+}
+
 void
 intel_attach_dp_colorspace_property(struct drm_connector *connector)
 {
@@ -333,6 +345,13 @@ intel_attach_dp_colorspace_property(struct drm_connector *connector)
 		drm_connector_attach_colorspace_property(connector);
 }
 
+void
+intel_attach_dp_colorformat_property(struct drm_connector *connector)
+{
+	if (!drm_mode_create_dp_color_format_property(connector, supported_colorformats))
+		drm_connector_attach_color_format_property(connector);
+}
+
 void
 intel_attach_scaling_mode_property(struct drm_connector *connector)
 {
diff --git a/drivers/gpu/drm/i915/display/intel_connector.h b/drivers/gpu/drm/i915/display/intel_connector.h
index 0aa86626e646..38401bc705e3 100644
--- a/drivers/gpu/drm/i915/display/intel_connector.h
+++ b/drivers/gpu/drm/i915/display/intel_connector.h
@@ -30,7 +30,9 @@ void intel_attach_force_audio_property(struct drm_connector *connector);
 void intel_attach_broadcast_rgb_property(struct drm_connector *connector);
 void intel_attach_aspect_ratio_property(struct drm_connector *connector);
 void intel_attach_hdmi_colorspace_property(struct drm_connector *connector);
+void intel_attach_hdmi_colorformat_property(struct drm_connector *connector);
 void intel_attach_dp_colorspace_property(struct drm_connector *connector);
+void intel_attach_dp_colorformat_property(struct drm_connector *connector);
 void intel_attach_scaling_mode_property(struct drm_connector *connector);
 void intel_connector_queue_modeset_retry_work(struct intel_connector *connector);
 void intel_connector_cancel_modeset_retry_work(struct intel_connector *connector);
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 38702a9e0f50..b06fbe56cbbe 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -2206,6 +2206,21 @@ to_intel_frontbuffer(struct drm_framebuffer *fb)
 	return fb ? to_intel_framebuffer(fb)->frontbuffer : NULL;
 }
 
+static inline __pure u32
+intel_output_format_to_drm_color_format(enum intel_output_format input)
+{
+	switch (input) {
+	case INTEL_OUTPUT_FORMAT_RGB:
+		return DRM_COLOR_FORMAT_RGB444;
+	case INTEL_OUTPUT_FORMAT_YCBCR444:
+		return DRM_COLOR_FORMAT_YCBCR444;
+	case INTEL_OUTPUT_FORMAT_YCBCR420:
+		return DRM_COLOR_FORMAT_YCBCR420;
+	}
+
+	return DRM_COLOR_FORMAT_NONE;
+}
+
 /*
  * Conversion functions/macros from various pointer types to struct
  * intel_display pointer.
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 0ec82fcbcf48..6fcd1f2dbefd 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1183,7 +1183,7 @@ dfp_can_convert(struct intel_dp *intel_dp,
 	return false;
 }
 
-static enum intel_output_format
+enum intel_output_format
 intel_dp_output_format(struct intel_connector *connector,
 		       enum intel_output_format sink_format)
 {
@@ -3141,17 +3141,23 @@ intel_dp_compute_output_format(struct intel_encoder *encoder,
 	struct intel_connector *connector = intel_dp->attached_connector;
 	const struct drm_display_info *info = &connector->base.display_info;
 	const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
-	bool ycbcr_420_only;
+	u32 sink_format_drm;
 	int ret;
 
-	ycbcr_420_only = drm_mode_is_420_only(info, adjusted_mode);
+	if ((conn_state->color_format == DRM_COLOR_FORMAT_YCBCR420 &&
+	     drm_mode_is_420_also(info, adjusted_mode)) ||
+	    drm_mode_is_420_only(info, adjusted_mode))
+		crtc_state->sink_format = INTEL_OUTPUT_FORMAT_YCBCR420;
+	else if (conn_state->color_format == DRM_COLOR_FORMAT_YCBCR444)
+		crtc_state->sink_format = INTEL_OUTPUT_FORMAT_YCBCR444;
+	else
+		crtc_state->sink_format = INTEL_OUTPUT_FORMAT_RGB;
 
-	if (ycbcr_420_only && !connector->base.ycbcr_420_allowed) {
+	if (crtc_state->sink_format == INTEL_OUTPUT_FORMAT_YCBCR420 &&
+	    !connector->base.ycbcr_420_allowed) {
 		drm_dbg_kms(display->drm,
-			    "YCbCr 4:2:0 mode but YCbCr 4:2:0 output not possible. Falling back to RGB.\n");
+			"YCbCr 4:2:0 mode requested but unsupported by connector. Trying RGB.\n");
 		crtc_state->sink_format = INTEL_OUTPUT_FORMAT_RGB;
-	} else {
-		crtc_state->sink_format = intel_dp_sink_format(connector, adjusted_mode);
 	}
 
 	crtc_state->output_format = intel_dp_output_format(connector, crtc_state->sink_format);
@@ -3159,6 +3165,11 @@ intel_dp_compute_output_format(struct intel_encoder *encoder,
 	ret = intel_dp_compute_link_config(encoder, crtc_state, conn_state,
 					   respect_downstream_limits);
 	if (ret) {
+		/*
+		 * If no valid link config can be found due to bandwidth constraints,
+		 * degrade from RGB/YCbCr 4:4:4 to YCbCr 4:2:0 if permitted by
+		 * the source and sink.
+		 */
 		if (crtc_state->sink_format == INTEL_OUTPUT_FORMAT_YCBCR420 ||
 		    !connector->base.ycbcr_420_allowed ||
 		    !drm_mode_is_420_also(info, adjusted_mode))
@@ -3169,9 +3180,22 @@ intel_dp_compute_output_format(struct intel_encoder *encoder,
 								   crtc_state->sink_format);
 		ret = intel_dp_compute_link_config(encoder, crtc_state, conn_state,
 						   respect_downstream_limits);
+		if (ret)
+			return ret;
 	}
 
-	return ret;
+	sink_format_drm = intel_output_format_to_drm_color_format(crtc_state->sink_format);
+	if (conn_state->color_format &&
+	    conn_state->color_format != sink_format_drm &&
+	    conn_state->color_format != DRM_COLOR_FORMAT_AUTO) {
+		drm_dbg_kms(display->drm,
+			    "Unsupported color format %s (0x%x), sink has 0x%x\n",
+			    drm_get_color_format_name(conn_state->color_format),
+			    conn_state->color_format, sink_format_drm);
+		return -EINVAL;
+	}
+
+	return 0;
 }
 
 void
@@ -6626,8 +6650,10 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *_connec
 	if (intel_bios_encoder_is_lspcon(dp_to_dig_port(intel_dp)->base.devdata)) {
 		drm_connector_attach_content_type_property(&connector->base);
 		intel_attach_hdmi_colorspace_property(&connector->base);
+		intel_attach_hdmi_colorformat_property(&connector->base);
 	} else {
 		intel_attach_dp_colorspace_property(&connector->base);
+		intel_attach_dp_colorformat_property(&connector->base);
 	}
 
 	if (intel_dp_has_gamut_metadata_dip(&dp_to_dig_port(intel_dp)->base))
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index 200a8b267f64..a7492c97ac97 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -205,6 +205,10 @@ bool intel_dp_compute_config_limits(struct intel_dp *intel_dp,
 void intel_dp_get_dsc_sink_cap(u8 dpcd_rev,
 			       const struct drm_dp_desc *desc, bool is_branch,
 			       struct intel_connector *connector);
+enum intel_output_format
+intel_dp_output_format(struct intel_connector *connector,
+		       enum intel_output_format sink_format);
+
 bool intel_dp_has_gamut_metadata_dip(struct intel_encoder *encoder);
 
 bool intel_dp_link_params_valid(struct intel_dp *intel_dp, int link_rate,
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 4c0b943fe86f..35f8db595e22 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -653,9 +653,11 @@ static int mst_stream_compute_config(struct intel_encoder *encoder,
 		to_intel_connector(conn_state->connector);
 	const struct drm_display_mode *adjusted_mode =
 		&pipe_config->hw.adjusted_mode;
+	const struct drm_display_info *info = &connector->base.display_info;
 	struct link_config_limits limits;
 	bool dsc_needed, joiner_needs_dsc;
 	int num_joined_pipes;
+	u32 sink_format_drm;
 	int ret = 0;
 
 	if (pipe_config->fec_enable &&
@@ -671,10 +673,36 @@ static int mst_stream_compute_config(struct intel_encoder *encoder,
 	if (num_joined_pipes > 1)
 		pipe_config->joiner_pipes = GENMASK(crtc->pipe + num_joined_pipes - 1, crtc->pipe);
 
-	pipe_config->sink_format = INTEL_OUTPUT_FORMAT_RGB;
-	pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
+	if ((conn_state->color_format == DRM_COLOR_FORMAT_YCBCR420 &&
+	     drm_mode_is_420_also(info, adjusted_mode)) ||
+	    drm_mode_is_420_only(info, adjusted_mode))
+		pipe_config->sink_format = INTEL_OUTPUT_FORMAT_YCBCR420;
+	else if (conn_state->color_format == DRM_COLOR_FORMAT_YCBCR444)
+		pipe_config->sink_format = INTEL_OUTPUT_FORMAT_YCBCR444;
+	else
+		pipe_config->sink_format = INTEL_OUTPUT_FORMAT_RGB;
+
+	if (pipe_config->sink_format == INTEL_OUTPUT_FORMAT_YCBCR420 &&
+	    !connector->base.ycbcr_420_allowed) {
+		drm_dbg_kms(display->drm,
+			"YCbCr 4:2:0 mode requested but it's unsupported by connector. Trying RGB.\n");
+		pipe_config->sink_format = INTEL_OUTPUT_FORMAT_RGB;
+	}
+
+	pipe_config->output_format = intel_dp_output_format(connector, pipe_config->sink_format);
 	pipe_config->has_pch_encoder = false;
 
+	sink_format_drm = intel_output_format_to_drm_color_format(pipe_config->sink_format);
+	if (conn_state->color_format &&
+	    conn_state->color_format != sink_format_drm &&
+	    conn_state->color_format != DRM_COLOR_FORMAT_AUTO) {
+		drm_dbg_kms(display->drm,
+			    "Unsupported color format %s (0x%x), sink has 0x%x\n",
+			    drm_get_color_format_name(conn_state->color_format),
+			    conn_state->color_format, sink_format_drm);
+		return -EINVAL;
+	}
+
 	joiner_needs_dsc = intel_dp_joiner_needs_dsc(display, num_joined_pipes);
 
 	dsc_needed = joiner_needs_dsc || intel_dp->force_dsc_en ||
@@ -1660,6 +1688,11 @@ static int mst_topology_add_connector_properties(struct intel_dp *intel_dp,
 	if (connector->base.max_bpc_property)
 		drm_connector_attach_max_bpc_property(&connector->base, 6, 12);
 
+	connector->base.color_format_property =
+		intel_dp->attached_connector->base.color_format_property;
+	if (connector->base.color_format_property)
+		intel_attach_dp_colorformat_property(&connector->base);
+
 	return drm_connector_set_path_property(&connector->base, pathprop);
 }
 
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 908faf17f93d..adecee10cb4c 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2271,21 +2271,28 @@ static int intel_hdmi_compute_output_format(struct intel_encoder *encoder,
 	struct intel_connector *connector = to_intel_connector(conn_state->connector);
 	const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
 	const struct drm_display_info *info = &connector->base.display_info;
-	bool ycbcr_420_only = drm_mode_is_420_only(info, adjusted_mode);
+	u32 sink_format_drm;
+	bool want_420;
 	int ret;
 
-	crtc_state->sink_format =
-		intel_hdmi_sink_format(crtc_state, connector, ycbcr_420_only);
-
-	if (ycbcr_420_only && crtc_state->sink_format != INTEL_OUTPUT_FORMAT_YCBCR420) {
-		drm_dbg_kms(display->drm,
-			    "YCbCr 4:2:0 mode but YCbCr 4:2:0 output not possible. Falling back to RGB.\n");
-		crtc_state->sink_format = INTEL_OUTPUT_FORMAT_RGB;
+	if (conn_state->color_format == DRM_COLOR_FORMAT_YCBCR444)
+		crtc_state->sink_format = INTEL_OUTPUT_FORMAT_YCBCR444;
+	else {
+		want_420 = ((conn_state->color_format == DRM_COLOR_FORMAT_YCBCR420 &&
+			     drm_mode_is_420(info, adjusted_mode)) ||
+			     drm_mode_is_420_only(info, adjusted_mode));
+		crtc_state->sink_format = intel_hdmi_sink_format(crtc_state, connector,
+								 want_420);
 	}
 
 	crtc_state->output_format = intel_hdmi_output_format(crtc_state);
 	ret = intel_hdmi_compute_clock(encoder, crtc_state, respect_downstream_limits);
 	if (ret) {
+		/*
+		 * If no valid link config can be found due to bandwidth constraints,
+		 * degrade from RGB/YCbCr 4:4:4 to YCbCr 4:2:0 if permitted by
+		 * the source and sink.
+		 */
 		if (crtc_state->sink_format == INTEL_OUTPUT_FORMAT_YCBCR420 ||
 		    !crtc_state->has_hdmi_sink ||
 		    !connector->base.ycbcr_420_allowed ||
@@ -2295,6 +2302,19 @@ static int intel_hdmi_compute_output_format(struct intel_encoder *encoder,
 		crtc_state->sink_format = INTEL_OUTPUT_FORMAT_YCBCR420;
 		crtc_state->output_format = intel_hdmi_output_format(crtc_state);
 		ret = intel_hdmi_compute_clock(encoder, crtc_state, respect_downstream_limits);
+		if (ret)
+			return ret;
+	}
+
+	sink_format_drm = intel_output_format_to_drm_color_format(crtc_state->sink_format);
+	if (conn_state->color_format &&
+	    conn_state->color_format != sink_format_drm &&
+	    conn_state->color_format != DRM_COLOR_FORMAT_AUTO) {
+		drm_dbg_kms(display->drm,
+			    "Unsupported color format %s (0x%x), current sink color format 0x%x\n",
+			    drm_get_color_format_name(conn_state->color_format),
+			    conn_state->color_format, sink_format_drm);
+		ret = -EINVAL;
 	}
 
 	return ret;
@@ -2690,8 +2710,10 @@ intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *_
 	if (DISPLAY_VER(display) >= 10)
 		drm_connector_attach_hdr_output_metadata_property(&connector->base);
 
-	if (!HAS_GMCH(display))
+	if (!HAS_GMCH(display)) {
 		drm_connector_attach_max_bpc_property(&connector->base, 8, 12);
+		intel_attach_hdmi_colorformat_property(&connector->base);
+	}
 }
 
 /*

-- 
2.51.2



From nicolas.frattaroli at collabora.com  Mon Nov 17 11:11:53 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 17 Nov 2025 20:11:53 +0100
Subject: [PATCH v4 09/10] drm/amdgpu: Implement "color format" DRM property
In-Reply-To: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
References: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
Message-ID: <20251117-color-format-v4-9-0ded72bd1b00@collabora.com>

The "color format" DRM property allows userspace to explicitly pick a
color format to use. If an unsupported color format is requested,
userspace will be given an error instead of silently having its request
disobeyed.

The default case, in which the property is either unset or set to Auto,
picks YCbCr 4:2:0 if it's a 4:2:0-only mode, and RGB in all other cases.

Co-developed-by: Werner Sembach <wse at tuxedocomputers.com>
Signed-off-by: Werner Sembach <wse at tuxedocomputers.com>
Co-developed-by: Andri Yngvason <andri at yngvason.is>
Signed-off-by: Andri Yngvason <andri at yngvason.is>
Co-developed-by: Marius Vlad <marius.vlad at collabora.com>
Signed-off-by: Marius Vlad <marius.vlad at collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  | 89 +++++++++++++++++++---
 .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c    | 14 ++++
 2 files changed, 94 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 598dc3ce993c..956dd4934fa6 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -6504,11 +6504,14 @@ static void fill_stream_properties_from_drm_display_mode(
 	const struct dc_stream_state *old_stream,
 	int requested_bpc)
 {
+	bool is_dp_or_hdmi = dc_is_hdmi_signal(stream->signal) || dc_is_dp_signal(stream->signal);
 	struct dc_crtc_timing *timing_out = &stream->timing;
 	const struct drm_display_info *info = &connector->display_info;
 	struct amdgpu_dm_connector *aconnector = NULL;
 	struct hdmi_vendor_infoframe hv_frame;
 	struct hdmi_avi_infoframe avi_frame;
+	bool want_420;
+	bool want_422;
 	ssize_t err;
 
 	if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
@@ -6521,19 +6524,38 @@ static void fill_stream_properties_from_drm_display_mode(
 	timing_out->h_border_right = 0;
 	timing_out->v_border_top = 0;
 	timing_out->v_border_bottom = 0;
-	/* TODO: un-hardcode */
-	if (drm_mode_is_420_only(info, mode_in) || (drm_mode_is_420_also(info, mode_in) &&
-	    aconnector && aconnector->force_yuv420_output))
+
+	want_420 = (aconnector && aconnector->force_yuv420_output) ||
+		   (connector_state->color_format == DRM_COLOR_FORMAT_YCBCR420);
+	want_422 = (aconnector && aconnector->force_yuv422_output) ||
+		   (connector_state->color_format == DRM_COLOR_FORMAT_YCBCR422);
+
+	if (drm_mode_is_420(info, mode_in) && want_420)
 		timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
-	else if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCBCR422)
-			&& aconnector
-			&& aconnector->force_yuv422_output)
+	else if ((info->color_formats & DRM_COLOR_FORMAT_YCBCR422) && want_422 && is_dp_or_hdmi)
 		timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR422;
-	else if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCBCR444)
-			&& stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
+	else if (connector_state->color_format == DRM_COLOR_FORMAT_YCBCR444 &&
+		 (info->color_formats & DRM_COLOR_FORMAT_YCBCR444) && is_dp_or_hdmi)
 		timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR444;
-	else
+	else if ((connector_state->color_format == DRM_COLOR_FORMAT_RGB444 ||
+		  connector_state->color_format == DRM_COLOR_FORMAT_AUTO) &&
+		 !drm_mode_is_420_only(info, mode_in))
 		timing_out->pixel_encoding = PIXEL_ENCODING_RGB;
+	else {
+		/*
+		 * If a format was explicitly requested but the requested format
+		 * can't be satisfied, set it to an invalid value so that an
+		 * error bubbles up to userspace. This way, userspace knows it
+		 * needs to make a better choice.
+		 */
+		if (connector_state->color_format &&
+			connector_state->color_format != DRM_COLOR_FORMAT_AUTO)
+			timing_out->pixel_encoding = PIXEL_ENCODING_UNDEFINED;
+		else if (drm_mode_is_420_only(info, mode_in))
+			timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
+		else
+			timing_out->pixel_encoding = PIXEL_ENCODING_RGB;
+	}
 
 	timing_out->timing_3d_format = TIMING_3D_FORMAT_NONE;
 	timing_out->display_color_depth = convert_color_depth_from_display_info(
@@ -7874,6 +7896,39 @@ static enum dc_status dm_validate_stream_and_context(struct dc *dc,
 	return dc_result;
 }
 
+static enum dc_status
+dm_validate_stream_color_format(const struct drm_connector_state *drm_state,
+				const struct dc_stream_state *stream)
+{
+	enum dc_pixel_encoding encoding;
+
+	if (!drm_state->color_format ||
+	    drm_state->color_format == DRM_COLOR_FORMAT_NONE)
+		return DC_OK;
+
+	switch (drm_state->color_format) {
+	case DRM_COLOR_FORMAT_AUTO:
+	case DRM_COLOR_FORMAT_RGB444:
+		encoding = PIXEL_ENCODING_RGB;
+		break;
+	case DRM_COLOR_FORMAT_YCBCR444:
+		encoding = PIXEL_ENCODING_YCBCR444;
+		break;
+	case DRM_COLOR_FORMAT_YCBCR422:
+		encoding = PIXEL_ENCODING_YCBCR422;
+		break;
+	case DRM_COLOR_FORMAT_YCBCR420:
+		encoding = PIXEL_ENCODING_YCBCR420;
+		break;
+	default:
+		encoding = PIXEL_ENCODING_UNDEFINED;
+		break;
+	}
+
+	return encoding == stream->timing.pixel_encoding ?
+		DC_OK : DC_UNSUPPORTED_VALUE;
+}
+
 struct dc_stream_state *
 create_validate_stream_for_sink(struct drm_connector *connector,
 				const struct drm_display_mode *drm_mode,
@@ -7920,6 +7975,9 @@ create_validate_stream_for_sink(struct drm_connector *connector,
 		if (dc_result == DC_OK)
 			dc_result = dm_validate_stream_and_context(adev->dm.dc, stream);
 
+		if (dc_result == DC_OK)
+			dc_result = dm_validate_stream_color_format(drm_state, stream);
+
 		if (dc_result != DC_OK) {
 			DRM_DEBUG_KMS("Pruned mode %d x %d (clk %d) %s %s -- %s\n",
 				      drm_mode->hdisplay,
@@ -8735,6 +8793,13 @@ static const u32 supported_colorspaces =
 	BIT(DRM_MODE_COLORIMETRY_BT2020_RGB) |
 	BIT(DRM_MODE_COLORIMETRY_BT2020_YCC);
 
+static const u32 supported_colorformats =
+	DRM_COLOR_FORMAT_AUTO |
+	DRM_COLOR_FORMAT_RGB444 |
+	DRM_COLOR_FORMAT_YCBCR444 |
+	DRM_COLOR_FORMAT_YCBCR422 |
+	DRM_COLOR_FORMAT_YCBCR420;
+
 void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
 				     struct amdgpu_dm_connector *aconnector,
 				     int connector_type,
@@ -8827,10 +8892,16 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
 	if (connector_type == DRM_MODE_CONNECTOR_HDMIA) {
 		if (!drm_mode_create_hdmi_colorspace_property(&aconnector->base, supported_colorspaces))
 			drm_connector_attach_colorspace_property(&aconnector->base);
+		if (!drm_mode_create_hdmi_color_format_property(&aconnector->base,
+								supported_colorformats))
+			drm_connector_attach_color_format_property(&aconnector->base);
 	} else if ((connector_type == DRM_MODE_CONNECTOR_DisplayPort && !aconnector->mst_root) ||
 		   connector_type == DRM_MODE_CONNECTOR_eDP) {
 		if (!drm_mode_create_dp_colorspace_property(&aconnector->base, supported_colorspaces))
 			drm_connector_attach_colorspace_property(&aconnector->base);
+		if (!drm_mode_create_dp_color_format_property(&aconnector->base,
+							      supported_colorformats))
+			drm_connector_attach_color_format_property(&aconnector->base);
 	}
 
 	if (connector_type == DRM_MODE_CONNECTOR_HDMIA ||
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 5e92eaa67aa3..7d35779c99d5 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -52,6 +52,13 @@
 
 #define PEAK_FACTOR_X1000 1006
 
+static const u32 supported_colorformats =
+	DRM_COLOR_FORMAT_AUTO |
+	DRM_COLOR_FORMAT_RGB444 |
+	DRM_COLOR_FORMAT_YCBCR444 |
+	DRM_COLOR_FORMAT_YCBCR422 |
+	DRM_COLOR_FORMAT_YCBCR420;
+
 /*
  * This function handles both native AUX and I2C-Over-AUX transactions.
  */
@@ -679,6 +686,13 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
 	if (connector->max_bpc_property)
 		drm_connector_attach_max_bpc_property(connector, 8, 16);
 
+	connector->color_format_property = master->base.color_format_property;
+	if (connector->color_format_property) {
+		if (!drm_mode_create_dp_color_format_property(&aconnector->base,
+							      supported_colorformats))
+			drm_connector_attach_color_format_property(&aconnector->base);
+	}
+
 	connector->vrr_capable_property = master->base.vrr_capable_property;
 	if (connector->vrr_capable_property)
 		drm_connector_attach_vrr_capable_property(connector);

-- 
2.51.2



From nicolas.frattaroli at collabora.com  Mon Nov 17 11:11:54 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Mon, 17 Nov 2025 20:11:54 +0100
Subject: [PATCH v4 10/10] drm/rockchip: Implement "color format" DRM
 property
In-Reply-To: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
References: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
Message-ID: <20251117-color-format-v4-10-0ded72bd1b00@collabora.com>

From: Derek Foreman <derek.foreman at collabora.com>

Register the color format property in the dw_hdmi_qp-rockchip driver,
and act on requested format changes as part of the connector state in
the vop2 video output driver.

Signed-off-by: Derek Foreman <derek.foreman at collabora.com>
Signed-off-by: Marius Vlad <marius.vlad at collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c |  3 ++
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c   | 46 ++++++++++++++++++++++++++
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h   |  2 ++
 3 files changed, 51 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
index 7c294751de19..7028166fdace 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
@@ -635,6 +635,9 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
 		return dev_err_probe(hdmi->dev, PTR_ERR(connector),
 				     "Failed to init bridge connector\n");
 
+	if (!drm_mode_create_hdmi_color_format_property(connector, supported_colorformats))
+		drm_connector_attach_color_format_property(connector);
+
 	return drm_connector_attach_encoder(connector, encoder);
 }
 
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 498df0ce4680..2fc9b21c5522 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1549,6 +1549,50 @@ static void vop2_dither_setup(struct drm_crtc *crtc, u32 *dsp_ctrl)
 				DITHER_DOWN_ALLEGRO);
 }
 
+static void vop2_bcsh_config(struct drm_crtc *crtc, struct vop2_video_port *vp)
+{
+	struct drm_connector_list_iter conn_iter;
+	struct drm_connector *connector;
+	u32 format = 0;
+	enum drm_colorspace colorspace = 0;
+	u32 val = 0;
+
+	drm_connector_list_iter_begin(crtc->dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
+		if (!(crtc->state->connector_mask & drm_connector_mask(connector)))
+			continue;
+
+		format = connector->state->color_format;
+		colorspace = connector->state->colorspace;
+		break;
+	}
+	drm_connector_list_iter_end(&conn_iter);
+
+	if (format == DRM_COLOR_FORMAT_YCBCR420 ||
+	    format == DRM_COLOR_FORMAT_YCBCR444 ||
+	    format == DRM_COLOR_FORMAT_YCBCR422) {
+		val = RK3568_VP_BCSH_CTRL__BCSH_R2Y_EN | BIT(7);
+
+		switch (colorspace) {
+		case DRM_MODE_COLORIMETRY_BT2020_RGB:
+		case DRM_MODE_COLORIMETRY_BT2020_YCC:
+			val |= BIT(7) | BIT(6);
+			break;
+		case DRM_MODE_COLORIMETRY_BT709_YCC:
+			val |= BIT(6);
+			break;
+		default:
+			break;
+		}
+		if (colorspace == DRM_MODE_COLORIMETRY_BT2020_RGB ||
+		    colorspace == DRM_MODE_COLORIMETRY_BT2020_YCC)
+			val |= BIT(6);
+	}
+
+	vop2_vp_write(vp, RK3568_VP_BCSH_CTRL, val);
+	vop2_vp_write(vp, RK3568_VP_BCSH_COLOR_BAR, 0);
+}
+
 static void vop2_post_config(struct drm_crtc *crtc)
 {
 	struct vop2_video_port *vp = to_vop2_video_port(crtc);
@@ -1600,6 +1644,8 @@ static void vop2_post_config(struct drm_crtc *crtc)
 	}
 
 	vop2_vp_write(vp, RK3568_VP_DSP_BG, 0);
+
+	vop2_bcsh_config(crtc, vp);
 }
 
 static int us_to_vertical_line(struct drm_display_mode *mode, int us)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index 9124191899ba..33fdc9d8d819 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -637,6 +637,8 @@ enum dst_factor_mode {
 
 #define RK3568_REG_CFG_DONE__GLB_CFG_DONE_EN		BIT(15)
 
+#define RK3568_VP_BCSH_CTRL__BCSH_R2Y_EN		BIT(4)
+
 #define RK3568_VP_DSP_CTRL__STANDBY			BIT(31)
 #define RK3568_VP_DSP_CTRL__DSP_LUT_EN			BIT(28)
 #define RK3568_VP_DSP_CTRL__DITHER_DOWN_MODE		BIT(20)

-- 
2.51.2



From geraldogabriel at gmail.com  Mon Nov 17 13:46:43 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Mon, 17 Nov 2025 18:46:43 -0300
Subject: [PATCH v2 0/4] PCI: rockchip: 5.0 GT/s speed may be dangerous
Message-ID: <cover.1763415705.git.geraldogabriel@gmail.com>

Dragan Simic already had warned me of potential issues with 5.0 GT/s
speed operation in Rockchip PCIe. However, in recent interactions
with Shawn Lin from Rockchip it came to my attention there's grave
danger in the unknown errata regarding 5.0 GT/s operational speed
of their PCIe core. Even if the odds are low, to contain any damage,
let's cover the remaining corner-cases where the default would lead
to 5.0 GT/s operation as well as add a comment to Root Complex driver
core, documenting this danger. Furthermore, remove redundant
declaration of max-link-speed from rk3399-nanopi-r4s.dtsi

Signed-off-by: Geraldo Nascimento <geraldogabriel at gmail.com>

---

Changes in v2:
- hard limit to 2.5 GT/s, not just warn
- add Reported-by: and Reviewed-by: Dragan Simic
- remove redundant declaration of max-link-speed from helios64 dts
- fix Link: of helios64 patch
- simplify RC mode comment
- Link to v1: https://lore.kernel.org/all/aRhR79u5BPtRRFw3 at geday/

Geraldo Nascimento (4):
  PCI: rockchip: limit RK3399 to 2.5 GT/s to prevent damage
  PCI: rockchip-host: comment danger of 5.0 GT/s speed
  arm64: dts: rockchip: remove dangerous max-link-speed from helios64
  arm64: dts: rockchip: remove redundant max-link-speed from nanopi-r4s

 arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts |  1 -
 arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dtsi    |  1 -
 drivers/pci/controller/pcie-rockchip-host.c            |  3 +++
 drivers/pci/controller/pcie-rockchip.c                 | 10 ++++++++--
 4 files changed, 11 insertions(+), 4 deletions(-)

-- 
2.49.0



From geraldogabriel at gmail.com  Mon Nov 17 13:47:05 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Mon, 17 Nov 2025 18:47:05 -0300
Subject: [PATCH v2 1/4] PCI: rockchip: limit RK3399 to 2.5 GT/s to prevent
 damage
In-Reply-To: <cover.1763415705.git.geraldogabriel@gmail.com>
References: <cover.1763415705.git.geraldogabriel@gmail.com>
Message-ID: <eaa9c75ca02a53f8bcc293b8bc73d013e26ec253.1763415706.git.geraldogabriel@gmail.com>

Shawn Lin from Rockchip has reiterated that there may be danger in using
their PCIe with 5.0 GT/s speeds. Warn the user if they make a DT change
from the default and drive at 2.5 GT/s only, even if the DT
max-link-speed property is invalid or inexistent.

This change is corroborated by RK3399 official datasheet [1], which
says maximum link speed for this platform is 2.5 GT/s.

[1] https://opensource.rock-chips.com/images/d/d7/Rockchip_RK3399_Datasheet_V2.1-20200323.pdf

Fixes: 956cd99b35a8 ("PCI: rockchip: Separate common code from RC driver")
Link: https://lore.kernel.org/all/ffd05070-9879-4468-94e3-b88968b4c21b at rock-chips.com/
Cc: stable at vger.kernel.org
Reported-by: Dragan Simic <dsimic at manjaro.org>
Reported-by: Shawn Lin <shawn.lin at rock-chips.com>
Reviewed-by: Dragan Simic <dsimic at manjaro.org>
Signed-off-by: Geraldo Nascimento <geraldogabriel at gmail.com>
---
 drivers/pci/controller/pcie-rockchip.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/pcie-rockchip.c b/drivers/pci/controller/pcie-rockchip.c
index 0f88da378805..992ccf4b139e 100644
--- a/drivers/pci/controller/pcie-rockchip.c
+++ b/drivers/pci/controller/pcie-rockchip.c
@@ -66,8 +66,14 @@ int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip)
 	}
 
 	rockchip->link_gen = of_pci_get_max_link_speed(node);
-	if (rockchip->link_gen < 0 || rockchip->link_gen > 2)
-		rockchip->link_gen = 2;
+	if (rockchip->link_gen < 0 || rockchip->link_gen > 2) {
+		rockchip->link_gen = 1;
+		dev_warn(dev, "invalid max-link-speed, set to 2.5 GT/s\n");
+	}
+	else if (rockchip->link_gen == 2) {
+		rockchip->link_gen = 1;
+		dev_warn(dev, "5.0 GT/s is dangerous, set to 2.5 GT/s\n");
+	}
 
 	for (i = 0; i < ROCKCHIP_NUM_PM_RSTS; i++)
 		rockchip->pm_rsts[i].id = rockchip_pci_pm_rsts[i];
-- 
2.49.0



From geraldogabriel at gmail.com  Mon Nov 17 13:47:22 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Mon, 17 Nov 2025 18:47:22 -0300
Subject: [PATCH v2 2/4] PCI: rockchip-host: comment danger of 5.0 GT/s speed
In-Reply-To: <cover.1763415705.git.geraldogabriel@gmail.com>
References: <cover.1763415705.git.geraldogabriel@gmail.com>
Message-ID: <2f2825741e189f5d915560eede6ff7bf827546f4.1763415706.git.geraldogabriel@gmail.com>

According to Rockchip sources, there is grave danger in enabling 5.0
GT/s speed for this core. Add a comment documenting that danger and
discouraging end-users from forcing higher speed.

Link: https://lore.kernel.org/all/ffd05070-9879-4468-94e3-b88968b4c21b at rock-chips.com/
Cc: stable at vger.kernel.org
Reported-by: Dragan Simic <dsimic at manjaro.org>
Reported-by: Shawn Lin <shawn.lin at rock-chips.com>
Reviewed-by: Dragan Simic <dsimic at manjaro.org>
Signed-off-by: Geraldo Nascimento <geraldogabriel at gmail.com>
---
 drivers/pci/controller/pcie-rockchip-host.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c
index ee1822ca01db..0af550277ee5 100644
--- a/drivers/pci/controller/pcie-rockchip-host.c
+++ b/drivers/pci/controller/pcie-rockchip-host.c
@@ -332,6 +332,9 @@ static int rockchip_pcie_host_init_port(struct rockchip_pcie *rockchip)
 		/*
 		 * Enable retrain for gen2. This should be configured only after
 		 * gen1 finished.
+		 *
+		 * Dangerous and may lead to catastrophic failure eventually!
+		 *
 		 */
 		status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_CR + PCI_EXP_LNKCTL2);
 		status &= ~PCI_EXP_LNKCTL2_TLS;
-- 
2.49.0



From geraldogabriel at gmail.com  Mon Nov 17 13:47:43 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Mon, 17 Nov 2025 18:47:43 -0300
Subject: [PATCH v2 3/4] arm64: dts: rockchip: remove dangerous max-link-speed
 from helios64
In-Reply-To: <cover.1763415705.git.geraldogabriel@gmail.com>
References: <cover.1763415705.git.geraldogabriel@gmail.com>
Message-ID: <43bb639c120f599106fca2deee6c6599b2692c5c.1763415706.git.geraldogabriel@gmail.com>

Shawn Lin from Rockchip strongly discourages attempts to use their
RK3399 PCIe core at 5.0 GT/s speed, citing concerns about catastrophic
failures that may happen. Even if the odds are low, drop from last user
of this non-default property for the RK3399 platform, helios64 board
dts.

Fixes: 755fff528b1b ("arm64: dts: rockchip: add variables for pcie completion to helios64")
Link: https://lore.kernel.org/all/e8524bf8-a90c-423f-8a58-9ef05a3db1dd at rock-chips.com/
Cc: stable at vger.kernel.org
Reported-by: Shawn Lin <shawn.lin at rock-chips.com>
Reviewed-by: Dragan Simic <dsimic at manjaro.org>
Signed-off-by: Geraldo Nascimento <geraldogabriel at gmail.com>
---
 arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
index e7d4a2f9a95e..78a7775c3b22 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
@@ -424,7 +424,6 @@ &pcie_phy {
 
 &pcie0 {
 	ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>;
-	max-link-speed = <2>;
 	num-lanes = <2>;
 	pinctrl-names = "default";
 	status = "okay";
-- 
2.49.0



From geraldogabriel at gmail.com  Mon Nov 17 13:47:59 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Mon, 17 Nov 2025 18:47:59 -0300
Subject: [PATCH v2 4/4] arm64: dts: rockchip: remove redundant max-link-speed
 from nanopi-r4s
In-Reply-To: <cover.1763415705.git.geraldogabriel@gmail.com>
References: <cover.1763415705.git.geraldogabriel@gmail.com>
Message-ID: <6694456a735844177c897581f785cc00c064c7d1.1763415706.git.geraldogabriel@gmail.com>

This is already the default in rk3399-base.dtsi, remove redundant
declaration from rk3399-nanopi-r4s.dtsi.

Fixes: db792e9adbf8 ("rockchip: rk3399: Add support for FriendlyARM NanoPi R4S")
Cc: stable at vger.kernel.org
Reported-by: Dragan Simic <dsimic at manjaro.org>
Reviewed-by: Dragan Simic <dsimic at manjaro.org>
Signed-off-by: Geraldo Nascimento <geraldogabriel at gmail.com>
---
 arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dtsi | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dtsi
index 8d94d9f91a5c..3a9a10f531bd 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dtsi
@@ -71,7 +71,6 @@ &i2c4 {
 };
 
 &pcie0 {
-	max-link-speed = <1>;
 	num-lanes = <1>;
 	vpcie3v3-supply = <&vcc3v3_sys>;
 };
-- 
2.49.0



From heiko at sntech.de  Mon Nov 17 13:59:04 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 17 Nov 2025 22:59:04 +0100
Subject: (subset) [PATCH v2 0/9] General RK3368 HDMI support and 2 outputs for RK3368-Lion
In-Reply-To: <20251021074254.87065-1-heiko@sntech.de>
References: <20251021074254.87065-1-heiko@sntech.de>
Message-ID: <176341673264.751370.3773925290539740879.b4-ty@sntech.de>


On Tue, 21 Oct 2025 09:42:45 +0200, Heiko Stuebner wrote:
> This series adds the necessary bits for HDMI output on RK3368 and enables
> this on RK3368-Lion. At the same time, use the recently added DSI support
> to enable the generic Video-Demo-adapter as an overlay on Lion as well.
> 
> 
> The reason I'm shaving this Yak is that the recently added DSI support
> created DTC warnings about a single endpoint with an address.
> 
> [...]

Applied, thanks!

[3/9] soc: rockchip: grf: Add select correct PWM implementation on RK3368
      commit: 048213a38e7ac1591f725e370c152cc80dd84105

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Mon Nov 17 14:18:32 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 17 Nov 2025 23:18:32 +0100
Subject: [GIT PULL] Rockchip dts fixes for 6.18 #1
Message-ID: <1901272.VLH7GnMWUR@phil>

Hi SoC maintainers,

please find a below some Rockchip fixes for the current 6.18 release-cycle.

Please pull

Thanks
Heiko


The following changes since commit 3a8660878839faadb4f1a6dd72c3179c1df56787:

  Linux 6.18-rc1 (2025-10-12 13:42:36 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git tags/v6.18-rockchip-dtsfixes1

for you to fetch changes up to b5414520793e68d266fdd97a84989d9831156aad:

  arm64: dts: rockchip: fix PCIe 3.3V regulator voltage on orangepi-5 (2025-11-14 00:15:33 +0100)

----------------------------------------------------------------
Regulator/supply fixes for a number of boards, removed too fast
cpu OPPs from rk3576 (not supported in newer vendor TF-A and never
supported in upstream TF-A). As well as some DTS validation fixes
and one pinctrl fix for the odroid-m1.

----------------------------------------------------------------
Alexey Charkov (1):
      arm64: dts: rockchip: Remove non-functioning CPU OPPs from RK3576

Anand Moon (1):
      arm64: dts: rockchip: Set correct pinctrl for I2S1 8ch TX on odroid-m1

Andrey Leonchikov (2):
      arm64: dts: rockchip: Fix PCIe power enable pin for BigTreeTech CB2 and Pi2
      arm64: dts: rockchip: Fix USB power enable pin for BTT CB2 and Pi2

Chukun Pan (1):
      arm64: dts: rockchip: drop reset from rk3576 i2c9 node

Diederik de Haas (2):
      arm64: dts: rockchip: Drop 'rockchip,grf' prop from tsadc on rk3328
      arm64: dts: rockchip: Fix vccio4-supply on rk3566-pinetab2

Dragan Simic (1):
      arm64: dts: rockchip: Make RK3588 GPU OPP table naming less generic

Heiko Stuebner (1):
      arm64: dts: rockchip: Fix indentation on rk3399 haikou demo dtso

Mykola Kvach (1):
      arm64: dts: rockchip: fix PCIe 3.3V regulator voltage on orangepi-5

Quentin Schulz (2):
      arm64: dts: rockchip: include rk3399-base instead of rk3399 in rk3399-op1
      arm64: dts: rockchip: disable HS400 on RK3588 Tiger

 arch/arm64/boot/dts/rockchip/rk3328.dtsi                   |  1 -
 arch/arm64/boot/dts/rockchip/rk3399-op1.dtsi               |  2 +-
 .../boot/dts/rockchip/rk3399-puma-haikou-video-demo.dtso   | 10 +++++-----
 arch/arm64/boot/dts/rockchip/rk3566-bigtreetech-cb2.dtsi   |  6 +++---
 arch/arm64/boot/dts/rockchip/rk3566-pinetab2.dtsi          |  2 +-
 arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts          |  2 ++
 arch/arm64/boot/dts/rockchip/rk3576.dtsi                   | 14 --------------
 arch/arm64/boot/dts/rockchip/rk3588-opp.dtsi               |  2 +-
 arch/arm64/boot/dts/rockchip/rk3588-tiger.dtsi             |  4 +---
 arch/arm64/boot/dts/rockchip/rk3588j.dtsi                  |  2 +-
 arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts        |  4 ++--
 11 files changed, 17 insertions(+), 32 deletions(-)





From heiko at sntech.de  Mon Nov 17 14:19:30 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 17 Nov 2025 23:19:30 +0100
Subject: [GIT PULL] Rockchip defconfig64 changes for 6.18 #1
Message-ID: <2101096.usQuhbGJ8B@phil>

The following changes since commit 3a8660878839faadb4f1a6dd72c3179c1df56787:

  Linux 6.18-rc1 (2025-10-12 13:42:36 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git tags/v6.19-rockchip-defconfig64-1

for you to fetch changes up to 60705b039f960378bb2a0a844f9378646bc0c6c8:

  arm64: defconfig: enable rockchip camera interface (2025-11-16 00:34:27 +0100)

----------------------------------------------------------------
Rockchip support for basic camera interface (CIF) and Synopsis DW-DP
driver, as well as the CEC extension to the DW-HDMI-QP driver.

----------------------------------------------------------------
Andy Yan (1):
      arm64: defconfig: Enable Rockchip extensions for Synopsys DW DP

Cristian Ciocaltea (1):
      arm64: defconfig: Enable DW HDMI QP CEC support

Michael Riesch (1):
      arm64: defconfig: enable rockchip camera interface

 arch/arm64/configs/defconfig | 3 +++
 1 file changed, 3 insertions(+)





From heiko at sntech.de  Mon Nov 17 14:20:51 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 17 Nov 2025 23:20:51 +0100
Subject: [GIT PULL] Rockchip driver changes for 6.19 #1
Message-ID: <2002416.CQOukoFCf9@phil>

The following changes since commit 3a8660878839faadb4f1a6dd72c3179c1df56787:

  Linux 6.18-rc1 (2025-10-12 13:42:36 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git tags/v6.19-rockchip-drivers1

for you to fetch changes up to 048213a38e7ac1591f725e370c152cc80dd84105:

  soc: rockchip: grf: Add select correct PWM implementation on RK3368 (2025-11-17 22:34:12 +0100)

----------------------------------------------------------------
Some additional sane defaults for the oldish rk3368 soc.

----------------------------------------------------------------
Heiko Stuebner (1):
      soc: rockchip: grf: Add select correct PWM implementation on RK3368

WeiHao Li (1):
      soc: rockchip: grf: Set pwm2/xin32k pad default to xin32k for rk3368

 drivers/soc/rockchip/grf.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)





From heiko at sntech.de  Mon Nov 17 14:21:50 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 17 Nov 2025 23:21:50 +0100
Subject: [GIT PULL] Rockchip defconfig64 changes for 6.18 #1
In-Reply-To: <2101096.usQuhbGJ8B@phil>
References: <2101096.usQuhbGJ8B@phil>
Message-ID: <2738363.Lt9SDvczpP@phil>

Am Montag, 17. November 2025, 23:19:30 Mitteleurop?ische Normalzeit schrieb Heiko Stuebner:
> The following changes since commit 3a8660878839faadb4f1a6dd72c3179c1df56787:

This is meant for 6.19 ... I messed up the subject with the wrong release.

Sorry about that
Heiko


> 
>   Linux 6.18-rc1 (2025-10-12 13:42:36 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git tags/v6.19-rockchip-defconfig64-1
> 
> for you to fetch changes up to 60705b039f960378bb2a0a844f9378646bc0c6c8:
> 
>   arm64: defconfig: enable rockchip camera interface (2025-11-16 00:34:27 +0100)
> 
> ----------------------------------------------------------------
> Rockchip support for basic camera interface (CIF) and Synopsis DW-DP
> driver, as well as the CEC extension to the DW-HDMI-QP driver.
> 
> ----------------------------------------------------------------
> Andy Yan (1):
>       arm64: defconfig: Enable Rockchip extensions for Synopsys DW DP
> 
> Cristian Ciocaltea (1):
>       arm64: defconfig: Enable DW HDMI QP CEC support
> 
> Michael Riesch (1):
>       arm64: defconfig: enable rockchip camera interface
> 
>  arch/arm64/configs/defconfig | 3 +++
>  1 file changed, 3 insertions(+)
> 






From heiko at sntech.de  Mon Nov 17 14:22:37 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 17 Nov 2025 23:22:37 +0100
Subject: [GIT PULL] Rockchip dts32 changes for 6.19 #1
Message-ID: <2311720.Mh6RI2rZIc@phil>

The following changes since commit 3a8660878839faadb4f1a6dd72c3179c1df56787:

  Linux 6.18-rc1 (2025-10-12 13:42:36 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git tags/v6.19-rockchip-dts32-1

for you to fetch changes up to 10712ce694a67304a99dbba20f8cb146ca5f4fd6:

  ARM: dts: rockchip: move edp assigned-clocks to edp node on rk3288 (2025-11-13 23:52:04 +0100)

----------------------------------------------------------------
A number of cleanups for older socs.

----------------------------------------------------------------
Johan Jonker (4):
      ARM: dts: rockchip: Adapt tps65910 nodes on RK3066 boards
      ARM: dts: rockchip: Remove mshc aliases from RK3288
      ARM: dts: rockchip: Add spi_flash label to rk3288-veyron
      ARM: dts: rockchip: move edp assigned-clocks to edp node on rk3288

 arch/arm/boot/dts/rockchip/rk3066a-bqcurie2.dts  | 34 +++++++++++++----------
 arch/arm/boot/dts/rockchip/rk3066a-marsboard.dts | 34 +++++++++++++----------
 arch/arm/boot/dts/rockchip/rk3066a-rayeager.dts  | 35 ++++++++++++++----------
 arch/arm/boot/dts/rockchip/rk3288-veyron.dtsi    |  2 +-
 arch/arm/boot/dts/rockchip/rk3288.dtsi           |  9 ++----
 5 files changed, 62 insertions(+), 52 deletions(-)





From heiko at sntech.de  Mon Nov 17 14:24:51 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 17 Nov 2025 23:24:51 +0100
Subject: [GIT PULL] Rockchip dts64 changes for 6.19 #1
Message-ID: <2046060.taCxCBeP46@phil>

Hi soc maintainers,

please find below and in the next mails Rockchip changes for for 6.19 .

As always the arm64 parts are the biggest chunk and for me as a
completionist the addition of display output on the old rk3368 is a fun
tidbit :-) .


Please pull.
Thanks
Heiko


The following changes since commit 3a8660878839faadb4f1a6dd72c3179c1df56787:

  Linux 6.18-rc1 (2025-10-12 13:42:36 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git tags/v6.19-rockchip-dts64-1

for you to fetch changes up to 78f316e90906d54c8aa6029e5c19ae83e420e56a:

  arm64: dts: rockchip: add vicap node to rk356x (2025-11-16 00:39:47 +0100)

----------------------------------------------------------------
New boards: 9Tripod X3568, 100ASK DShanPi A1, LinkEase EasePi R1,
FriendlyElec NanoPi R76S

Interesting archeological addition: RK3368 (2015) gets display
output afterall.

New peripherals: vicap on px30 and rk356x, PCIe Gen2x1 on RK3528,
use actual clock-ids for SCMI clocks - not hardcoded numbers,
CQE support for the eMMC on RK3588.

As well as a number of enablements for individual boards.
For example enablement for the now usable NPU.

----------------------------------------------------------------
Chaoyi Chen (1):
      arm64: dts: rockchip: Enable DisplayPort for rk3588-evb2

Chris Morgan (6):
      arm64: dts: rockchip: enable NPU on Gameforce Ace
      arm64: dts: rockchip: Add device type for Indiedroid Nova.
      arm64: dts: rockchip: enable NPU on Indiedroid Nova
      arm64: dts: rockchip: Enable HS400 for Indiedroid Nova
      arm64: dts: rockchip: Fix DMA for Indiedroid Nova Bluetooth
      arm64: dts: rockchip: Enable USB-C DP Alt for Indiedroid Nova

Chukun Pan (4):
      arm64: dts: rockchip: fixes regulator for 100ASK DshanPi A1
      arm64: dts: rockchip: fixes ethernet for 100ASK DshanPi A1
      arm64: dts: rockchip: fixes vcc3v3_s0 supply for 100ASK DshanPi A1
      arm64: dts: rockchip: fixes audio for 100ASK DshanPi A1

Coia Prant (4):
      dt-bindings: vendor-prefixes: Add 9Tripod
      dt-bindings: arm: rockchip: Add 9Tripod X3568 series
      arm64: dts: rockchip: Add devicetree for the 9Tripod X3568 v4
      arm64: dts: rockchip: clean up devicetree for 9Tripod X3568 v4

FUKAUMI Naoki (6):
      arm64: dts: rockchip: Fix USB Type-C host mode for Radxa ROCK 5B+/5T
      arm64: dts: rockchip: Switch microSD card detect to gpio on Radxa ROCK 5 ITX/5C
      arm64: dts: rockchip: Remove sdmmc max-frequency for Radxa ROCK 5 ITX/5B/5B+/5T
      arm64: dts: rockchip: Move the EEPROM to correct I2C bus on Radxa ROCK 5A
      arm64: dts: rockchip: Add eeprom vcc-supply for Radxa ROCK 5A
      arm64: dts: rockchip: Add eeprom vcc-supply for Radxa ROCK 3C

Heiko Stuebner (5):
      dt-bindings: clock: rk3568: Add SCMI clock ids
      Merge branch 'v6.19-shared/clkids' into v6.19-armsoc/dts64
      arm64: dts: rockchip: use SCMI clock id for cpu clock on rk356x
      arm64: dts: rockchip: add missing clocks for cpu cores on rk356x
      arm64: dts: rockchip: use SCMI clock id for gpu clock on rk356x

Hsun Lai (2):
      dt-bindings: arm: rockchip: Add 100ASK DShanPi A1
      arm64: dts: rockchip: add DTs for 100ASK DShanPi A1

Johan Jonker (1):
      arm64: dts: rockchip: correct assigned-clock-rates spelling on 2 boards

Liangbin Lian (3):
      dt-bindings: vendor-prefixes: Document LinkEase
      dt-bindings: arm: rockchip: Add LinkEase EasePi R1
      arm64: dts: rockchip: add LinkEase EasePi R1

Mehdi Djait (1):
      arm64: dts: rockchip: add the vip node to px30

Michael Riesch (1):
      arm64: dts: rockchip: add vicap node to rk356x

Sebastian Reichel (1):
      arm64: dts: rockchip: add eMMC CQE support for rk3588

Shawn Lin (1):
      arm64: dts: rockchip: Remove sdmmc max-frequency on RK3588S EVB1 board

Tianling Shen (2):
      dt-bindings: arm: rockchip: Add FriendlyElec NanoPi R76S
      arm64: dts: rockchip: Add devicetree for the FriendlyElec NanoPi R76S

Torsten Duwe (1):
      arm64: dts: rockchip: enable HDMI audio on Rock 5 ITX

WeiHao Li (3):
      arm64: dts: rockchip: Add display subsystem for RK3368
      arm64: dts: rockchip: Add D-PHY for RK3368
      arm64: dts: rockchip: Add DSI for RK3368

Yao Zi (2):
      arm64: dts: rockchip: Add PCIe Gen2x1 controller for RK3528
      arm64: dts: rockchip: Enable PCIe controller on Radxa E20C

 .../devicetree/bindings/arm/rockchip.yaml          |  21 +
 .../devicetree/bindings/vendor-prefixes.yaml       |   4 +
 arch/arm64/boot/dts/rockchip/Makefile              |   4 +
 arch/arm64/boot/dts/rockchip/px30.dtsi             |  12 +
 arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts    |   2 +-
 arch/arm64/boot/dts/rockchip/rk3328-evb.dts        |   2 +-
 arch/arm64/boot/dts/rockchip/rk3368.dtsi           |  73 ++
 arch/arm64/boot/dts/rockchip/rk3528-radxa-e20c.dts |  12 +
 arch/arm64/boot/dts/rockchip/rk3528.dtsi           |  56 +-
 arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts    |   1 +
 .../boot/dts/rockchip/rk3568-9tripod-x3568-v4.dts  | 880 +++++++++++++++++++++
 arch/arm64/boot/dts/rockchip/rk3568-easepi-r1.dts  | 623 +++++++++++++++
 arch/arm64/boot/dts/rockchip/rk356x-base.dtsi      |  51 +-
 .../boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts | 749 ++++++++++++++++++
 .../arm64/boot/dts/rockchip/rk3576-nanopi-r76s.dts | 860 ++++++++++++++++++++
 arch/arm64/boot/dts/rockchip/rk3588-base.dtsi      |   1 +
 arch/arm64/boot/dts/rockchip/rk3588-evb2-v10.dts   |  48 ++
 arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts |  19 +-
 .../boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi   |  13 +-
 .../boot/dts/rockchip/rk3588-rock-5b-plus.dts      |   5 +
 arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts    |   4 +
 arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts    |   4 +
 arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts  |   1 -
 .../boot/dts/rockchip/rk3588s-gameforce-ace.dts    |  34 +
 .../boot/dts/rockchip/rk3588s-indiedroid-nova.dts  | 122 ++-
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts   |  23 +-
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts   |   9 +
 include/dt-bindings/clock/rk3568-cru.h             |   6 +
 28 files changed, 3603 insertions(+), 36 deletions(-)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-9tripod-x3568-v4.dts
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-easepi-r1.dts
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3576-nanopi-r76s.dts





From cristian.ciocaltea at collabora.com  Mon Nov 17 15:42:23 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 18 Nov 2025 01:42:23 +0200
Subject: [PATCH i-g-t v2] tests: (Re)add kms_crtc_background_color test
Message-ID: <20251118-crtc-bgcolor-v2-1-dce4063f85a9@collabora.com>

Provide test to verify the behavior of BACKGROUND_COLOR DRM CRTC
property.

This is achieved by filling a full-screen primary plane with a given
color and comparing the resulting CRC with the one obtained after
turning off all planes while having the CRTC background set to the same
color.

Also note this is a reworked version of the test that has been dropped
over 5 years ago via commit 33f07391e5f6 ("tests: Remove
kms_crtc_background_color test"), as the required kernel changes never
landed because of missing support in userland.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
This has been tested on both VKMS and the Rockchip RK3588 SoC based
Radxa ROCK 5B board.  It relies on the kernel series [1] introducing the
BACKGROUND_COLOR CRTC property and a few additional patches from [2]
enabling the required CRC functionality for the Rockchip platform.

The patch adding support for setting custom background color in VKMS is
currently available at [3], but will be submitted soon as part of [1].

It's worth noting CRC is only supported by the display controller (VOP2)
present in the RK3576 SoC variant.  However, the computation is done by
the hardware before applying the background color, hence it has limited
usage in IGT testing.

Luckily, the frame CRCs can be captured through DPCD, i.e. at
DisplayPort AUX channel level, hence I used the USB-C DP AltMode capable
port of the aforementioned board to perform the actual validation.

[1] https://lore.kernel.org/all/20251013-rk3588-bgcolor-v2-0-25cc3810ba8c at collabora.com/
[2] https://gitlab.collabora.com/hardware-enablement/rockchip-3588/linux/-/commits/cristicc/rk3588-vop2-crc
[3] https://gitlab.collabora.com/hardware-enablement/rockchip-3588/linux/-/commits/cristicc/vkms-bgcolor

* Test results on VKMS

virtme-ng$ IGT_FORCE_DRIVER=vkms build/tests/kms_crtc_background_color

IGT-Version: 2.2-gf50583245 (x86_64) (Linux: 6.18.0-rc5-next-20251111+ x86_64)
Using IGT_SRANDOM=1763159189 for randomisation
Opened device: /dev/dri/card0
Starting subtest: background-color-red
Starting dynamic subtest: pipe-A-Virtual-1
Dynamic subtest pipe-A-Virtual-1: SUCCESS (0.071s)
Subtest background-color-red: SUCCESS (0.072s)
Starting subtest: background-color-green
Starting dynamic subtest: pipe-A-Virtual-1
Dynamic subtest pipe-A-Virtual-1: SUCCESS (0.072s)
Subtest background-color-green: SUCCESS (0.072s)
Starting subtest: background-color-blue
Starting dynamic subtest: pipe-A-Virtual-1
Dynamic subtest pipe-A-Virtual-1: SUCCESS (0.072s)
Subtest background-color-blue: SUCCESS (0.072s)
Starting subtest: background-color-yellow
Starting dynamic subtest: pipe-A-Virtual-1
Dynamic subtest pipe-A-Virtual-1: SUCCESS (0.073s)
Subtest background-color-yellow: SUCCESS (0.073s)
Starting subtest: background-color-purple
Starting dynamic subtest: pipe-A-Virtual-1
Dynamic subtest pipe-A-Virtual-1: SUCCESS (0.073s)
Subtest background-color-purple: SUCCESS (0.073s)
Starting subtest: background-color-cyan
Starting dynamic subtest: pipe-A-Virtual-1
Dynamic subtest pipe-A-Virtual-1: SUCCESS (0.073s)
Subtest background-color-cyan: SUCCESS (0.073s)
Starting subtest: background-color-black
Starting dynamic subtest: pipe-A-Virtual-1
Dynamic subtest pipe-A-Virtual-1: SUCCESS (0.073s)
Subtest background-color-black: SUCCESS (0.073s)
Starting subtest: background-color-white
Starting dynamic subtest: pipe-A-Virtual-1
Dynamic subtest pipe-A-Virtual-1: SUCCESS (0.072s)
Subtest background-color-white: SUCCESS (0.072s)

* Test results on ROCK5B

rock5b$ cat /sys/kernel/debug/dri/1/vop2/summary

Video Port0: DISABLED
Video Port1: DISABLED
Video Port2: ACTIVE
    Connector: DP-1
	bus_format[1018]: RGB101010_1X30
	output_mode[f] color_space[0]
	background color (10bpc): r=0x0 g=0x0 b=0x0
    Display mode: 3840x2160p60
	clk[594000] real_clk[594000] type[48] flag[9]
	H: 3840 4016 4104 4400
	V: 2160 2164 2174 2250
    Cluster2-win0: ACTIVE
	win_id: 2
	format: XR24 little-endian (0x34325258) glb_alpha[0xff]
	rotate: xmirror: 0 ymirror: 0 rotate_90: 0 rotate_270: 0
	zpos: 0
	src: pos[0, 0] rect[3840 x 2160]
	dst: pos[0, 0] rect[3840 x 2160]
	buf[0]: addr: 0x0000000000000000 pitch: 15360 offset: 0

rock5b$ build/tests/kms_crtc_background_color --device drm:/dev/dri/card1

IGT-Version: 2.2-g3e4ec308e (aarch64) (Linux: 6.18.0-rc1 aarch64)
Using IGT_SRANDOM=1762774806 for randomisation
Opened device: /dev/dri/card1
Starting subtest: background-color-red
Starting dynamic subtest: pipe-C-DP-1
Dynamic subtest pipe-C-DP-1: SUCCESS (0.491s)
Subtest background-color-red: SUCCESS (0.493s)
Starting subtest: background-color-green
Starting dynamic subtest: pipe-C-DP-1
Dynamic subtest pipe-C-DP-1: SUCCESS (0.533s)
Subtest background-color-green: SUCCESS (0.535s)
Starting subtest: background-color-blue
Starting dynamic subtest: pipe-C-DP-1
Dynamic subtest pipe-C-DP-1: SUCCESS (0.541s)
Subtest background-color-blue: SUCCESS (0.544s)
Starting subtest: background-color-yellow
Starting dynamic subtest: pipe-C-DP-1
Dynamic subtest pipe-C-DP-1: SUCCESS (0.535s)
Subtest background-color-yellow: SUCCESS (0.537s)
Starting subtest: background-color-purple
Starting dynamic subtest: pipe-C-DP-1
Dynamic subtest pipe-C-DP-1: SUCCESS (0.536s)
Subtest background-color-purple: SUCCESS (0.538s)
Starting subtest: background-color-cyan
Starting dynamic subtest: pipe-C-DP-1
Dynamic subtest pipe-C-DP-1: SUCCESS (0.539s)
Subtest background-color-cyan: SUCCESS (0.541s)
Starting subtest: background-color-black
Starting dynamic subtest: pipe-C-DP-1
(kms_crtc_background_color:744) igt_pipe_crc-WARNING: Warning on condition all_zero in function crc_sanity_checks, file ../lib/igt_pipe_crc.c:475
(kms_crtc_background_color:744) igt_pipe_crc-WARNING: Suspicious CRC: All values are 0.
(kms_crtc_background_color:744) igt_pipe_crc-WARNING: Warning on condition all_zero in function crc_sanity_checks, file ../lib/igt_pipe_crc.c:475
(kms_crtc_background_color:744) igt_pipe_crc-WARNING: Suspicious CRC: All values are 0.
Dynamic subtest pipe-C-DP-1: SUCCESS (0.535s)
Subtest background-color-black: SUCCESS (0.537s)
Starting subtest: background-color-white
Starting dynamic subtest: pipe-C-DP-1
Dynamic subtest pipe-C-DP-1: SUCCESS (0.540s)
Subtest background-color-white: SUCCESS (0.542s)
---
Changes in v2:
- Added VKMS test report
- Set the value of the CRTC background color property with 16bpc instead
  of 8bpc, to avoid CRC check failures because of framebuffer format
  precision mismatch - display controller drivers shall convert it back
  from 16bpc to their internal representation of the pixel color if
  necessary, e.g. VKMS already uses 16bpc, hence no conversion is
  required in that case
- Replaced deprecated DRM_FORMAT_MOD_NONE with DRM_FORMAT_MOD_LINEAR
- Updated copyright section
- Link to v1: https://lore.kernel.org/r/20251110-crtc-bgcolor-v1-1-28669b692970 at collabora.com
---
 lib/igt_kms.c                     |   1 +
 lib/igt_kms.h                     |   3 +-
 tests/kms_crtc_background_color.c | 140 ++++++++++++++++++++++++++++++++++++++
 tests/meson.build                 |   1 +
 4 files changed, 144 insertions(+), 1 deletion(-)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 8973ffdb22a6..a6f547c04ce3 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -705,6 +705,7 @@ const char * const igt_plane_prop_names[IGT_NUM_PLANE_PROPS] = {
 };
 
 const char * const igt_crtc_prop_names[IGT_NUM_CRTC_PROPS] = {
+	[IGT_CRTC_BACKGROUND] = "BACKGROUND_COLOR",
 	[IGT_CRTC_CTM] = "CTM",
 	[IGT_CRTC_GAMMA_LUT] = "GAMMA_LUT",
 	[IGT_CRTC_GAMMA_LUT_SIZE] = "GAMMA_LUT_SIZE",
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index f7ff0b17eb02..8e757a204197 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -156,7 +156,8 @@ void kmstest_restore_vt_mode(void);
 void kmstest_set_vt_text_mode(void);
 
 enum igt_atomic_crtc_properties {
-       IGT_CRTC_CTM = 0,
+       IGT_CRTC_BACKGROUND = 0,
+       IGT_CRTC_CTM,
        IGT_CRTC_GAMMA_LUT,
        IGT_CRTC_GAMMA_LUT_SIZE,
        IGT_CRTC_DEGAMMA_LUT,
diff --git a/tests/kms_crtc_background_color.c b/tests/kms_crtc_background_color.c
new file mode 100644
index 000000000000..079c85ec55a2
--- /dev/null
+++ b/tests/kms_crtc_background_color.c
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright ? 2013,2014 Intel Corporation
+ * Copyright ? 2025 Amazon.com, Inc. or its affiliates.
+ * Copyright ? 2025 Collabora, Ltd.
+ */
+
+#include "igt.h"
+
+IGT_TEST_DESCRIPTION("Test crtc background color feature");
+
+typedef struct {
+	int drm_fd;
+	int debugfs;
+	igt_display_t display;
+} data_t;
+
+#define __DRM_ARGB64_PREP(c, shift)					\
+	(((__u64)(c) & 0xffffU) << (shift))
+
+#define DRM_ARGB64_PREP(alpha, red, green, blue)			\
+	(__DRM_ARGB64_PREP(alpha, 48) |					\
+	 __DRM_ARGB64_PREP(red,   32) |					\
+	 __DRM_ARGB64_PREP(green, 16) |					\
+	 __DRM_ARGB64_PREP(blue,   0))
+
+static void test_background(data_t *data, enum pipe pipe, igt_output_t *output,
+			    __u16 red, __u16 green, __u16 blue)
+{
+	igt_display_t *display = &data->display;
+	igt_crc_t plane_crc, bg_crc;
+	igt_pipe_crc_t *pipe_crc;
+	igt_plane_t *plane;
+	drmModeModeInfo *mode;
+	struct igt_fb fb;
+
+	igt_display_reset(display);
+
+	igt_output_set_pipe(output, pipe);
+	mode = igt_output_get_mode(output);
+
+	plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
+
+	/* Fill the primary plane and set the background to the same color */
+	igt_create_color_fb(data->drm_fd,
+			    mode->hdisplay, mode->vdisplay,
+			    DRM_FORMAT_XRGB8888,
+			    DRM_FORMAT_MOD_LINEAR,
+			    (double)red / 0xffff,
+			    (double)green / 0xffff,
+			    (double)blue / 0xffff,
+			    &fb);
+
+	igt_plane_set_fb(plane, &fb);
+	igt_pipe_set_prop_value(&data->display, pipe, IGT_CRTC_BACKGROUND,
+				DRM_ARGB64_PREP(0xffff, red, green, blue));
+	igt_display_commit2(&data->display, COMMIT_ATOMIC);
+
+	pipe_crc = igt_pipe_crc_new(data->drm_fd, pipe, IGT_PIPE_CRC_SOURCE_AUTO);
+	igt_pipe_crc_collect_crc(pipe_crc, &plane_crc);
+
+	/* Turn off the primary plane so that only the background is visible */
+	igt_plane_set_fb(plane, NULL);
+	igt_display_commit2(&data->display, COMMIT_ATOMIC);
+	igt_pipe_crc_collect_crc(pipe_crc, &bg_crc);
+
+	/*
+	 * The test assumes hardware is able to generate valid CRCs when setting
+	 * the background color. Some platforms, e.g. Intel, might require at
+	 * least one plane to be visible before reading the pipe-level ("dmux")
+	 * CRC. Other platforms, e.g. Rockchip, do not take background color
+	 * into account when computing CRC at CRTC level.
+	 * A possible workaround would be to use alternative CRC sources, e.g.
+	 * where computation is performed at encoder or sink level.
+	 */
+	igt_assert_crc_equal(&plane_crc, &bg_crc);
+
+	/* Clean-up */
+	igt_pipe_set_prop_value(&data->display, pipe, IGT_CRTC_BACKGROUND,
+				DRM_ARGB64_PREP(0xffff, 0, 0, 0));
+	igt_pipe_crc_free(pipe_crc);
+	igt_output_set_pipe(output, PIPE_NONE);
+	igt_display_commit(display);
+	igt_remove_fb(data->drm_fd, &fb);
+}
+
+igt_main
+{
+	igt_output_t *output;
+	data_t data = {};
+	enum pipe pipe;
+	int i;
+
+	struct {
+		const char *color;
+		__u16 red;
+		__u16 green;
+		__u16 blue;
+	} tests[] = {
+		{ "red",    0xffff, 0x0000, 0x0000, },
+		{ "green",  0x0000, 0xffff, 0x0000, },
+		{ "blue",   0x0000, 0x0000, 0xffff, },
+		{ "yellow", 0xffff, 0xffff, 0x0000, },
+		{ "purple", 0xffff, 0x0000, 0xffff, },
+		{ "cyan",   0x0000, 0xffff, 0xffff, },
+		{ "black",  0x0000, 0x0000, 0x0000, },
+		{ "white",  0xffff, 0xffff, 0xffff, },
+	};
+
+	igt_fixture {
+		data.drm_fd = drm_open_driver_master(DRIVER_ANY);
+
+		kmstest_set_vt_graphics_mode();
+
+		igt_display_require(&data.display, data.drm_fd);
+		igt_display_require_output(&data.display);
+		igt_require_pipe_crc(data.drm_fd);
+
+		data.debugfs = igt_debugfs_dir(data.drm_fd);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(tests); i++) {
+		igt_describe_f("Test crtc background color %s", tests[i].color);
+		igt_subtest_with_dynamic_f("background-color-%s", tests[i].color) {
+			for_each_pipe_with_single_output(&data.display, pipe, output) {
+				igt_require(igt_pipe_has_prop(&data.display, pipe,
+							      IGT_CRTC_BACKGROUND));
+
+				igt_dynamic_f("pipe-%s-%s", kmstest_pipe_name(pipe), output->name)
+					test_background(&data, pipe, output, tests[i].red,
+							tests[i].green, tests[i].blue);
+			}
+		}
+	}
+
+	igt_fixture {
+		igt_display_fini(&data.display);
+		drm_close_driver(data.drm_fd);
+	}
+}
diff --git a/tests/meson.build b/tests/meson.build
index ecc0f4c7f6f3..14067fd3d770 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -27,6 +27,7 @@ test_progs = [
 	'kms_color',
 	'kms_concurrent',
 	'kms_content_protection',
+	'kms_crtc_background_color',
 	'kms_cursor_crc',
 	'kms_cursor_edge_walk',
 	'kms_cursor_legacy',

---
base-commit: 3813b62c3c6200f69d6cc8be1c5e621243ace24f
change-id: 20251110-crtc-bgcolor-f6ed9a58e0bf



From cristian.ciocaltea at collabora.com  Mon Nov 17 15:51:58 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 18 Nov 2025 01:51:58 +0200
Subject: [PATCH v3 0/4] Introduce BACKGROUND_COLOR DRM CRTC property
Message-ID: <20251118-rk3588-bgcolor-v3-0-a2cc909428ea@collabora.com>

Some display controllers can be hardware-configured to present non-black
colors for pixels which are not covered by any plane (or are exposed
through transparent regions of higher planes).

The 1st patch of the series provides DIV_ROUND_CLOSEST() to uapi, as a
prerequisite to the 2nd patch introducing the BACKGROUND_COLOR DRM
property that can be attached to a CRTC via a dedicated helper function.
A 64-bit ARGB color value format is also defined and can be manipulated
with the help of a few utility macros.

Note this is a reworked version of the patch [1] submitted (many) years
ago by Matt Roper.  The main changes are:

* Renamed DRM_ARGB_<COMP>() to DRM_ARGB64_GET<C>_BPC() while providing
  convenience wrappers to extract all 16 bits of a specific color via
  DRM_ARGB64_GET<C>()
* Replaced drm_argb() function with DRM_ARGB64_PREP_BPC() macro, to
  improve uAPI consistency and readability; additionally fixed a bug in
  case of using bpc < 16: the unused least-significant bits of a given
  component in the output value would contain the unused
  most-significant bits of the following component in the input value,
  instead of being set to 0
* Replaced GENMASK_ULL(63, 0) with U64_MAX when calling
  drm_property_create_range() to create the BACKGROUND_COLOR property
* Moved crtc_state->bgcolor initialization from
  __drm_atomic_helper_crtc_reset() to
  __drm_atomic_helper_crtc_state_reset()
* Replaced '*bgcolor*' occurrences to '*background_color*' for
  consistency with the actual property name in both storage field and
  helper functions names

The subsequent patches add background color support to VKMS and the VOP2
display controller used in the RK3568, RK3576, and RK3588 Rockchip SoC
families.

The validation has been done using a dedicated IGT test [2] - see the
reported results below.

On the userland side, a Weston merge request [3] is available, providing
support for the BACKGROUND_COLOR CRTC property to the DRM backend.  It
relies on the already existing background-color setting in weston.ini:

  [shell]
  background-color=0xAARRGGBB

[1] https://lore.kernel.org/all/20190930224707.14904-2-matthew.d.roper at intel.com/
[2] https://lore.kernel.org/all/20251118-crtc-bgcolor-v2-1-dce4063f85a9 at collabora.com/
[3] https://gitlab.freedesktop.org/wayland/weston/-/merge_requests/1845

IGT kms_crtc_background_color test results
==========================================

* VKMS

virtme-ng$ IGT_FORCE_DRIVER=vkms build/tests/kms_crtc_background_color

IGT-Version: 2.2-gf50583245 (x86_64) (Linux: 6.18.0-rc5-next-20251111+ x86_64)
Using IGT_SRANDOM=1763159189 for randomisation
Opened device: /dev/dri/card0
Starting subtest: background-color-red
Starting dynamic subtest: pipe-A-Virtual-1
Dynamic subtest pipe-A-Virtual-1: SUCCESS (0.071s)
Subtest background-color-red: SUCCESS (0.072s)
Starting subtest: background-color-green
Starting dynamic subtest: pipe-A-Virtual-1
Dynamic subtest pipe-A-Virtual-1: SUCCESS (0.072s)
Subtest background-color-green: SUCCESS (0.072s)
Starting subtest: background-color-blue
Starting dynamic subtest: pipe-A-Virtual-1
Dynamic subtest pipe-A-Virtual-1: SUCCESS (0.072s)
Subtest background-color-blue: SUCCESS (0.072s)
Starting subtest: background-color-yellow
Starting dynamic subtest: pipe-A-Virtual-1
Dynamic subtest pipe-A-Virtual-1: SUCCESS (0.073s)
Subtest background-color-yellow: SUCCESS (0.073s)
Starting subtest: background-color-purple
Starting dynamic subtest: pipe-A-Virtual-1
Dynamic subtest pipe-A-Virtual-1: SUCCESS (0.073s)
Subtest background-color-purple: SUCCESS (0.073s)
Starting subtest: background-color-cyan
Starting dynamic subtest: pipe-A-Virtual-1
Dynamic subtest pipe-A-Virtual-1: SUCCESS (0.073s)
Subtest background-color-cyan: SUCCESS (0.073s)
Starting subtest: background-color-black
Starting dynamic subtest: pipe-A-Virtual-1
Dynamic subtest pipe-A-Virtual-1: SUCCESS (0.073s)
Subtest background-color-black: SUCCESS (0.073s)
Starting subtest: background-color-white
Starting dynamic subtest: pipe-A-Virtual-1
Dynamic subtest pipe-A-Virtual-1: SUCCESS (0.072s)
Subtest background-color-white: SUCCESS (0.072s)

* Radxa ROCK 5B (RK3588)

rock5b$ build/tests/kms_crtc_background_color --device drm:/dev/dri/card1

IGT-Version: 2.2-g3e4ec308e (aarch64) (Linux: 6.18.0-rc1 aarch64)
Using IGT_SRANDOM=1762774806 for randomisation
Opened device: /dev/dri/card1
Starting subtest: background-color-red
Starting dynamic subtest: pipe-C-DP-1
Dynamic subtest pipe-C-DP-1: SUCCESS (0.491s)
Subtest background-color-red: SUCCESS (0.493s)
Starting subtest: background-color-green
Starting dynamic subtest: pipe-C-DP-1
Dynamic subtest pipe-C-DP-1: SUCCESS (0.533s)
Subtest background-color-green: SUCCESS (0.535s)
Starting subtest: background-color-blue
Starting dynamic subtest: pipe-C-DP-1
Dynamic subtest pipe-C-DP-1: SUCCESS (0.541s)
Subtest background-color-blue: SUCCESS (0.544s)
Starting subtest: background-color-yellow
Starting dynamic subtest: pipe-C-DP-1
Dynamic subtest pipe-C-DP-1: SUCCESS (0.535s)
Subtest background-color-yellow: SUCCESS (0.537s)
Starting subtest: background-color-purple
Starting dynamic subtest: pipe-C-DP-1
Dynamic subtest pipe-C-DP-1: SUCCESS (0.536s)
Subtest background-color-purple: SUCCESS (0.538s)
Starting subtest: background-color-cyan
Starting dynamic subtest: pipe-C-DP-1
Dynamic subtest pipe-C-DP-1: SUCCESS (0.539s)
Subtest background-color-cyan: SUCCESS (0.541s)
Starting subtest: background-color-black
Starting dynamic subtest: pipe-C-DP-1
(kms_crtc_background_color:744) igt_pipe_crc-WARNING: Warning on condition all_zero in function crc_sanity_checks, file ../lib/igt_pipe_crc.c:475
(kms_crtc_background_color:744) igt_pipe_crc-WARNING: Suspicious CRC: All values are 0.
(kms_crtc_background_color:744) igt_pipe_crc-WARNING: Warning on condition all_zero in function crc_sanity_checks, file ../lib/igt_pipe_crc.c:475
(kms_crtc_background_color:744) igt_pipe_crc-WARNING: Suspicious CRC: All values are 0.
Dynamic subtest pipe-C-DP-1: SUCCESS (0.535s)
Subtest background-color-black: SUCCESS (0.537s)
Starting subtest: background-color-white
Starting dynamic subtest: pipe-C-DP-1
Dynamic subtest pipe-C-DP-1: SUCCESS (0.540s)
Subtest background-color-white: SUCCESS (0.542s)

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
Changes in v3:
- Added new patches:
  * uapi: Provide DIV_ROUND_CLOSEST()
  * drm/vkms: Support setting custom background color
- Improved DRM_ARGB64_{PREP|GET}*() helpers by using a conversion ratio
  for better color approximation when dealing with less than 16 bits of
  precision
- Mentioned the IGT test in the cover letter while documenting the
  validation results; also dropped references to the now useless
  modetest wrapper script and its generated report
- Rebased series onto latest drm-misc-next
- Link to v2: https://lore.kernel.org/r/20251013-rk3588-bgcolor-v2-0-25cc3810ba8c at collabora.com

Changes in v2:
- Improved uAPI consistency and readability by introducing
  DRM_ARGB64_PREP*() and DRM_ARGB64_GET*() helper macros
- Updated several code comment sections
- Referenced the counterpart Weston support in the cover letter
- Rebased series onto v6.18-rc1
- Link to v1: https://lore.kernel.org/r/20250902-rk3588-bgcolor-v1-0-fd97df91d89f at collabora.com

---
Cristian Ciocaltea (4):
      uapi: Provide DIV_ROUND_CLOSEST()
      drm: Add CRTC background color property
      drm/vkms: Support setting custom background color
      drm/rockchip: vop2: Support setting custom background color

 drivers/gpu/drm/drm_atomic_state_helper.c    |  1 +
 drivers/gpu/drm/drm_atomic_uapi.c            |  4 ++
 drivers/gpu/drm/drm_blend.c                  | 39 ++++++++++++++--
 drivers/gpu/drm/drm_mode_config.c            |  6 +++
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 13 +++++-
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  4 ++
 drivers/gpu/drm/vkms/vkms_composer.c         | 10 ++++-
 drivers/gpu/drm/vkms/vkms_crtc.c             |  3 ++
 include/drm/drm_blend.h                      |  4 +-
 include/drm/drm_crtc.h                       | 12 +++++
 include/drm/drm_mode_config.h                |  5 +++
 include/linux/math.h                         | 18 +-------
 include/uapi/drm/drm_mode.h                  | 67 ++++++++++++++++++++++++++++
 include/uapi/linux/const.h                   | 17 +++++++
 14 files changed, 178 insertions(+), 25 deletions(-)
---
base-commit: 92c49b3f4df8f9acfa95551ef38fc00c675319fd
change-id: 20250829-rk3588-bgcolor-c1a7b9a507bc



From cristian.ciocaltea at collabora.com  Mon Nov 17 15:51:59 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 18 Nov 2025 01:51:59 +0200
Subject: [PATCH v3 1/4] uapi: Provide DIV_ROUND_CLOSEST()
In-Reply-To: <20251118-rk3588-bgcolor-v3-0-a2cc909428ea@collabora.com>
References: <20251118-rk3588-bgcolor-v3-0-a2cc909428ea@collabora.com>
Message-ID: <20251118-rk3588-bgcolor-v3-1-a2cc909428ea@collabora.com>

Currently DIV_ROUND_CLOSEST() is only available for the kernel via
include/linux/math.h.

Expose it to userland as well by adding __KERNEL_DIV_ROUND_CLOSEST() as
a common definition in uapi.

Additionally, ensure it allows building ISO C applications by switching
from the 'typeof' GNU extension to the ISO-friendly __typeof__.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 include/linux/math.h       | 18 +-----------------
 include/uapi/linux/const.h | 17 +++++++++++++++++
 2 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/include/linux/math.h b/include/linux/math.h
index 0198c92cbe3e..24bb868f971c 100644
--- a/include/linux/math.h
+++ b/include/linux/math.h
@@ -89,23 +89,7 @@
 }							\
 )
 
-/*
- * Divide positive or negative dividend by positive or negative divisor
- * and round to closest integer. Result is undefined for negative
- * divisors if the dividend variable type is unsigned and for negative
- * dividends if the divisor variable type is unsigned.
- */
-#define DIV_ROUND_CLOSEST(x, divisor)(			\
-{							\
-	typeof(x) __x = x;				\
-	typeof(divisor) __d = divisor;			\
-	(((typeof(x))-1) > 0 ||				\
-	 ((typeof(divisor))-1) > 0 ||			\
-	 (((__x) > 0) == ((__d) > 0))) ?		\
-		(((__x) + ((__d) / 2)) / (__d)) :	\
-		(((__x) - ((__d) / 2)) / (__d));	\
-}							\
-)
+#define DIV_ROUND_CLOSEST __KERNEL_DIV_ROUND_CLOSEST
 /*
  * Same as above but for u64 dividends. divisor must be a 32-bit
  * number.
diff --git a/include/uapi/linux/const.h b/include/uapi/linux/const.h
index b8f629ef135f..471877322f47 100644
--- a/include/uapi/linux/const.h
+++ b/include/uapi/linux/const.h
@@ -50,4 +50,21 @@
 
 #define __KERNEL_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
 
+/*
+ * Divide positive or negative dividend by positive or negative divisor
+ * and round to closest integer. Result is undefined for negative
+ * divisors if the dividend variable type is unsigned and for negative
+ * dividends if the divisor variable type is unsigned.
+ */
+#define __KERNEL_DIV_ROUND_CLOSEST(x, divisor)(		\
+{							\
+	__typeof__(x) __x = x;				\
+	__typeof__(divisor) __d = divisor;		\
+	(((__typeof__(x))-1) > 0 ||			\
+	 ((__typeof__(divisor))-1) > 0 ||		\
+	 (((__x) > 0) == ((__d) > 0))) ?		\
+		(((__x) + ((__d) / 2)) / (__d)) :	\
+		(((__x) - ((__d) / 2)) / (__d));	\
+}							\
+)
 #endif /* _UAPI_LINUX_CONST_H */

-- 
2.51.2



From cristian.ciocaltea at collabora.com  Mon Nov 17 15:52:00 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 18 Nov 2025 01:52:00 +0200
Subject: [PATCH v3 2/4] drm: Add CRTC background color property
In-Reply-To: <20251118-rk3588-bgcolor-v3-0-a2cc909428ea@collabora.com>
References: <20251118-rk3588-bgcolor-v3-0-a2cc909428ea@collabora.com>
Message-ID: <20251118-rk3588-bgcolor-v3-2-a2cc909428ea@collabora.com>

Some display controllers can be hardware programmed to show non-black
colors for pixels that are either not covered by any plane or are
exposed through transparent regions of higher planes.  This feature can
help reduce memory bandwidth usage, e.g. in compositors managing a UI
with a solid background color while using smaller planes to render the
remaining content.

To support this capability, introduce the BACKGROUND_COLOR standard DRM
mode property, which can be attached to a CRTC through the
drm_crtc_attach_background_color_property() helper function.

Additionally, define a 64-bit ARGB format value to be built with the
help of a couple of dedicated DRM_ARGB64_PREP*() helpers.  Individual
color components can be extracted with desired precision using the
corresponding DRM_ARGB64_GET*() macros.

Co-developed-by: Matt Roper <matthew.d.roper at intel.com>
Signed-off-by: Matt Roper <matthew.d.roper at intel.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/gpu/drm/drm_atomic_state_helper.c |  1 +
 drivers/gpu/drm/drm_atomic_uapi.c         |  4 ++
 drivers/gpu/drm/drm_blend.c               | 39 ++++++++++++++++--
 drivers/gpu/drm/drm_mode_config.c         |  6 +++
 include/drm/drm_blend.h                   |  4 +-
 include/drm/drm_crtc.h                    | 12 ++++++
 include/drm/drm_mode_config.h             |  5 +++
 include/uapi/drm/drm_mode.h               | 67 +++++++++++++++++++++++++++++++
 8 files changed, 133 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index 7142e163e618..fc93ef6eebc4 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -75,6 +75,7 @@ __drm_atomic_helper_crtc_state_reset(struct drm_crtc_state *crtc_state,
 				     struct drm_crtc *crtc)
 {
 	crtc_state->crtc = crtc;
+	crtc_state->background_color = DRM_ARGB64_PREP(0xffff, 0, 0, 0);
 }
 EXPORT_SYMBOL(__drm_atomic_helper_crtc_state_reset);
 
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index b2cb5ae5a139..211541d753ce 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -407,6 +407,8 @@ static int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
 					&replaced);
 		state->color_mgmt_changed |= replaced;
 		return ret;
+	} else if (property == config->background_color_property) {
+		state->background_color = val;
 	} else if (property == config->prop_out_fence_ptr) {
 		s32 __user *fence_ptr = u64_to_user_ptr(val);
 
@@ -454,6 +456,8 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc,
 		*val = (state->ctm) ? state->ctm->base.id : 0;
 	else if (property == config->gamma_lut_property)
 		*val = (state->gamma_lut) ? state->gamma_lut->base.id : 0;
+	else if (property == config->background_color_property)
+		*val = state->background_color;
 	else if (property == config->prop_out_fence_ptr)
 		*val = 0;
 	else if (property == crtc->scaling_filter_property)
diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
index 6852d73c931c..f249af2a11af 100644
--- a/drivers/gpu/drm/drm_blend.c
+++ b/drivers/gpu/drm/drm_blend.c
@@ -191,10 +191,6 @@
  *		 plane does not expose the "alpha" property, then this is
  *		 assumed to be 1.0
  *
- * Note that all the property extensions described here apply either to the
- * plane or the CRTC (e.g. for the background color, which currently is not
- * exposed and assumed to be black).
- *
  * SCALING_FILTER:
  *     Indicates scaling filter to be used for plane scaler
  *
@@ -207,6 +203,25 @@
  *
  * Drivers can set up this property for a plane by calling
  * drm_plane_create_scaling_filter_property
+ *
+ * The property extensions described above all apply to the plane.  Drivers
+ * may also expose the following crtc property extension:
+ *
+ * BACKGROUND_COLOR:
+ *	Background color is set up with drm_crtc_attach_background_color_property(),
+ *	and expects a 64-bit ARGB value following DRM_FORMAT_ARGB16161616, as
+ *	generated by the DRM_ARGB64_PREP*() helpers. It controls the color of a
+ *	full-screen layer that exists below all planes. This color will be used
+ *	for pixels not covered by any plane and may also be blended with plane
+ *	contents as allowed by a plane's alpha values.
+ *	The background color defaults to black, and is assumed to be black for
+ *	drivers that do not expose this property. Although background color
+ *	isn't a plane, it is assumed that the color provided here undergoes the
+ *	CRTC degamma/CSC/gamma transformations applied after the planes blending.
+ *	Note that the color value includes an alpha channel, hence non-opaque
+ *	background color values are allowed, but since physically transparent
+ *	monitors do not (yet) exists, the final alpha value may not reach the
+ *	video sink or it may simply ignore it.
  */
 
 /**
@@ -621,3 +636,19 @@ int drm_plane_create_blend_mode_property(struct drm_plane *plane,
 	return 0;
 }
 EXPORT_SYMBOL(drm_plane_create_blend_mode_property);
+
+/**
+ * drm_crtc_attach_background_color_property - attach background color property
+ * @crtc: drm crtc
+ *
+ * Attaches the background color property to @crtc.  The property defaults to
+ * solid black and will accept 64-bit ARGB values in the format generated by
+ * DRM_ARGB64_PREP*() helpers.
+ */
+void drm_crtc_attach_background_color_property(struct drm_crtc *crtc)
+{
+	drm_object_attach_property(&crtc->base,
+				   crtc->dev->mode_config.background_color_property,
+				   DRM_ARGB64_PREP(0xffff, 0, 0, 0));
+}
+EXPORT_SYMBOL(drm_crtc_attach_background_color_property);
diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
index 25f376869b3a..6d70bfab45ca 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -375,6 +375,12 @@ static int drm_mode_create_standard_properties(struct drm_device *dev)
 		return -ENOMEM;
 	dev->mode_config.gamma_lut_size_property = prop;
 
+	prop = drm_property_create_range(dev, 0,
+					 "BACKGROUND_COLOR", 0, U64_MAX);
+	if (!prop)
+		return -ENOMEM;
+	dev->mode_config.background_color_property = prop;
+
 	prop = drm_property_create(dev,
 				   DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB,
 				   "IN_FORMATS", 0);
diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h
index 88bdfec3bd88..c7e888767c81 100644
--- a/include/drm/drm_blend.h
+++ b/include/drm/drm_blend.h
@@ -31,8 +31,9 @@
 #define DRM_MODE_BLEND_COVERAGE		1
 #define DRM_MODE_BLEND_PIXEL_NONE	2
 
-struct drm_device;
 struct drm_atomic_state;
+struct drm_crtc;
+struct drm_device;
 struct drm_plane;
 
 static inline bool drm_rotation_90_or_270(unsigned int rotation)
@@ -58,4 +59,5 @@ int drm_atomic_normalize_zpos(struct drm_device *dev,
 			      struct drm_atomic_state *state);
 int drm_plane_create_blend_mode_property(struct drm_plane *plane,
 					 unsigned int supported_modes);
+void drm_crtc_attach_background_color_property(struct drm_crtc *crtc);
 #endif
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 66278ffeebd6..d99a74258d3d 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -274,6 +274,18 @@ struct drm_crtc_state {
 	 */
 	struct drm_property_blob *gamma_lut;
 
+	/**
+	 * @background_color:
+	 *
+	 * RGB value representing the pipe's background color.  The background
+	 * color (aka "canvas color") of a pipe is the color that will be used
+	 * for pixels not covered by a plane, or covered by transparent pixels
+	 * of a plane.  The value here should be built using DRM_ARGB64_PREP*()
+	 * helpers, while the individual color components can be extracted with
+	 * desired precision via the DRM_ARGB64_GET*() macros.
+	 */
+	u64 background_color;
+
 	/**
 	 * @target_vblank:
 	 *
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 2e848b816218..ea422afec5c4 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -814,6 +814,11 @@ struct drm_mode_config {
 	 * gamma LUT as supported by the driver (read-only).
 	 */
 	struct drm_property *gamma_lut_size_property;
+	/**
+	 * @background_color_property: Optional CRTC property to set the
+	 * background color.
+	 */
+	struct drm_property *background_color_property;
 
 	/**
 	 * @suggested_x_property: Optional connector property with a hint for
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 1e0e02a79b5c..63b9489fd582 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -27,6 +27,8 @@
 #ifndef _DRM_MODE_H
 #define _DRM_MODE_H
 
+#include <linux/const.h>
+
 #include "drm.h"
 
 #if defined(__cplusplus)
@@ -1411,6 +1413,71 @@ struct drm_mode_closefb {
 	__u32 pad;
 };
 
+/*
+ * Put 16-bit ARGB values into a standard 64-bit representation that can be
+ * used for ioctl parameters, inter-driver communication, etc.
+ *
+ * If the component values being provided contain less than 16 bits of
+ * precision, use a conversion ratio to get a better color approximation.
+ * The ratio is computed as (2^16 - 1) / (2^bpc - 1), where bpc and 16 are
+ * the input and output precision, respectively.
+ */
+#define __DRM_ARGB64_PREP(c, shift)					\
+	(((__u64)(c) & 0xffffU) << (shift))
+
+#define __DRM_ARGB64_PREP_BPC(c, shift, bpc)(				\
+{									\
+	__u16 mask = (1U << (bpc)) - 1;					\
+	__u16 conv = __KERNEL_DIV_ROUND_CLOSEST((mask & (c)) *		\
+						0xffffU, mask);		\
+	__DRM_ARGB64_PREP(conv, shift);					\
+}									\
+)
+
+#define DRM_ARGB64_PREP_BPC(alpha, red, green, blue, bpc)(		\
+{									\
+	__typeof__(bpc) __bpc = bpc;					\
+	__DRM_ARGB64_PREP_BPC(alpha, 48, __bpc) |			\
+	__DRM_ARGB64_PREP_BPC(red,   32, __bpc) |			\
+	__DRM_ARGB64_PREP_BPC(green, 16, __bpc) |			\
+	__DRM_ARGB64_PREP_BPC(blue,   0, __bpc);			\
+}									\
+)
+
+#define DRM_ARGB64_PREP(alpha, red, green, blue)			\
+	(__DRM_ARGB64_PREP(alpha, 48) |					\
+	 __DRM_ARGB64_PREP(red,   32) |					\
+	 __DRM_ARGB64_PREP(green, 16) |					\
+	 __DRM_ARGB64_PREP(blue,   0))
+
+/*
+ * Extract the specified color component from a standard 64-bit ARGB value.
+ *
+ * If the requested precision is less than 16 bits, make use of a conversion
+ * ratio calculated as (2^bpc - 1) / (2^16 - 1), where bpc and 16 are the
+ * output and input precision, respectively.
+ */
+#define __DRM_ARGB64_GET(c, shift)					\
+	((__u16)(((__u64)(c) >> (shift)) & 0xffffU))
+
+#define __DRM_ARGB64_GET_BPC(c, shift, bpc)(				\
+{									\
+	__u16 comp = __DRM_ARGB64_GET(c, shift);			\
+	__KERNEL_DIV_ROUND_CLOSEST(comp * ((1U << (bpc)) - 1),		\
+				   0xffffU);				\
+}									\
+)
+
+#define DRM_ARGB64_GETA_BPC(c, bpc)	__DRM_ARGB64_GET_BPC(c, 48, bpc)
+#define DRM_ARGB64_GETR_BPC(c, bpc)	__DRM_ARGB64_GET_BPC(c, 32, bpc)
+#define DRM_ARGB64_GETG_BPC(c, bpc)	__DRM_ARGB64_GET_BPC(c, 16, bpc)
+#define DRM_ARGB64_GETB_BPC(c, bpc)	__DRM_ARGB64_GET_BPC(c, 0, bpc)
+
+#define DRM_ARGB64_GETA(c)		__DRM_ARGB64_GET(c, 48)
+#define DRM_ARGB64_GETR(c)		__DRM_ARGB64_GET(c, 32)
+#define DRM_ARGB64_GETG(c)		__DRM_ARGB64_GET(c, 16)
+#define DRM_ARGB64_GETB(c)		__DRM_ARGB64_GET(c, 0)
+
 #if defined(__cplusplus)
 }
 #endif

-- 
2.51.2



From cristian.ciocaltea at collabora.com  Mon Nov 17 15:52:01 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 18 Nov 2025 01:52:01 +0200
Subject: [PATCH v3 3/4] drm/vkms: Support setting custom background color
In-Reply-To: <20251118-rk3588-bgcolor-v3-0-a2cc909428ea@collabora.com>
References: <20251118-rk3588-bgcolor-v3-0-a2cc909428ea@collabora.com>
Message-ID: <20251118-rk3588-bgcolor-v3-3-a2cc909428ea@collabora.com>

Make use of the BACKGROUND_COLOR CRTC property when filling the
background during blending.  It already defaults to solid black.

Since the internal representation of the pixel color in VKMS relies on
16 bits of precision, use the newly introduced DRM_ARGB64_GET{R|G|B}()
helpers to access the individual components of the background color
property, which is compliant with DRM_FORMAT_ARGB16161616.

It's worth noting the alpha component is ignored, hence non-opaque
background colors are not supported.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/gpu/drm/vkms/vkms_composer.c | 10 ++++++++--
 drivers/gpu/drm/vkms/vkms_crtc.c     |  3 +++
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c
index c1ab12a44621..19e73817bf78 100644
--- a/drivers/gpu/drm/vkms/vkms_composer.c
+++ b/drivers/gpu/drm/vkms/vkms_composer.c
@@ -373,8 +373,14 @@ static void blend(struct vkms_writeback_job *wb,
 {
 	struct vkms_plane_state **plane = crtc_state->active_planes;
 	u32 n_active_planes = crtc_state->num_active_planes;
-
-	const struct pixel_argb_u16 background_color = { .a = 0xffff };
+	u64 bgcolor = crtc_state->base.background_color;
+
+	const struct pixel_argb_u16 background_color = {
+		.a = 0xffff,
+		.r = DRM_ARGB64_GETR(bgcolor),
+		.g = DRM_ARGB64_GETG(bgcolor),
+		.b = DRM_ARGB64_GETB(bgcolor),
+	};
 
 	int crtc_y_limit = crtc_state->base.mode.vdisplay;
 	int crtc_x_limit = crtc_state->base.mode.hdisplay;
diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
index 9a7db1d51022..2514c367f710 100644
--- a/drivers/gpu/drm/vkms/vkms_crtc.c
+++ b/drivers/gpu/drm/vkms/vkms_crtc.c
@@ -4,6 +4,7 @@
 
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
+#include <drm/drm_blend.h>
 #include <drm/drm_managed.h>
 #include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
@@ -228,6 +229,8 @@ struct vkms_output *vkms_crtc_init(struct drm_device *dev, struct drm_plane *pri
 
 	drm_crtc_enable_color_mgmt(crtc, 0, false, VKMS_LUT_SIZE);
 
+	drm_crtc_attach_background_color_property(crtc);
+
 	spin_lock_init(&vkms_out->lock);
 	spin_lock_init(&vkms_out->composer_lock);
 

-- 
2.51.2



From cristian.ciocaltea at collabora.com  Mon Nov 17 15:52:02 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 18 Nov 2025 01:52:02 +0200
Subject: [PATCH v3 4/4] drm/rockchip: vop2: Support setting custom
 background color
In-Reply-To: <20251118-rk3588-bgcolor-v3-0-a2cc909428ea@collabora.com>
References: <20251118-rk3588-bgcolor-v3-0-a2cc909428ea@collabora.com>
Message-ID: <20251118-rk3588-bgcolor-v3-4-a2cc909428ea@collabora.com>

The Rockchip VOP2 display controller allows configuring the background
color of each video output port.

Since a previous patch introduced the BACKGROUND_COLOR CRTC property,
which defaults to solid black, make use of it when programming the
hardware.

Note the maximum precision allowed by the display controller is 10bpc,
while the alpha component is not supported, hence ignored.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 13 ++++++++++++-
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  4 ++++
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 498df0ce4680..87110beba366 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1554,6 +1554,7 @@ static void vop2_post_config(struct drm_crtc *crtc)
 	struct vop2_video_port *vp = to_vop2_video_port(crtc);
 	struct vop2 *vop2 = vp->vop2;
 	struct drm_display_mode *mode = &crtc->state->adjusted_mode;
+	u64 bgcolor = crtc->state->background_color;
 	u16 vtotal = mode->crtc_vtotal;
 	u16 hdisplay = mode->crtc_hdisplay;
 	u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
@@ -1599,7 +1600,11 @@ static void vop2_post_config(struct drm_crtc *crtc)
 		vop2_vp_write(vp, RK3568_VP_POST_DSP_VACT_INFO_F1, val);
 	}
 
-	vop2_vp_write(vp, RK3568_VP_DSP_BG, 0);
+	/* Background color is programmed with 10 bits of precision */
+	val = FIELD_PREP(RK3568_VP_DSP_BG__DSP_BG_RED, DRM_ARGB64_GETR_BPC(bgcolor, 10));
+	val |= FIELD_PREP(RK3568_VP_DSP_BG__DSP_BG_GREEN, DRM_ARGB64_GETG_BPC(bgcolor, 10));
+	val |= FIELD_PREP(RK3568_VP_DSP_BG__DSP_BG_BLUE, DRM_ARGB64_GETB_BPC(bgcolor, 10));
+	vop2_vp_write(vp, RK3568_VP_DSP_BG, val);
 }
 
 static int us_to_vertical_line(struct drm_display_mode *mode, int us)
@@ -1984,6 +1989,10 @@ static int vop2_crtc_state_dump(struct drm_crtc *crtc, struct seq_file *s)
 		   drm_get_bus_format_name(vcstate->bus_format));
 	seq_printf(s, "\toutput_mode[%x]", vcstate->output_mode);
 	seq_printf(s, " color_space[%d]\n", vcstate->color_space);
+	seq_printf(s, "\tbackground color (10bpc): r=0x%x g=0x%x b=0x%x\n",
+		   DRM_ARGB64_GETR_BPC(cstate->background_color, 10),
+		   DRM_ARGB64_GETG_BPC(cstate->background_color, 10),
+		   DRM_ARGB64_GETB_BPC(cstate->background_color, 10));
 	seq_printf(s, "    Display mode: %dx%d%s%d\n",
 		   mode->hdisplay, mode->vdisplay, interlaced ? "i" : "p",
 		   drm_mode_vrefresh(mode));
@@ -2473,6 +2482,8 @@ static int vop2_create_crtcs(struct vop2 *vop2)
 			return dev_err_probe(drm->dev, ret,
 					     "crtc init for video_port%d failed\n", i);
 
+		drm_crtc_attach_background_color_property(&vp->crtc);
+
 		drm_crtc_helper_add(&vp->crtc, &vop2_crtc_helper_funcs);
 		if (vop2->lut_regs) {
 			const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index 9124191899ba..37722652844a 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -658,6 +658,10 @@ enum dst_factor_mode {
 #define RK3588_VP_CLK_CTRL__DCLK_OUT_DIV		GENMASK(3, 2)
 #define RK3588_VP_CLK_CTRL__DCLK_CORE_DIV		GENMASK(1, 0)
 
+#define RK3568_VP_DSP_BG__DSP_BG_RED			GENMASK(29, 20)
+#define RK3568_VP_DSP_BG__DSP_BG_GREEN			GENMASK(19, 10)
+#define RK3568_VP_DSP_BG__DSP_BG_BLUE			GENMASK(9, 0)
+
 #define RK3568_VP_POST_SCL_CTRL__VSCALEDOWN		BIT(1)
 #define RK3568_VP_POST_SCL_CTRL__HSCALEDOWN		BIT(0)
 

-- 
2.51.2



From shawn.lin at rock-chips.com  Mon Nov 17 16:43:41 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Tue, 18 Nov 2025 08:43:41 +0800
Subject: [PATCH v2 0/4] PCI: rockchip: 5.0 GT/s speed may be dangerous
In-Reply-To: <cover.1763415705.git.geraldogabriel@gmail.com>
References: <cover.1763415705.git.geraldogabriel@gmail.com>
Message-ID: <7e050003-f4ea-4e89-8140-2159c670182f@rock-chips.com>

? 2025/11/18 ??? 5:46, Geraldo Nascimento ??:
> Dragan Simic already had warned me of potential issues with 5.0 GT/s
> speed operation in Rockchip PCIe. However, in recent interactions
> with Shawn Lin from Rockchip it came to my attention there's grave
> danger in the unknown errata regarding 5.0 GT/s operational speed
> of their PCIe core. Even if the odds are low, to contain any damage,
> let's cover the remaining corner-cases where the default would lead
> to 5.0 GT/s operation as well as add a comment to Root Complex driver
> core, documenting this danger. Furthermore, remove redundant
> declaration of max-link-speed from rk3399-nanopi-r4s.dtsi
> 
> Signed-off-by: Geraldo Nascimento <geraldogabriel at gmail.com>
> 

Thanks for fixing these.

Acked-by: Shawn Lin <shawn.lin at rock-chips.com>

> ---
> 
> Changes in v2:
> - hard limit to 2.5 GT/s, not just warn
> - add Reported-by: and Reviewed-by: Dragan Simic
> - remove redundant declaration of max-link-speed from helios64 dts
> - fix Link: of helios64 patch
> - simplify RC mode comment
> - Link to v1: https://lore.kernel.org/all/aRhR79u5BPtRRFw3 at geday/
> 
> Geraldo Nascimento (4):
>    PCI: rockchip: limit RK3399 to 2.5 GT/s to prevent damage
>    PCI: rockchip-host: comment danger of 5.0 GT/s speed
>    arm64: dts: rockchip: remove dangerous max-link-speed from helios64
>    arm64: dts: rockchip: remove redundant max-link-speed from nanopi-r4s
> 
>   arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts |  1 -
>   arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dtsi    |  1 -
>   drivers/pci/controller/pcie-rockchip-host.c            |  3 +++
>   drivers/pci/controller/pcie-rockchip.c                 | 10 ++++++++--
>   4 files changed, 11 insertions(+), 4 deletions(-)
> 



From helgaas at kernel.org  Mon Nov 17 16:50:56 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Mon, 17 Nov 2025 18:50:56 -0600
Subject: [RFC v1 2/5] PCI: rockchip: Fix Device Control register offset
 for Max payload size
In-Reply-To: <20251117181023.482138-3-linux.amoon@gmail.com>
Message-ID: <20251118005056.GA2541796@bhelgaas>

On Mon, Nov 17, 2025 at 11:40:10PM +0530, Anand Moon wrote:
> As per 17.6.6.1.29 PCI Express Device Capabilities Register
> (PCIE_RC_CONFIG_DC) reside at offset 0xc8 within the Root Complex (RC)
> configuration space, not at the offset of the PCI Express Capability
> List (0xc0). Following changes corrects the register offset to use
> PCIE_RC_CONFIG_DC (0xc8) to configure Max Payload Size.
> 
> Signed-off-by: Anand Moon <linux.amoon at gmail.com>
> ---
>  drivers/pci/controller/pcie-rockchip-host.c | 4 ++--
>  drivers/pci/controller/pcie-rockchip.h      | 1 +
>  2 files changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c
> index f0de5b2590c4..d51780f4a254 100644
> --- a/drivers/pci/controller/pcie-rockchip-host.c
> +++ b/drivers/pci/controller/pcie-rockchip-host.c
> @@ -382,10 +382,10 @@ static int rockchip_pcie_host_init_port(struct rockchip_pcie *rockchip)
>  		rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_CR + PCI_EXP_LNKCAP);
>  	}
>  
> -	status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_CR + PCI_EXP_DEVCTL);
> +	status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_DC + PCI_EXP_DEVCTL);
>  	status &= ~PCI_EXP_DEVCTL_PAYLOAD;
>  	status |= PCI_EXP_DEVCTL_PAYLOAD_256B;
> -	rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_CR + PCI_EXP_DEVCTL);
> +	rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_DC + PCI_EXP_DEVCTL);
>  
>  	return 0;
>  err_power_off_phy:
> diff --git a/drivers/pci/controller/pcie-rockchip.h b/drivers/pci/controller/pcie-rockchip.h
> index 5d8a3ae38599..c0ec6c32ea16 100644
> --- a/drivers/pci/controller/pcie-rockchip.h
> +++ b/drivers/pci/controller/pcie-rockchip.h
> @@ -157,6 +157,7 @@
>  #define PCIE_EP_CONFIG_LCS		(PCIE_EP_CONFIG_BASE + 0xd0)
>  #define PCIE_RC_CONFIG_RID_CCR		(PCIE_RC_CONFIG_BASE + 0x08)
>  #define PCIE_RC_CONFIG_CR		(PCIE_RC_CONFIG_BASE + 0xc0)
> +#define PCIE_RC_CONFIG_DC		(PCIE_RC_CONFIG_BASE + 0xc8)

Per the RK3399 TRM:

  DEVCAP              0xc4
  DEVCTL and DEVSTA   0xc8
  LNKCAP              0xcc
  LNKCTL and LNKSTA   0xd0
  SLTCAP              0xd4
  SLTCTL and SLTSTA   0xd8

That all makes good sense and matches the relative offsets in the PCIe
Capability.

I have no idea how we got from that to the mind-bendingly obtuse
#defines here:

  PCIE_RC_CONFIG_CR == PCIE_RC_CONFIG_BASE + 0xc0
                    == 0xa00000 + 0xc0
                    == 0xa000c0

  PCIE_RC_CONFIG_DC == PCIE_RC_CONFIG_BASE + 0xc8
                    == 0xa00000 + 0xc8
                    == 0xa000c8

  PCIE_RC_CONFIG_LC == PCIE_RC_CONFIG_BASE + 0xd0
                    == 0xa00000 + 0xd0
                    == 0xa000d0

  PCIE_RC_CONFIG_SR == PCIE_RC_CONFIG_BASE + 0xd4
                    == 0xa00000 + 0xd4
                    == 0xa000d4

And they're used like this:

  PCIE_RC_CONFIG_CR + PCI_EXP_LNKCAP == 0xa000c0 + 0x0c
                                     == 0xa000cc

  PCIE_RC_CONFIG_CR + PCI_EXP_LNKCTL == 0xa000c0 + 0x10
                                     == 0xa000d0

  PCIE_RC_CONFIG_DC + PCI_EXP_DEVCTL == 0xa000c8 + 0x08
                                     == 0xa000d0     <-- same as LNKCTL? 

  PCIE_RC_CONFIG_SR + PCI_EXP_DEVCAP == 0xa000d4 + 0x04
                                     == 0xa000d8     <--

  PCIE_RC_CONFIG_LC + PCI_EXP_LNKCTL == 0xa000d0 + 0x10
                                     == 0xa000e0     <-- but LNKCTL was at 0xa000d0 above?

And the mappings don't make any sense to me:

  CR -> LNKCAP & LNKCTL
  DC -> DEVCTL (ok, this one makes a *little* sense)
  SR -> DEVCAP
  LC -> LNKCTL (would make some sense except that we have CR above)

This is all just really hard to read.  It looks like if we defined a
single base address for the PCIe Capability, we shouldn't need all the
_CR, _DC, _LC, _SR, etc #defines.  E.g., we could have

  #define ROCKCHIP_RP_PCIE_CAP ...

  rockchip_pcie_read(rockchip, ROCKCHIP_RP_PCIE_CAP + PCI_EXP_DEVCAP)
  rockchip_pcie_read(rockchip, ROCKCHIP_RP_PCIE_CAP + PCI_EXP_LNKCTL)
  ...

with maybe some minor adjustment for 16-bit registers since Rockchip
only seems to support 32-bit accesses (?)

None of these registers are *Root Complex* registers; they're all part
of a PCIe Capability, which applies to a Root *Port*.

>  #define PCIE_RC_CONFIG_LC		(PCIE_RC_CONFIG_BASE + 0xd0)
>  #define PCIE_RC_CONFIG_L1_SUBSTATE_CTRL2 (PCIE_RC_CONFIG_BASE + 0x90c)
>  #define PCIE_RC_CONFIG_THP_CAP		(PCIE_RC_CONFIG_BASE + 0x274)
> -- 
> 2.50.1
> 


From shawn.lin at rock-chips.com  Mon Nov 17 16:54:26 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Tue, 18 Nov 2025 08:54:26 +0800
Subject: [RFC v1 0/5] Fix some register offset as per RK3399 TRM part 2
In-Reply-To: <20251117181023.482138-1-linux.amoon@gmail.com>
References: <20251117181023.482138-1-linux.amoon@gmail.com>
Message-ID: <20d86c90-9066-4a44-8fff-f4e3edef256e@rock-chips.com>

Hi Anand,

? 2025/11/18 ??? 2:10, Anand Moon ??:
> In order to enable ASPM we need to fix the register offset as
> RK3399 TRM part 2 - PCIe Controller.
> 
> Tested on Radxa Rock Pi 4b.
> 

I checked your patch, and it looks like indeed we made some mistakes
here. Could you add fixes tag for each?

BTW, regarding to patch 1, I think you should leave out ASPM part, that
should be another topic after these fixes.

> Thanks
> -Anand
> 
> Anand Moon (5):
>    PCI: rockchip: Fix Link Control register offset and enable ASPM/CLKREQ
>    PCI: rockchip: Fix Device Control register offset for Max payload size
>    PCI: rockchip: Fix Slot Capability Register offset for slot power
>      limit
>    PCI: rockchip: Fix Link Control and Status Register 2 for target link
>      speed
>    PCI: rockchip: Fix Linkwidth Control Register offset for Retrain Link
> 
>   drivers/pci/controller/pcie-rockchip-host.c | 31 +++++++++++----------
>   drivers/pci/controller/pcie-rockchip.h      |  5 ++++
>   2 files changed, 21 insertions(+), 15 deletions(-)
> 
> 
> base-commit: e7c375b181600caf135cfd03eadbc45eb530f2cb



From chaoyi.chen at rock-chips.com  Mon Nov 17 17:30:29 2025
From: chaoyi.chen at rock-chips.com (Chaoyi Chen)
Date: Tue, 18 Nov 2025 09:30:29 +0800
Subject: [PATCH v2 3/3] iommu: Allow drivers to say if they use
 report_iommu_fault()
In-Reply-To: <3-v2-25fc75484cab+ab-iommu_set_fault_jgg@nvidia.com>
References: <3-v2-25fc75484cab+ab-iommu_set_fault_jgg@nvidia.com>
Message-ID: <26019e39-d36a-4290-ac80-c8b0b09104c8@rock-chips.com>

Hello Jason,

On 11/7/2025 4:34 AM, Jason Gunthorpe wrote:
> report_iommu_fault() is an older API that has been superseded by
> iommu_report_device_fault() which is capable to support PRI.
>
> Only two external drivers consume this, drivers/remoteproc and
> drivers/gpu/drm/msm. Ideally they would move over to the new APIs, but for
> now protect against accidentally mix and matching the wrong components.
>
> The iommu drivers support either the old iommu_set_fault_handler() via the
> driver calling report_iommu_fault(), or they are newer server focused
> drivers that call iommu_report_device_fault().
>
> Include a flag in the iommu_ops if the driver calls report_iommu_fault()
> and block iommu_set_fault_handler() for domain's of iommu drivers that
> can't support it.
>
> Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
> Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> Reviewed-by: Vasant Hegde <vasant.hegde at amd.com>
> Reviewed-by: Kevin Tian <kevin.tian at intel.com>

Sorry for the noise. Sometimes non-IOMMU drivers, such as DRM devices, also want to handle IOMMU fault events, so they might use iommu_set_fault_handler() before. What API should they use as an alternative now? Thank you.


-- 
Best,
Chaoyi



From zhangqing at rock-chips.com  Mon Nov 17 17:39:26 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Tue, 18 Nov 2025 09:39:26 +0800
Subject: [PATCH v10 0/3] rockchip: add can for RK3576 Soc
Message-ID: <20251118013929.2697132-1-zhangqing@rock-chips.com>

rk3576 can is a new CAN controller:
new register layout and Bit position definition:
There are major differences from the previous rk3568.
All errata on the rk3568 have been fixed and redesigned.

RK3576 TRM update: CANFD is replaced with RKCAN.

Change in V10:
[PATCH v10 1/3]: Add ACK for commit message.
[PATCH v10 2/3]: No change.
[PATCH v10 3/3]: Update commit message, fix get_berr_counter.
		 Add log for errata, drop RKCANFD_QUIRK_CANFD_BROKEN.

Change in V9(Drop dma):
[PATCH v9 1/3]: Drop dma, fix "allOf:"
[PATCH v9 2/3]: No change.
[PATCH v9 3/3]: Drop dma for commit message.

Change in V8:
[PATCH v8 1/4]: Drop CANFD, correction format warning.
[PATCH v8 2/4]: Drop fifo_setup of rkcanfd_devtype_data.
[PATCH v8 3/4]: Drop CANFD.
[PATCH v8 4/4]: Drop CANFD.

Change in V7:
[PATCH v7 1/4]: Correction format warning.
[PATCH v7 2/4]: No change.
[PATCH v7 3/4]: Correct the writing of some registers and
                correct the annotations.
[PATCH v7 4/4]: Optimize the structure parameters and
                ensure error handling.

Change in V6:
[PATCH v6 1/4]: Fix dma is support only for rk3576.
[PATCH v6 2/4]: Fix the compilation warning.
[PATCH v6 3/4]: Fix the compilation warning.
[PATCH v6 4/4]: Fix the compilation warning.

Change in V5:
[PATCH v5 1/4]: Add rk3576 canfd to rockchip,rk3568v2-canfd.yaml, remove
                rockchip,rk3576-canfd.yaml
[PATCH v5 2/4]: Encapsulate some hardware operation functions into
                rkcanfd_devtype_data to provide differentiated
                implementations for different models
                (such as RK3568v2/v3)..
[PATCH v5 3/4]: Add rk3576 canfd,fix the register naming rule,
                Delete the variables used by rockchip itself.
[PATCH v5 4/4]: Fix .h sorting.


Change in V4:
[PATCH v4 1/3]: Correct the format and add explanations.
[PATCH v4 2/3]: No change.
[PATCH v4 3/3]: No change.

Change in V3:
[PATCH v3 1/3]: Add documentation for the rk3576 CAN-FD.
[PATCH v3 2/3]: Adjust the differentiated code section and
                add dma function.
[PATCH v3 3/3]: Remove dma, no use dma by default.

Change in V2:
[PATCH v2 1/2]: remove rk3576_canfd.c, use the rockchip_canfd driver
[PATCH v2 2/2]: code style.

Elaine Zhang (3):
  dt-bindings: can: rockchip_canfd: add rk3576 CAN controller
  net: can: rockchip: Refactor the rkcanfd_devtype_data structure
  net: can: rockchip: add can for RK3576 Soc

 .../net/can/rockchip,rk3568v2-canfd.yaml      |   4 +-
 .../net/can/rockchip/rockchip_canfd-core.c    | 505 ++++++++++++++++--
 drivers/net/can/rockchip/rockchip_canfd-rx.c  | 103 ++++
 drivers/net/can/rockchip/rockchip_canfd-tx.c  |  20 +
 drivers/net/can/rockchip/rockchip_canfd.h     | 268 ++++++++++
 5 files changed, 857 insertions(+), 43 deletions(-)

-- 
2.34.1



From zhangqing at rock-chips.com  Mon Nov 17 17:39:28 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Tue, 18 Nov 2025 09:39:28 +0800
Subject: [PATCH v10 2/3] net: can: rockchip: Refactor the rkcanfd_devtype_data structure
In-Reply-To: <20251118013929.2697132-1-zhangqing@rock-chips.com>
References: <20251118013929.2697132-1-zhangqing@rock-chips.com>
Message-ID: <20251118013929.2697132-3-zhangqing@rock-chips.com>

Add new function pointer:
Encapsulate some hardware operation functions into
rkcanfd_devtype_data to provide differentiated implementations for
different models (such as RK3568v2/v3).

Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
---
 .../net/can/rockchip/rockchip_canfd-core.c    | 100 ++++++++++--------
 drivers/net/can/rockchip/rockchip_canfd.h     |  10 ++
 2 files changed, 68 insertions(+), 42 deletions(-)

diff --git a/drivers/net/can/rockchip/rockchip_canfd-core.c b/drivers/net/can/rockchip/rockchip_canfd-core.c
index 046f0a0ae4d4..761cb36148ff 100644
--- a/drivers/net/can/rockchip/rockchip_canfd-core.c
+++ b/drivers/net/can/rockchip/rockchip_canfd-core.c
@@ -24,32 +24,6 @@
 
 #include "rockchip_canfd.h"
 
-static const struct rkcanfd_devtype_data rkcanfd_devtype_data_rk3568v2 = {
-	.model = RKCANFD_MODEL_RK3568V2,
-	.quirks = RKCANFD_QUIRK_RK3568_ERRATUM_1 | RKCANFD_QUIRK_RK3568_ERRATUM_2 |
-		RKCANFD_QUIRK_RK3568_ERRATUM_3 | RKCANFD_QUIRK_RK3568_ERRATUM_4 |
-		RKCANFD_QUIRK_RK3568_ERRATUM_5 | RKCANFD_QUIRK_RK3568_ERRATUM_6 |
-		RKCANFD_QUIRK_RK3568_ERRATUM_7 | RKCANFD_QUIRK_RK3568_ERRATUM_8 |
-		RKCANFD_QUIRK_RK3568_ERRATUM_9 | RKCANFD_QUIRK_RK3568_ERRATUM_10 |
-		RKCANFD_QUIRK_RK3568_ERRATUM_11 | RKCANFD_QUIRK_RK3568_ERRATUM_12 |
-		RKCANFD_QUIRK_CANFD_BROKEN,
-};
-
-/* The rk3568 CAN-FD errata sheet as of Tue 07 Nov 2023 11:25:31 +08:00
- * states that only the rk3568v2 is affected by erratum 5, but tests
- * with the rk3568v2 and rk3568v3 show that the RX_FIFO_CNT is
- * sometimes too high. In contrast to the errata sheet mark rk3568v3
- * as effected by erratum 5, too.
- */
-static const struct rkcanfd_devtype_data rkcanfd_devtype_data_rk3568v3 = {
-	.model = RKCANFD_MODEL_RK3568V3,
-	.quirks = RKCANFD_QUIRK_RK3568_ERRATUM_1 | RKCANFD_QUIRK_RK3568_ERRATUM_2 |
-		RKCANFD_QUIRK_RK3568_ERRATUM_5 | RKCANFD_QUIRK_RK3568_ERRATUM_7 |
-		RKCANFD_QUIRK_RK3568_ERRATUM_8 | RKCANFD_QUIRK_RK3568_ERRATUM_10 |
-		RKCANFD_QUIRK_RK3568_ERRATUM_11 | RKCANFD_QUIRK_RK3568_ERRATUM_12 |
-		RKCANFD_QUIRK_CANFD_BROKEN,
-};
-
 static const char *__rkcanfd_get_model_str(enum rkcanfd_model model)
 {
 	switch (model) {
@@ -212,7 +186,7 @@ static int rkcanfd_get_berr_counter(const struct net_device *ndev,
 	if (err)
 		return err;
 
-	rkcanfd_get_berr_counter_corrected(priv, bec);
+	priv->devtype_data.get_berr_counter(priv, bec);
 
 	pm_runtime_put(ndev->dev.parent);
 
@@ -302,7 +276,7 @@ static void rkcanfd_chip_start(struct rkcanfd_priv *priv)
 
 	rkcanfd_set_bittiming(priv);
 
-	rkcanfd_chip_interrupts_disable(priv);
+	priv->devtype_data.interrupts_disable(priv);
 	rkcanfd_chip_set_work_mode(priv);
 
 	priv->can.state = CAN_STATE_ERROR_ACTIVE;
@@ -316,7 +290,7 @@ static void __rkcanfd_chip_stop(struct rkcanfd_priv *priv, const enum can_state
 	priv->can.state = state;
 
 	rkcanfd_chip_set_reset_mode(priv);
-	rkcanfd_chip_interrupts_disable(priv);
+	priv->devtype_data.interrupts_disable(priv);
 }
 
 static void rkcanfd_chip_stop(struct rkcanfd_priv *priv, const enum can_state state)
@@ -342,8 +316,8 @@ static int rkcanfd_set_mode(struct net_device *ndev,
 
 	switch (mode) {
 	case CAN_MODE_START:
-		rkcanfd_chip_start(priv);
-		rkcanfd_chip_interrupts_enable(priv);
+		priv->devtype_data.chip_start(priv);
+		priv->devtype_data.interrupts_enable(priv);
 		netif_wake_queue(ndev);
 		break;
 
@@ -537,7 +511,7 @@ static int rkcanfd_handle_error_int(struct rkcanfd_priv *priv)
 		if (cf) {
 			struct can_berr_counter bec;
 
-			rkcanfd_get_berr_counter_corrected(priv, &bec);
+			priv->devtype_data.get_berr_counter(priv, &bec);
 			cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR | CAN_ERR_CNT;
 			cf->data[6] = bec.txerr;
 			cf->data[7] = bec.rxerr;
@@ -567,7 +541,7 @@ static int rkcanfd_handle_state_error_int(struct rkcanfd_priv *priv)
 	u32 timestamp;
 	int err;
 
-	rkcanfd_get_berr_counter_corrected(priv, &bec);
+	priv->devtype_data.get_berr_counter(priv, &bec);
 	can_state_get_by_berr_counter(ndev, &bec, &tx_state, &rx_state);
 
 	new_state = max(tx_state, rx_state);
@@ -581,7 +555,7 @@ static int rkcanfd_handle_state_error_int(struct rkcanfd_priv *priv)
 	can_change_state(ndev, cf, tx_state, rx_state);
 
 	if (new_state == CAN_STATE_BUS_OFF) {
-		rkcanfd_chip_stop(priv, CAN_STATE_BUS_OFF);
+		priv->devtype_data.chip_stop(priv, CAN_STATE_BUS_OFF);
 		can_bus_off(ndev);
 	}
 
@@ -620,7 +594,7 @@ rkcanfd_handle_rx_fifo_overflow_int(struct rkcanfd_priv *priv)
 	if (!skb)
 		return 0;
 
-	rkcanfd_get_berr_counter_corrected(priv, &bec);
+	priv->devtype_data.get_berr_counter(priv, &bec);
 
 	cf->can_id |= CAN_ERR_CRTL | CAN_ERR_CNT;
 	cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
@@ -719,21 +693,21 @@ static int rkcanfd_open(struct net_device *ndev)
 	if (err)
 		goto out_close_candev;
 
-	rkcanfd_chip_start(priv);
+	priv->devtype_data.chip_start(priv);
 	can_rx_offload_enable(&priv->offload);
 
-	err = request_irq(ndev->irq, rkcanfd_irq, IRQF_SHARED, ndev->name, priv);
+	err = request_irq(ndev->irq, priv->devtype_data.irq, IRQF_SHARED, ndev->name, priv);
 	if (err)
 		goto out_rkcanfd_chip_stop;
 
-	rkcanfd_chip_interrupts_enable(priv);
+	priv->devtype_data.interrupts_enable(priv);
 
 	netif_start_queue(ndev);
 
 	return 0;
 
 out_rkcanfd_chip_stop:
-	rkcanfd_chip_stop_sync(priv, CAN_STATE_STOPPED);
+	priv->devtype_data.chip_stop_sync(priv, CAN_STATE_STOPPED);
 	pm_runtime_put(ndev->dev.parent);
 out_close_candev:
 	close_candev(ndev);
@@ -746,10 +720,10 @@ static int rkcanfd_stop(struct net_device *ndev)
 
 	netif_stop_queue(ndev);
 
-	rkcanfd_chip_interrupts_disable(priv);
+	priv->devtype_data.interrupts_disable(priv);
 	free_irq(ndev->irq, priv);
 	can_rx_offload_disable(&priv->offload);
-	rkcanfd_chip_stop_sync(priv, CAN_STATE_STOPPED);
+	priv->devtype_data.chip_stop_sync(priv, CAN_STATE_STOPPED);
 	close_candev(ndev);
 
 	pm_runtime_put(ndev->dev.parent);
@@ -818,7 +792,7 @@ static int rkcanfd_register(struct rkcanfd_priv *priv)
 	if (err)
 		goto out_pm_runtime_put_sync;
 
-	rkcanfd_register_done(priv);
+	priv->devtype_data.register_done(priv);
 
 	pm_runtime_put(ndev->dev.parent);
 
@@ -840,6 +814,48 @@ static inline void rkcanfd_unregister(struct rkcanfd_priv *priv)
 	pm_runtime_disable(ndev->dev.parent);
 }
 
+static const struct rkcanfd_devtype_data rkcanfd_devtype_data_rk3568v2 = {
+	.model = RKCANFD_MODEL_RK3568V2,
+	.quirks = RKCANFD_QUIRK_RK3568_ERRATUM_1 | RKCANFD_QUIRK_RK3568_ERRATUM_2 |
+		RKCANFD_QUIRK_RK3568_ERRATUM_3 | RKCANFD_QUIRK_RK3568_ERRATUM_4 |
+		RKCANFD_QUIRK_RK3568_ERRATUM_5 | RKCANFD_QUIRK_RK3568_ERRATUM_6 |
+		RKCANFD_QUIRK_RK3568_ERRATUM_7 | RKCANFD_QUIRK_RK3568_ERRATUM_8 |
+		RKCANFD_QUIRK_RK3568_ERRATUM_9 | RKCANFD_QUIRK_RK3568_ERRATUM_10 |
+		RKCANFD_QUIRK_RK3568_ERRATUM_11 | RKCANFD_QUIRK_RK3568_ERRATUM_12 |
+		RKCANFD_QUIRK_CANFD_BROKEN,
+	.get_berr_counter = rkcanfd_get_berr_counter_corrected,
+	.interrupts_enable = rkcanfd_chip_interrupts_enable,
+	.interrupts_disable = rkcanfd_chip_interrupts_disable,
+	.chip_start = rkcanfd_chip_start,
+	.chip_stop = rkcanfd_chip_stop,
+	.chip_stop_sync = rkcanfd_chip_stop_sync,
+	.irq = rkcanfd_irq,
+	.register_done = rkcanfd_register_done,
+};
+
+/* The rk3568 CAN-FD errata sheet as of Tue 07 Nov 2023 11:25:31 +08:00
+ * states that only the rk3568v2 is affected by erratum 5, but tests
+ * with the rk3568v2 and rk3568v3 show that the RX_FIFO_CNT is
+ * sometimes too high. In contrast to the errata sheet mark rk3568v3
+ * as effected by erratum 5, too.
+ */
+static const struct rkcanfd_devtype_data rkcanfd_devtype_data_rk3568v3 = {
+	.model = RKCANFD_MODEL_RK3568V3,
+	.quirks = RKCANFD_QUIRK_RK3568_ERRATUM_1 | RKCANFD_QUIRK_RK3568_ERRATUM_2 |
+		RKCANFD_QUIRK_RK3568_ERRATUM_5 | RKCANFD_QUIRK_RK3568_ERRATUM_7 |
+		RKCANFD_QUIRK_RK3568_ERRATUM_8 | RKCANFD_QUIRK_RK3568_ERRATUM_10 |
+		RKCANFD_QUIRK_RK3568_ERRATUM_11 | RKCANFD_QUIRK_RK3568_ERRATUM_12 |
+		RKCANFD_QUIRK_CANFD_BROKEN,
+	.get_berr_counter = rkcanfd_get_berr_counter_corrected,
+	.interrupts_enable = rkcanfd_chip_interrupts_enable,
+	.interrupts_disable = rkcanfd_chip_interrupts_disable,
+	.chip_start = rkcanfd_chip_start,
+	.chip_stop = rkcanfd_chip_stop,
+	.chip_stop_sync = rkcanfd_chip_stop_sync,
+	.irq = rkcanfd_irq,
+	.register_done = rkcanfd_register_done,
+};
+
 static const struct of_device_id rkcanfd_of_match[] = {
 	{
 		.compatible = "rockchip,rk3568v2-canfd",
diff --git a/drivers/net/can/rockchip/rockchip_canfd.h b/drivers/net/can/rockchip/rockchip_canfd.h
index 93131c7d7f54..72f26b96add0 100644
--- a/drivers/net/can/rockchip/rockchip_canfd.h
+++ b/drivers/net/can/rockchip/rockchip_canfd.h
@@ -436,9 +436,19 @@ enum rkcanfd_model {
 	RKCANFD_MODEL_RK3568V3 = 0x35683,
 };
 
+struct rkcanfd_priv;
+
 struct rkcanfd_devtype_data {
 	enum rkcanfd_model model;
 	u32 quirks;
+	void (*get_berr_counter)(struct rkcanfd_priv *priv, struct can_berr_counter *bec);
+	void (*interrupts_enable)(const struct rkcanfd_priv *priv);
+	void (*interrupts_disable)(const struct rkcanfd_priv *priv);
+	void (*chip_start)(struct rkcanfd_priv *priv);
+	void (*chip_stop)(struct rkcanfd_priv *priv, const enum can_state state);
+	void (*chip_stop_sync)(struct rkcanfd_priv *priv, const enum can_state state);
+	irqreturn_t (*irq)(int irq, void *dev_id);
+	void (*register_done)(const struct rkcanfd_priv *priv);
 };
 
 struct rkcanfd_fifo_header {
-- 
2.34.1



From zhangqing at rock-chips.com  Mon Nov 17 17:39:29 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Tue, 18 Nov 2025 09:39:29 +0800
Subject: [PATCH v10 3/3] net: can: rockchip: add can for RK3576 Soc
In-Reply-To: <20251118013929.2697132-1-zhangqing@rock-chips.com>
References: <20251118013929.2697132-1-zhangqing@rock-chips.com>
Message-ID: <20251118013929.2697132-4-zhangqing@rock-chips.com>

Is new controller, all errata issues on rk3568 have been fixed.

The main differences are:
1. New register layout
2. Different bit position definition
3. Time stamp register removed
4. Hardware filtering function has been updated(ATF), with the addition of
   MASK MODE and LIST MODE
5. Add auto retx config and status

Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
---
 .../net/can/rockchip/rockchip_canfd-core.c    | 405 ++++++++++++++++++
 drivers/net/can/rockchip/rockchip_canfd-rx.c  | 103 +++++
 drivers/net/can/rockchip/rockchip_canfd-tx.c  |  20 +
 drivers/net/can/rockchip/rockchip_canfd.h     | 258 +++++++++++
 4 files changed, 786 insertions(+)

diff --git a/drivers/net/can/rockchip/rockchip_canfd-core.c b/drivers/net/can/rockchip/rockchip_canfd-core.c
index 761cb36148ff..a42d86ada888 100644
--- a/drivers/net/can/rockchip/rockchip_canfd-core.c
+++ b/drivers/net/can/rockchip/rockchip_canfd-core.c
@@ -31,6 +31,8 @@ static const char *__rkcanfd_get_model_str(enum rkcanfd_model model)
 		return "rk3568v2";
 	case RKCANFD_MODEL_RK3568V3:
 		return "rk3568v3";
+	case RKCAN_MODEL_RK3576:
+		return "rk3576";
 	}
 
 	return "<unknown>";
@@ -176,6 +178,13 @@ static void rkcanfd_get_berr_counter_corrected(struct rkcanfd_priv *priv,
 		    !!(reg_state & RKCANFD_REG_STATE_ERROR_WARNING_STATE));
 }
 
+static void rk3576can_get_berr_counter_corrected(struct rkcanfd_priv *priv,
+						 struct can_berr_counter *bec)
+{
+	bec->rxerr = rkcanfd_read(priv, RK3576CAN_REG_RXERRORCNT);
+	bec->txerr = rkcanfd_read(priv, RK3576CAN_REG_TXERRORCNT);
+}
+
 static int rkcanfd_get_berr_counter(const struct net_device *ndev,
 				    struct can_berr_counter *bec)
 {
@@ -206,6 +215,11 @@ static void rkcanfd_chip_interrupts_disable(const struct rkcanfd_priv *priv)
 	rkcanfd_write(priv, RKCANFD_REG_INT_MASK, RKCANFD_REG_INT_ALL);
 }
 
+static void rk3576can_chip_interrupts_disable(const struct rkcanfd_priv *priv)
+{
+	rkcanfd_write(priv, RK3576CAN_REG_INT_MASK, RK3576CAN_REG_INT_ALL);
+}
+
 static void rkcanfd_chip_fifo_setup(struct rkcanfd_priv *priv)
 {
 	u32 reg;
@@ -220,6 +234,48 @@ static void rkcanfd_chip_fifo_setup(struct rkcanfd_priv *priv)
 	netdev_reset_queue(priv->ndev);
 }
 
+static void rk3576can_chip_fifo_setup(struct rkcanfd_priv *priv)
+{
+	u32 reg_ism, reg_water;
+
+	reg_ism = FIELD_PREP(RK3576CAN_REG_STR_CTL_ISM_SEL,
+			     RK3576CAN_REG_STR_CTL_ISM_SEL_CANFD_FIXED) |
+		  RK3576CAN_REG_STR_CTL_STORAGE_TIMEOUT_MODE;
+	reg_water = RK3576CAN_ISM_WATERMASK_CANFD;
+
+	/* internal sram mode */
+	rkcanfd_write(priv, RK3576CAN_REG_STR_CTL, reg_ism);
+	rkcanfd_write(priv, RK3576CAN_REG_STR_WTM, reg_water);
+	WRITE_ONCE(priv->tx_head, 0);
+	WRITE_ONCE(priv->tx_tail, 0);
+	netdev_reset_queue(priv->ndev);
+}
+
+static void rk3576can_atf_config(struct rkcanfd_priv *priv, int mode)
+{
+	int i;
+
+	switch (mode) {
+	case RK3576CAN_REG_ATFM_MASK_SEL_MASK_MODE:
+		for (i = 0; i < 5; i++) {
+			rkcanfd_write(priv, RK3576CAN_REG_ATF(i), 0);
+			rkcanfd_write(priv, RK3576CAN_REG_ATFM(i), RK3576CAN_REG_ATFM_ID);
+		}
+		break;
+	case RK3576CAN_REG_ATFM_MASK_SEL_LIST_MODE:
+		for (i = 0; i < 5; i++) {
+			rkcanfd_write(priv, RK3576CAN_REG_ATF(i), 0);
+			rkcanfd_write(priv, RK3576CAN_REG_ATFM(i), RK3576CAN_REG_ATFM_MASK_SEL);
+		}
+		break;
+	default:
+		rkcanfd_write(priv, RK3576CAN_REG_ATF_CTL, RK3576CAN_REG_ATF_CTL_ATF_DIS_ALL);
+		return;
+	}
+
+	rkcanfd_write(priv, RK3576CAN_REG_ATF_CTL, 0);
+}
+
 static void rkcanfd_chip_start(struct rkcanfd_priv *priv)
 {
 	u32 reg;
@@ -285,6 +341,61 @@ static void rkcanfd_chip_start(struct rkcanfd_priv *priv)
 		   rkcanfd_read(priv, RKCANFD_REG_MODE));
 }
 
+static void rk3576can_chip_start(struct rkcanfd_priv *priv)
+
+{
+	u32 reg;
+
+	rkcanfd_chip_set_reset_mode(priv);
+
+	/* Receiving Filter: accept all */
+	rk3576can_atf_config(priv, RK3576CAN_REG_ATFM_MASK_SEL_MASK_MODE);
+
+	/* enable:
+	 * - WORK_MODE: transition from reset to working mode
+	 */
+	reg = rkcanfd_read(priv, RKCANFD_REG_MODE);
+	priv->reg_mode_default = reg | RKCANFD_REG_MODE_WORK_MODE;
+
+	if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) {
+		priv->reg_mode_default |= RKCANFD_REG_MODE_LBACK_MODE;
+		rkcanfd_write(priv, RK3576CAN_REG_ERROR_MASK,
+			      RK3576CAN_REG_ERROR_MASK_ACK_ERROR);
+	}
+
+	/* mask, i.e. ignore:
+	 * - RX_FINISH_INT - Rx finish interrupt
+	 */
+	priv->reg_int_mask_default = RK3576CAN_REG_INT_RX_FINISH_INT;
+
+	/* Do not mask the bus error interrupt if the bus error
+	 * reporting is requested.
+	 */
+	if (!(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING))
+		priv->reg_int_mask_default |= RKCANFD_REG_INT_ERROR_INT;
+
+	memset(&priv->bec, 0x0, sizeof(priv->bec));
+
+	rk3576can_chip_fifo_setup(priv);
+
+	rkcanfd_write(priv, RK3576CAN_REG_AUTO_RETX_CFG,
+		      RK3576CAN_REG_AUTO_RETX_CFG_AUTO_RETX_EN);
+
+	rkcanfd_write(priv, RK3576CAN_REG_BRS_CFG,
+		      RK3576CAN_REG_BRS_CFG_BRS_NEGSYNC_EN |
+		      RK3576CAN_REG_BRS_CFG_BRS_POSSYNC_EN);
+
+	rkcanfd_set_bittiming(priv);
+
+	priv->devtype_data.interrupts_disable(priv);
+	rkcanfd_chip_set_work_mode(priv);
+
+	priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+	netdev_dbg(priv->ndev, "%s: reg_mode=0x%08x\n", __func__,
+		   rkcanfd_read(priv, RKCANFD_REG_MODE));
+}
+
 static void __rkcanfd_chip_stop(struct rkcanfd_priv *priv, const enum can_state state)
 {
 	priv->can.state = state;
@@ -301,6 +412,13 @@ static void rkcanfd_chip_stop(struct rkcanfd_priv *priv, const enum can_state st
 	__rkcanfd_chip_stop(priv, state);
 }
 
+static void rk3576can_chip_stop(struct rkcanfd_priv *priv, const enum can_state state)
+{
+	priv->can.state = state;
+
+	__rkcanfd_chip_stop(priv, state);
+}
+
 static void rkcanfd_chip_stop_sync(struct rkcanfd_priv *priv, const enum can_state state)
 {
 	priv->can.state = state;
@@ -309,6 +427,13 @@ static void rkcanfd_chip_stop_sync(struct rkcanfd_priv *priv, const enum can_sta
 	__rkcanfd_chip_stop(priv, state);
 }
 
+static void rk3576can_chip_stop_sync(struct rkcanfd_priv *priv, const enum can_state state)
+{
+	priv->can.state = state;
+
+	__rkcanfd_chip_stop(priv, state);
+}
+
 static int rkcanfd_set_mode(struct net_device *ndev,
 			    enum can_mode mode)
 {
@@ -364,6 +489,9 @@ static const char *rkcanfd_get_error_type_str(unsigned int type)
 #define RKCAN_ERROR_CODE(reg_ec, code) \
 	((reg_ec) & RKCANFD_REG_ERROR_CODE_##code ? __stringify(code) " " : "")
 
+#define RK3576CAN_ERROR_CODE(reg_ec, code) \
+	((reg_ec) & RK3576CAN_REG_ERROR_CODE_##code ? __stringify(code) " " : "")
+
 static void
 rkcanfd_handle_error_int_reg_ec(struct rkcanfd_priv *priv, struct can_frame *cf,
 				const u32 reg_ec)
@@ -493,6 +621,128 @@ rkcanfd_handle_error_int_reg_ec(struct rkcanfd_priv *priv, struct can_frame *cf,
 	}
 }
 
+static void
+rk3576can_handle_error_int_reg_ec(struct rkcanfd_priv *priv, struct can_frame *cf,
+				  const u32 reg_ec)
+{
+	struct net_device_stats *stats = &priv->ndev->stats;
+	unsigned int type;
+	u32 reg_state, reg_cmd;
+
+	type = FIELD_GET(RK3576CAN_REG_ERROR_CODE_TYPE, reg_ec);
+	reg_cmd = rkcanfd_read(priv, RK3576CAN_REG_CMD);
+	reg_state = rkcanfd_read(priv, RK3576CAN_REG_STATE);
+
+	netdev_dbg(priv->ndev, "%s Error in %s %s Phase: %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s(0x%08x) CMD=%u RX=%u TX=%u Error-Warning=%u Bus-Off=%u\n",
+		   rkcanfd_get_error_type_str(type),
+		   reg_ec & RK3576CAN_REG_ERROR_CODE_DIRECTION_RX ? "RX" : "TX",
+		   reg_ec & RK3576CAN_REG_ERROR_CODE_PHASE ? "Data" : "Arbitration",
+		   RK3576CAN_ERROR_CODE(reg_ec, TX_ACK_EOF),
+		   RK3576CAN_ERROR_CODE(reg_ec, TX_CRC),
+		   RK3576CAN_ERROR_CODE(reg_ec, TX_STUFF_COUNT),
+		   RK3576CAN_ERROR_CODE(reg_ec, TX_DATA),
+		   RK3576CAN_ERROR_CODE(reg_ec, TX_SOF_DLC),
+		   RK3576CAN_ERROR_CODE(reg_ec, TX_IDLE),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_ERROR),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_OVERLOAD),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_SPACE),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_EOF),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_ACK_LIM),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_ACK),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_CRC_LIM),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_CRC),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_STUFF_COUNT),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_DATA),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_DLC),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_BRS_ESI),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_RES),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_FDF),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_ID2_RTR),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_SOF_IDE),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_BUS_IDLE),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_BUS_INT),
+		   RK3576CAN_ERROR_CODE(reg_ec, RX_STOP),
+		   reg_ec, reg_cmd,
+		   !!(reg_state & RK3576CAN_REG_STATE_RX_PERIOD),
+		   !!(reg_state & RK3576CAN_REG_STATE_TX_PERIOD),
+		   !!(reg_state & RK3576CAN_REG_STATE_ERROR_WARNING_STATE),
+		   !!(reg_state & RK3576CAN_REG_STATE_BUS_OFF_STATE));
+
+	priv->can.can_stats.bus_error++;
+
+	if (reg_ec & RK3576CAN_REG_ERROR_CODE_DIRECTION_RX)
+		stats->rx_errors++;
+	else
+		stats->tx_errors++;
+
+	if (!cf)
+		return;
+
+	if (reg_ec & RK3576CAN_REG_ERROR_CODE_DIRECTION_RX) {
+		if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_SOF_IDE)
+			cf->data[3] = CAN_ERR_PROT_LOC_SOF;
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_ID2_RTR)
+			cf->data[3] = CAN_ERR_PROT_LOC_RTR;
+		/* RKCANFD_REG_ERROR_CODE_RX_FDF */
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_RES)
+			cf->data[3] = CAN_ERR_PROT_LOC_RES0;
+		/* RKCANFD_REG_ERROR_CODE_RX_BRS_ESI */
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_DLC)
+			cf->data[3] = CAN_ERR_PROT_LOC_DLC;
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_DATA)
+			cf->data[3] = CAN_ERR_PROT_LOC_DATA;
+		/* RKCANFD_REG_ERROR_CODE_RX_STUFF_COUNT */
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_CRC)
+			cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_CRC_LIM)
+			cf->data[3] = CAN_ERR_PROT_LOC_ACK_DEL;
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_ACK)
+			cf->data[3] = CAN_ERR_PROT_LOC_ACK;
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_ACK_LIM)
+			cf->data[3] = CAN_ERR_PROT_LOC_ACK_DEL;
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_EOF)
+			cf->data[3] = CAN_ERR_PROT_LOC_EOF;
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_RX_SPACE)
+			cf->data[3] = CAN_ERR_PROT_LOC_EOF;
+	} else {
+		cf->data[2] |= CAN_ERR_PROT_TX;
+
+		if (reg_ec & RK3576CAN_REG_ERROR_CODE_TX_SOF_DLC)
+			cf->data[3] = CAN_ERR_PROT_LOC_SOF;
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_TX_DATA)
+			cf->data[3] = CAN_ERR_PROT_LOC_DATA;
+		/* RKCANFD_REG_ERROR_CODE_TX_STUFF_COUNT */
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_TX_CRC)
+			cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
+		else if (reg_ec & RK3576CAN_REG_ERROR_CODE_TX_ACK_EOF)
+			cf->data[3] = CAN_ERR_PROT_LOC_ACK_DEL;
+	}
+
+	switch (reg_ec & RK3576CAN_REG_ERROR_CODE_TYPE) {
+	case FIELD_PREP_CONST(RK3576CAN_REG_ERROR_CODE_TYPE,
+			      RK3576CAN_REG_ERROR_CODE_TYPE_BIT):
+
+		cf->data[2] |= CAN_ERR_PROT_BIT;
+		break;
+	case FIELD_PREP_CONST(RK3576CAN_REG_ERROR_CODE_TYPE,
+			      RK3576CAN_REG_ERROR_CODE_TYPE_STUFF):
+		cf->data[2] |= CAN_ERR_PROT_STUFF;
+		break;
+	case FIELD_PREP_CONST(RK3576CAN_REG_ERROR_CODE_TYPE,
+			      RK3576CAN_REG_ERROR_CODE_TYPE_FORM):
+		cf->data[2] |= CAN_ERR_PROT_FORM;
+		break;
+	case FIELD_PREP_CONST(RK3576CAN_REG_ERROR_CODE_TYPE,
+			      RK3576CAN_REG_ERROR_CODE_TYPE_ACK):
+		cf->can_id |= CAN_ERR_ACK;
+		break;
+	case FIELD_PREP_CONST(RK3576CAN_REG_ERROR_CODE_TYPE,
+			      RK3576CAN_REG_ERROR_CODE_TYPE_CRC):
+		cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
+		break;
+	}
+}
+
 static int rkcanfd_handle_error_int(struct rkcanfd_priv *priv)
 {
 	struct net_device_stats *stats = &priv->ndev->stats;
@@ -530,6 +780,41 @@ static int rkcanfd_handle_error_int(struct rkcanfd_priv *priv)
 	return 0;
 }
 
+static int rkcanfd_handle_rk3576_error_int(struct rkcanfd_priv *priv)
+{
+	struct net_device_stats *stats = &priv->ndev->stats;
+	struct can_frame *cf = NULL;
+	u32 reg_ec;
+	struct sk_buff *skb;
+	int err;
+
+	reg_ec = rkcanfd_read(priv, RK3576CAN_REG_ERROR_CODE);
+	if (!reg_ec)
+		return 0;
+
+	if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) {
+		skb = alloc_can_err_skb(priv->ndev, &cf);
+		if (cf) {
+			struct can_berr_counter bec;
+
+			priv->devtype_data.get_berr_counter(priv, &bec);
+			cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR | CAN_ERR_CNT;
+			cf->data[6] = bec.txerr;
+			cf->data[7] = bec.rxerr;
+		}
+	}
+
+	rk3576can_handle_error_int_reg_ec(priv, cf, reg_ec);
+	if (!cf)
+		return 0;
+
+	err = can_rx_offload_queue_tail(&priv->offload, skb);
+	if (err)
+		stats->rx_fifo_errors++;
+
+	return 0;
+}
+
 static int rkcanfd_handle_state_error_int(struct rkcanfd_priv *priv)
 {
 	struct net_device_stats *stats = &priv->ndev->stats;
@@ -575,6 +860,50 @@ static int rkcanfd_handle_state_error_int(struct rkcanfd_priv *priv)
 	return 0;
 }
 
+static int rkcanfd_handle_rk3576_state_error_int(struct rkcanfd_priv *priv)
+{
+	struct net_device_stats *stats = &priv->ndev->stats;
+	enum can_state new_state, rx_state, tx_state;
+	struct net_device *ndev = priv->ndev;
+	struct can_berr_counter bec;
+	struct can_frame *cf = NULL;
+	struct sk_buff *skb;
+	int err;
+
+	rk3576can_get_berr_counter_corrected(priv, &bec);
+	can_state_get_by_berr_counter(ndev, &bec, &tx_state, &rx_state);
+
+	new_state = max(tx_state, rx_state);
+	if (new_state == priv->can.state)
+		return 0;
+
+	/* The skb allocation might fail, but can_change_state()
+	 * handles cf == NULL.
+	 */
+	skb = alloc_can_err_skb(priv->ndev, &cf);
+	can_change_state(ndev, cf, tx_state, rx_state);
+
+	if (new_state == CAN_STATE_BUS_OFF) {
+		priv->devtype_data.chip_stop(priv, CAN_STATE_BUS_OFF);
+		can_bus_off(ndev);
+	}
+
+	if (!skb)
+		return 0;
+
+	if (new_state != CAN_STATE_BUS_OFF) {
+		cf->can_id |= CAN_ERR_CNT;
+		cf->data[6] = bec.txerr;
+		cf->data[7] = bec.rxerr;
+	}
+
+	err = can_rx_offload_queue_tail(&priv->offload, skb);
+	if (err)
+		stats->rx_fifo_errors++;
+
+	return 0;
+}
+
 static int
 rkcanfd_handle_rx_fifo_overflow_int(struct rkcanfd_priv *priv)
 {
@@ -621,6 +950,55 @@ rkcanfd_handle_rx_fifo_overflow_int(struct rkcanfd_priv *priv)
 	err; \
 })
 
+static irqreturn_t rk3576can_irq(int irq, void *dev_id)
+{
+	struct rkcanfd_priv *priv = dev_id;
+	u32 reg_int_unmasked, reg_int;
+
+	reg_int_unmasked = rkcanfd_read(priv, RK3576CAN_REG_INT);
+	reg_int = reg_int_unmasked & ~priv->reg_int_mask_default;
+
+	if (!reg_int)
+		return IRQ_NONE;
+
+	rkcanfd_write(priv, RK3576CAN_REG_INT, reg_int);
+
+	if (reg_int & (RK3576CAN_REG_INT_RXSTR_TIMEOUT_INT |
+		       RK3576CAN_REG_INT_ISM_WTM_INT |
+		       RK3576CAN_REG_INT_RX_FIFO_FULL_INT)) {
+		rkcanfd_write(priv, RK3576CAN_REG_INT_MASK,
+			      priv->reg_int_mask_default | RK3576CAN_REG_INT_ISM_WTM_INT |
+			      RK3576CAN_REG_INT_RXSTR_TIMEOUT_INT |
+			      RK3576CAN_REG_INT_RX_FINISH_INT);
+		rkcanfd_handle(priv, rk3576_rx_int);
+	}
+
+	if (reg_int & RK3576CAN_REG_INT_TX_FINISH_INT)
+		rkcanfd_handle(priv, rk3576_tx_int);
+
+	if (reg_int & RK3576CAN_REG_INT_ERROR_INT)
+		rkcanfd_handle(priv, rk3576_error_int);
+
+	if (reg_int & (RK3576CAN_REG_INT_BUS_OFF_INT |
+		       RK3576CAN_REG_INT_PASSIVE_ERROR_INT |
+		       RK3576CAN_REG_INT_ERROR_WARNING_INT) ||
+	    priv->can.state > CAN_STATE_ERROR_ACTIVE)
+		rkcanfd_handle(priv, rk3576_state_error_int);
+
+	if (reg_int & RK3576CAN_REG_INT_WAKEUP_INT)
+		netdev_info(priv->ndev, "%s: WAKEUP_INT\n", __func__);
+
+	if (reg_int & RK3576CAN_REG_INT_BUS_OFF_RECOVERY_INT)
+		netdev_info(priv->ndev, "%s: BUS_OFF_RECOVERY_INT\n", __func__);
+
+	if (reg_int & RK3576CAN_REG_INT_OVERLOAD_INT)
+		netdev_info(priv->ndev, "%s: OVERLOAD_INT\n", __func__);
+
+	can_rx_offload_irq_finish(&priv->offload);
+
+	return IRQ_HANDLED;
+}
+
 static irqreturn_t rkcanfd_irq(int irq, void *dev_id)
 {
 	struct rkcanfd_priv *priv = dev_id;
@@ -775,6 +1153,17 @@ static void rkcanfd_register_done(const struct rkcanfd_priv *priv)
 			    RKCANFD_ERRATUM_5_SYSCLOCK_HZ_MIN / MEGA);
 }
 
+static void rk3576can_register_done(const struct rkcanfd_priv *priv)
+{
+	u32 dev_id;
+
+	dev_id = rkcanfd_read(priv, RK3576CAN_REG_RTL_VERSION);
+	netdev_info(priv->ndev,
+		    "Rockchip-CANFD %s rev%u. (errata 0x%04x) found\n",
+		    rkcanfd_get_model_str(priv), dev_id,
+		    priv->devtype_data.quirks);
+}
+
 static int rkcanfd_register(struct rkcanfd_priv *priv)
 {
 	struct net_device *ndev = priv->ndev;
@@ -856,6 +1245,19 @@ static const struct rkcanfd_devtype_data rkcanfd_devtype_data_rk3568v3 = {
 	.register_done = rkcanfd_register_done,
 };
 
+/* The rk3576 CAN-FD */
+static const struct rkcanfd_devtype_data rkcan_devtype_data_rk3576 = {
+	.model = RKCAN_MODEL_RK3576,
+	.get_berr_counter = rk3576can_get_berr_counter_corrected,
+	.interrupts_enable = rkcanfd_chip_interrupts_enable,
+	.interrupts_disable = rk3576can_chip_interrupts_disable,
+	.chip_start = rk3576can_chip_start,
+	.chip_stop = rk3576can_chip_stop,
+	.chip_stop_sync = rk3576can_chip_stop_sync,
+	.irq = rk3576can_irq,
+	.register_done = rk3576can_register_done,
+};
+
 static const struct of_device_id rkcanfd_of_match[] = {
 	{
 		.compatible = "rockchip,rk3568v2-canfd",
@@ -863,6 +1265,9 @@ static const struct of_device_id rkcanfd_of_match[] = {
 	}, {
 		.compatible = "rockchip,rk3568v3-canfd",
 		.data = &rkcanfd_devtype_data_rk3568v3,
+	},  {
+		.compatible = "rockchip,rk3576-can",
+		.data = &rkcan_devtype_data_rk3576,
 	}, {
 		/* sentinel */
 	},
diff --git a/drivers/net/can/rockchip/rockchip_canfd-rx.c b/drivers/net/can/rockchip/rockchip_canfd-rx.c
index 475c0409e215..6bc4b0185502 100644
--- a/drivers/net/can/rockchip/rockchip_canfd-rx.c
+++ b/drivers/net/can/rockchip/rockchip_canfd-rx.c
@@ -91,6 +91,47 @@ rkcanfd_fifo_header_to_cfd_header(const struct rkcanfd_priv *priv,
 	return len + cfd->len;
 }
 
+static unsigned int
+rk3576can_fifo_header_to_cfd_header(const struct rkcanfd_priv *priv,
+				    const struct rk3576can_fifo_header *header,
+				    struct canfd_frame *cfd)
+{
+	unsigned int len = sizeof(*cfd) - sizeof(cfd->data);
+	u8 dlc;
+
+	if (header->frameinfo & RK3576CAN_REG_RXFRD_FRAMEINFO_FRAME_FORMAT)
+		cfd->can_id = FIELD_GET(RKCANFD_REG_FD_ID_EFF, header->id) |
+			CAN_EFF_FLAG;
+	else
+		cfd->can_id = FIELD_GET(RKCANFD_REG_FD_ID_SFF, header->id);
+
+	dlc = FIELD_GET(RK3576CAN_REG_RXFRD_FRAMEINFO_DATA_LENGTH,
+			header->frameinfo);
+
+	/* CAN-FD */
+	if (header->frameinfo & RK3576CAN_REG_RXFRD_FRAMEINFO_FDF) {
+		cfd->len = can_fd_dlc2len(dlc);
+
+		/* The cfd is not allocated by alloc_canfd_skb(), so
+		 * set CANFD_FDF here.
+		 */
+		cfd->flags |= CANFD_FDF;
+
+		if (header->frameinfo & RK3576CAN_REG_RXFRD_FRAMEINFO_BRS)
+			cfd->flags |= CANFD_BRS;
+	} else {
+		cfd->len = can_cc_dlc2len(dlc);
+
+		if (header->frameinfo & RK3576CAN_REG_RXFRD_FRAMEINFO_RTR) {
+			cfd->can_id |= CAN_RTR_FLAG;
+
+			return len;
+		}
+	}
+
+	return len + cfd->len;
+}
+
 static int rkcanfd_rxstx_filter(struct rkcanfd_priv *priv,
 				const struct canfd_frame *cfd_rx, const u32 ts,
 				bool *tx_done)
@@ -198,6 +239,44 @@ rkcanfd_fifo_header_empty(const struct rkcanfd_fifo_header *header)
 		header->frameinfo == header->ts;
 }
 
+static int rk3576can_handle_rx_int_one(struct rkcanfd_priv *priv)
+{
+	struct net_device_stats *stats = &priv->ndev->stats;
+	struct canfd_frame cfd[1] = { }, *skb_cfd;
+	struct rk3576can_fifo_header header[1] = { };
+	struct sk_buff *skb;
+	unsigned int len;
+	int err;
+
+	/* read header into separate struct and convert it later */
+	rkcanfd_read_rep(priv, RKCANFD_REG_RX_FIFO_RDATA,
+			 header, sizeof(*header));
+	/* read data directly into cfd */
+	rkcanfd_read_rep(priv, RKCANFD_REG_RX_FIFO_RDATA,
+			 cfd->data, sizeof(cfd->data));
+
+	len = rk3576can_fifo_header_to_cfd_header(priv, header, cfd);
+
+	if (header->frameinfo & RK3576CAN_REG_RXFRD_FRAMEINFO_FDF)
+		skb = alloc_canfd_skb(priv->ndev, &skb_cfd);
+	else
+		skb = alloc_can_skb(priv->ndev, (struct can_frame **)&skb_cfd);
+
+	if (!skb) {
+		stats->rx_dropped++;
+
+		return 0;
+	}
+
+	memcpy(skb_cfd, cfd, len);
+
+	err = can_rx_offload_queue_tail(&priv->offload, skb);
+	if (err)
+		stats->rx_fifo_errors++;
+
+	return 0;
+}
+
 static int rkcanfd_handle_rx_int_one(struct rkcanfd_priv *priv)
 {
 	struct net_device_stats *stats = &priv->ndev->stats;
@@ -284,6 +363,15 @@ rkcanfd_rx_fifo_get_len(const struct rkcanfd_priv *priv)
 	return FIELD_GET(RKCANFD_REG_RX_FIFO_CTRL_RX_FIFO_CNT, reg);
 }
 
+static inline unsigned int
+rk3576can_rx_fifo_get_len(const struct rkcanfd_priv *priv)
+{
+	const u32 reg = rkcanfd_read(priv, RK3576CAN_REG_STR_STATE);
+	int val = FIELD_GET(RK3576CAN_REG_STR_STATE_INTM_LEFT_CNT, reg);
+
+	return DIV_ROUND_UP(val, RK3576CAN_REG_STR_STATE_INTM_LEFT_CNT_UNIT);
+}
+
 int rkcanfd_handle_rx_int(struct rkcanfd_priv *priv)
 {
 	unsigned int len;
@@ -297,3 +385,18 @@ int rkcanfd_handle_rx_int(struct rkcanfd_priv *priv)
 
 	return 0;
 }
+
+int rkcanfd_handle_rk3576_rx_int(struct rkcanfd_priv *priv)
+{
+	unsigned int len;
+	int err;
+
+	while ((len = rk3576can_rx_fifo_get_len(priv))) {
+		err = rk3576can_handle_rx_int_one(priv);
+		if (err)
+			return err;
+	}
+	rkcanfd_write(priv, RK3576CAN_REG_INT_MASK, priv->reg_int_mask_default);
+	return 0;
+}
+
diff --git a/drivers/net/can/rockchip/rockchip_canfd-tx.c b/drivers/net/can/rockchip/rockchip_canfd-tx.c
index 12200dcfd338..de2f673c31ed 100644
--- a/drivers/net/can/rockchip/rockchip_canfd-tx.c
+++ b/drivers/net/can/rockchip/rockchip_canfd-tx.c
@@ -165,3 +165,23 @@ void rkcanfd_handle_tx_done_one(struct rkcanfd_priv *priv, const u32 ts,
 							    frame_len_p);
 	stats->tx_packets++;
 }
+
+int rkcanfd_handle_rk3576_tx_int(struct rkcanfd_priv *priv)
+{
+	struct net_device_stats *stats = &priv->ndev->stats;
+	unsigned int tx_tail;
+	unsigned int frame_len = 0;
+
+	tx_tail = rkcanfd_get_tx_tail(priv);
+
+	stats->tx_bytes +=
+		can_rx_offload_get_echo_skb_queue_tail(&priv->offload,
+						       tx_tail, &frame_len);
+	stats->tx_packets++;
+	WRITE_ONCE(priv->tx_tail, priv->tx_tail + 1);
+	netif_subqueue_completed_wake(priv->ndev, 0, 1, frame_len,
+				      rkcanfd_get_effective_tx_free(priv),
+				      RKCANFD_TX_START_THRESHOLD);
+	return 0;
+}
+
diff --git a/drivers/net/can/rockchip/rockchip_canfd.h b/drivers/net/can/rockchip/rockchip_canfd.h
index 72f26b96add0..77c673cfea3b 100644
--- a/drivers/net/can/rockchip/rockchip_canfd.h
+++ b/drivers/net/can/rockchip/rockchip_canfd.h
@@ -287,6 +287,256 @@
 #define RKCANFD_REG_RX_FIFO_RDATA 0x400
 #define RKCANFD_REG_TXE_FIFO_RDATA 0x500
 
+#define RK3576CAN_REG_MODE 0x000
+#define RK3576CAN_REG_CMD 0x004
+
+#define RK3576CAN_REG_STATE 0x008
+#define RK3576CAN_REG_STATE_SLEEP_STATE BIT(5)
+#define RK3576CAN_REG_STATE_BUS_OFF_STATE BIT(4)
+#define RK3576CAN_REG_STATE_ERROR_WARNING_STATE BIT(3)
+#define RK3576CAN_REG_STATE_TX_PERIOD BIT(2)
+#define RK3576CAN_REG_STATE_RX_PERIOD BIT(1)
+#define RK3576CAN_REG_STATE_TX_BUFFER_FULL BIT(0)
+
+#define RK3576CAN_REG_INT 0x00c
+#define RK3576CAN_REG_INT_BUSOFF_RCY_INT BIT(19)
+#define RK3576CAN_REG_INT_ESM_WTM_INT BIT(18)
+#define RK3576CAN_REG_INT_ISM_WTM_INT BIT(17)
+#define RK3576CAN_REG_INT_BUSINT_INT BIT(16)
+#define RK3576CAN_REG_INT_RXSTR_TIMEOUT_INT BIT(15)
+#define RK3576CAN_REG_INT_MFI_TIMEOUT_INT BIT(14)
+#define RK3576CAN_REG_INT_MFI_INT BIT(13)
+#define RK3576CAN_REG_INT_AUTO_RETX_FAIL_INT BIT(12)
+#define RK3576CAN_REG_INT_WAKEUP_INT BIT(11)
+#define RK3576CAN_REG_INT_BUS_OFF_RECOVERY_INT BIT(10)
+#define RK3576CAN_REG_INT_BUS_OFF_INT BIT(9)
+#define RK3576CAN_REG_INT_RX_FIFO_OVERFLOW_INT BIT(8)
+#define RK3576CAN_REG_INT_RX_FIFO_FULL_INT BIT(7)
+#define RK3576CAN_REG_INT_ERROR_INT BIT(6)
+#define RK3576CAN_REG_INT_TX_ARBIT_FAIL_INT BIT(5)
+#define RK3576CAN_REG_INT_PASSIVE_ERROR_INT BIT(4)
+#define RK3576CAN_REG_INT_OVERLOAD_INT BIT(3)
+#define RK3576CAN_REG_INT_ERROR_WARNING_INT BIT(2)
+#define RK3576CAN_REG_INT_TX_FINISH_INT BIT(1)
+#define RK3576CAN_REG_INT_RX_FINISH_INT BIT(0)
+
+#define RK3576CAN_REG_INT_ALL \
+	(RK3576CAN_REG_INT_BUSOFF_RCY_INT | \
+	 RK3576CAN_REG_INT_ESM_WTM_INT | \
+	 RK3576CAN_REG_INT_ISM_WTM_INT | \
+	 RK3576CAN_REG_INT_BUSINT_INT | \
+	 RK3576CAN_REG_INT_RXSTR_TIMEOUT_INT | \
+	 RK3576CAN_REG_INT_MFI_TIMEOUT_INT | \
+	 RK3576CAN_REG_INT_MFI_INT | \
+	 RK3576CAN_REG_INT_AUTO_RETX_FAIL_INT | \
+	 RK3576CAN_REG_INT_WAKEUP_INT | \
+	 RK3576CAN_REG_INT_BUS_OFF_RECOVERY_INT | \
+	 RK3576CAN_REG_INT_BUS_OFF_INT | \
+	 RK3576CAN_REG_INT_RX_FIFO_OVERFLOW_INT | \
+	 RK3576CAN_REG_INT_RX_FIFO_FULL_INT | \
+	 RK3576CAN_REG_INT_ERROR_INT | \
+	 RK3576CAN_REG_INT_TX_ARBIT_FAIL_INT | \
+	 RK3576CAN_REG_INT_PASSIVE_ERROR_INT | \
+	 RK3576CAN_REG_INT_OVERLOAD_INT | \
+	 RK3576CAN_REG_INT_ERROR_WARNING_INT | \
+	 RK3576CAN_REG_INT_TX_FINISH_INT | \
+	 RK3576CAN_REG_INT_RX_FINISH_INT)
+
+#define RK3576CAN_REG_INT_ALL_ERROR \
+	(RK3576CAN_REG_INT_BUS_OFF_INT | \
+	 RK3576CAN_REG_INT_ERROR_INT | \
+	 RK3576CAN_REG_INT_PASSIVE_ERROR_INT | \
+	 RK3576CAN_REG_INT_ERROR_WARNING_INT)
+
+#define RK3576CAN_REG_INT_MASK 0x010
+
+#define RK3576CAN_REG_FD_NOMINAL_BITTIMING 0x100
+#define RK3576CAN_REG_FD_NOMINAL_BITTIMING_SAMPLE_MODE BIT(31)
+#define RK3576CAN_REG_FD_NOMINAL_BITTIMING_SJW GENMASK(30, 24)
+#define RK3576CAN_REG_FD_NOMINAL_BITTIMING_BRP GENMASK(23, 16)
+#define RK3576CAN_REG_FD_NOMINAL_BITTIMING_TSEG2 GENMASK(14, 8)
+#define RK3576CAN_REG_FD_NOMINAL_BITTIMING_TSEG1 GENMASK(7, 0)
+
+#define RK3576CAN_REG_FD_DATA_BITTIMING 0x104
+#define RK3576CAN_REG_FD_DATA_BITTIMING_BRS_TSEG1 GENMASK(31, 24)
+#define RK3576CAN_REG_FD_DATA_BITTIMING_BRS_MODE BIT(23)
+#define RK3576CAN_REG_FD_DATA_BITTIMING_ACKSLOT_SYNC_DIS BIT(22)
+#define RK3576CAN_REG_FD_DATA_BITTIMING_SJW GENMASK(20, 17)
+#define RK3576CAN_REG_FD_DATA_BITTIMING_BRP GENMASK(16, 9)
+#define RK3576CAN_REG_FD_DATA_BITTIMING_TSEG2 GENMASK(8, 5)
+#define RK3576CAN_REG_FD_DATA_BITTIMING_TSEG1 GENMASK(4, 0)
+
+#define RK3576CAN_REG_TRANSMIT_DELAY_COMPENSATION 0x108
+#define RK3576CAN_REG_TRANSMIT_DELAY_COMPENSATION_TDC_OFFSET GENMASK(6, 1)
+#define RK3576CAN_REG_TRANSMIT_DELAY_COMPENSATION_TDC_ENABLE BIT(0)
+
+#define RK3576CAN_REG_BRS_CFG 0x10c
+#define RK3576CAN_REG_BRS_CFG_TRIPLE_SYNC_MODE BIT(31)
+#define RK3576CAN_REG_BRS_CFG_SP2_DTSEG1 GENMASK(30, 26)
+#define RK3576CAN_REG_BRS_CFG_SP2_NTSEG1 GENMASK(25, 18)
+#define RK3576CAN_REG_BRS_CFG_SP1_DTSEG1 GENMASK(17, 13)
+#define RK3576CAN_REG_BRS_CFG_SP1_NTSEG1 GENMASK(12, 5)
+#define RK3576CAN_REG_BRS_CFG_RESYNC_MODE BIT(3)
+#define RK3576CAN_REG_BRS_CFG_BRS_POSSYNC_EN BIT(1)
+#define RK3576CAN_REG_BRS_CFG_BRS_NEGSYNC_EN BIT(0)
+
+#define RK3576CAN_REG_LOOP_CNT 0x110
+
+#define RK3576CAN_REG_DMA_CTRL 0x11c
+#define RK3576CAN_REG_DMA_CTRL_DMA_RX_EN BIT(9)
+#define RK3576CAN_REG_DMA_CTRL_DMA_THR GENMASK(8, 0)
+
+#define RK3576CAN_REG_FD_TXFRAMEINFO 0x200
+
+#define RK3576CAN_REG_FD_TXID 0x204
+#define RK3576CAN_REG_FD_ID_EFF GENMASK(28, 0)
+#define RK3576CAN_REG_FD_ID_SFF GENMASK(11, 0)
+
+#define RK3576CAN_REG_FD_TXDATA0 0x208
+#define RK3576CAN_REG_FD_TXDATA1 0x20c
+#define RK3576CAN_REG_FD_TXDATA2 0x210
+#define RK3576CAN_REG_FD_TXDATA3 0x214
+#define RK3576CAN_REG_FD_TXDATA4 0x218
+#define RK3576CAN_REG_FD_TXDATA5 0x21c
+#define RK3576CAN_REG_FD_TXDATA6 0x220
+#define RK3576CAN_REG_FD_TXDATA7 0x224
+#define RK3576CAN_REG_FD_TXDATA8 0x228
+#define RK3576CAN_REG_FD_TXDATA9 0x22c
+#define RK3576CAN_REG_FD_TXDATA10 0x230
+#define RK3576CAN_REG_FD_TXDATA11 0x234
+#define RK3576CAN_REG_FD_TXDATA12 0x238
+#define RK3576CAN_REG_FD_TXDATA13 0x23c
+#define RK3576CAN_REG_FD_TXDATA14 0x240
+#define RK3576CAN_REG_FD_TXDATA15 0x244
+
+#define RK3576CAN_REG_RXFRD 0x400
+#define RK3576CAN_REG_RXFRD_FRAMEINFO_FRAME_FORMAT BIT(23)
+#define RK3576CAN_REG_RXFRD_FRAMEINFO_RTR BIT(22)
+#define RK3576CAN_REG_RXFRD_FRAMEINFO_FDF BIT(21)
+#define RK3576CAN_REG_RXFRD_FRAMEINFO_BRS BIT(20)
+#define RK3576CAN_REG_RXFRD_FRAMEINFO_DATA_LENGTH GENMASK(27, 24)
+
+#define RK3576CAN_REG_STR_CTL 0x600
+#define RK3576CAN_REG_STR_CTL_STORAGE_TIMEOUT_MODE BIT(8)
+#define RK3576CAN_REG_STR_CTL_ESM_SEL_MASK GENMASK(7, 6)
+#define RK3576CAN_REG_STR_CTL_RX_STORAGE_RESET BIT(4)
+#define RK3576CAN_REG_STR_CTL_ISM_SEL GENMASK(3, 2)
+#define RK3576CAN_REG_STR_CTL_ISM_SEL_FLEXIBLE 0x0
+#define RK3576CAN_REG_STR_CTL_ISM_SEL_CAN_FIXED 0x1
+#define RK3576CAN_REG_STR_CTL_ISM_SEL_CANFD_FIXED 0x2
+#define RK3576CAN_REG_STR_CTL_EXT_STORAGE_MODE BIT(1)
+#define RK3576CAN_REG_STR_CTL_BUFFER_MODE_ENABLE BIT(0)
+
+#define RK3576CAN_REG_STR_STATE 0x604
+#define RK3576CAN_REG_STR_STATE_INTM_FRAME_CNT GENMASK(25, 17)
+#define RK3576CAN_REG_STR_STATE_INTM_LEFT_CNT GENMASK(16, 8)
+#define RK3576CAN_REG_STR_STATE_INTM_LEFT_CNT_UNIT 18
+#define RK3576CAN_REG_STR_STATE_EXTM_FULL BIT(3)
+#define RK3576CAN_REG_STR_STATE_EXTM_EMPTY BIT(2)
+#define RK3576CAN_REG_STR_STATE_INTM_FULL BIT(1)
+#define RK3576CAN_REG_STR_STATE_INTM_EMPTY BIT(0)
+
+#define RK3576CAN_REG_STR_TIMEOUT 0x608
+
+#define RK3576CAN_REG_STR_WTM 0x60c
+#define RK3576CAN_REG_ATF(n) (0x700 + ((n) << 2))
+#define RK3576CAN_REG_ATFM(n) (0x714 + ((n) << 2))
+#define RK3576CAN_REG_ATFM_MASK_SEL BIT(31)
+#define RK3576CAN_REG_ATFM_RTR_EN BIT(30)
+#define RK3576CAN_REG_ATFM_RTR BIT(29)
+#define RK3576CAN_REG_ATFM_MASK_SEL_MASK_MODE 0x0
+#define RK3576CAN_REG_ATFM_MASK_SEL_LIST_MODE 0x1
+#define RK3576CAN_REG_ATFM_ID GENMASK(28, 0)
+
+#define RK3576CAN_REG_ATF_DLC 0x728
+#define RK3576CAN_REG_ATF_DLC_ATF_DLC_MODE BIT(5)
+#define RK3576CAN_REG_ATF_DLC_ATF_DLC_EN BIT(4)
+#define RK3576CAN_REG_ATF_DLC_ATF_DLC GENMASK(3, 0)
+
+#define RK3576CAN_REG_ATF_CTL 0x72c
+#define RK3576CAN_REG_ATF_CTL_ATF_DIS(n) BIT(n)
+#define RK3576CAN_REG_ATF_CTL_ATF_DIS_ALL GENMASK(15, 0)
+
+#define RK3576CAN_REG_SPACE_CTRL 0x800
+
+#define RK3576CAN_REG_AUTO_RETX_CFG 0x808
+#define RK3576CAN_REG_AUTO_RETX_CFG_RETX_TIME_LIMIT GENMASK(18, 3)
+#define RK3576CAN_REG_AUTO_RETX_CFG_RETX_LIMIT_EN BIT(1)
+#define RK3576CAN_REG_AUTO_RETX_CFG_AUTO_RETX_EN BIT(0)
+
+#define RK3576CAN_REG_AUTO_RETX_STATE0 0x80c
+#define RK3576CAN_REG_AUTO_RETX_STATE0_AUTO_RETX_CNT GENMASK(15, 0)
+
+#define RK3576CAN_REG_AUTO_RETX_STATE1 0x810
+#define RK3576CAN_REG_OLF_CFG 0x814
+#define RK3576CAN_REG_RXINT_CTRL 0x818
+#define RK3576CAN_REG_RXINT_TIMEOUT 0x81c
+#define RK3576CAN_REG_OTHER_CFG 0x820
+#define RK3576CAN_REG_WAVE_FILTER_CFG 0x824
+#define RK3576CAN_REG_RBC_CFG 0x828
+#define RK3576CAN_REG_TXCRC_CFG 0x82c
+
+#define RK3576CAN_REG_BUSOFFRCY_CFG 0x830
+#define RK3576CAN_REG_BUSOFF_RCY_THR 0x834
+
+#define RK3576CAN_REG_ERROR_CODE 0x900
+#define RK3576CAN_REG_ERROR_MASK 0x904
+#define RK3576CAN_REG_ERROR_MASK_ACK_ERROR BIT(4)
+#define RK3576CAN_REG_ERROR_MASK_FORM_ERROR BIT(3)
+#define RK3576CAN_REG_ERROR_MASK_CRC_ERROR BIT(2)
+#define RK3576CAN_REG_ERROR_MASK_STUFF_ERROR BIT(1)
+#define RK3576CAN_REG_ERROR_MASK_BIT_ERROR BIT(0)
+
+#define RK3576CAN_REG_RXERRORCNT 0x910
+#define RK3576CAN_REG_TXERRORCNT 0x914
+#define RK3576CAN_REG_RX_RXSRAM_RDATA 0xc00
+#define RK3576CAN_REG_RTL_VERSION 0xf0c
+
+#define RK3576CAN_REG_ERROR_CODE_PHASE BIT(29)
+#define RK3576CAN_REG_ERROR_CODE_TYPE GENMASK(28, 26)
+#define RK3576CAN_REG_ERROR_CODE_TYPE_BIT 0x0
+#define RK3576CAN_REG_ERROR_CODE_TYPE_STUFF 0x1
+#define RK3576CAN_REG_ERROR_CODE_TYPE_FORM 0x2
+#define RK3576CAN_REG_ERROR_CODE_TYPE_ACK 0x3
+#define RK3576CAN_REG_ERROR_CODE_TYPE_CRC 0x4
+#define RK3576CAN_REG_ERROR_CODE_DIRECTION_RX BIT(25)
+#define RK3576CAN_REG_ERROR_CODE_TX GENMASK(24, 19)
+#define RK3576CAN_REG_ERROR_CODE_TX_ACK_EOF BIT(24)
+#define RK3576CAN_REG_ERROR_CODE_TX_CRC BIT(23)
+#define RK3576CAN_REG_ERROR_CODE_TX_STUFF_COUNT BIT(22)
+#define RK3576CAN_REG_ERROR_CODE_TX_DATA BIT(21)
+#define RK3576CAN_REG_ERROR_CODE_TX_SOF_DLC BIT(20)
+#define RK3576CAN_REG_ERROR_CODE_TX_IDLE BIT(19)
+#define RK3576CAN_REG_ERROR_CODE_RX GENMASK(18, 0)
+#define RK3576CAN_REG_ERROR_CODE_RX_ERROR BIT(18)
+#define RK3576CAN_REG_ERROR_CODE_RX_OVERLOAD BIT(17)
+#define RK3576CAN_REG_ERROR_CODE_RX_SPACE BIT(16)
+#define RK3576CAN_REG_ERROR_CODE_RX_EOF BIT(15)
+#define RK3576CAN_REG_ERROR_CODE_RX_ACK_LIM BIT(14)
+#define RK3576CAN_REG_ERROR_CODE_RX_ACK BIT(13)
+#define RK3576CAN_REG_ERROR_CODE_RX_CRC_LIM BIT(12)
+#define RK3576CAN_REG_ERROR_CODE_RX_CRC BIT(11)
+#define RK3576CAN_REG_ERROR_CODE_RX_STUFF_COUNT BIT(10)
+#define RK3576CAN_REG_ERROR_CODE_RX_DATA BIT(9)
+#define RK3576CAN_REG_ERROR_CODE_RX_DLC BIT(8)
+#define RK3576CAN_REG_ERROR_CODE_RX_BRS_ESI BIT(7)
+#define RK3576CAN_REG_ERROR_CODE_RX_RES BIT(6)
+#define RK3576CAN_REG_ERROR_CODE_RX_FDF BIT(5)
+#define RK3576CAN_REG_ERROR_CODE_RX_ID2_RTR BIT(4)
+#define RK3576CAN_REG_ERROR_CODE_RX_SOF_IDE BIT(3)
+#define RK3576CAN_REG_ERROR_CODE_RX_BUS_IDLE BIT(2)
+#define RK3576CAN_REG_ERROR_CODE_RX_BUS_INT BIT(1)
+#define RK3576CAN_REG_ERROR_CODE_RX_STOP BIT(0)
+
+#define RK3576CAN_ISM_WATERMASK_CAN 0x6c /* word */
+#define RK3576CAN_ISM_WATERMASK_CANFD 0x6c /* word */
+
+#define RK3576CAN_SRAM_MAX_DEPTH 256 /* word */
+
+#define RK3576CAN_CANFD_FILTER GENMASK(28, 0)
+
+#define RK3576CAN_CANFD_FIFO_CNT GENMASK(7, 0)
+
 #define DEVICE_NAME "rockchip_canfd"
 #define RKCANFD_NAPI_WEIGHT 32
 #define RKCANFD_TXFIFO_DEPTH 2
@@ -434,6 +684,7 @@
 enum rkcanfd_model {
 	RKCANFD_MODEL_RK3568V2 = 0x35682,
 	RKCANFD_MODEL_RK3568V3 = 0x35683,
+	RKCAN_MODEL_RK3576 = 0x3576,
 };
 
 struct rkcanfd_priv;
@@ -457,6 +708,11 @@ struct rkcanfd_fifo_header {
 	u32 ts;
 };
 
+struct rk3576can_fifo_header {
+	u32 frameinfo;
+	u32 id;
+};
+
 struct rkcanfd_stats {
 	struct u64_stats_sync syncp;
 
@@ -546,6 +802,8 @@ rkcanfd_get_tx_free(const struct rkcanfd_priv *priv)
 void rkcanfd_ethtool_init(struct rkcanfd_priv *priv);
 
 int rkcanfd_handle_rx_int(struct rkcanfd_priv *priv);
+int rkcanfd_handle_rk3576_tx_int(struct rkcanfd_priv *priv);
+int rkcanfd_handle_rk3576_rx_int(struct rkcanfd_priv *priv);
 
 void rkcanfd_skb_set_timestamp(const struct rkcanfd_priv *priv,
 			       struct sk_buff *skb, const u32 timestamp);
-- 
2.34.1



From zhangqing at rock-chips.com  Mon Nov 17 17:39:27 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Tue, 18 Nov 2025 09:39:27 +0800
Subject: [PATCH v10 1/3] dt-bindings: can: rockchip_canfd: add rk3576 CAN controller
In-Reply-To: <20251118013929.2697132-1-zhangqing@rock-chips.com>
References: <20251118013929.2697132-1-zhangqing@rock-chips.com>
Message-ID: <20251118013929.2697132-2-zhangqing@rock-chips.com>

Add documentation for the rockchip rk3576 CAN controller.

Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
Acked-by: Conor Dooley <conor.dooley at microchip.com>
---
 .../devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml  | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml b/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml
index a077c0330013..d63c8c8e3f45 100644
--- a/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml
+++ b/Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml
@@ -16,7 +16,9 @@ allOf:
 properties:
   compatible:
     oneOf:
-      - const: rockchip,rk3568v2-canfd
+      - enum:
+          - rockchip,rk3568v2-canfd
+          - rockchip,rk3576-can
       - items:
           - const: rockchip,rk3568v3-canfd
           - const: rockchip,rk3568v2-canfd
-- 
2.34.1



From michael.opdenacker at rootcommit.com  Mon Nov 17 21:27:15 2025
From: michael.opdenacker at rootcommit.com (Michael Opdenacker)
Date: Tue, 18 Nov 2025 05:27:15 +0000 (UTC)
Subject: [PATCH v2 1/2] dt-bindings: arm: rockchip: Add Asus Tinker Board
 3 and 3S
In-Reply-To: <e4cd11d0-463c-e707-5110-6b92899b1ba3@manjaro.org>
References: <e4cd11d0-463c-e707-5110-6b92899b1ba3@manjaro.org>
Message-ID: <0c224662-b3c2-4075-8b68-c0ae27421ba8@rootcommit.com>

Hi Dragan

On 11/15/25 01:52, Dragan Simic wrote:
> I'm sorry again for not mentioning it in my earlier responses,
> but shouldn't this addition be specified like below:
>
>       - description: Asus Tinker Board 3/3S
>         items:
>           - enum:
> 	   - asus,rk3566-tinker-board-3
>             - asus,rk3566-tinker-board-3s
>           - const: rockchip,rk3566
>
> ... because the introduced .dts files define the actual board DTs,
> by descending from the common .dtsi file, while they're compatible
> in the sense of the 3S board variant extending the 3 variant.

Actually, "make dtbs_check" fails if rk3566-tinker-board-3s.dts has:
compatible = "asus,rk3566-tinker-board-3s", 
"asus,rk3566-tinker-board-3", "rockchip,rk3566";

The failure is:
arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3s.dtb: / 
(asus,rk3566-tinker-board-3s): compatible: 'oneOf' conditional failed, 
one must be fixed:
 ? ? ['asus,rk3566-tinker-board-3s', 'asus,rk3566-tinker-board-3', 
'rockchip,rk3566'] is too long
 ? ? ['asus,rk3566-tinker-board-3s', 'asus,rk3566-tinker-board-3', 
'rockchip,rk3566'] is too short

If I understand correctly, to keep the?rk3566-tinker-board-3s.dts file 
as it is, you need Asus Tinker Board 3 and 3S to have two different 
descriptions as in V2:

- description: Asus Tinker Board 3 items: - const: 
asus,rk3566-tinker-board-3 - const: rockchip,rk3566 - description: Asus 
Tinker Board 3S items: - const: asus,rk3566-tinker-board-3s - const: 
asus,rk3566-tinker-board-3 - const: rockchip,rk3566

The other solution is to remove the "asus,rk3566-tinker-board-3" 
compatible from?rk3566-tinker-board-3s.dts, which is not a big deal in 
my opinion. In addition, if some code turns out to work only on 3 but 
not on 3S, though that's not expected if 3S is indeed a superset of 3, 
we won't be stuck.

I can submit a V3 along these lines.
Cheers
Michael.

-- 
Michael Opdenacker
Root Commit
Yocto Project and OpenEmbedded Training course - Learn by doing:
https://rootcommit.com/training/yocto/



From geraldogabriel at gmail.com  Mon Nov 17 23:17:25 2025
From: geraldogabriel at gmail.com (Geraldo Nascimento)
Date: Tue, 18 Nov 2025 04:17:25 -0300
Subject: [PATCH v2 0/4] PCI: rockchip: 5.0 GT/s speed may be dangerous
In-Reply-To: <e5d5c0dc-81d6-ae0e-7552-c2e4fb39bb0a@manjaro.org>
References: <e5d5c0dc-81d6-ae0e-7552-c2e4fb39bb0a@manjaro.org>
Message-ID: <aRwdhbt0AcLQ1LgF@geday>

On Tue, Nov 18, 2025 at 07:45:45AM +0100, Dragan Simic wrote:
> Technically, you shouldn't have included my Reviewed-by tags in some
> of the patches in the v2 of this series, because the patches were
> either modified significantly since I gave my Reviewed-by for them
> in the v1, or they were actually introduced in the v2.
> 
> However, I checked all four patches in the v2 again and everything
> is still fine, so just to make sure, please feel free to include for
> the entire series:
> 
> Reviewed-by: Dragan Simic <dsimic at manjaro.org>

Hi Dragan,

Oops, sorry about that, and thanks for calling me out on this matter.
I'll definitely bear this in mind for future submissions.

Glad it worked out in the end.

Regards,
Geraldo Nascimento


From dsimic at manjaro.org  Mon Nov 17 22:45:45 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Tue, 18 Nov 2025 07:45:45 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v2 0/4] =?utf-8?q?PCI=3A?==?utf-8?q?_rockchip=3A?=
 =?utf-8?q?_5=2E0?= GT/s speed may be dangerous
Message-ID: <e5d5c0dc-81d6-ae0e-7552-c2e4fb39bb0a@manjaro.org>

Hello Geraldo,

Thanks a lot for the v2!  Please, see some comments below.

On Monday, November 17, 2025 22:46 CET, Geraldo Nascimento <geraldogabriel at gmail.com> wrote:
> Dragan Simic already had warned me of potential issues with 5.0 GT/s
> speed operation in Rockchip PCIe. However, in recent interactions
> with Shawn Lin from Rockchip it came to my attention there's grave
> danger in the unknown errata regarding 5.0 GT/s operational speed
> of their PCIe core. Even if the odds are low, to contain any damage,
> let's cover the remaining corner-cases where the default would lead
> to 5.0 GT/s operation as well as add a comment to Root Complex driver
> core, documenting this danger. Furthermore, remove redundant
> declaration of max-link-speed from rk3399-nanopi-r4s.dtsi
> 
> Signed-off-by: Geraldo Nascimento <geraldogabriel at gmail.com>

As a note, Signed-off-by tags are redundant in cover letters, because
there's no source code in them that can actually be signed off.

> Changes in v2:
> - hard limit to 2.5 GT/s, not just warn
> - add Reported-by: and Reviewed-by: Dragan Simic
> - remove redundant declaration of max-link-speed from helios64 dts
> - fix Link: of helios64 patch
> - simplify RC mode comment
> - Link to v1: https://lore.kernel.org/all/aRhR79u5BPtRRFw3 at geday/

Technically, you shouldn't have included my Reviewed-by tags in some
of the patches in the v2 of this series, because the patches were
either modified significantly since I gave my Reviewed-by for them
in the v1, or they were actually introduced in the v2.

However, I checked all four patches in the v2 again and everything
is still fine, so just to make sure, please feel free to include for
the entire series:

Reviewed-by: Dragan Simic <dsimic at manjaro.org>

> Geraldo Nascimento (4):
>   PCI: rockchip: limit RK3399 to 2.5 GT/s to prevent damage
>   PCI: rockchip-host: comment danger of 5.0 GT/s speed
>   arm64: dts: rockchip: remove dangerous max-link-speed from helios64
>   arm64: dts: rockchip: remove redundant max-link-speed from nanopi-r4s
> 
>  arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts |  1 -
>  arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dtsi    |  1 -
>  drivers/pci/controller/pcie-rockchip-host.c            |  3 +++
>  drivers/pci/controller/pcie-rockchip.c                 | 10 ++++++++--
>  4 files changed, 11 insertions(+), 4 deletions(-)




From mripard at kernel.org  Tue Nov 18 00:46:04 2025
From: mripard at kernel.org (Maxime Ripard)
Date: Tue, 18 Nov 2025 09:46:04 +0100
Subject: [PATCH v2 2/3] drm/bridge: dw-hdmi-qp: Add support for missing
 HPD
In-Reply-To: <20251113192939.30031-3-macroalpha82@gmail.com>
References: <20251113192939.30031-1-macroalpha82@gmail.com>
 <20251113192939.30031-3-macroalpha82@gmail.com>
Message-ID: <avdnpwnxs6cql7eyckdt37szpcf5ztgxlc7juwu6tqj5xxu56a@nrwljig2p67i>

Hi,

On Thu, Nov 13, 2025 at 01:29:38PM -0600, Chris Morgan wrote:
> From: Chris Morgan <macromorgan at hotmail.com>
> 
> Add support for the dw-hdmi-qp driver to handle devices with missing
> HPD pins.
> 
> Since in this situation we are now polling for the EDID data via i2c
> change the error message to a debug message when we are unable to
> complete an i2c read, as a disconnected device would otherwise fill
> dmesg with i2c read errors.
> 
> Signed-off-by: Chris Morgan <macromorgan at hotmail.com>

You must also disable any mode using the scrambler when there's no
hotplug interrupt available.

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 273 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251118/9de1571e/attachment.sig>

From neil.armstrong at linaro.org  Tue Nov 18 01:08:09 2025
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Tue, 18 Nov 2025 10:08:09 +0100
Subject: [PATCH v9 06/10] phy: rockchip: phy-rockchip-typec: Add DRM AUX
 bridge
In-Reply-To: <20251111105040.94-7-kernel@airkyi.com>
References: <20251111105040.94-1-kernel@airkyi.com>
 <20251111105040.94-7-kernel@airkyi.com>
Message-ID: <7ca46d0d-d235-421e-95cb-901efb856b0c@linaro.org>

On 11/11/25 11:50, Chaoyi Chen wrote:
> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> 
> Using the DRM_AUX_BRIDGE helper to create the transparent DRM bridge
> device.
> 
> Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> ---
> 
> (no changes since v7)
> 
> Changes in v6:
> - Fix depend in Kconfig.
> 
>   drivers/phy/rockchip/Kconfig              |  2 +
>   drivers/phy/rockchip/phy-rockchip-typec.c | 52 +++++++++++++++++++++++
>   2 files changed, 54 insertions(+)
> 
> diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
> index db4adc7c53da..bcb5476222fc 100644
> --- a/drivers/phy/rockchip/Kconfig
> +++ b/drivers/phy/rockchip/Kconfig
> @@ -120,6 +120,8 @@ config PHY_ROCKCHIP_TYPEC
>   	tristate "Rockchip TYPEC PHY Driver"
>   	depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST)
>   	depends on TYPEC || TYPEC=n
> +	depends on DRM || DRM=n
> +	select DRM_AUX_BRIDGE if DRM_BRIDGE
>   	select EXTCON
>   	select GENERIC_PHY
>   	select RESET_CONTROLLER
> diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c
> index 1f5b4142cbe4..748a6eb8ad95 100644
> --- a/drivers/phy/rockchip/phy-rockchip-typec.c
> +++ b/drivers/phy/rockchip/phy-rockchip-typec.c
> @@ -36,6 +36,7 @@
>    * orientation, false is normal orientation.
>    */
>   
> +#include <linux/auxiliary_bus.h>
>   #include <linux/clk.h>
>   #include <linux/clk-provider.h>
>   #include <linux/delay.h>
> @@ -56,6 +57,7 @@
>   #include <linux/phy/phy.h>
>   #include <linux/usb/typec_dp.h>
>   #include <linux/usb/typec_mux.h>
> +#include <drm/bridge/aux-bridge.h>
>   
>   #define CMN_SSM_BANDGAP			(0x21 << 2)
>   #define CMN_SSM_BIAS			(0x22 << 2)
> @@ -415,6 +417,7 @@ struct rockchip_usb3phy_port_cfg {
>   
>   struct rockchip_typec_phy {
>   	struct device *dev;
> +	struct auxiliary_device dp_port_dev;
>   	void __iomem *base;
>   	struct extcon_dev *extcon;
>   	struct typec_mux_dev *mux;
> @@ -1299,6 +1302,51 @@ static void tcphy_typec_mux_unregister(void *data)
>   	typec_mux_unregister(tcphy->mux);
>   }
>   
> +static void tcphy_dp_port_dev_release(struct device *dev)
> +{
> +	struct auxiliary_device *adev = to_auxiliary_dev(dev);
> +
> +	of_node_put(adev->dev.of_node);
> +}
> +
> +static void tcphy_dp_port_unregister_adev(void *_adev)
> +{
> +	struct auxiliary_device *adev = _adev;
> +
> +	auxiliary_device_delete(adev);
> +	auxiliary_device_uninit(adev);
> +}
> +
> +static int tcphy_aux_bridge_register(struct rockchip_typec_phy *tcphy, struct device_node *np)
> +{
> +	struct auxiliary_device *adev = &tcphy->dp_port_dev;
> +	int ret;
> +
> +	adev->name = "dp_port";
> +	adev->dev.parent = tcphy->dev;
> +	adev->dev.of_node = of_node_get(np);
> +	adev->dev.release = tcphy_dp_port_dev_release;
> +
> +	ret = auxiliary_device_init(adev);
> +

Drop this empty line.

> +	if (ret) {
> +		of_node_put(adev->dev.of_node);
> +		return ret;
> +	}
> +
> +	ret = auxiliary_device_add(adev);
> +	if (ret) {
> +		auxiliary_device_uninit(adev);
> +		return ret;
> +	}
> +
> +	devm_add_action_or_reset(tcphy->dev, tcphy_dp_port_unregister_adev, adev);
> +
> +	ret = drm_aux_bridge_register(&adev->dev);

Adding an aux device to an aux device looks quite overengineered to me !

If it's a matter of using the proper of_node, you may instead create a separate
drm_aux_bridge_register() like drm_aux_bridge_register_from_node() instead.

Neil

> +
> +	return 0;
> +}
> +
>   static int tcphy_setup_typec_mux(struct rockchip_typec_phy *tcphy)
>   {
>   	struct typec_mux_desc mux_desc = {};
> @@ -1312,6 +1360,10 @@ static int tcphy_setup_typec_mux(struct rockchip_typec_phy *tcphy)
>   	if (!of_property_read_bool(np, "mode-switch"))
>   		goto put_np;
>   
> +	ret = tcphy_aux_bridge_register(tcphy, np);
> +	if (ret)
> +		goto put_np;
> +
>   	mux_desc.drvdata = tcphy;
>   	mux_desc.fwnode = device_get_named_child_node(tcphy->dev, "dp-port");
>   	mux_desc.set = tcphy_typec_mux_set;



From neil.armstrong at linaro.org  Tue Nov 18 01:12:48 2025
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Tue, 18 Nov 2025 10:12:48 +0100
Subject: [PATCH] phy: rockchip: naneng-combphy: Fix PCIe L1ss support
In-Reply-To: <1763004478-218446-1-git-send-email-shawn.lin@rock-chips.com>
References: <1763004478-218446-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <70a23bf8-6648-489e-908f-d7727f5cccd3@linaro.org>

On 11/13/25 04:27, Shawn Lin wrote:
> Need to control the delay PLL turnoff time if PCIe works on
> L1 PM substates.

Can you elaborate ?

> 
> Fixes: f13bff25161b ("phy: rockchip-naneng-combo: Support rk3562")
> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
> ---
> 
>   drivers/phy/rockchip/phy-rockchip-naneng-combphy.c | 9 +++++++++
>   1 file changed, 9 insertions(+)
> 
> diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
> index af9a5c7..5b6f80e 100644
> --- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
> +++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
> @@ -106,6 +106,10 @@
>   #define RK3568_PHYREG18				0x44
>   #define RK3568_PHYREG18_PLL_LOOP		0x32
>   
> +#define RK3568_PHYREG30				0x74
> +#define RK3568_PHYREG30_GATE_TX_PCK_SEL         BIT(7)
> +#define RK3568_PHYREG30_GATE_TX_PCK_DLY_PLL_OFF BIT(7)
> +
>   #define RK3568_PHYREG32				0x7C
>   #define RK3568_PHYREG32_SSC_MASK		GENMASK(7, 4)
>   #define RK3568_PHYREG32_SSC_DIR_MASK		GENMASK(5, 4)
> @@ -665,6 +669,11 @@ static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv)
>   	case REF_CLOCK_100MHz:
>   		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
>   		if (priv->type == PHY_TYPE_PCIE) {
> +			/* Gate_tx_pck_sel length select for L1ss support */
> +			rockchip_combphy_updatel(priv, RK3568_PHYREG30_GATE_TX_PCK_SEL,
> +						 RK3568_PHYREG30_GATE_TX_PCK_DLY_PLL_OFF,
> +						 RK3568_PHYREG30);
> +
>   			/* PLL KVCO tuning fine */
>   			val = FIELD_PREP(RK3568_PHYREG33_PLL_KVCO_MASK,
>   					 RK3568_PHYREG33_PLL_KVCO_VALUE);

Please use proper patch versioning when sending a new version, with a proper
changelog.

Neil


From chaoyi.chen at rock-chips.com  Tue Nov 18 01:37:39 2025
From: chaoyi.chen at rock-chips.com (Chaoyi Chen)
Date: Tue, 18 Nov 2025 17:37:39 +0800
Subject: [PATCH v9 06/10] phy: rockchip: phy-rockchip-typec: Add DRM AUX
 bridge
In-Reply-To: <7ca46d0d-d235-421e-95cb-901efb856b0c@linaro.org>
References: <20251111105040.94-1-kernel@airkyi.com>
 <20251111105040.94-7-kernel@airkyi.com>
 <7ca46d0d-d235-421e-95cb-901efb856b0c@linaro.org>
Message-ID: <525040d5-84db-4de1-aed0-3b4b5a672f8b@rock-chips.com>

Hi Neil,

On 11/18/2025 5:08 PM, Neil Armstrong wrote:
> On 11/11/25 11:50, Chaoyi Chen wrote:
>> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
>>
>> Using the DRM_AUX_BRIDGE helper to create the transparent DRM bridge
>> device.
>>
>> Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
>> ---
>>
>> (no changes since v7)
>>
>> Changes in v6:
>> - Fix depend in Kconfig.
>>
>> ? drivers/phy/rockchip/Kconfig????????????? |? 2 +
>> ? drivers/phy/rockchip/phy-rockchip-typec.c | 52 +++++++++++++++++++++++
>> ? 2 files changed, 54 insertions(+)
>>
>> diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
>> index db4adc7c53da..bcb5476222fc 100644
>> --- a/drivers/phy/rockchip/Kconfig
>> +++ b/drivers/phy/rockchip/Kconfig
>> @@ -120,6 +120,8 @@ config PHY_ROCKCHIP_TYPEC
>> ????? tristate "Rockchip TYPEC PHY Driver"
>> ????? depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST)
>> ????? depends on TYPEC || TYPEC=n
>> +??? depends on DRM || DRM=n
>> +??? select DRM_AUX_BRIDGE if DRM_BRIDGE
>> ????? select EXTCON
>> ????? select GENERIC_PHY
>> ????? select RESET_CONTROLLER
>> diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c
>> index 1f5b4142cbe4..748a6eb8ad95 100644
>> --- a/drivers/phy/rockchip/phy-rockchip-typec.c
>> +++ b/drivers/phy/rockchip/phy-rockchip-typec.c
>> @@ -36,6 +36,7 @@
>> ?? * orientation, false is normal orientation.
>> ?? */
>> ? +#include <linux/auxiliary_bus.h>
>> ? #include <linux/clk.h>
>> ? #include <linux/clk-provider.h>
>> ? #include <linux/delay.h>
>> @@ -56,6 +57,7 @@
>> ? #include <linux/phy/phy.h>
>> ? #include <linux/usb/typec_dp.h>
>> ? #include <linux/usb/typec_mux.h>
>> +#include <drm/bridge/aux-bridge.h>
>> ? ? #define CMN_SSM_BANDGAP??????????? (0x21 << 2)
>> ? #define CMN_SSM_BIAS??????????? (0x22 << 2)
>> @@ -415,6 +417,7 @@ struct rockchip_usb3phy_port_cfg {
>> ? ? struct rockchip_typec_phy {
>> ????? struct device *dev;
>> +??? struct auxiliary_device dp_port_dev;
>> ????? void __iomem *base;
>> ????? struct extcon_dev *extcon;
>> ????? struct typec_mux_dev *mux;
>> @@ -1299,6 +1302,51 @@ static void tcphy_typec_mux_unregister(void *data)
>> ????? typec_mux_unregister(tcphy->mux);
>> ? }
>> ? +static void tcphy_dp_port_dev_release(struct device *dev)
>> +{
>> +??? struct auxiliary_device *adev = to_auxiliary_dev(dev);
>> +
>> +??? of_node_put(adev->dev.of_node);
>> +}
>> +
>> +static void tcphy_dp_port_unregister_adev(void *_adev)
>> +{
>> +??? struct auxiliary_device *adev = _adev;
>> +
>> +??? auxiliary_device_delete(adev);
>> +??? auxiliary_device_uninit(adev);
>> +}
>> +
>> +static int tcphy_aux_bridge_register(struct rockchip_typec_phy *tcphy, struct device_node *np)
>> +{
>> +??? struct auxiliary_device *adev = &tcphy->dp_port_dev;
>> +??? int ret;
>> +
>> +??? adev->name = "dp_port";
>> +??? adev->dev.parent = tcphy->dev;
>> +??? adev->dev.of_node = of_node_get(np);
>> +??? adev->dev.release = tcphy_dp_port_dev_release;
>> +
>> +??? ret = auxiliary_device_init(adev);
>> +
>
> Drop this empty line.

>
>> +??? if (ret) {
>> +??????? of_node_put(adev->dev.of_node);
>> +??????? return ret;
>> +??? }
>> +
>> +??? ret = auxiliary_device_add(adev);
>> +??? if (ret) {
>> +??????? auxiliary_device_uninit(adev);
>> +??????? return ret;
>> +??? }
>> +
>> +??? devm_add_action_or_reset(tcphy->dev, tcphy_dp_port_unregister_adev, adev);
>> +
>> +??? ret = drm_aux_bridge_register(&adev->dev);
>
> Adding an aux device to an aux device looks quite overengineered to me !
>
> If it's a matter of using the proper of_node, you may instead create a separate
> drm_aux_bridge_register() like drm_aux_bridge_register_from_node() instead.

Yes, as you said, the aux device here is only to let the drm_aux_bridge get the correct of_node. I will add the API you mentioned in v10. Thank you.


-- 
Best,
Chaoyi



From shawn.lin at rock-chips.com  Tue Nov 18 01:52:05 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Tue, 18 Nov 2025 17:52:05 +0800
Subject: [PATCH v2 1/2] phy: rockchip: naneng-combphy: Fix PCIe L1ss support RK3528
Message-ID: <1763459526-35004-1-git-send-email-shawn.lin@rock-chips.com>

When PCIe link enters L1 PM substates, the PHY will turn off its
PLL for power-saving. However, it turns off the PLL too fast which
leads the PHY to be broken. According to the PHY document, we need
to delay PLL turnoff time.

Fixes: bbcca4fac873 ("phy: rockchip: naneng-combphy: Add RK3528 support")
Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
---

Changes in v2:
- add more commit message

 drivers/phy/rockchip/phy-rockchip-naneng-combphy.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
index a3ef198..e303bec 100644
--- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
+++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
@@ -21,6 +21,9 @@
 #define REF_CLOCK_100MHz		(100 * HZ_PER_MHZ)
 
 /* RK3528 COMBO PHY REG */
+#define RK3528_PHYREG5				0x14
+#define RK3528_PHYREG5_GATE_TX_PCK_SEL		BIT(3)
+#define RK3528_PHYREG5_GATE_TX_PCK_DLY_PLL_OFF	BIT(3)
 #define RK3528_PHYREG6				0x18
 #define RK3528_PHYREG6_PLL_KVCO			GENMASK(12, 10)
 #define RK3528_PHYREG6_PLL_KVCO_VALUE		0x2
@@ -504,6 +507,10 @@ static int rk3528_combphy_cfg(struct rockchip_combphy_priv *priv)
 	case REF_CLOCK_100MHz:
 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
 		if (priv->type == PHY_TYPE_PCIE) {
+			/* Gate_tx_pck_sel length select for L1ss support */
+			rockchip_combphy_updatel(priv, RK3528_PHYREG5_GATE_TX_PCK_SEL,
+						 RK3528_PHYREG5_GATE_TX_PCK_DLY_PLL_OFF, RK3528_PHYREG5);
+
 			/* PLL KVCO tuning fine */
 			val = FIELD_PREP(RK3528_PHYREG6_PLL_KVCO, RK3528_PHYREG6_PLL_KVCO_VALUE);
 			rockchip_combphy_updatel(priv, RK3528_PHYREG6_PLL_KVCO, val,
-- 
2.7.4



From shawn.lin at rock-chips.com  Tue Nov 18 01:52:06 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Tue, 18 Nov 2025 17:52:06 +0800
Subject: [PATCH v2 2/2] phy: rockchip: naneng-combphy: Fix PCIe L1ss support RK3562
In-Reply-To: <1763459526-35004-1-git-send-email-shawn.lin@rock-chips.com>
References: <1763459526-35004-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1763459526-35004-2-git-send-email-shawn.lin@rock-chips.com>

When PCIe link enters L1 PM substates, the PHY will turn off its
PLL for power-saving. However, it turns off the PLL too fast which
leads the PHY to be broken. According to the PHY document, we need
to delay PLL turnoff time.

Fixes: f13bff25161b ("phy: rockchip-naneng-combo: Support rk3562")
Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
---

Changes in v2:
- add more commit message

 drivers/phy/rockchip/phy-rockchip-naneng-combphy.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
index e303bec..7f8fc8e 100644
--- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
+++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
@@ -106,6 +106,10 @@
 #define RK3568_PHYREG18				0x44
 #define RK3568_PHYREG18_PLL_LOOP		0x32
 
+#define RK3568_PHYREG30				0x74
+#define RK3568_PHYREG30_GATE_TX_PCK_SEL         BIT(7)
+#define RK3568_PHYREG30_GATE_TX_PCK_DLY_PLL_OFF BIT(7)
+
 #define RK3568_PHYREG32				0x7C
 #define RK3568_PHYREG32_SSC_MASK		GENMASK(7, 4)
 #define RK3568_PHYREG32_SSC_DIR_MASK		GENMASK(5, 4)
@@ -664,6 +668,10 @@ static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv)
 	case REF_CLOCK_100MHz:
 		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
 		if (priv->type == PHY_TYPE_PCIE) {
+			/* Gate_tx_pck_sel length select for L1ss support */
+			rockchip_combphy_updatel(priv, RK3568_PHYREG30_GATE_TX_PCK_SEL,
+						 RK3568_PHYREG30_GATE_TX_PCK_DLY_PLL_OFF,
+						 RK3568_PHYREG30);
 			/* PLL KVCO tuning fine */
 			val = FIELD_PREP(RK3568_PHYREG33_PLL_KVCO_MASK,
 					 RK3568_PHYREG33_PLL_KVCO_VALUE);
-- 
2.7.4



From louisalexis.eyraud at collabora.com  Tue Nov 18 02:24:22 2025
From: louisalexis.eyraud at collabora.com (Louis-Alexis Eyraud)
Date: Tue, 18 Nov 2025 11:24:22 +0100
Subject: [PATCH v2 RESEND 4/9] phy: mediatek: phy-mtk-hdmi-mt8195:
 convert from round_rate() to determine_rate()
In-Reply-To: <20251106-phy-clk-route-rate-v2-resend-v1-4-e2058963bfb1@redhat.com>
References: <20251106-phy-clk-route-rate-v2-resend-v1-0-e2058963bfb1@redhat.com>
	 <20251106-phy-clk-route-rate-v2-resend-v1-4-e2058963bfb1@redhat.com>
Message-ID: <815d7300e19db00f84091f0925b2e509c4453fa0.camel@collabora.com>

Hi,

On Thu, 2025-11-06 at 18:25 -0500, Brian Masney wrote:
> The round_rate() clk ops is deprecated, so migrate this driver from
> round_rate() to determine_rate() using the Coccinelle semantic patch
> on the cover letter of this series.
> 
> Signed-off-by: Brian Masney <bmasney at redhat.com>
> ---
> ?drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c | 10 +++++-----
> ?1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
> b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
> index
> b38f3ae26b3f3d8c9e73b43d86510acf6cedb471..1426a2db984d53b91125b18f772
> 5738c44f19555 100644
> --- a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
> +++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
> @@ -418,13 +418,13 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw
> *hw, unsigned long rate,
> ?	return mtk_hdmi_pll_calc(hdmi_phy, hw, rate, parent_rate);
> ?}
> ?
> -static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long
> rate,
> -				??? unsigned long *parent_rate)
> +static int mtk_hdmi_pll_determine_rate(struct clk_hw *hw,
> +				?????? struct clk_rate_request *req)
> ?{
> ?	struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
> ?
> -	hdmi_phy->pll_rate = rate;
> -	return rate;
> +	hdmi_phy->pll_rate = req->rate;
> +	return 0;
> ?}
> ?
> ?static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
> @@ -439,7 +439,7 @@ static const struct clk_ops mtk_hdmi_pll_ops = {
> ?	.prepare = mtk_hdmi_pll_prepare,
> ?	.unprepare = mtk_hdmi_pll_unprepare,
> ?	.set_rate = mtk_hdmi_pll_set_rate,
> -	.round_rate = mtk_hdmi_pll_round_rate,
> +	.determine_rate = mtk_hdmi_pll_determine_rate,
> ?	.recalc_rate = mtk_hdmi_pll_recalc_rate,
> ?};
> ?
Tested OK on Mediatek Genio 510-EVK (MT8370) and Genio 1200-EVK
(MT8395) boards.

Tested-by: Louis-Alexis Eyraud <louisalexis.eyraud at collabora.com>

Regards,
Louis-Alexis


From devnull+michael.riesch.collabora.com at kernel.org  Tue Nov 18 03:12:27 2025
From: devnull+michael.riesch.collabora.com at kernel.org (Michael Riesch via B4 Relay)
Date: Tue, 18 Nov 2025 12:12:27 +0100
Subject: [PATCH v2 3/3] arm64: defconfig: enable rockchip mipi csi-2
 receiver
In-Reply-To: <20251114-rockchip-mipi-receiver-v2-0-eb9b43377fc4@collabora.com>
References: <20251114-rockchip-mipi-receiver-v2-0-eb9b43377fc4@collabora.com>
Message-ID: <20251114-rockchip-mipi-receiver-v2-3-eb9b43377fc4@collabora.com>

From: Michael Riesch <michael.riesch at collabora.com>

The Rockchip MIPI CSI-2 Receiver is integrated into recent Rockchip
SoCs, such as the RK3568 and the RK3588.
Enable the driver for it in the default configuration.

Signed-off-by: Michael Riesch <michael.riesch at collabora.com>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index e3a2d37bd104..a161666f2894 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -883,6 +883,7 @@ CONFIG_VIDEO_RENESAS_FCP=m
 CONFIG_VIDEO_RENESAS_FDP1=m
 CONFIG_VIDEO_RENESAS_VSP1=m
 CONFIG_VIDEO_RCAR_DRIF=m
+CONFIG_VIDEO_ROCKCHIP_CSI=m
 CONFIG_VIDEO_ROCKCHIP_RGA=m
 CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=m
 CONFIG_VIDEO_SAMSUNG_S5P_JPEG=m

-- 
2.39.5




From devnull+michael.riesch.collabora.com at kernel.org  Tue Nov 18 03:12:25 2025
From: devnull+michael.riesch.collabora.com at kernel.org (Michael Riesch via B4 Relay)
Date: Tue, 18 Nov 2025 12:12:25 +0100
Subject: [PATCH v2 1/3] media: dt-bindings: add rockchip mipi csi-2
 receiver
In-Reply-To: <20251114-rockchip-mipi-receiver-v2-0-eb9b43377fc4@collabora.com>
References: <20251114-rockchip-mipi-receiver-v2-0-eb9b43377fc4@collabora.com>
Message-ID: <20251114-rockchip-mipi-receiver-v2-1-eb9b43377fc4@collabora.com>

From: Michael Riesch <michael.riesch at collabora.com>

Add documentation for the Rockchip MIPI CSI-2 Receiver.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
Reviewed-by: Rob Herring (Arm) <robh at kernel.org>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
Signed-off-by: Michael Riesch <michael.riesch at collabora.com>
---
 .../bindings/media/rockchip,rk3568-mipi-csi.yaml   | 146 +++++++++++++++++++++
 MAINTAINERS                                        |   6 +
 2 files changed, 152 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/rockchip,rk3568-mipi-csi.yaml b/Documentation/devicetree/bindings/media/rockchip,rk3568-mipi-csi.yaml
new file mode 100644
index 000000000000..52fe959af8f9
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/rockchip,rk3568-mipi-csi.yaml
@@ -0,0 +1,146 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/rockchip,rk3568-mipi-csi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip MIPI CSI-2 Receiver
+
+maintainers:
+  - Michael Riesch <michael.riesch at collabora.com>
+
+description:
+  The Rockchip MIPI CSI-2 Receiver is a CSI-2 bridge with one input port and
+  one output port. It receives the data with the help of an external MIPI PHY
+  (C-PHY or D-PHY) and passes it to the Rockchip RK3568 Video Capture (VICAP)
+  block.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - rockchip,rk3588-mipi-csi
+          - const: rockchip,rk3568-mipi-csi
+      - const: rockchip,rk3568-mipi-csi
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    items:
+      - description: Interrupt that signals changes in CSI2HOST_ERR1.
+      - description: Interrupt that signals changes in CSI2HOST_ERR2.
+
+  interrupt-names:
+    items:
+      - const: err1
+      - const: err2
+
+  clocks:
+    maxItems: 1
+
+  phys:
+    maxItems: 1
+    description: MIPI C-PHY or D-PHY.
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port at 0:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description: Input port node. Connect to e.g., a MIPI CSI-2 image sensor.
+
+        properties:
+          endpoint:
+            $ref: video-interfaces.yaml#
+            unevaluatedProperties: false
+
+            properties:
+              bus-type:
+                enum:
+                  - 1 # MEDIA_BUS_TYPE_CSI2_CPHY
+                  - 4 # MEDIA_BUS_TYPE_CSI2_DPHY
+
+              data-lanes:
+                minItems: 1
+                maxItems: 4
+
+            required:
+              - bus-type
+              - data-lanes
+
+      port at 1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: Output port connected to a RK3568 VICAP port.
+
+    required:
+      - port at 0
+      - port at 1
+
+  power-domains:
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - phys
+  - ports
+  - power-domains
+  - resets
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/rk3568-cru.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/media/video-interfaces.h>
+    #include <dt-bindings/power/rk3568-power.h>
+
+    soc {
+        interrupt-parent = <&gic>;
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        csi: csi at fdfb0000 {
+            compatible = "rockchip,rk3568-mipi-csi";
+            reg = <0x0 0xfdfb0000 0x0 0x10000>;
+            interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+                         <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+            interrupt-names = "err1", "err2";
+            clocks = <&cru PCLK_CSI2HOST1>;
+            phys = <&csi_dphy>;
+            power-domains = <&power RK3568_PD_VI>;
+            resets = <&cru SRST_P_CSI2HOST1>;
+
+            ports {
+                #address-cells = <1>;
+                #size-cells = <0>;
+
+                csi_in: port at 0 {
+                    reg = <0>;
+
+                    csi_input: endpoint {
+                        bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>;
+                        data-lanes = <1 2 3 4>;
+                        remote-endpoint = <&imx415_output>;
+                    };
+                };
+
+                csi_out: port at 1 {
+                    reg = <1>;
+
+                    csi_output: endpoint {
+                        remote-endpoint = <&vicap_mipi_input>;
+                    };
+                };
+            };
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 4205ca007e07..145473671a4a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22299,6 +22299,12 @@ F:	Documentation/userspace-api/media/v4l/metafmt-rkisp1.rst
 F:	drivers/media/platform/rockchip/rkisp1
 F:	include/uapi/linux/rkisp1-config.h
 
+ROCKCHIP MIPI CSI-2 RECEIVER DRIVER
+M:	Michael Riesch <michael.riesch at collabora.com>
+L:	linux-media at vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/media/rockchip,rk3568-mipi-csi.yaml
+
 ROCKCHIP RK3568 RANDOM NUMBER GENERATOR SUPPORT
 M:	Daniel Golle <daniel at makrotopia.org>
 M:	Aurelien Jarno <aurelien at aurel32.net>

-- 
2.39.5




From devnull+michael.riesch.collabora.com at kernel.org  Tue Nov 18 03:12:24 2025
From: devnull+michael.riesch.collabora.com at kernel.org (Michael Riesch via B4 Relay)
Date: Tue, 18 Nov 2025 12:12:24 +0100
Subject: [PATCH v2 0/3] media: rockchip: add driver for the rockchip mipi
 csi-2 receiver
Message-ID: <20251114-rockchip-mipi-receiver-v2-0-eb9b43377fc4@collabora.com>

Habidere,

This series adds support for the Rockchip MIPI CSI-2 Receiver that is
integrated into recent Rockchip SoCs, such as the RK3568 and the RK3588.

These changes have been discussed and reviewed thoroughly in roughly 10
iterations of the rkcif patch series (see [0] and predecessors). Thus,
they should be ready for inclusion in mainline.

However, as has been discussed in [0], it would be beneficial to add
support for the split mode (a feature of the Rockchip CSI-2 DPHY)
before integrating the MIPI CSI-2 Receiver into the respective SoC
device tree includes. We can readily add the DT binding and the driver
as I am positive they will not need to be changed when this feature is
introduced, but there are no patches in the series that introduce the
DT nodes.

This constitutes a small step towards mainline video capture and camera
support on the Rockchip RK3588.

Looking forward to your comments!

Signed-off-by: Michael Riesch <michael.riesch at collabora.com>

[0] https://lore.kernel.org/r/20240220-rk3568-vicap-v14-0-b38b6da0fc80 at collabora.com

---
Changes in v2:
- dropped one R-b by Bryan, as there were two of them on the same patch
  (Krzysztof)
- Link to v1: https://lore.kernel.org/r/20251114-rockchip-mipi-receiver-v1-0-d13086e810dd at collabora.com

---
Michael Riesch (3):
      media: dt-bindings: add rockchip mipi csi-2 receiver
      media: rockchip: add driver for the rockchip mipi csi-2 receiver
      arm64: defconfig: enable rockchip mipi csi-2 receiver

 .../bindings/media/rockchip,rk3568-mipi-csi.yaml   | 146 ++++
 MAINTAINERS                                        |   7 +
 arch/arm64/configs/defconfig                       |   1 +
 drivers/media/platform/rockchip/Kconfig            |   1 +
 drivers/media/platform/rockchip/Makefile           |   1 +
 drivers/media/platform/rockchip/rkcsi/Kconfig      |  16 +
 drivers/media/platform/rockchip/rkcsi/Makefile     |   3 +
 drivers/media/platform/rockchip/rkcsi/rkcsi.c      | 742 +++++++++++++++++++++
 8 files changed, 917 insertions(+)
---
base-commit: 1f2353f5a1af995efbf7bea44341aa0d03460b28
change-id: 20251114-rockchip-mipi-receiver-0baf244c9c8e

Best regards,
-- 
Michael Riesch <michael.riesch at collabora.com>




From devnull+michael.riesch.collabora.com at kernel.org  Tue Nov 18 03:12:26 2025
From: devnull+michael.riesch.collabora.com at kernel.org (Michael Riesch via B4 Relay)
Date: Tue, 18 Nov 2025 12:12:26 +0100
Subject: [PATCH v2 2/3] media: rockchip: add driver for the rockchip mipi
 csi-2 receiver
In-Reply-To: <20251114-rockchip-mipi-receiver-v2-0-eb9b43377fc4@collabora.com>
References: <20251114-rockchip-mipi-receiver-v2-0-eb9b43377fc4@collabora.com>
Message-ID: <20251114-rockchip-mipi-receiver-v2-2-eb9b43377fc4@collabora.com>

From: Michael Riesch <michael.riesch at collabora.com>

The Rockchip MIPI CSI-2 Receiver is a CSI-2 bridge with one input
port and one output port. It receives the data with the help of an
external MIPI PHY (C-PHY or D-PHY) and passes it to the Rockchip
Video Capture (VICAP) block.

Add a V4L2 subdevice driver for this unit.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
Reviewed-by: Mehdi Djait <mehdi.djait at linux.intel.com>
Signed-off-by: Michael Riesch <michael.riesch at collabora.com>
---
 MAINTAINERS                                    |   1 +
 drivers/media/platform/rockchip/Kconfig        |   1 +
 drivers/media/platform/rockchip/Makefile       |   1 +
 drivers/media/platform/rockchip/rkcsi/Kconfig  |  16 +
 drivers/media/platform/rockchip/rkcsi/Makefile |   3 +
 drivers/media/platform/rockchip/rkcsi/rkcsi.c  | 742 +++++++++++++++++++++++++
 6 files changed, 764 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 145473671a4a..b389f2e631ce 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22304,6 +22304,7 @@ M:	Michael Riesch <michael.riesch at collabora.com>
 L:	linux-media at vger.kernel.org
 S:	Maintained
 F:	Documentation/devicetree/bindings/media/rockchip,rk3568-mipi-csi.yaml
+F:	drivers/media/platform/rockchip/rkcsi/
 
 ROCKCHIP RK3568 RANDOM NUMBER GENERATOR SUPPORT
 M:	Daniel Golle <daniel at makrotopia.org>
diff --git a/drivers/media/platform/rockchip/Kconfig b/drivers/media/platform/rockchip/Kconfig
index ba401d32f01b..54b698c4cd2c 100644
--- a/drivers/media/platform/rockchip/Kconfig
+++ b/drivers/media/platform/rockchip/Kconfig
@@ -4,5 +4,6 @@ comment "Rockchip media platform drivers"
 
 source "drivers/media/platform/rockchip/rga/Kconfig"
 source "drivers/media/platform/rockchip/rkcif/Kconfig"
+source "drivers/media/platform/rockchip/rkcsi/Kconfig"
 source "drivers/media/platform/rockchip/rkisp1/Kconfig"
 source "drivers/media/platform/rockchip/rkvdec/Kconfig"
diff --git a/drivers/media/platform/rockchip/Makefile b/drivers/media/platform/rockchip/Makefile
index 0e0b2cbbd4bd..522a7d3e30b0 100644
--- a/drivers/media/platform/rockchip/Makefile
+++ b/drivers/media/platform/rockchip/Makefile
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-y += rga/
 obj-y += rkcif/
+obj-y += rkcsi/
 obj-y += rkisp1/
 obj-y += rkvdec/
diff --git a/drivers/media/platform/rockchip/rkcsi/Kconfig b/drivers/media/platform/rockchip/rkcsi/Kconfig
new file mode 100644
index 000000000000..d8004198c386
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkcsi/Kconfig
@@ -0,0 +1,16 @@
+config VIDEO_ROCKCHIP_CSI
+	tristate "Rockchip MIPI CSI-2 Receiver"
+	depends on VIDEO_DEV
+	depends on ARCH_ROCKCHIP || COMPILE_TEST
+	depends on V4L_PLATFORM_DRIVERS
+	depends on PM && COMMON_CLK
+	select MEDIA_CONTROLLER
+	select V4L2_FWNODE
+	select VIDEO_V4L2_SUBDEV_API
+	help
+	  This is a driver for Rockchip MIPI CSI-2 Receiver. It is featured
+	  in various Rockchips SoCs, usually in combination with a Video
+	  Capture (VICAP) unit (see Rockchip Camera Interface (CIF) driver).
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called rockchip-mipi-csi.
diff --git a/drivers/media/platform/rockchip/rkcsi/Makefile b/drivers/media/platform/rockchip/rkcsi/Makefile
new file mode 100644
index 000000000000..147712cbb68a
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkcsi/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_VIDEO_ROCKCHIP_CSI) += rockchip-mipi-csi.o
+rockchip-mipi-csi-objs += rkcsi.o
diff --git a/drivers/media/platform/rockchip/rkcsi/rkcsi.c b/drivers/media/platform/rockchip/rkcsi/rkcsi.c
new file mode 100644
index 000000000000..d4108ce5bbf9
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkcsi/rkcsi.c
@@ -0,0 +1,742 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Rockchip MIPI CSI-2 Receiver Driver
+ *
+ * Copyright (C) 2019 Rockchip Electronics Co., Ltd.
+ * Copyright (C) 2025 Michael Riesch <michael.riesch at wolfvision.net>
+ * Copyright (C) 2025 Collabora, Ltd.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
+#include <linux/of_platform.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+
+#include <media/mipi-csi2.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-subdev.h>
+
+#define CSI2HOST_N_LANES     0x04
+#define CSI2HOST_CSI2_RESETN 0x10
+#define CSI2HOST_PHY_STATE   0x14
+#define CSI2HOST_ERR1	     0x20
+#define CSI2HOST_ERR2	     0x24
+#define CSI2HOST_MSK1	     0x28
+#define CSI2HOST_MSK2	     0x2c
+#define CSI2HOST_CONTROL     0x40
+
+#define SW_CPHY_EN(x)	     ((x) << 0)
+#define SW_DSI_EN(x)	     ((x) << 4)
+#define SW_DATATYPE_FS(x)    ((x) << 8)
+#define SW_DATATYPE_FE(x)    ((x) << 14)
+#define SW_DATATYPE_LS(x)    ((x) << 20)
+#define SW_DATATYPE_LE(x)    ((x) << 26)
+
+#define RKCSI_CLKS_MAX	     1
+
+enum {
+	RKCSI_PAD_SINK,
+	RKCSI_PAD_SRC,
+	RKCSI_PAD_MAX,
+};
+
+struct rkcsi_format {
+	u32 code;
+	u8 depth;
+	u8 csi_dt;
+};
+
+struct rkcsi_device {
+	struct device *dev;
+
+	void __iomem *base_addr;
+	struct clk_bulk_data *clks;
+	unsigned int clks_num;
+	struct phy *phy;
+	struct reset_control *reset;
+
+	const struct rkcsi_format *formats;
+	unsigned int formats_num;
+
+	struct media_pad pads[RKCSI_PAD_MAX];
+	struct v4l2_async_notifier notifier;
+	struct v4l2_fwnode_endpoint vep;
+	struct v4l2_subdev sd;
+
+	struct v4l2_subdev *source_sd;
+	u32 source_pad;
+};
+
+static const struct v4l2_mbus_framefmt default_format = {
+	.width = 3840,
+	.height = 2160,
+	.code = MEDIA_BUS_FMT_SRGGB10_1X10,
+	.field = V4L2_FIELD_NONE,
+	.colorspace = V4L2_COLORSPACE_RAW,
+	.ycbcr_enc = V4L2_YCBCR_ENC_601,
+	.quantization = V4L2_QUANTIZATION_FULL_RANGE,
+	.xfer_func = V4L2_XFER_FUNC_NONE,
+};
+
+static const struct rkcsi_format formats[] = {
+	/* YUV formats */
+	{
+		.code = MEDIA_BUS_FMT_YUYV8_1X16,
+		.depth = 16,
+		.csi_dt = MIPI_CSI2_DT_YUV422_8B,
+	},
+	{
+		.code = MEDIA_BUS_FMT_UYVY8_1X16,
+		.depth = 16,
+		.csi_dt = MIPI_CSI2_DT_YUV422_8B,
+	},
+	{
+		.code = MEDIA_BUS_FMT_YVYU8_1X16,
+		.depth = 16,
+		.csi_dt = MIPI_CSI2_DT_YUV422_8B,
+	},
+	{
+		.code = MEDIA_BUS_FMT_VYUY8_1X16,
+		.depth = 16,
+		.csi_dt = MIPI_CSI2_DT_YUV422_8B,
+	},
+	/* RGB formats */
+	{
+		.code = MEDIA_BUS_FMT_RGB888_1X24,
+		.depth = 24,
+		.csi_dt = MIPI_CSI2_DT_RGB888,
+	},
+	{
+		.code = MEDIA_BUS_FMT_BGR888_1X24,
+		.depth = 24,
+		.csi_dt = MIPI_CSI2_DT_RGB888,
+	},
+	/* Bayer formats */
+	{
+		.code = MEDIA_BUS_FMT_SBGGR8_1X8,
+		.depth = 8,
+		.csi_dt = MIPI_CSI2_DT_RAW8,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGBRG8_1X8,
+		.depth = 8,
+		.csi_dt = MIPI_CSI2_DT_RAW8,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGRBG8_1X8,
+		.depth = 8,
+		.csi_dt = MIPI_CSI2_DT_RAW8,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SRGGB8_1X8,
+		.depth = 8,
+		.csi_dt = MIPI_CSI2_DT_RAW8,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SBGGR10_1X10,
+		.depth = 10,
+		.csi_dt = MIPI_CSI2_DT_RAW10,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGBRG10_1X10,
+		.depth = 10,
+		.csi_dt = MIPI_CSI2_DT_RAW10,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGRBG10_1X10,
+		.depth = 10,
+		.csi_dt = MIPI_CSI2_DT_RAW10,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SRGGB10_1X10,
+		.depth = 10,
+		.csi_dt = MIPI_CSI2_DT_RAW10,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SBGGR12_1X12,
+		.depth = 12,
+		.csi_dt = MIPI_CSI2_DT_RAW12,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGBRG12_1X12,
+		.depth = 12,
+		.csi_dt = MIPI_CSI2_DT_RAW12,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGRBG12_1X12,
+		.depth = 12,
+		.csi_dt = MIPI_CSI2_DT_RAW12,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SRGGB12_1X12,
+		.depth = 12,
+		.csi_dt = MIPI_CSI2_DT_RAW12,
+	},
+};
+
+static inline struct rkcsi_device *to_rkcsi(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct rkcsi_device, sd);
+}
+
+static inline __maybe_unused void rkcsi_write(struct rkcsi_device *csi_dev,
+					      unsigned int addr, u32 val)
+{
+	writel(val, csi_dev->base_addr + addr);
+}
+
+static inline __maybe_unused u32 rkcsi_read(struct rkcsi_device *csi_dev,
+					    unsigned int addr)
+{
+	return readl(csi_dev->base_addr + addr);
+}
+
+static const struct rkcsi_format *
+rkcsi_find_format(struct rkcsi_device *csi_dev, u32 mbus_code)
+{
+	const struct rkcsi_format *format;
+
+	WARN_ON(csi_dev->formats_num == 0);
+
+	for (int i = 0; i < csi_dev->formats_num; i++) {
+		format = &csi_dev->formats[i];
+		if (format->code == mbus_code)
+			return format;
+	}
+
+	return NULL;
+}
+
+static int rkcsi_start(struct rkcsi_device *csi_dev)
+{
+	struct media_pad *source_pad =
+		&csi_dev->source_sd->entity.pads[csi_dev->source_pad];
+	enum v4l2_mbus_type bus_type = csi_dev->vep.bus_type;
+	union phy_configure_opts opts;
+	s64 link_freq;
+	u32 lanes = csi_dev->vep.bus.mipi_csi2.num_data_lanes;
+	u32 control = 0;
+	int ret;
+
+	if (lanes < 1 || lanes > 4)
+		return -EINVAL;
+
+	/* set mult and div to 0, thus completely rely on V4L2_CID_LINK_FREQ */
+	link_freq = v4l2_get_link_freq(source_pad, 0, 0);
+	if (link_freq <= 0)
+		return -EINVAL;
+
+	if (bus_type == V4L2_MBUS_CSI2_DPHY) {
+		struct phy_configure_opts_mipi_dphy *cfg = &opts.mipi_dphy;
+
+		ret = phy_mipi_dphy_get_default_config_for_hsclk(link_freq * 2,
+								 lanes, cfg);
+		if (ret)
+			return ret;
+
+		ret = phy_set_mode(csi_dev->phy, PHY_MODE_MIPI_DPHY);
+		if (ret)
+			return ret;
+
+		ret = phy_configure(csi_dev->phy, &opts);
+		if (ret)
+			return ret;
+
+		control |= SW_CPHY_EN(0);
+
+	} else if (bus_type == V4L2_MBUS_CSI2_CPHY) {
+		/* TODO: implement CPHY configuration */
+		return -EOPNOTSUPP;
+	} else {
+		return -EINVAL;
+	}
+
+	control |= SW_DATATYPE_FS(0x00) | SW_DATATYPE_FE(0x01) |
+		   SW_DATATYPE_LS(0x02) | SW_DATATYPE_LE(0x03);
+
+	rkcsi_write(csi_dev, CSI2HOST_N_LANES, lanes - 1);
+	rkcsi_write(csi_dev, CSI2HOST_CONTROL, control);
+	rkcsi_write(csi_dev, CSI2HOST_CSI2_RESETN, 1);
+
+	ret = phy_power_on(csi_dev->phy);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void rkcsi_stop(struct rkcsi_device *csi_dev)
+{
+	phy_power_off(csi_dev->phy);
+
+	rkcsi_write(csi_dev, CSI2HOST_CSI2_RESETN, 0);
+	rkcsi_write(csi_dev, CSI2HOST_MSK1, ~0);
+	rkcsi_write(csi_dev, CSI2HOST_MSK2, ~0);
+}
+
+static const struct media_entity_operations rkcsi_media_ops = {
+	.link_validate = v4l2_subdev_link_validate,
+};
+
+static int rkcsi_enum_mbus_code(struct v4l2_subdev *sd,
+				struct v4l2_subdev_state *sd_state,
+				struct v4l2_subdev_mbus_code_enum *code)
+{
+	struct rkcsi_device *csi_dev = to_rkcsi(sd);
+
+	if (code->pad == RKCSI_PAD_SRC) {
+		const struct v4l2_mbus_framefmt *sink_fmt;
+
+		if (code->index)
+			return -EINVAL;
+
+		sink_fmt = v4l2_subdev_state_get_format(sd_state,
+							RKCSI_PAD_SINK);
+		code->code = sink_fmt->code;
+
+		return 0;
+	} else if (code->pad == RKCSI_PAD_SINK) {
+		if (code->index > csi_dev->formats_num)
+			return -EINVAL;
+
+		code->code = csi_dev->formats[code->index].code;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static int rkcsi_set_fmt(struct v4l2_subdev *sd,
+			 struct v4l2_subdev_state *state,
+			 struct v4l2_subdev_format *format)
+{
+	struct rkcsi_device *csi_dev = to_rkcsi(sd);
+	const struct rkcsi_format *fmt;
+	struct v4l2_mbus_framefmt *sink, *src;
+
+	/* the format on the source pad always matches the sink pad */
+	if (format->pad == RKCSI_PAD_SRC)
+		return v4l2_subdev_get_fmt(sd, state, format);
+
+	sink = v4l2_subdev_state_get_format(state, format->pad, format->stream);
+	if (!sink)
+		return -EINVAL;
+
+	fmt = rkcsi_find_format(csi_dev, format->format.code);
+	if (!fmt)
+		format->format = default_format;
+
+	*sink = format->format;
+
+	/* propagate the format to the source pad */
+	src = v4l2_subdev_state_get_opposite_stream_format(state, format->pad,
+							   format->stream);
+	if (!src)
+		return -EINVAL;
+
+	*src = *sink;
+
+	return 0;
+}
+
+static int rkcsi_set_routing(struct v4l2_subdev *sd,
+			     struct v4l2_subdev_state *state,
+			     enum v4l2_subdev_format_whence which,
+			     struct v4l2_subdev_krouting *routing)
+{
+	int ret;
+
+	ret = v4l2_subdev_routing_validate(sd, routing,
+					   V4L2_SUBDEV_ROUTING_ONLY_1_TO_1);
+	if (ret)
+		return ret;
+
+	ret = v4l2_subdev_set_routing_with_fmt(sd, state, routing,
+					       &default_format);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int rkcsi_enable_streams(struct v4l2_subdev *sd,
+				struct v4l2_subdev_state *state, u32 pad,
+				u64 streams_mask)
+{
+	struct rkcsi_device *csi_dev = to_rkcsi(sd);
+	struct v4l2_subdev *remote_sd;
+	struct media_pad *sink_pad, *remote_pad;
+	struct device *dev = csi_dev->dev;
+	u64 mask;
+	int ret;
+
+	sink_pad = &sd->entity.pads[RKCSI_PAD_SINK];
+	remote_pad = media_pad_remote_pad_first(sink_pad);
+	remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity);
+
+	mask = v4l2_subdev_state_xlate_streams(state, RKCSI_PAD_SINK,
+					       RKCSI_PAD_SRC, &streams_mask);
+
+	ret = pm_runtime_resume_and_get(dev);
+	if (ret)
+		goto err;
+
+	ret = rkcsi_start(csi_dev);
+	if (ret) {
+		dev_err(dev, "failed to enable CSI hardware\n");
+		goto err_pm_runtime_put;
+	}
+
+	ret = v4l2_subdev_enable_streams(remote_sd, remote_pad->index, mask);
+	if (ret)
+		goto err_csi_stop;
+
+	return 0;
+
+err_csi_stop:
+	rkcsi_stop(csi_dev);
+err_pm_runtime_put:
+	pm_runtime_put_sync(dev);
+err:
+	return ret;
+}
+
+static int rkcsi_disable_streams(struct v4l2_subdev *sd,
+				 struct v4l2_subdev_state *state, u32 pad,
+				 u64 streams_mask)
+{
+	struct rkcsi_device *csi_dev = to_rkcsi(sd);
+	struct v4l2_subdev *remote_sd;
+	struct media_pad *sink_pad, *remote_pad;
+	struct device *dev = csi_dev->dev;
+	u64 mask;
+	int ret;
+
+	sink_pad = &sd->entity.pads[RKCSI_PAD_SINK];
+	remote_pad = media_pad_remote_pad_first(sink_pad);
+	remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity);
+
+	mask = v4l2_subdev_state_xlate_streams(state, RKCSI_PAD_SINK,
+					       RKCSI_PAD_SRC, &streams_mask);
+
+	ret = v4l2_subdev_disable_streams(remote_sd, remote_pad->index, mask);
+
+	rkcsi_stop(csi_dev);
+
+	pm_runtime_mark_last_busy(dev);
+	pm_runtime_put_autosuspend(dev);
+
+	return ret;
+}
+
+static const struct v4l2_subdev_pad_ops rkcsi_pad_ops = {
+	.enum_mbus_code = rkcsi_enum_mbus_code,
+	.get_fmt = v4l2_subdev_get_fmt,
+	.set_fmt = rkcsi_set_fmt,
+	.set_routing = rkcsi_set_routing,
+	.enable_streams = rkcsi_enable_streams,
+	.disable_streams = rkcsi_disable_streams,
+};
+
+static const struct v4l2_subdev_ops rkcsi_ops = {
+	.pad = &rkcsi_pad_ops,
+};
+
+static int rkcsi_init_state(struct v4l2_subdev *sd,
+			    struct v4l2_subdev_state *state)
+{
+	struct v4l2_subdev_route routes[] = {
+		{
+			.sink_pad = RKCSI_PAD_SINK,
+			.sink_stream = 0,
+			.source_pad = RKCSI_PAD_SRC,
+			.source_stream = 0,
+			.flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
+		},
+	};
+	struct v4l2_subdev_krouting routing = {
+		.len_routes = ARRAY_SIZE(routes),
+		.num_routes = ARRAY_SIZE(routes),
+		.routes = routes,
+	};
+	int ret;
+
+	ret = v4l2_subdev_set_routing_with_fmt(sd, state, &routing,
+					       &default_format);
+
+	return ret;
+}
+
+static const struct v4l2_subdev_internal_ops rkcsi_internal_ops = {
+	.init_state = rkcsi_init_state,
+};
+
+static int rkcsi_notifier_bound(struct v4l2_async_notifier *notifier,
+				struct v4l2_subdev *sd,
+				struct v4l2_async_connection *asd)
+{
+	struct rkcsi_device *csi_dev =
+		container_of(notifier, struct rkcsi_device, notifier);
+	int source_pad;
+
+	source_pad = media_entity_get_fwnode_pad(&sd->entity, sd->fwnode,
+						 MEDIA_PAD_FL_SOURCE);
+	if (source_pad < 0) {
+		dev_err(csi_dev->dev, "failed to find source pad for %s\n",
+			sd->name);
+		return source_pad;
+	}
+
+	csi_dev->source_sd = sd;
+	csi_dev->source_pad = source_pad;
+
+	return media_create_pad_link(&sd->entity, source_pad,
+				     &csi_dev->sd.entity, RKCSI_PAD_SINK,
+				     MEDIA_LNK_FL_ENABLED);
+}
+
+static const struct v4l2_async_notifier_operations rkcsi_notifier_ops = {
+	.bound = rkcsi_notifier_bound,
+};
+
+static int rkcsi_register_notifier(struct rkcsi_device *csi_dev)
+{
+	struct v4l2_async_connection *asd;
+	struct v4l2_async_notifier *ntf = &csi_dev->notifier;
+	struct v4l2_fwnode_endpoint *vep = &csi_dev->vep;
+	struct v4l2_subdev *sd = &csi_dev->sd;
+	struct device *dev = csi_dev->dev;
+	struct fwnode_handle *ep;
+	int ret = 0;
+
+	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0, 0);
+	if (!ep)
+		return dev_err_probe(dev, -ENODEV, "failed to get endpoint\n");
+
+	vep->bus_type = V4L2_MBUS_UNKNOWN;
+	ret = v4l2_fwnode_endpoint_parse(ep, vep);
+	if (ret) {
+		ret = dev_err_probe(dev, ret, "failed to parse endpoint\n");
+		goto out;
+	}
+
+	if (vep->bus_type != V4L2_MBUS_CSI2_DPHY &&
+	    vep->bus_type != V4L2_MBUS_CSI2_CPHY) {
+		ret = dev_err_probe(dev, -EINVAL,
+				    "invalid bus type of endpoint\n");
+		goto out;
+	}
+
+	v4l2_async_subdev_nf_init(ntf, sd);
+	ntf->ops = &rkcsi_notifier_ops;
+
+	asd = v4l2_async_nf_add_fwnode_remote(ntf, ep,
+					      struct v4l2_async_connection);
+	if (IS_ERR(asd)) {
+		ret = PTR_ERR(asd);
+		goto err_nf_cleanup;
+	}
+
+	ret = v4l2_async_nf_register(ntf);
+	if (ret) {
+		ret = dev_err_probe(dev, ret, "failed to register notifier\n");
+		goto err_nf_cleanup;
+	}
+
+	goto out;
+
+err_nf_cleanup:
+	v4l2_async_nf_cleanup(ntf);
+out:
+	fwnode_handle_put(ep);
+	return ret;
+}
+
+static int rkcsi_register(struct rkcsi_device *csi_dev)
+{
+	struct media_pad *pads = csi_dev->pads;
+	struct v4l2_subdev *sd = &csi_dev->sd;
+	int ret;
+
+	ret = rkcsi_register_notifier(csi_dev);
+	if (ret)
+		goto err;
+
+	v4l2_subdev_init(sd, &rkcsi_ops);
+	sd->dev = csi_dev->dev;
+	sd->entity.ops = &rkcsi_media_ops;
+	sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
+	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_STREAMS;
+	sd->internal_ops = &rkcsi_internal_ops;
+	sd->owner = THIS_MODULE;
+	snprintf(sd->name, sizeof(sd->name), "rockchip-mipi-csi %s",
+		 dev_name(csi_dev->dev));
+
+	pads[RKCSI_PAD_SINK].flags = MEDIA_PAD_FL_SINK |
+				     MEDIA_PAD_FL_MUST_CONNECT;
+	pads[RKCSI_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;
+	ret = media_entity_pads_init(&sd->entity, RKCSI_PAD_MAX, pads);
+	if (ret)
+		goto err_notifier_unregister;
+
+	ret = v4l2_subdev_init_finalize(sd);
+	if (ret)
+		goto err_entity_cleanup;
+
+	ret = v4l2_async_register_subdev(sd);
+	if (ret) {
+		dev_err(sd->dev, "failed to register CSI subdev\n");
+		goto err_subdev_cleanup;
+	}
+
+	return 0;
+
+err_subdev_cleanup:
+	v4l2_subdev_cleanup(sd);
+err_entity_cleanup:
+	media_entity_cleanup(&sd->entity);
+err_notifier_unregister:
+	v4l2_async_nf_unregister(&csi_dev->notifier);
+	v4l2_async_nf_cleanup(&csi_dev->notifier);
+err:
+	return ret;
+}
+
+static void rkcsi_unregister(struct rkcsi_device *csi_dev)
+{
+	struct v4l2_subdev *sd = &csi_dev->sd;
+
+	v4l2_async_unregister_subdev(sd);
+	v4l2_subdev_cleanup(sd);
+	media_entity_cleanup(&sd->entity);
+	v4l2_async_nf_unregister(&csi_dev->notifier);
+	v4l2_async_nf_cleanup(&csi_dev->notifier);
+}
+
+static const struct of_device_id rkcsi_of_match[] = {
+	{
+		.compatible = "rockchip,rk3568-mipi-csi",
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(of, rkcsi_of_match);
+
+static int rkcsi_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct rkcsi_device *csi_dev;
+	int ret;
+
+	csi_dev = devm_kzalloc(dev, sizeof(*csi_dev), GFP_KERNEL);
+	if (!csi_dev)
+		return -ENOMEM;
+	csi_dev->dev = dev;
+	dev_set_drvdata(dev, csi_dev);
+
+	csi_dev->base_addr = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(csi_dev->base_addr))
+		return PTR_ERR(csi_dev->base_addr);
+
+	ret = devm_clk_bulk_get_all(dev, &csi_dev->clks);
+	if (ret != RKCSI_CLKS_MAX)
+		return dev_err_probe(dev, -ENODEV, "failed to get clocks\n");
+	csi_dev->clks_num = ret;
+
+	csi_dev->phy = devm_phy_get(dev, NULL);
+	if (IS_ERR(csi_dev->phy))
+		return dev_err_probe(dev, PTR_ERR(csi_dev->phy),
+				     "failed to get MIPI CSI PHY\n");
+
+	csi_dev->reset = devm_reset_control_get_exclusive(dev, NULL);
+	if (IS_ERR(csi_dev->reset))
+		return dev_err_probe(dev, PTR_ERR(csi_dev->reset),
+				     "failed to get reset\n");
+
+	csi_dev->formats = formats;
+	csi_dev->formats_num = ARRAY_SIZE(formats);
+
+	pm_runtime_enable(dev);
+
+	ret = phy_init(csi_dev->phy);
+	if (ret) {
+		ret = dev_err_probe(dev, ret,
+				    "failed to initialize MIPI CSI PHY\n");
+		goto err_pm_runtime_disable;
+	}
+
+	ret = rkcsi_register(csi_dev);
+	if (ret)
+		goto err_phy_exit;
+
+	return 0;
+
+err_phy_exit:
+	phy_exit(csi_dev->phy);
+err_pm_runtime_disable:
+	pm_runtime_disable(dev);
+	return ret;
+}
+
+static void rkcsi_remove(struct platform_device *pdev)
+{
+	struct rkcsi_device *csi_dev = platform_get_drvdata(pdev);
+	struct device *dev = &pdev->dev;
+
+	rkcsi_unregister(csi_dev);
+	phy_exit(csi_dev->phy);
+	pm_runtime_disable(dev);
+}
+
+static int rkcsi_runtime_suspend(struct device *dev)
+{
+	struct rkcsi_device *csi_dev = dev_get_drvdata(dev);
+
+	clk_bulk_disable_unprepare(csi_dev->clks_num, csi_dev->clks);
+
+	return 0;
+}
+
+static int rkcsi_runtime_resume(struct device *dev)
+{
+	struct rkcsi_device *csi_dev = dev_get_drvdata(dev);
+	int ret;
+
+	reset_control_assert(csi_dev->reset);
+	udelay(5);
+	reset_control_deassert(csi_dev->reset);
+
+	ret = clk_bulk_prepare_enable(csi_dev->clks_num, csi_dev->clks);
+	if (ret) {
+		dev_err(dev, "failed to enable clocks\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct dev_pm_ops rkcsi_pm_ops = {
+	.runtime_suspend = rkcsi_runtime_suspend,
+	.runtime_resume = rkcsi_runtime_resume,
+};
+
+static struct platform_driver rkcsi_drv = {
+	.driver = {
+		   .name = "rockchip-mipi-csi",
+		   .of_match_table = rkcsi_of_match,
+		   .pm = &rkcsi_pm_ops,
+	},
+	.probe = rkcsi_probe,
+	.remove = rkcsi_remove,
+};
+module_platform_driver(rkcsi_drv);
+
+MODULE_DESCRIPTION("Rockchip MIPI CSI-2 Receiver platform driver");
+MODULE_LICENSE("GPL");

-- 
2.39.5




From linux.amoon at gmail.com  Tue Nov 18 03:16:30 2025
From: linux.amoon at gmail.com (Anand Moon)
Date: Tue, 18 Nov 2025 16:46:30 +0530
Subject: [RFC v1 2/5] PCI: rockchip: Fix Device Control register offset
 for Max payload size
In-Reply-To: <20251118005056.GA2541796@bhelgaas>
References: <20251117181023.482138-3-linux.amoon@gmail.com> <20251118005056.GA2541796@bhelgaas>
Message-ID: <CANAwSgSMiRrPp5G+guGQSsqArz7M750NAg8SQoorUQ7gJhUxHQ@mail.gmail.com>

Hi Bjorn

Thanks for your review comments.

On Tue, 18 Nov 2025 at 06:21, Bjorn Helgaas <helgaas at kernel.org> wrote:
>
> On Mon, Nov 17, 2025 at 11:40:10PM +0530, Anand Moon wrote:
> > As per 17.6.6.1.29 PCI Express Device Capabilities Register
> > (PCIE_RC_CONFIG_DC) reside at offset 0xc8 within the Root Complex (RC)
> > configuration space, not at the offset of the PCI Express Capability
> > List (0xc0). Following changes corrects the register offset to use
> > PCIE_RC_CONFIG_DC (0xc8) to configure Max Payload Size.
> >
> > Signed-off-by: Anand Moon <linux.amoon at gmail.com>
> > ---
> >  drivers/pci/controller/pcie-rockchip-host.c | 4 ++--
> >  drivers/pci/controller/pcie-rockchip.h      | 1 +
> >  2 files changed, 3 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c
> > index f0de5b2590c4..d51780f4a254 100644
> > --- a/drivers/pci/controller/pcie-rockchip-host.c
> > +++ b/drivers/pci/controller/pcie-rockchip-host.c
> > @@ -382,10 +382,10 @@ static int rockchip_pcie_host_init_port(struct rockchip_pcie *rockchip)
> >               rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_CR + PCI_EXP_LNKCAP);
> >       }
> >
> > -     status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_CR + PCI_EXP_DEVCTL);
> > +     status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_DC + PCI_EXP_DEVCTL);
> >       status &= ~PCI_EXP_DEVCTL_PAYLOAD;
> >       status |= PCI_EXP_DEVCTL_PAYLOAD_256B;
> > -     rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_CR + PCI_EXP_DEVCTL);
> > +     rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_DC + PCI_EXP_DEVCTL);
> >
> >       return 0;
> >  err_power_off_phy:
> > diff --git a/drivers/pci/controller/pcie-rockchip.h b/drivers/pci/controller/pcie-rockchip.h
> > index 5d8a3ae38599..c0ec6c32ea16 100644
> > --- a/drivers/pci/controller/pcie-rockchip.h
> > +++ b/drivers/pci/controller/pcie-rockchip.h
> > @@ -157,6 +157,7 @@
> >  #define PCIE_EP_CONFIG_LCS           (PCIE_EP_CONFIG_BASE + 0xd0)
> >  #define PCIE_RC_CONFIG_RID_CCR               (PCIE_RC_CONFIG_BASE + 0x08)
> >  #define PCIE_RC_CONFIG_CR            (PCIE_RC_CONFIG_BASE + 0xc0)
> > +#define PCIE_RC_CONFIG_DC            (PCIE_RC_CONFIG_BASE + 0xc8)
>
> Per the RK3399 TRM:
>
>   DEVCAP              0xc4
>   DEVCTL and DEVSTA   0xc8
>   LNKCAP              0xcc
>   LNKCTL and LNKSTA   0xd0
>   SLTCAP              0xd4
>   SLTCTL and SLTSTA   0xd8
>
> That all makes good sense and matches the relative offsets in the PCIe
> Capability.
>
> I have no idea how we got from that to the mind-bendingly obtuse
> #defines here:
>
>   PCIE_RC_CONFIG_CR == PCIE_RC_CONFIG_BASE + 0xc0
>                     == 0xa00000 + 0xc0
>                     == 0xa000c0
>
>   PCIE_RC_CONFIG_DC == PCIE_RC_CONFIG_BASE + 0xc8
>                     == 0xa00000 + 0xc8
>                     == 0xa000c8
>
>   PCIE_RC_CONFIG_LC == PCIE_RC_CONFIG_BASE + 0xd0
>                     == 0xa00000 + 0xd0
>                     == 0xa000d0
>
>   PCIE_RC_CONFIG_SR == PCIE_RC_CONFIG_BASE + 0xd4
>                     == 0xa00000 + 0xd4
>                     == 0xa000d4
>
> And they're used like this:
>
>   PCIE_RC_CONFIG_CR + PCI_EXP_LNKCAP == 0xa000c0 + 0x0c
>                                      == 0xa000cc
>
>   PCIE_RC_CONFIG_CR + PCI_EXP_LNKCTL == 0xa000c0 + 0x10
>                                      == 0xa000d0
>
>   PCIE_RC_CONFIG_DC + PCI_EXP_DEVCTL == 0xa000c8 + 0x08
>                                      == 0xa000d0     <-- same as LNKCTL?
>
>   PCIE_RC_CONFIG_SR + PCI_EXP_DEVCAP == 0xa000d4 + 0x04
>                                      == 0xa000d8     <--
>
>   PCIE_RC_CONFIG_LC + PCI_EXP_LNKCTL == 0xa000d0 + 0x10
>                                      == 0xa000e0     <-- but LNKCTL was at 0xa000d0 above?
>
> And the mappings don't make any sense to me:
You are correct, PCIE_RC_CONFIG_DC + PCI_EXP_DEVCTL  results in an
incorrect offset.

As per my understanding
#define PCI_EXP_DEVCTL 0x08 /* Device Control */
#define  PCI_EXP_DEVCTL_PAYLOAD 0x00e0 /* Max_Payload_Size */
#define  PCI_EXP_DEVCTL_PAYLOAD_128B 0x0000 /* 128 Bytes */
#define  PCI_EXP_DEVCTL_PAYLOAD_256B 0x0020 /* 256 Bytes */
#define  PCI_EXP_DEVCTL_PAYLOAD_512B 0x0040 /* 512 Bytes */
#define  PCI_EXP_DEVCTL_PAYLOAD_1024B 0x0060 /* 1024 Bytes */

What I was thinking about was mapping it to a register to offset the
Max_Payload_Size (7:5) at PCIE_RC_CONFIG_DC (0xa000c8).

Sorry for the noise.
>
>   CR -> LNKCAP & LNKCTL
>   DC -> DEVCTL (ok, this one makes a *little* sense)
>   SR -> DEVCAP
>   LC -> LNKCTL (would make some sense except that we have CR above)
>
> This is all just really hard to read.  It looks like if we defined a
> single base address for the PCIe Capability, we shouldn't need all the
> _CR, _DC, _LC, _SR, etc #defines.  E.g., we could have
>
>   #define ROCKCHIP_RP_PCIE_CAP ...
#define ROCKCHIP_RP_PCIE_CAP (PCIE_RC_CONFIG_BASE + 0xc0)
Is this ok? But the current code uses the same.
>
>   rockchip_pcie_read(rockchip, ROCKCHIP_RP_PCIE_CAP + PCI_EXP_DEVCAP)
>   rockchip_pcie_read(rockchip, ROCKCHIP_RP_PCIE_CAP + PCI_EXP_LNKCTL)
>   ...
>
> with maybe some minor adjustment for 16-bit registers since Rockchip
> only seems to support 32-bit accesses (?)
>
> None of these registers are *Root Complex* registers; they're all part
> of a PCIe Capability, which applies to a Root *Port*.
>
Ok, I understood
> >  #define PCIE_RC_CONFIG_LC            (PCIE_RC_CONFIG_BASE + 0xd0)
> >  #define PCIE_RC_CONFIG_L1_SUBSTATE_CTRL2 (PCIE_RC_CONFIG_BASE + 0x90c)
> >  #define PCIE_RC_CONFIG_THP_CAP               (PCIE_RC_CONFIG_BASE + 0x274)
> > --
> > 2.50.1
> >
Thanks
-Anand


From lkp at intel.com  Tue Nov 18 04:06:08 2025
From: lkp at intel.com (kernel test robot)
Date: Tue, 18 Nov 2025 20:06:08 +0800
Subject: [PATCH v4 02/10] drm: Add new general DRM property "color format"
In-Reply-To: <20251117-color-format-v4-2-0ded72bd1b00@collabora.com>
References: <20251117-color-format-v4-2-0ded72bd1b00@collabora.com>
Message-ID: <202511181958.eS8Ctiow-lkp@intel.com>

Hi Nicolas,

kernel test robot noticed the following build warnings:

[auto build test WARNING on d1d18879e01e4c9efcb85a96d188a8e4326136dd]

url:    https://github.com/intel-lab-lkp/linux/commits/Nicolas-Frattaroli/drm-amd-display-Remove-unnecessary-SIGNAL_TYPE_HDMI_TYPE_A-check/20251118-031440
base:   d1d18879e01e4c9efcb85a96d188a8e4326136dd
patch link:    https://lore.kernel.org/r/20251117-color-format-v4-2-0ded72bd1b00%40collabora.com
patch subject: [PATCH v4 02/10] drm: Add new general DRM property "color format"
config: arm-randconfig-001-20251118 (https://download.01.org/0day-ci/archive/20251118/202511181958.eS8Ctiow-lkp at intel.com/config)
compiler: arm-linux-gnueabi-gcc (GCC) 8.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251118/202511181958.eS8Ctiow-lkp at intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202511181958.eS8Ctiow-lkp at intel.com/

All warnings (new ones prefixed by >>):

>> Warning: drivers/gpu/drm/drm_connector.c:1392 function parameter 'color_fmt' not described in 'drm_get_color_format_name'
>> Warning: drivers/gpu/drm/drm_connector.c:1392 function parameter 'color_fmt' not described in 'drm_get_color_format_name'

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


From neil.armstrong at linaro.org  Tue Nov 18 05:47:40 2025
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Tue, 18 Nov 2025 14:47:40 +0100
Subject: [PATCH v2 1/2] phy: rockchip: naneng-combphy: Fix PCIe L1ss
 support RK3528
In-Reply-To: <1763459526-35004-1-git-send-email-shawn.lin@rock-chips.com>
References: <1763459526-35004-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <710f2b4a-b443-44cd-aec8-ce9a8630dfbc@linaro.org>

On 11/18/25 10:52, Shawn Lin wrote:
> When PCIe link enters L1 PM substates, the PHY will turn off its
> PLL for power-saving. However, it turns off the PLL too fast which
> leads the PHY to be broken. According to the PHY document, we need
> to delay PLL turnoff time.
> 
> Fixes: bbcca4fac873 ("phy: rockchip: naneng-combphy: Add RK3528 support")
> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
> ---
> 
> Changes in v2:
> - add more commit message
> 
>   drivers/phy/rockchip/phy-rockchip-naneng-combphy.c | 7 +++++++
>   1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
> index a3ef198..e303bec 100644
> --- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
> +++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
> @@ -21,6 +21,9 @@
>   #define REF_CLOCK_100MHz		(100 * HZ_PER_MHZ)
>   
>   /* RK3528 COMBO PHY REG */
> +#define RK3528_PHYREG5				0x14
> +#define RK3528_PHYREG5_GATE_TX_PCK_SEL		BIT(3)
> +#define RK3528_PHYREG5_GATE_TX_PCK_DLY_PLL_OFF	BIT(3)
>   #define RK3528_PHYREG6				0x18
>   #define RK3528_PHYREG6_PLL_KVCO			GENMASK(12, 10)
>   #define RK3528_PHYREG6_PLL_KVCO_VALUE		0x2
> @@ -504,6 +507,10 @@ static int rk3528_combphy_cfg(struct rockchip_combphy_priv *priv)
>   	case REF_CLOCK_100MHz:
>   		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
>   		if (priv->type == PHY_TYPE_PCIE) {
> +			/* Gate_tx_pck_sel length select for L1ss support */
> +			rockchip_combphy_updatel(priv, RK3528_PHYREG5_GATE_TX_PCK_SEL,
> +						 RK3528_PHYREG5_GATE_TX_PCK_DLY_PLL_OFF, RK3528_PHYREG5);
> +
>   			/* PLL KVCO tuning fine */
>   			val = FIELD_PREP(RK3528_PHYREG6_PLL_KVCO, RK3528_PHYREG6_PLL_KVCO_VALUE);
>   			rockchip_combphy_updatel(priv, RK3528_PHYREG6_PLL_KVCO, val,

Thanks for updating, it's clearer now !

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From neil.armstrong at linaro.org  Tue Nov 18 05:47:53 2025
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Tue, 18 Nov 2025 14:47:53 +0100
Subject: [PATCH v2 2/2] phy: rockchip: naneng-combphy: Fix PCIe L1ss
 support RK3562
In-Reply-To: <1763459526-35004-2-git-send-email-shawn.lin@rock-chips.com>
References: <1763459526-35004-1-git-send-email-shawn.lin@rock-chips.com>
 <1763459526-35004-2-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <6e166ac1-6c36-482d-9d0d-1cb841f2286d@linaro.org>

On 11/18/25 10:52, Shawn Lin wrote:
> When PCIe link enters L1 PM substates, the PHY will turn off its
> PLL for power-saving. However, it turns off the PLL too fast which
> leads the PHY to be broken. According to the PHY document, we need
> to delay PLL turnoff time.
> 
> Fixes: f13bff25161b ("phy: rockchip-naneng-combo: Support rk3562")
> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
> ---
> 
> Changes in v2:
> - add more commit message
> 
>   drivers/phy/rockchip/phy-rockchip-naneng-combphy.c | 8 ++++++++
>   1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
> index e303bec..7f8fc8e 100644
> --- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
> +++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
> @@ -106,6 +106,10 @@
>   #define RK3568_PHYREG18				0x44
>   #define RK3568_PHYREG18_PLL_LOOP		0x32
>   
> +#define RK3568_PHYREG30				0x74
> +#define RK3568_PHYREG30_GATE_TX_PCK_SEL         BIT(7)
> +#define RK3568_PHYREG30_GATE_TX_PCK_DLY_PLL_OFF BIT(7)
> +
>   #define RK3568_PHYREG32				0x7C
>   #define RK3568_PHYREG32_SSC_MASK		GENMASK(7, 4)
>   #define RK3568_PHYREG32_SSC_DIR_MASK		GENMASK(5, 4)
> @@ -664,6 +668,10 @@ static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv)
>   	case REF_CLOCK_100MHz:
>   		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
>   		if (priv->type == PHY_TYPE_PCIE) {
> +			/* Gate_tx_pck_sel length select for L1ss support */
> +			rockchip_combphy_updatel(priv, RK3568_PHYREG30_GATE_TX_PCK_SEL,
> +						 RK3568_PHYREG30_GATE_TX_PCK_DLY_PLL_OFF,
> +						 RK3568_PHYREG30);
>   			/* PLL KVCO tuning fine */
>   			val = FIELD_PREP(RK3568_PHYREG33_PLL_KVCO_MASK,
>   					 RK3568_PHYREG33_PLL_KVCO_VALUE);

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From neil.armstrong at linaro.org  Tue Nov 18 05:50:13 2025
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Tue, 18 Nov 2025 14:50:13 +0100
Subject: [PATCH 6/9] phy: rockchip: inno-dsidphy: Add support for rk3506
In-Reply-To: <20251106020632.92-7-kernel@airkyi.com>
References: <20251106020632.92-1-kernel@airkyi.com>
 <20251106020632.92-7-kernel@airkyi.com>
Message-ID: <96596cf7-4b19-4873-ba16-936e398e876f@linaro.org>

On 11/6/25 03:06, Chaoyi Chen wrote:
> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> 
> For MIPI mode, the inno-dsidphy found on RK3506 supports up to 2 lanes
> and a maximum data rate of 1.5GHz.
> 
> Signed-off-by: Hongming Zou <hongming.zou at rock-chips.com>
> Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> ---
>   .../phy/rockchip/phy-rockchip-inno-dsidphy.c  | 91 ++++++++++++++++++-
>   1 file changed, 88 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> index d5b1a4e2f7d3..30d5e5ddff4a 100644
> --- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> +++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> @@ -99,10 +99,30 @@
>   #define VOD_MID_RANGE				0x3
>   #define VOD_BIG_RANGE				0x7
>   #define VOD_MAX_RANGE				0xf
> +/* Analog Register Part: reg18 */
> +#define LANE0_PRE_EMPHASIS_ENABLE_MASK		BIT(6)
> +#define LANE0_PRE_EMPHASIS_ENABLE		BIT(6)
> +#define LANE0_PRE_EMPHASIS_DISABLE		0
> +#define LANE1_PRE_EMPHASIS_ENABLE_MASK		BIT(5)
> +#define LANE1_PRE_EMPHASIS_ENABLE		BIT(5)
> +#define LANE1_PRE_EMPHASIS_DISABLE		0
> +/* Analog Register Part: reg19 */
> +#define PRE_EMPHASIS_RANGE_SET_MASK		GENMASK(7, 6)
> +#define PRE_EMPHASIS_RANGE_SET(x)		UPDATE(x, 7, 6)
>   /* Analog Register Part: reg1E */
>   #define PLL_MODE_SEL_MASK			GENMASK(6, 5)
>   #define PLL_MODE_SEL_LVDS_MODE			0
>   #define PLL_MODE_SEL_MIPI_MODE			BIT(5)
> +/* Analog Register Part: reg20 */
> +#define LANE0_PRE_EMPHASIS_RANGE_SET_MASK	GENMASK(7, 6)
> +#define LANE0_PRE_EMPHASIS_RANGE_SET(x)		UPDATE(x, 7, 6)
> +/* Analog Register Part: reg21 */
> +#define LANE1_PRE_EMPHASIS_RANGE_SET_MASK	GENMASK(7, 6)
> +#define LANE1_PRE_EMPHASIS_RANGE_SET(x)		UPDATE(x, 7, 6)
> +#define PRE_EMPHASIS_MIN_RANGE			0x0
> +#define PRE_EMPHASIS_MID_RANGE			0x1
> +#define PRE_EMPHASIS_MAX_RANGE			0x2
> +#define PRE_EMPHASIS_RESERVED_RANGE		0x3
>   /* Digital Register Part: reg00 */
>   #define REG_DIG_RSTN_MASK			BIT(0)
>   #define REG_DIG_RSTN_NORMAL			BIT(0)
> @@ -193,6 +213,7 @@
>   
>   enum phy_max_rate {
>   	MAX_1GHZ,
> +	MAX_1_5GHZ,
>   	MAX_2_5GHZ,
>   };
>   
> @@ -200,6 +221,7 @@ struct inno_video_phy_plat_data {
>   	const struct inno_mipi_dphy_timing *inno_mipi_dphy_timing_table;
>   	const unsigned int num_timings;
>   	enum phy_max_rate max_rate;
> +	unsigned int max_lanes;
>   };
>   
>   struct inno_dsidphy {
> @@ -258,6 +280,24 @@ struct inno_mipi_dphy_timing inno_mipi_dphy_timing_table_max_1ghz[] = {
>   	{1000000000, 0x0, 0x09, 0x20, 0x09, 0x27},
>   };
>   
> +static const
> +struct inno_mipi_dphy_timing inno_mipi_dphy_timing_table_max_1_5ghz[] = {
> +	{ 110, 0x02, 0x7f, 0x16, 0x02, 0x02},
> +	{ 150, 0x02, 0x7f, 0x16, 0x03, 0x02},
> +	{ 200, 0x02, 0x7f, 0x17, 0x04, 0x02},
> +	{ 250, 0x02, 0x7f, 0x17, 0x05, 0x04},
> +	{ 300, 0x02, 0x7f, 0x18, 0x06, 0x04},
> +	{ 400, 0x03, 0x7e, 0x19, 0x07, 0x04},
> +	{ 500, 0x03, 0x7c, 0x1b, 0x07, 0x08},
> +	{ 600, 0x03, 0x70, 0x1d, 0x08, 0x10},
> +	{ 700, 0x05, 0x40, 0x1e, 0x08, 0x30},
> +	{ 800, 0x05, 0x02, 0x1f, 0x09, 0x30},
> +	{1000, 0x05, 0x08, 0x20, 0x09, 0x30},
> +	{1200, 0x06, 0x03, 0x32, 0x14, 0x0f},
> +	{1400, 0x09, 0x03, 0x32, 0x14, 0x0f},
> +	{1500, 0x0d, 0x42, 0x36, 0x0e, 0x0f},
> +};
> +
>   static const
>   struct inno_mipi_dphy_timing inno_mipi_dphy_timing_table_max_2_5ghz[] = {
>   	{ 110000000, 0x02, 0x7f, 0x16, 0x02, 0x02},
> @@ -372,6 +412,7 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
>   	u32 hs_exit, clk_post, clk_pre, wakeup, lpx, ta_go, ta_sure, ta_wait;
>   	u32 hs_prepare, hs_trail, hs_zero, clk_lane_hs_zero, data_lane_hs_zero;
>   	unsigned int i;
> +	u32 val;
>   
>   	timings = inno->pdata->inno_mipi_dphy_timing_table;
>   
> @@ -393,6 +434,23 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
>   		phy_update_bits(inno, REGISTER_PART_ANALOG, 0x0b,
>   				CLOCK_LANE_VOD_RANGE_SET_MASK,
>   				CLOCK_LANE_VOD_RANGE_SET(VOD_MAX_RANGE));
> +	} else if (inno->pdata->max_rate == MAX_1_5GHZ) {
> +		phy_update_bits(inno, REGISTER_PART_ANALOG, 0x18,
> +				LANE0_PRE_EMPHASIS_ENABLE_MASK, LANE0_PRE_EMPHASIS_ENABLE);
> +		phy_update_bits(inno, REGISTER_PART_ANALOG, 0x18,
> +				LANE1_PRE_EMPHASIS_ENABLE_MASK, LANE1_PRE_EMPHASIS_ENABLE);
> +		phy_update_bits(inno, REGISTER_PART_ANALOG, 0x19,
> +				PRE_EMPHASIS_RANGE_SET_MASK,
> +				PRE_EMPHASIS_RANGE_SET(PRE_EMPHASIS_MID_RANGE));
> +		phy_update_bits(inno, REGISTER_PART_ANALOG, 0x1a,
> +				LANE0_PRE_EMPHASIS_RANGE_SET_MASK,
> +				LANE0_PRE_EMPHASIS_RANGE_SET(PRE_EMPHASIS_MID_RANGE));
> +		phy_update_bits(inno, REGISTER_PART_ANALOG, 0x1b,
> +				LANE1_PRE_EMPHASIS_RANGE_SET_MASK,
> +				LANE1_PRE_EMPHASIS_RANGE_SET(PRE_EMPHASIS_MID_RANGE));
> +		phy_update_bits(inno, REGISTER_PART_ANALOG, 0x0b,
> +				CLOCK_LANE_VOD_RANGE_SET_MASK,
> +				CLOCK_LANE_VOD_RANGE_SET(VOD_MAX_RANGE));
>   	}
>   	/* Enable PLL and LDO */
>   	phy_update_bits(inno, REGISTER_PART_ANALOG, 0x01,
> @@ -518,10 +576,25 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
>   				T_TA_WAIT_CNT(ta_wait));
>   	}
>   
> -	/* Enable all lanes on analog part */
> +	/* Enable lanes on analog part */
> +	switch (inno->pdata->max_lanes) {
> +	case 1:
> +		val =  LANE_EN_0;
> +		break;
> +	case 2:
> +		val =  LANE_EN_0 | LANE_EN_1;
> +		break;
> +	case 3:
> +		val = LANE_EN_0 | LANE_EN_1 | LANE_EN_2;
> +		break;
> +	case 4:
> +	default:
> +		val = LANE_EN_0 | LANE_EN_1 | LANE_EN_2 | LANE_EN_3;
> +		break;
> +	}
> +
>   	phy_update_bits(inno, REGISTER_PART_ANALOG, 0x00,
> -			LANE_EN_MASK, LANE_EN_CK | LANE_EN_3 | LANE_EN_2 |
> -			LANE_EN_1 | LANE_EN_0);
> +			LANE_EN_MASK, LANE_EN_CK | val);
>   }
>   
>   static void inno_dsidphy_lvds_mode_enable(struct inno_dsidphy *inno)
> @@ -680,12 +753,21 @@ static const struct inno_video_phy_plat_data max_1ghz_video_phy_plat_data = {
>   	.inno_mipi_dphy_timing_table = inno_mipi_dphy_timing_table_max_1ghz,
>   	.num_timings = ARRAY_SIZE(inno_mipi_dphy_timing_table_max_1ghz),
>   	.max_rate = MAX_1GHZ,
> +	.max_lanes = 4,
> +};
> +
> +static const struct inno_video_phy_plat_data max_1_5ghz_video_phy_plat_data = {
> +	.inno_mipi_dphy_timing_table = inno_mipi_dphy_timing_table_max_1_5ghz,
> +	.num_timings = ARRAY_SIZE(inno_mipi_dphy_timing_table_max_1_5ghz),
> +	.max_rate = MAX_1_5GHZ,
> +	.max_lanes = 2,
>   };
>   
>   static const struct inno_video_phy_plat_data max_2_5ghz_video_phy_plat_data = {
>   	.inno_mipi_dphy_timing_table = inno_mipi_dphy_timing_table_max_2_5ghz,
>   	.num_timings = ARRAY_SIZE(inno_mipi_dphy_timing_table_max_2_5ghz),
>   	.max_rate = MAX_2_5GHZ,
> +	.max_lanes = 4,
>   };
>   
>   static int inno_dsidphy_probe(struct platform_device *pdev)
> @@ -767,6 +849,9 @@ static const struct of_device_id inno_dsidphy_of_match[] = {
>   	}, {
>   		.compatible = "rockchip,rk3368-dsi-dphy",
>   		.data = &max_1ghz_video_phy_plat_data,
> +	}, {
> +		.compatible = "rockchip,rk3506-dsi-dphy",
> +		.data = &max_1_5ghz_video_phy_plat_data,
>   	}, {
>   		.compatible = "rockchip,rk3568-dsi-dphy",
>   		.data = &max_2_5ghz_video_phy_plat_data,

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From neil.armstrong at linaro.org  Tue Nov 18 05:50:37 2025
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Tue, 18 Nov 2025 14:50:37 +0100
Subject: [PATCH 5/9] drm/panel: ilitek-ili9881d: Add support for
 Wanchanglong W552946AAA panel
In-Reply-To: <20251106020632.92-6-kernel@airkyi.com>
References: <20251106020632.92-1-kernel@airkyi.com>
 <20251106020632.92-6-kernel@airkyi.com>
Message-ID: <e21760e8-4eaf-4181-a328-5d0d205b7ae0@linaro.org>

On 11/6/25 03:06, Chaoyi Chen wrote:
> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> 
> W552946AAA is a panel by Wanchanglong. This panel utilizes the
> Ilitek ILI9881D controller.
> 
> W552946AAA is similar to W552946ABA, but the W552946AAA only
> uses 2 lanes.
> 
> Tested on rk3506g-evb1-v10.
> 
> Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> ---
>   drivers/gpu/drm/panel/panel-ilitek-ili9881c.c | 225 ++++++++++++++++++
>   1 file changed, 225 insertions(+)
> 
> diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c
> index ad4993b2f92a..9b3e9450808d 100644
> --- a/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c
> +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c
> @@ -820,6 +820,204 @@ static const struct ili9881c_instr tl050hdv35_init[] = {
>   	ILI9881C_COMMAND_INSTR(0xd3, 0x39),
>   };
>   
> +static const struct ili9881c_instr w552946aaa_init[] = {
> +	ILI9881C_SWITCH_PAGE_INSTR(3),
> +	ILI9881C_COMMAND_INSTR(0x01, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x02, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x03, 0x53),
> +	ILI9881C_COMMAND_INSTR(0x04, 0x53),
> +	ILI9881C_COMMAND_INSTR(0x05, 0x13),
> +	ILI9881C_COMMAND_INSTR(0x06, 0x04),
> +	ILI9881C_COMMAND_INSTR(0x07, 0x02),
> +	ILI9881C_COMMAND_INSTR(0x08, 0x02),
> +	ILI9881C_COMMAND_INSTR(0x09, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x0a, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x0b, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x0c, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x0d, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x0e, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x0f, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x10, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x11, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x12, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x13, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x14, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x15, 0x08),
> +	ILI9881C_COMMAND_INSTR(0x16, 0x10),
> +	ILI9881C_COMMAND_INSTR(0x17, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x18, 0x08),
> +	ILI9881C_COMMAND_INSTR(0x19, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x1a, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x1b, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x1c, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x1d, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x1e, 0xc0),
> +	ILI9881C_COMMAND_INSTR(0x1f, 0x80),
> +	ILI9881C_COMMAND_INSTR(0x20, 0x02),
> +	ILI9881C_COMMAND_INSTR(0x21, 0x09),
> +	ILI9881C_COMMAND_INSTR(0x22, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x23, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x24, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x25, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x26, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x27, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x28, 0x55),
> +	ILI9881C_COMMAND_INSTR(0x29, 0x03),
> +	ILI9881C_COMMAND_INSTR(0x2a, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x2b, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x2c, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x2d, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x2e, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x2f, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x30, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x31, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x32, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x33, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x34, 0x04),
> +	ILI9881C_COMMAND_INSTR(0x35, 0x05),
> +	ILI9881C_COMMAND_INSTR(0x36, 0x05),
> +	ILI9881C_COMMAND_INSTR(0x37, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x38, 0x3c),
> +	ILI9881C_COMMAND_INSTR(0x39, 0x35),
> +	ILI9881C_COMMAND_INSTR(0x3a, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x3b, 0x40),
> +	ILI9881C_COMMAND_INSTR(0x3c, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x3d, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x3e, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x3f, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x40, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x41, 0x88),
> +	ILI9881C_COMMAND_INSTR(0x42, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x43, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x44, 0x1f),
> +	ILI9881C_COMMAND_INSTR(0x50, 0x01),
> +	ILI9881C_COMMAND_INSTR(0x51, 0x23),
> +	ILI9881C_COMMAND_INSTR(0x52, 0x45),
> +	ILI9881C_COMMAND_INSTR(0x53, 0x67),
> +	ILI9881C_COMMAND_INSTR(0x54, 0x89),
> +	ILI9881C_COMMAND_INSTR(0x55, 0xab),
> +	ILI9881C_COMMAND_INSTR(0x56, 0x01),
> +	ILI9881C_COMMAND_INSTR(0x57, 0x23),
> +	ILI9881C_COMMAND_INSTR(0x58, 0x45),
> +	ILI9881C_COMMAND_INSTR(0x59, 0x67),
> +	ILI9881C_COMMAND_INSTR(0x5a, 0x89),
> +	ILI9881C_COMMAND_INSTR(0x5b, 0xab),
> +	ILI9881C_COMMAND_INSTR(0x5c, 0xcd),
> +	ILI9881C_COMMAND_INSTR(0x5d, 0xef),
> +	ILI9881C_COMMAND_INSTR(0x5e, 0x03),
> +	ILI9881C_COMMAND_INSTR(0x5f, 0x14),
> +	ILI9881C_COMMAND_INSTR(0x60, 0x15),
> +	ILI9881C_COMMAND_INSTR(0x61, 0x0c),
> +	ILI9881C_COMMAND_INSTR(0x62, 0x0d),
> +	ILI9881C_COMMAND_INSTR(0x63, 0x0e),
> +	ILI9881C_COMMAND_INSTR(0x64, 0x0f),
> +	ILI9881C_COMMAND_INSTR(0x65, 0x10),
> +	ILI9881C_COMMAND_INSTR(0x66, 0x11),
> +	ILI9881C_COMMAND_INSTR(0x67, 0x08),
> +	ILI9881C_COMMAND_INSTR(0x68, 0x02),
> +	ILI9881C_COMMAND_INSTR(0x69, 0x0a),
> +	ILI9881C_COMMAND_INSTR(0x6a, 0x02),
> +	ILI9881C_COMMAND_INSTR(0x6b, 0x02),
> +	ILI9881C_COMMAND_INSTR(0x6c, 0x02),
> +	ILI9881C_COMMAND_INSTR(0x6d, 0x02),
> +	ILI9881C_COMMAND_INSTR(0x6e, 0x02),
> +	ILI9881C_COMMAND_INSTR(0x6f, 0x02),
> +	ILI9881C_COMMAND_INSTR(0x70, 0x02),
> +	ILI9881C_COMMAND_INSTR(0x71, 0x02),
> +	ILI9881C_COMMAND_INSTR(0x72, 0x06),
> +	ILI9881C_COMMAND_INSTR(0x73, 0x02),
> +	ILI9881C_COMMAND_INSTR(0x74, 0x02),
> +	ILI9881C_COMMAND_INSTR(0x75, 0x14),
> +	ILI9881C_COMMAND_INSTR(0x76, 0x15),
> +	ILI9881C_COMMAND_INSTR(0x77, 0x0f),
> +	ILI9881C_COMMAND_INSTR(0x78, 0x0e),
> +	ILI9881C_COMMAND_INSTR(0x79, 0x0d),
> +	ILI9881C_COMMAND_INSTR(0x7a, 0x0c),
> +	ILI9881C_COMMAND_INSTR(0x7b, 0x11),
> +	ILI9881C_COMMAND_INSTR(0x7c, 0x10),
> +	ILI9881C_COMMAND_INSTR(0x7d, 0x06),
> +	ILI9881C_COMMAND_INSTR(0x7e, 0x02),
> +	ILI9881C_COMMAND_INSTR(0x7f, 0x0a),
> +	ILI9881C_COMMAND_INSTR(0x80, 0x02),
> +	ILI9881C_COMMAND_INSTR(0x81, 0x02),
> +	ILI9881C_COMMAND_INSTR(0x82, 0x02),
> +	ILI9881C_COMMAND_INSTR(0x83, 0x02),
> +	ILI9881C_COMMAND_INSTR(0x84, 0x02),
> +	ILI9881C_COMMAND_INSTR(0x85, 0x02),
> +	ILI9881C_COMMAND_INSTR(0x86, 0x02),
> +	ILI9881C_COMMAND_INSTR(0x87, 0x02),
> +	ILI9881C_COMMAND_INSTR(0x88, 0x08),
> +	ILI9881C_COMMAND_INSTR(0x89, 0x02),
> +	ILI9881C_COMMAND_INSTR(0x8a, 0x02),
> +	ILI9881C_SWITCH_PAGE_INSTR(4),
> +	ILI9881C_COMMAND_INSTR(0x00, 0x80),
> +	ILI9881C_COMMAND_INSTR(0x70, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x71, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x66, 0xfe),
> +	ILI9881C_COMMAND_INSTR(0x82, 0x15),
> +	ILI9881C_COMMAND_INSTR(0x84, 0x15),
> +	ILI9881C_COMMAND_INSTR(0x85, 0x15),
> +	ILI9881C_COMMAND_INSTR(0x3a, 0x24),
> +	ILI9881C_COMMAND_INSTR(0x32, 0xac),
> +	ILI9881C_COMMAND_INSTR(0x8c, 0x80),
> +	ILI9881C_COMMAND_INSTR(0x3c, 0xf5),
> +	ILI9881C_COMMAND_INSTR(0x88, 0x33),
> +	ILI9881C_SWITCH_PAGE_INSTR(1),
> +	ILI9881C_COMMAND_INSTR(0x22, 0x0a),
> +	ILI9881C_COMMAND_INSTR(0x31, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x53, 0x78),
> +	ILI9881C_COMMAND_INSTR(0x55, 0x7b),
> +	ILI9881C_COMMAND_INSTR(0x60, 0x20),
> +	ILI9881C_COMMAND_INSTR(0x61, 0x00),
> +	ILI9881C_COMMAND_INSTR(0x62, 0x0d),
> +	ILI9881C_COMMAND_INSTR(0x63, 0x00),
> +	ILI9881C_COMMAND_INSTR(0xa0, 0x00),
> +	ILI9881C_COMMAND_INSTR(0xa1, 0x10),
> +	ILI9881C_COMMAND_INSTR(0xa2, 0x1c),
> +	ILI9881C_COMMAND_INSTR(0xa3, 0x13),
> +	ILI9881C_COMMAND_INSTR(0xa4, 0x15),
> +	ILI9881C_COMMAND_INSTR(0xa5, 0x26),
> +	ILI9881C_COMMAND_INSTR(0xa6, 0x1a),
> +	ILI9881C_COMMAND_INSTR(0xa7, 0x1d),
> +	ILI9881C_COMMAND_INSTR(0xa8, 0x67),
> +	ILI9881C_COMMAND_INSTR(0xa9, 0x1c),
> +	ILI9881C_COMMAND_INSTR(0xaa, 0x29),
> +	ILI9881C_COMMAND_INSTR(0xab, 0x5b),
> +	ILI9881C_COMMAND_INSTR(0xac, 0x26),
> +	ILI9881C_COMMAND_INSTR(0xad, 0x28),
> +	ILI9881C_COMMAND_INSTR(0xae, 0x5c),
> +	ILI9881C_COMMAND_INSTR(0xaf, 0x30),
> +	ILI9881C_COMMAND_INSTR(0xb0, 0x31),
> +	ILI9881C_COMMAND_INSTR(0xb1, 0x32),
> +	ILI9881C_COMMAND_INSTR(0xb2, 0x00),
> +	ILI9881C_COMMAND_INSTR(0xb1, 0x2e),
> +	ILI9881C_COMMAND_INSTR(0xb2, 0x32),
> +	ILI9881C_COMMAND_INSTR(0xb3, 0x00),
> +	ILI9881C_COMMAND_INSTR(0xb6, 0x02),
> +	ILI9881C_COMMAND_INSTR(0xb7, 0x03),
> +	ILI9881C_COMMAND_INSTR(0xc0, 0x00),
> +	ILI9881C_COMMAND_INSTR(0xc1, 0x10),
> +	ILI9881C_COMMAND_INSTR(0xc2, 0x1c),
> +	ILI9881C_COMMAND_INSTR(0xc3, 0x13),
> +	ILI9881C_COMMAND_INSTR(0xc4, 0x15),
> +	ILI9881C_COMMAND_INSTR(0xc5, 0x26),
> +	ILI9881C_COMMAND_INSTR(0xc6, 0x1a),
> +	ILI9881C_COMMAND_INSTR(0xc7, 0x1d),
> +	ILI9881C_COMMAND_INSTR(0xc8, 0x67),
> +	ILI9881C_COMMAND_INSTR(0xc9, 0x1c),
> +	ILI9881C_COMMAND_INSTR(0xca, 0x29),
> +	ILI9881C_COMMAND_INSTR(0xcb, 0x5b),
> +	ILI9881C_COMMAND_INSTR(0xcc, 0x26),
> +	ILI9881C_COMMAND_INSTR(0xcd, 0x28),
> +	ILI9881C_COMMAND_INSTR(0xce, 0x5c),
> +	ILI9881C_COMMAND_INSTR(0xcf, 0x30),
> +	ILI9881C_COMMAND_INSTR(0xd0, 0x31),
> +	ILI9881C_COMMAND_INSTR(0xd1, 0x2e),
> +	ILI9881C_COMMAND_INSTR(0xd2, 0x32),
> +	ILI9881C_COMMAND_INSTR(0xd3, 0x00),
> +	ILI9881C_SWITCH_PAGE_INSTR(0),
> +};
> +
>   static const struct ili9881c_instr w552946ab_init[] = {
>   	ILI9881C_SWITCH_PAGE_INSTR(3),
>   	ILI9881C_COMMAND_INSTR(0x01, 0x00),
> @@ -1772,6 +1970,23 @@ static const struct drm_display_mode tl050hdv35_default_mode = {
>   	.height_mm	= 110,
>   };
>   
> +static const struct drm_display_mode w552946aaa_default_mode = {
> +	.clock		= 65000,
> +
> +	.hdisplay	= 720,
> +	.hsync_start	= 720 + 52,
> +	.hsync_end	= 720 + 52 + 8,
> +	.htotal		= 720 + 52 + 8 + 48,
> +
> +	.vdisplay	= 1280,
> +	.vsync_start	= 1280 + 16,
> +	.vsync_end	= 1280 + 16 + 6,
> +	.vtotal		= 1280 + 16 + 6 + 15,
> +
> +	.width_mm	= 68,
> +	.height_mm	= 121,
> +};
> +
>   static const struct drm_display_mode w552946aba_default_mode = {
>   	.clock		= 64000,
>   
> @@ -1983,6 +2198,15 @@ static const struct ili9881c_desc tl050hdv35_desc = {
>   	.default_address_mode = 0x03,
>   };
>   
> +static const struct ili9881c_desc w552946aaa_desc = {
> +	.init = w552946aaa_init,
> +	.init_length = ARRAY_SIZE(w552946aaa_init),
> +	.mode = &w552946aaa_default_mode,
> +	.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
> +		      MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_NO_EOT_PACKET,
> +	.lanes = 2,
> +};
> +
>   static const struct ili9881c_desc w552946aba_desc = {
>   	.init = w552946ab_init,
>   	.init_length = ARRAY_SIZE(w552946ab_init),
> @@ -2023,6 +2247,7 @@ static const struct of_device_id ili9881c_of_match[] = {
>   	{ .compatible = "feixin,k101-im2byl02", .data = &k101_im2byl02_desc },
>   	{ .compatible = "startek,kd050hdfia020", .data = &kd050hdfia020_desc },
>   	{ .compatible = "tdo,tl050hdv35", .data = &tl050hdv35_desc },
> +	{ .compatible = "wanchanglong,w552946aaa", .data = &w552946aaa_desc },
>   	{ .compatible = "wanchanglong,w552946aba", .data = &w552946aba_desc },
>   	{ .compatible = "ampire,am8001280g", .data = &am8001280g_desc },
>   	{ .compatible = "raspberrypi,dsi-7inch", &rpi_7inch_desc },

Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From michael.opdenacker at rootcommit.com  Tue Nov 18 07:56:41 2025
From: michael.opdenacker at rootcommit.com (Michael Opdenacker)
Date: Tue, 18 Nov 2025 15:56:41 +0000 (UTC)
Subject: [PATCH v3 0/2] arm64: dts: rockchip: add Tinker Board 3 and 3S
 device tree
Message-ID: <20251118-tinker3-v3-0-2903693f2ebb@rootcommit.com>

Add initial device tree support for Asus Tinker Board 3 [1] and 3S [2],
which are SBCs based on the Rockchip 3566 SoC.

The "3S" version ("S" for "storage") is just a regular Tinker Board 3
fitted with a 16 GB eMMC and a "mask ROM" DIP switch
(to mask the eMMC and enter "Mask ROM" mode for recovery).

This adds support for:
- Debug UART (/dev/ttyS2)
- SD card (/dev/mmcblk1)
- eMMC (/dev/mmcblk0, only on Tinker Board 3S)
- I2C:
  - i2c0 (internal bus with a PMIC and regulators)
  - i2c2 (internal bus with an at24 eeprom and an RTC device)
- USB 2.0 ports
- 2 GPIO LEDS

This code was tested on Tinker Board 3S using the "master"
branch of the Linux kernel.

[1] https://tinker-board.asus.com/series/tinker-board-3.html
[2] https://tinker-board.asus.com/series/tinker-board-3s.html

Changes in V3:
- rockchip.yaml: group Tinker Board 3/3S in the same section
- Remove this Acked-by as the code changed substantially:
  Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
- Remove "asus,rk3566-tinker-board-3" from rk3566-tinker-board-3s.dts,
  which conflicted with the change in rockchip.yaml and
  could create an issue if some code unexpectedly turns out
  to be compatible with 3 but not 3S.
  If you don't agree, than we can keep V2.

Changes in V2:
- Rename "Tinker board" to "Tinker Board"
  in commit messages and DT code
- Insert "-board" in DT file names
- Insert "-board" in new compatible string too
- Commit messages: change the way the references are introduced
  ("[1] https://..." instead of "Link: https://... [1]")
- Reorder alias properties and node names
- Add missing "cpu-supply" property to cpu nodes
- Use standard "eeprom at addr" node name for at24 eeprom
- DT commit message: add missing "Asus" before "Tinker"

Michael Opdenacker (2):
  dt-bindings: arm: rockchip: Add Asus Tinker Board 3 and 3S
  arm64: dts: rockchip: Add Asus Tinker Board 3 and 3S device tree

.../devicetree/bindings/arm/rockchip.yaml     |  11 +
 arch/arm64/boot/dts/rockchip/Makefile         |   2 +
 .../dts/rockchip/rk3566-tinker-board-3.dts    |  14 +
 .../dts/rockchip/rk3566-tinker-board-3.dtsi   | 280 ++++++++++++++++++
 .../dts/rockchip/rk3566-tinker-board-3s.dts   |  30 ++
 5 files changed, 337 insertions(+)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3.dts
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3.dtsi
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3s.dts

---
Michael Opdenacker (2):
      dt-bindings: arm: rockchip: Add Asus Tinker Board 3/3S
      arm64: dts: rockchip: Add Asus Tinker Board 3 and 3S device tree

 .../devicetree/bindings/arm/rockchip.yaml          |   7 +
 arch/arm64/boot/dts/rockchip/Makefile              |   2 +
 .../boot/dts/rockchip/rk3566-tinker-board-3.dts    |  14 ++
 .../boot/dts/rockchip/rk3566-tinker-board-3.dtsi   | 280 +++++++++++++++++++++
 .../boot/dts/rockchip/rk3566-tinker-board-3s.dts   |  30 +++
 5 files changed, 333 insertions(+)
---
base-commit: e7c375b181600caf135cfd03eadbc45eb530f2cb
change-id: 20251117-tinker3-88e32dfa9138

Best regards,
-- 
Michael Opdenacker <michael.opdenacker at rootcommit.com>



From michael.opdenacker at rootcommit.com  Tue Nov 18 07:56:43 2025
From: michael.opdenacker at rootcommit.com (Michael Opdenacker)
Date: Tue, 18 Nov 2025 15:56:43 +0000 (UTC)
Subject: [PATCH v3 2/2] arm64: dts: rockchip: Add Asus Tinker Board 3 and
 3S device tree
In-Reply-To: <20251118-tinker3-v3-0-2903693f2ebb@rootcommit.com>
References: <20251118-tinker3-v3-0-2903693f2ebb@rootcommit.com>
Message-ID: <20251118-tinker3-v3-2-2903693f2ebb@rootcommit.com>

Add initial device tree support for Asus Tinker Board 3 [1] and 3S [2],
which are SBCs based on the Rockchip 3566 SoC.

The "3S" version ("S" for "storage") just adds a 16 GB eMMC
and a "mask ROM" DIP switch (to mask the eMMC and enter "Mask ROM"
mode for recovery) to the "3" version.

This adds support for:
- Debug UART (/dev/ttyS2)
- SD card (/dev/mmcblk1)
- eMMC (/dev/mmcblk0, only on Tinker Board 3S)
- I2C:
  - i2c0 (internal bus with a PMIC and regulators)
  - i2c2 (internal bus with an at24 eeprom and an RTC device)
- USB 2.0 ports
- 2 GPIO LEDS

[1] https://tinker-board.asus.com/series/tinker-board-3.html
[2] https://tinker-board.asus.com/series/tinker-board-3s.html

Signed-off-by: Michael Opdenacker <michael.opdenacker at rootcommit.com>
---
 arch/arm64/boot/dts/rockchip/Makefile              |   2 +
 .../boot/dts/rockchip/rk3566-tinker-board-3.dts    |  14 ++
 .../boot/dts/rockchip/rk3566-tinker-board-3.dtsi   | 280 +++++++++++++++++++++
 .../boot/dts/rockchip/rk3566-tinker-board-3s.dts   |  30 +++
 4 files changed, 326 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index ad684e3831bc..e0d8b9ed176d 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -130,6 +130,8 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-lubancat-1.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-nanopi-r3s.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-bigtreetech-cb2-manta.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-bigtreetech-pi2.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-tinker-board-3.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-tinker-board-3s.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-bpi-r2-pro.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-v10.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-fastrhino-r66s.dtb
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3.dts b/arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3.dts
new file mode 100644
index 000000000000..af11faff5564
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2025 Michael Opdenacker <michael.opdenacker at rootcommit.com>
+ */
+
+/dts-v1/;
+
+#include "rk3566-tinker-board-3.dtsi"
+
+/ {
+	model = "Asus Tinker Board 3";
+	compatible = "asus,rk3566-tinker-board-3", "rockchip,rk3566";
+};
+
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3.dtsi
new file mode 100644
index 000000000000..8544d56031f2
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3.dtsi
@@ -0,0 +1,280 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2025 Michael Opdenacker <michael.opdenacker at rootcommit.com>
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
+#include "rk3566.dtsi"
+
+/ {
+	aliases {
+		i2c0 = &i2c0;
+		i2c2 = &i2c2;
+		mmc1 = &sdmmc0;
+		serial2 = &uart2;
+	};
+
+	chosen {
+		stdout-path = "serial2:1500000n8";
+	};
+
+	gpio_leds: gpio-leds {
+		compatible = "gpio-leds";
+
+		act-led {
+			gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger="mmc1";
+		};
+
+		rsv-led {
+			gpios = <&gpio0 RK_PD6 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger="none";
+		};
+	};
+
+	vcc3v3_sys: regulator-3v3-vcc-sys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+
+	vcc5v0_sys: regulator-5v0-vcc-sys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+	};
+
+	vcc5v0_usb_host: regulator-5v0-vcc-usb-host {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&usb_host_pwren_h>;
+		regulator-name = "vcc5v0_usb_host";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc5v0_sys>;
+	};
+};
+
+&cpu0 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu1 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu2 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu3 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&i2c0 {
+	status = "okay";
+
+	rk809: pmic at 20 {
+		compatible = "rockchip,rk809";
+		reg = <0x20>;
+		assigned-clocks = <&cru I2S1_MCLKOUT_TX>;
+		assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>;
+		#clock-cells = <1>;
+		clocks = <&cru I2S1_MCLKOUT_TX>;
+		clock-names = "mclk";
+		clock-output-names = "rk809-clkout1", "rk809-clkout2";
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_int_l>, <&i2s1m0_mclk>;
+		#sound-dai-cells = <0>;
+		system-power-controller;
+		wakeup-source;
+
+		vcc1-supply = <&vcc3v3_sys>;
+		vcc2-supply = <&vcc3v3_sys>;
+		vcc3-supply = <&vcc3v3_sys>;
+		vcc4-supply = <&vcc3v3_sys>;
+		vcc5-supply = <&vcc3v3_sys>;
+		vcc6-supply = <&vcc3v3_sys>;
+		vcc7-supply = <&vcc3v3_sys>;
+		vcc8-supply = <&vcc3v3_sys>;
+		vcc9-supply = <&vcc3v3_sys>;
+
+		regulators {
+			vcc_1v8: DCDC_REG5 {
+				regulator-name = "vcc_1v8";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_3v3: SWITCH_REG1 {
+				regulator-name = "vcc_3v3";
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc3v3_sd: SWITCH_REG2 {
+				regulator-name = "vcc3v3_sd";
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vccio_sd: LDO_REG5 {
+				regulator-name = "vccio_sd";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+		};
+	};
+
+	vdd_cpu: regulator at 40 {
+		compatible = "silergy,syr827";
+		reg = <0x40>;
+		fcs,suspend-voltage-selector = <1>;
+		regulator-name = "vdd_cpu";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <830000>;
+		regulator-max-microvolt = <1200000>;
+		regulator-ramp-delay = <2300>;
+		vin-supply = <&vcc3v3_sys>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+};
+
+&i2c2 {
+	status = "okay";
+
+	eeprom at 50 {
+		compatible = "atmel,24c08";
+		reg = <0x50>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&tb3_eeprom>;
+		status = "okay";
+	};
+
+	rtc_isl1208: rtc at 6f {
+		compatible = "isil,isl1208";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_externalrtc_reg>;
+		interrupt-names = "irq";
+		interrupts-extended = <&gpio0 RK_PD3 IRQ_TYPE_EDGE_FALLING>;
+		reg = <0x6f>;
+		status = "okay";
+	};
+};
+
+&pinctrl {
+	pmic {
+		pmic_int_l: pmic-int-l {
+			rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	usb {
+		usb_host_pwren_h: usb-host-pwren-h {
+			rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		usb_otg_pwren_h: usb-otg-pwren-h {
+			rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	rtc {
+		pinctrl_externalrtc_reg: externalrtcreggrp {
+			rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	eeprom {
+		tb3_eeprom: tb3-eeprom {
+			rockchip,pins = <3 RK_PC1 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+};
+
+&sdmmc0 {
+	bus-width = <4>;
+	cap-sd-highspeed;
+	disable-wp;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
+	vmmc-supply = <&vcc3v3_sd>;
+	vqmmc-supply = <&vccio_sd>;
+	status = "okay";
+};
+
+&uart2 {
+	status = "okay";
+};
+
+&usb_host0_ehci {
+	status = "okay";
+};
+
+&usb_host0_ohci {
+	status = "okay";
+};
+
+&usb_host1_ehci {
+	status = "okay";
+};
+
+&usb_host1_ohci {
+	status = "okay";
+};
+
+&usb2phy0 {
+	status = "okay";
+};
+
+&usb2phy0_host {
+	phy-supply = <&vcc5v0_usb_host>;
+	status = "okay";
+};
+
+&usb2phy1 {
+	status = "okay";
+};
+
+&usb2phy1_host {
+	phy-supply = <&vcc5v0_usb_host>;
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3s.dts b/arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3s.dts
new file mode 100644
index 000000000000..3624ebc8a26f
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3s.dts
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2025 Michael Opdenacker <michael.opdenacker at rootcommit.com>
+ */
+
+/dts-v1/;
+
+#include "rk3566-tinker-board-3.dtsi"
+
+/ {
+	model = "Asus Tinker Board 3S";
+	compatible = "asus,rk3566-tinker-board-3s", "rockchip,rk3566";
+
+	aliases {
+		mmc0 = &sdhci;
+	};
+};
+
+&sdhci {
+	bus-width = <8>;
+	cap-mmc-highspeed;
+	max-frequency = <200000000>;
+	mmc-hs200-1_8v;
+	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
+	vmmc-supply = <&vcc_3v3>;
+	vqmmc-supply = <&vcc_1v8>;
+	status = "okay";
+};

-- 
2.43.0



From michael.opdenacker at rootcommit.com  Tue Nov 18 07:56:42 2025
From: michael.opdenacker at rootcommit.com (Michael Opdenacker)
Date: Tue, 18 Nov 2025 15:56:42 +0000 (UTC)
Subject: [PATCH v3 1/2] dt-bindings: arm: rockchip: Add Asus Tinker Board
 3/3S
In-Reply-To: <20251118-tinker3-v3-0-2903693f2ebb@rootcommit.com>
References: <20251118-tinker3-v3-0-2903693f2ebb@rootcommit.com>
Message-ID: <20251118-tinker3-v3-1-2903693f2ebb@rootcommit.com>

Document the compatible strings for Asus Tinker Board 3 [1] and 3S [2],
which are SBCs based on the Rockchip 3566 SoC.

The "3S" version ("S" for "storage") just adds a 16 GB eMMC
and a "mask ROM" DIP switch to the "3" version.

[1] https://tinker-board.asus.com/series/tinker-board-3.html
[2] https://tinker-board.asus.com/series/tinker-board-3s.html

Signed-off-by: Michael Opdenacker <michael.opdenacker at rootcommit.com>

---

Changes in V3:

- Remove this Acked-by as the binding code changed substantially:
  Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---
 Documentation/devicetree/bindings/arm/rockchip.yaml | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
index 6aceaa8acbb2..800c11323a4f 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.yaml
+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
@@ -86,6 +86,13 @@ properties:
           - const: asus,rk3288-tinker-s
           - const: rockchip,rk3288
 
+      - description: Asus Tinker Board 3/3S
+        items:
+          - enum:
+              - asus,rk3566-tinker-board-3
+              - asus,rk3566-tinker-board-3s
+          - const: rockchip,rk3566
+
       - description: Beelink A1
         items:
           - const: azw,beelink-a1

-- 
2.43.0



From krzk at kernel.org  Tue Nov 18 08:31:03 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Tue, 18 Nov 2025 17:31:03 +0100
Subject: [PATCH v3 1/2] dt-bindings: arm: rockchip: Add Asus Tinker Board
 3/3S
In-Reply-To: <20251118-tinker3-v3-1-2903693f2ebb@rootcommit.com>
References: <20251118-tinker3-v3-0-2903693f2ebb@rootcommit.com>
 <20251118-tinker3-v3-1-2903693f2ebb@rootcommit.com>
Message-ID: <e134902e-e298-45d0-b94f-77748bb948c4@kernel.org>

On 18/11/2025 16:56, Michael Opdenacker wrote:
> Document the compatible strings for Asus Tinker Board 3 [1] and 3S [2],
> which are SBCs based on the Rockchip 3566 SoC.
> 
> The "3S" version ("S" for "storage") just adds a 16 GB eMMC
> and a "mask ROM" DIP switch to the "3" version.
> 
> [1] https://tinker-board.asus.com/series/tinker-board-3.html
> [2] https://tinker-board.asus.com/series/tinker-board-3s.html
> 
> Signed-off-by: Michael Opdenacker <michael.opdenacker at rootcommit.com>
> 
> ---
> 
> Changes in V3:
> 
> - Remove this Acked-by as the binding code changed substantially:
>   Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>

Above commit msg and DTS suggests they are pretty compatible with each
other, so I don't quite get why this changed. Your changelog says
"unexpectedly turns out to be compatible with 3 but not 3S.", but is
this real or are you just guessing? I think you were tricked to change
correct code into this.

Anyway, however odd this is, I don't care enough to stop this patchset, so:

Acked-by: Krzysztof Kozlowski <krzk at kernel.org>


Best regards,
Krzysztof


From Frank.li at nxp.com  Tue Nov 18 09:15:01 2025
From: Frank.li at nxp.com (Frank Li)
Date: Tue, 18 Nov 2025 12:15:01 -0500
Subject: [PATCH v2 2/3] media: rockchip: add driver for the rockchip mipi
 csi-2 receiver
In-Reply-To: <20251114-rockchip-mipi-receiver-v2-2-eb9b43377fc4@collabora.com>
References: <20251114-rockchip-mipi-receiver-v2-0-eb9b43377fc4@collabora.com>
 <20251114-rockchip-mipi-receiver-v2-2-eb9b43377fc4@collabora.com>
Message-ID: <aRyplYZOrGsSxSlp@lizhi-Precision-Tower-5810>

On Tue, Nov 18, 2025 at 12:12:26PM +0100, Michael Riesch via B4 Relay wrote:
> From: Michael Riesch <michael.riesch at collabora.com>
>
> The Rockchip MIPI CSI-2 Receiver is a CSI-2 bridge with one input
> port and one output port. It receives the data with the help of an
> external MIPI PHY (C-PHY or D-PHY) and passes it to the Rockchip
> Video Capture (VICAP) block.
>
> Add a V4L2 subdevice driver for this unit.
>
> Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue at linaro.org>
> Reviewed-by: Mehdi Djait <mehdi.djait at linux.intel.com>
> Signed-off-by: Michael Riesch <michael.riesch at collabora.com>
> ---
>  MAINTAINERS                                    |   1 +
>  drivers/media/platform/rockchip/Kconfig        |   1 +
>  drivers/media/platform/rockchip/Makefile       |   1 +
>  drivers/media/platform/rockchip/rkcsi/Kconfig  |  16 +
>  drivers/media/platform/rockchip/rkcsi/Makefile |   3 +
>  drivers/media/platform/rockchip/rkcsi/rkcsi.c  | 742 +++++++++++++++++++++++++
>  6 files changed, 764 insertions(+)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 145473671a4a..b389f2e631ce 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -22304,6 +22304,7 @@ M:	Michael Riesch <michael.riesch at collabora.com>
>  L:	linux-media at vger.kernel.org
>  S:	Maintained
>  F:	Documentation/devicetree/bindings/media/rockchip,rk3568-mipi-csi.yaml
> +F:	drivers/media/platform/rockchip/rkcsi/
>
>  ROCKCHIP RK3568 RANDOM NUMBER GENERATOR SUPPORT
>  M:	Daniel Golle <daniel at makrotopia.org>
> diff --git a/drivers/media/platform/rockchip/Kconfig b/drivers/media/platform/rockchip/Kconfig
> index ba401d32f01b..54b698c4cd2c 100644
> --- a/drivers/media/platform/rockchip/Kconfig
> +++ b/drivers/media/platform/rockchip/Kconfig
> @@ -4,5 +4,6 @@ comment "Rockchip media platform drivers"
>
>  source "drivers/media/platform/rockchip/rga/Kconfig"
>  source "drivers/media/platform/rockchip/rkcif/Kconfig"
> +source "drivers/media/platform/rockchip/rkcsi/Kconfig"
>  source "drivers/media/platform/rockchip/rkisp1/Kconfig"
>  source "drivers/media/platform/rockchip/rkvdec/Kconfig"
> diff --git a/drivers/media/platform/rockchip/Makefile b/drivers/media/platform/rockchip/Makefile
> index 0e0b2cbbd4bd..522a7d3e30b0 100644
> --- a/drivers/media/platform/rockchip/Makefile
> +++ b/drivers/media/platform/rockchip/Makefile
> @@ -1,5 +1,6 @@
>  # SPDX-License-Identifier: GPL-2.0-only
>  obj-y += rga/
>  obj-y += rkcif/
> +obj-y += rkcsi/
>  obj-y += rkisp1/
>  obj-y += rkvdec/
> diff --git a/drivers/media/platform/rockchip/rkcsi/Kconfig b/drivers/media/platform/rockchip/rkcsi/Kconfig
> new file mode 100644
> index 000000000000..d8004198c386
> --- /dev/null
> +++ b/drivers/media/platform/rockchip/rkcsi/Kconfig
> @@ -0,0 +1,16 @@
> +config VIDEO_ROCKCHIP_CSI
> +	tristate "Rockchip MIPI CSI-2 Receiver"
> +	depends on VIDEO_DEV
> +	depends on ARCH_ROCKCHIP || COMPILE_TEST
> +	depends on V4L_PLATFORM_DRIVERS
> +	depends on PM && COMMON_CLK
> +	select MEDIA_CONTROLLER
> +	select V4L2_FWNODE
> +	select VIDEO_V4L2_SUBDEV_API
> +	help
> +	  This is a driver for Rockchip MIPI CSI-2 Receiver. It is featured
> +	  in various Rockchips SoCs, usually in combination with a Video
> +	  Capture (VICAP) unit (see Rockchip Camera Interface (CIF) driver).
> +
> +	  To compile this driver as a module, choose M here: the module
> +	  will be called rockchip-mipi-csi.
> diff --git a/drivers/media/platform/rockchip/rkcsi/Makefile b/drivers/media/platform/rockchip/rkcsi/Makefile
> new file mode 100644
> index 000000000000..147712cbb68a
> --- /dev/null
> +++ b/drivers/media/platform/rockchip/rkcsi/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0
> +obj-$(CONFIG_VIDEO_ROCKCHIP_CSI) += rockchip-mipi-csi.o
> +rockchip-mipi-csi-objs += rkcsi.o
> diff --git a/drivers/media/platform/rockchip/rkcsi/rkcsi.c b/drivers/media/platform/rockchip/rkcsi/rkcsi.c
> new file mode 100644
> index 000000000000..d4108ce5bbf9
> --- /dev/null
> +++ b/drivers/media/platform/rockchip/rkcsi/rkcsi.c
> @@ -0,0 +1,742 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Rockchip MIPI CSI-2 Receiver Driver
> + *
> + * Copyright (C) 2019 Rockchip Electronics Co., Ltd.
> + * Copyright (C) 2025 Michael Riesch <michael.riesch at wolfvision.net>
> + * Copyright (C) 2025 Collabora, Ltd.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_graph.h>
> +#include <linux/of_platform.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/reset.h>
> +
> +#include <media/mipi-csi2.h>
> +#include <media/v4l2-ctrls.h>
> +#include <media/v4l2-fwnode.h>
> +#include <media/v4l2-subdev.h>
> +
> +#define CSI2HOST_N_LANES     0x04
> +#define CSI2HOST_CSI2_RESETN 0x10
> +#define CSI2HOST_PHY_STATE   0x14
> +#define CSI2HOST_ERR1	     0x20
> +#define CSI2HOST_ERR2	     0x24
> +#define CSI2HOST_MSK1	     0x28
> +#define CSI2HOST_MSK2	     0x2c
> +#define CSI2HOST_CONTROL     0x40

Look like that is designware CSI2 controller, can we build common library
for all dwc csi2 controller, instead of every vendor create individual one.

First try at
https://lore.kernel.org/linux-media/20250821-95_cam-v3-21-c9286fbb34b9 at nxp.com/

Toshiba have similar patch
https://lore.kernel.org/linux-media/aPZd39riAxqfw3mT at lizhi-Precision-Tower-5810/

Frank

> +
> +#define SW_CPHY_EN(x)	     ((x) << 0)
> +#define SW_DSI_EN(x)	     ((x) << 4)
> +#define SW_DATATYPE_FS(x)    ((x) << 8)
> +#define SW_DATATYPE_FE(x)    ((x) << 14)
> +#define SW_DATATYPE_LS(x)    ((x) << 20)
> +#define SW_DATATYPE_LE(x)    ((x) << 26)
> +
> +#define RKCSI_CLKS_MAX	     1
> +
> +enum {
> +	RKCSI_PAD_SINK,
> +	RKCSI_PAD_SRC,
> +	RKCSI_PAD_MAX,
> +};
> +
> +struct rkcsi_format {
> +	u32 code;
> +	u8 depth;
> +	u8 csi_dt;
> +};
> +
> +struct rkcsi_device {
> +	struct device *dev;
> +
> +	void __iomem *base_addr;
> +	struct clk_bulk_data *clks;
> +	unsigned int clks_num;
> +	struct phy *phy;
> +	struct reset_control *reset;
> +
> +	const struct rkcsi_format *formats;
> +	unsigned int formats_num;
> +
> +	struct media_pad pads[RKCSI_PAD_MAX];
> +	struct v4l2_async_notifier notifier;
> +	struct v4l2_fwnode_endpoint vep;
> +	struct v4l2_subdev sd;
> +
> +	struct v4l2_subdev *source_sd;
> +	u32 source_pad;
> +};
> +
> +static const struct v4l2_mbus_framefmt default_format = {
> +	.width = 3840,
> +	.height = 2160,
> +	.code = MEDIA_BUS_FMT_SRGGB10_1X10,
> +	.field = V4L2_FIELD_NONE,
> +	.colorspace = V4L2_COLORSPACE_RAW,
> +	.ycbcr_enc = V4L2_YCBCR_ENC_601,
> +	.quantization = V4L2_QUANTIZATION_FULL_RANGE,
> +	.xfer_func = V4L2_XFER_FUNC_NONE,
> +};
> +
> +static const struct rkcsi_format formats[] = {
> +	/* YUV formats */
> +	{
> +		.code = MEDIA_BUS_FMT_YUYV8_1X16,
> +		.depth = 16,
> +		.csi_dt = MIPI_CSI2_DT_YUV422_8B,
> +	},
> +	{
> +		.code = MEDIA_BUS_FMT_UYVY8_1X16,
> +		.depth = 16,
> +		.csi_dt = MIPI_CSI2_DT_YUV422_8B,
> +	},
> +	{
> +		.code = MEDIA_BUS_FMT_YVYU8_1X16,
> +		.depth = 16,
> +		.csi_dt = MIPI_CSI2_DT_YUV422_8B,
> +	},
> +	{
> +		.code = MEDIA_BUS_FMT_VYUY8_1X16,
> +		.depth = 16,
> +		.csi_dt = MIPI_CSI2_DT_YUV422_8B,
> +	},
> +	/* RGB formats */
> +	{
> +		.code = MEDIA_BUS_FMT_RGB888_1X24,
> +		.depth = 24,
> +		.csi_dt = MIPI_CSI2_DT_RGB888,
> +	},
> +	{
> +		.code = MEDIA_BUS_FMT_BGR888_1X24,
> +		.depth = 24,
> +		.csi_dt = MIPI_CSI2_DT_RGB888,
> +	},
> +	/* Bayer formats */
> +	{
> +		.code = MEDIA_BUS_FMT_SBGGR8_1X8,
> +		.depth = 8,
> +		.csi_dt = MIPI_CSI2_DT_RAW8,
> +	},
> +	{
> +		.code = MEDIA_BUS_FMT_SGBRG8_1X8,
> +		.depth = 8,
> +		.csi_dt = MIPI_CSI2_DT_RAW8,
> +	},
> +	{
> +		.code = MEDIA_BUS_FMT_SGRBG8_1X8,
> +		.depth = 8,
> +		.csi_dt = MIPI_CSI2_DT_RAW8,
> +	},
> +	{
> +		.code = MEDIA_BUS_FMT_SRGGB8_1X8,
> +		.depth = 8,
> +		.csi_dt = MIPI_CSI2_DT_RAW8,
> +	},
> +	{
> +		.code = MEDIA_BUS_FMT_SBGGR10_1X10,
> +		.depth = 10,
> +		.csi_dt = MIPI_CSI2_DT_RAW10,
> +	},
> +	{
> +		.code = MEDIA_BUS_FMT_SGBRG10_1X10,
> +		.depth = 10,
> +		.csi_dt = MIPI_CSI2_DT_RAW10,
> +	},
> +	{
> +		.code = MEDIA_BUS_FMT_SGRBG10_1X10,
> +		.depth = 10,
> +		.csi_dt = MIPI_CSI2_DT_RAW10,
> +	},
> +	{
> +		.code = MEDIA_BUS_FMT_SRGGB10_1X10,
> +		.depth = 10,
> +		.csi_dt = MIPI_CSI2_DT_RAW10,
> +	},
> +	{
> +		.code = MEDIA_BUS_FMT_SBGGR12_1X12,
> +		.depth = 12,
> +		.csi_dt = MIPI_CSI2_DT_RAW12,
> +	},
> +	{
> +		.code = MEDIA_BUS_FMT_SGBRG12_1X12,
> +		.depth = 12,
> +		.csi_dt = MIPI_CSI2_DT_RAW12,
> +	},
> +	{
> +		.code = MEDIA_BUS_FMT_SGRBG12_1X12,
> +		.depth = 12,
> +		.csi_dt = MIPI_CSI2_DT_RAW12,
> +	},
> +	{
> +		.code = MEDIA_BUS_FMT_SRGGB12_1X12,
> +		.depth = 12,
> +		.csi_dt = MIPI_CSI2_DT_RAW12,
> +	},
> +};
> +
> +static inline struct rkcsi_device *to_rkcsi(struct v4l2_subdev *sd)
> +{
> +	return container_of(sd, struct rkcsi_device, sd);
> +}
> +
> +static inline __maybe_unused void rkcsi_write(struct rkcsi_device *csi_dev,
> +					      unsigned int addr, u32 val)
> +{
> +	writel(val, csi_dev->base_addr + addr);
> +}
> +
> +static inline __maybe_unused u32 rkcsi_read(struct rkcsi_device *csi_dev,
> +					    unsigned int addr)
> +{
> +	return readl(csi_dev->base_addr + addr);
> +}
> +
> +static const struct rkcsi_format *
> +rkcsi_find_format(struct rkcsi_device *csi_dev, u32 mbus_code)
> +{
> +	const struct rkcsi_format *format;
> +
> +	WARN_ON(csi_dev->formats_num == 0);
> +
> +	for (int i = 0; i < csi_dev->formats_num; i++) {
> +		format = &csi_dev->formats[i];
> +		if (format->code == mbus_code)
> +			return format;
> +	}
> +
> +	return NULL;
> +}
> +
> +static int rkcsi_start(struct rkcsi_device *csi_dev)
> +{
> +	struct media_pad *source_pad =
> +		&csi_dev->source_sd->entity.pads[csi_dev->source_pad];
> +	enum v4l2_mbus_type bus_type = csi_dev->vep.bus_type;
> +	union phy_configure_opts opts;
> +	s64 link_freq;
> +	u32 lanes = csi_dev->vep.bus.mipi_csi2.num_data_lanes;
> +	u32 control = 0;
> +	int ret;
> +
> +	if (lanes < 1 || lanes > 4)
> +		return -EINVAL;
> +
> +	/* set mult and div to 0, thus completely rely on V4L2_CID_LINK_FREQ */
> +	link_freq = v4l2_get_link_freq(source_pad, 0, 0);
> +	if (link_freq <= 0)
> +		return -EINVAL;
> +
> +	if (bus_type == V4L2_MBUS_CSI2_DPHY) {
> +		struct phy_configure_opts_mipi_dphy *cfg = &opts.mipi_dphy;
> +
> +		ret = phy_mipi_dphy_get_default_config_for_hsclk(link_freq * 2,
> +								 lanes, cfg);
> +		if (ret)
> +			return ret;
> +
> +		ret = phy_set_mode(csi_dev->phy, PHY_MODE_MIPI_DPHY);
> +		if (ret)
> +			return ret;
> +
> +		ret = phy_configure(csi_dev->phy, &opts);
> +		if (ret)
> +			return ret;
> +
> +		control |= SW_CPHY_EN(0);
> +
> +	} else if (bus_type == V4L2_MBUS_CSI2_CPHY) {
> +		/* TODO: implement CPHY configuration */
> +		return -EOPNOTSUPP;
> +	} else {
> +		return -EINVAL;
> +	}
> +
> +	control |= SW_DATATYPE_FS(0x00) | SW_DATATYPE_FE(0x01) |
> +		   SW_DATATYPE_LS(0x02) | SW_DATATYPE_LE(0x03);
> +
> +	rkcsi_write(csi_dev, CSI2HOST_N_LANES, lanes - 1);
> +	rkcsi_write(csi_dev, CSI2HOST_CONTROL, control);
> +	rkcsi_write(csi_dev, CSI2HOST_CSI2_RESETN, 1);
> +
> +	ret = phy_power_on(csi_dev->phy);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static void rkcsi_stop(struct rkcsi_device *csi_dev)
> +{
> +	phy_power_off(csi_dev->phy);
> +
> +	rkcsi_write(csi_dev, CSI2HOST_CSI2_RESETN, 0);
> +	rkcsi_write(csi_dev, CSI2HOST_MSK1, ~0);
> +	rkcsi_write(csi_dev, CSI2HOST_MSK2, ~0);
> +}
> +
> +static const struct media_entity_operations rkcsi_media_ops = {
> +	.link_validate = v4l2_subdev_link_validate,
> +};
> +
> +static int rkcsi_enum_mbus_code(struct v4l2_subdev *sd,
> +				struct v4l2_subdev_state *sd_state,
> +				struct v4l2_subdev_mbus_code_enum *code)
> +{
> +	struct rkcsi_device *csi_dev = to_rkcsi(sd);
> +
> +	if (code->pad == RKCSI_PAD_SRC) {
> +		const struct v4l2_mbus_framefmt *sink_fmt;
> +
> +		if (code->index)
> +			return -EINVAL;
> +
> +		sink_fmt = v4l2_subdev_state_get_format(sd_state,
> +							RKCSI_PAD_SINK);
> +		code->code = sink_fmt->code;
> +
> +		return 0;
> +	} else if (code->pad == RKCSI_PAD_SINK) {
> +		if (code->index > csi_dev->formats_num)
> +			return -EINVAL;
> +
> +		code->code = csi_dev->formats[code->index].code;
> +		return 0;
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static int rkcsi_set_fmt(struct v4l2_subdev *sd,
> +			 struct v4l2_subdev_state *state,
> +			 struct v4l2_subdev_format *format)
> +{
> +	struct rkcsi_device *csi_dev = to_rkcsi(sd);
> +	const struct rkcsi_format *fmt;
> +	struct v4l2_mbus_framefmt *sink, *src;
> +
> +	/* the format on the source pad always matches the sink pad */
> +	if (format->pad == RKCSI_PAD_SRC)
> +		return v4l2_subdev_get_fmt(sd, state, format);
> +
> +	sink = v4l2_subdev_state_get_format(state, format->pad, format->stream);
> +	if (!sink)
> +		return -EINVAL;
> +
> +	fmt = rkcsi_find_format(csi_dev, format->format.code);
> +	if (!fmt)
> +		format->format = default_format;
> +
> +	*sink = format->format;
> +
> +	/* propagate the format to the source pad */
> +	src = v4l2_subdev_state_get_opposite_stream_format(state, format->pad,
> +							   format->stream);
> +	if (!src)
> +		return -EINVAL;
> +
> +	*src = *sink;
> +
> +	return 0;
> +}
> +
> +static int rkcsi_set_routing(struct v4l2_subdev *sd,
> +			     struct v4l2_subdev_state *state,
> +			     enum v4l2_subdev_format_whence which,
> +			     struct v4l2_subdev_krouting *routing)
> +{
> +	int ret;
> +
> +	ret = v4l2_subdev_routing_validate(sd, routing,
> +					   V4L2_SUBDEV_ROUTING_ONLY_1_TO_1);
> +	if (ret)
> +		return ret;
> +
> +	ret = v4l2_subdev_set_routing_with_fmt(sd, state, routing,
> +					       &default_format);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static int rkcsi_enable_streams(struct v4l2_subdev *sd,
> +				struct v4l2_subdev_state *state, u32 pad,
> +				u64 streams_mask)
> +{
> +	struct rkcsi_device *csi_dev = to_rkcsi(sd);
> +	struct v4l2_subdev *remote_sd;
> +	struct media_pad *sink_pad, *remote_pad;
> +	struct device *dev = csi_dev->dev;
> +	u64 mask;
> +	int ret;
> +
> +	sink_pad = &sd->entity.pads[RKCSI_PAD_SINK];
> +	remote_pad = media_pad_remote_pad_first(sink_pad);
> +	remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity);
> +
> +	mask = v4l2_subdev_state_xlate_streams(state, RKCSI_PAD_SINK,
> +					       RKCSI_PAD_SRC, &streams_mask);
> +
> +	ret = pm_runtime_resume_and_get(dev);
> +	if (ret)
> +		goto err;
> +
> +	ret = rkcsi_start(csi_dev);
> +	if (ret) {
> +		dev_err(dev, "failed to enable CSI hardware\n");
> +		goto err_pm_runtime_put;
> +	}
> +
> +	ret = v4l2_subdev_enable_streams(remote_sd, remote_pad->index, mask);
> +	if (ret)
> +		goto err_csi_stop;
> +
> +	return 0;
> +
> +err_csi_stop:
> +	rkcsi_stop(csi_dev);
> +err_pm_runtime_put:
> +	pm_runtime_put_sync(dev);
> +err:
> +	return ret;
> +}
> +
> +static int rkcsi_disable_streams(struct v4l2_subdev *sd,
> +				 struct v4l2_subdev_state *state, u32 pad,
> +				 u64 streams_mask)
> +{
> +	struct rkcsi_device *csi_dev = to_rkcsi(sd);
> +	struct v4l2_subdev *remote_sd;
> +	struct media_pad *sink_pad, *remote_pad;
> +	struct device *dev = csi_dev->dev;
> +	u64 mask;
> +	int ret;
> +
> +	sink_pad = &sd->entity.pads[RKCSI_PAD_SINK];
> +	remote_pad = media_pad_remote_pad_first(sink_pad);
> +	remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity);
> +
> +	mask = v4l2_subdev_state_xlate_streams(state, RKCSI_PAD_SINK,
> +					       RKCSI_PAD_SRC, &streams_mask);
> +
> +	ret = v4l2_subdev_disable_streams(remote_sd, remote_pad->index, mask);
> +
> +	rkcsi_stop(csi_dev);
> +
> +	pm_runtime_mark_last_busy(dev);
> +	pm_runtime_put_autosuspend(dev);
> +
> +	return ret;
> +}
> +
> +static const struct v4l2_subdev_pad_ops rkcsi_pad_ops = {
> +	.enum_mbus_code = rkcsi_enum_mbus_code,
> +	.get_fmt = v4l2_subdev_get_fmt,
> +	.set_fmt = rkcsi_set_fmt,
> +	.set_routing = rkcsi_set_routing,
> +	.enable_streams = rkcsi_enable_streams,
> +	.disable_streams = rkcsi_disable_streams,
> +};
> +
> +static const struct v4l2_subdev_ops rkcsi_ops = {
> +	.pad = &rkcsi_pad_ops,
> +};
> +
> +static int rkcsi_init_state(struct v4l2_subdev *sd,
> +			    struct v4l2_subdev_state *state)
> +{
> +	struct v4l2_subdev_route routes[] = {
> +		{
> +			.sink_pad = RKCSI_PAD_SINK,
> +			.sink_stream = 0,
> +			.source_pad = RKCSI_PAD_SRC,
> +			.source_stream = 0,
> +			.flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
> +		},
> +	};
> +	struct v4l2_subdev_krouting routing = {
> +		.len_routes = ARRAY_SIZE(routes),
> +		.num_routes = ARRAY_SIZE(routes),
> +		.routes = routes,
> +	};
> +	int ret;
> +
> +	ret = v4l2_subdev_set_routing_with_fmt(sd, state, &routing,
> +					       &default_format);
> +
> +	return ret;
> +}
> +
> +static const struct v4l2_subdev_internal_ops rkcsi_internal_ops = {
> +	.init_state = rkcsi_init_state,
> +};
> +
> +static int rkcsi_notifier_bound(struct v4l2_async_notifier *notifier,
> +				struct v4l2_subdev *sd,
> +				struct v4l2_async_connection *asd)
> +{
> +	struct rkcsi_device *csi_dev =
> +		container_of(notifier, struct rkcsi_device, notifier);
> +	int source_pad;
> +
> +	source_pad = media_entity_get_fwnode_pad(&sd->entity, sd->fwnode,
> +						 MEDIA_PAD_FL_SOURCE);
> +	if (source_pad < 0) {
> +		dev_err(csi_dev->dev, "failed to find source pad for %s\n",
> +			sd->name);
> +		return source_pad;
> +	}
> +
> +	csi_dev->source_sd = sd;
> +	csi_dev->source_pad = source_pad;
> +
> +	return media_create_pad_link(&sd->entity, source_pad,
> +				     &csi_dev->sd.entity, RKCSI_PAD_SINK,
> +				     MEDIA_LNK_FL_ENABLED);
> +}
> +
> +static const struct v4l2_async_notifier_operations rkcsi_notifier_ops = {
> +	.bound = rkcsi_notifier_bound,
> +};
> +
> +static int rkcsi_register_notifier(struct rkcsi_device *csi_dev)
> +{
> +	struct v4l2_async_connection *asd;
> +	struct v4l2_async_notifier *ntf = &csi_dev->notifier;
> +	struct v4l2_fwnode_endpoint *vep = &csi_dev->vep;
> +	struct v4l2_subdev *sd = &csi_dev->sd;
> +	struct device *dev = csi_dev->dev;
> +	struct fwnode_handle *ep;
> +	int ret = 0;
> +
> +	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0, 0);
> +	if (!ep)
> +		return dev_err_probe(dev, -ENODEV, "failed to get endpoint\n");
> +
> +	vep->bus_type = V4L2_MBUS_UNKNOWN;
> +	ret = v4l2_fwnode_endpoint_parse(ep, vep);
> +	if (ret) {
> +		ret = dev_err_probe(dev, ret, "failed to parse endpoint\n");
> +		goto out;
> +	}
> +
> +	if (vep->bus_type != V4L2_MBUS_CSI2_DPHY &&
> +	    vep->bus_type != V4L2_MBUS_CSI2_CPHY) {
> +		ret = dev_err_probe(dev, -EINVAL,
> +				    "invalid bus type of endpoint\n");
> +		goto out;
> +	}
> +
> +	v4l2_async_subdev_nf_init(ntf, sd);
> +	ntf->ops = &rkcsi_notifier_ops;
> +
> +	asd = v4l2_async_nf_add_fwnode_remote(ntf, ep,
> +					      struct v4l2_async_connection);
> +	if (IS_ERR(asd)) {
> +		ret = PTR_ERR(asd);
> +		goto err_nf_cleanup;
> +	}
> +
> +	ret = v4l2_async_nf_register(ntf);
> +	if (ret) {
> +		ret = dev_err_probe(dev, ret, "failed to register notifier\n");
> +		goto err_nf_cleanup;
> +	}
> +
> +	goto out;
> +
> +err_nf_cleanup:
> +	v4l2_async_nf_cleanup(ntf);
> +out:
> +	fwnode_handle_put(ep);
> +	return ret;
> +}
> +
> +static int rkcsi_register(struct rkcsi_device *csi_dev)
> +{
> +	struct media_pad *pads = csi_dev->pads;
> +	struct v4l2_subdev *sd = &csi_dev->sd;
> +	int ret;
> +
> +	ret = rkcsi_register_notifier(csi_dev);
> +	if (ret)
> +		goto err;
> +
> +	v4l2_subdev_init(sd, &rkcsi_ops);
> +	sd->dev = csi_dev->dev;
> +	sd->entity.ops = &rkcsi_media_ops;
> +	sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
> +	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_STREAMS;
> +	sd->internal_ops = &rkcsi_internal_ops;
> +	sd->owner = THIS_MODULE;
> +	snprintf(sd->name, sizeof(sd->name), "rockchip-mipi-csi %s",
> +		 dev_name(csi_dev->dev));
> +
> +	pads[RKCSI_PAD_SINK].flags = MEDIA_PAD_FL_SINK |
> +				     MEDIA_PAD_FL_MUST_CONNECT;
> +	pads[RKCSI_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;
> +	ret = media_entity_pads_init(&sd->entity, RKCSI_PAD_MAX, pads);
> +	if (ret)
> +		goto err_notifier_unregister;
> +
> +	ret = v4l2_subdev_init_finalize(sd);
> +	if (ret)
> +		goto err_entity_cleanup;
> +
> +	ret = v4l2_async_register_subdev(sd);
> +	if (ret) {
> +		dev_err(sd->dev, "failed to register CSI subdev\n");
> +		goto err_subdev_cleanup;
> +	}
> +
> +	return 0;
> +
> +err_subdev_cleanup:
> +	v4l2_subdev_cleanup(sd);
> +err_entity_cleanup:
> +	media_entity_cleanup(&sd->entity);
> +err_notifier_unregister:
> +	v4l2_async_nf_unregister(&csi_dev->notifier);
> +	v4l2_async_nf_cleanup(&csi_dev->notifier);
> +err:
> +	return ret;
> +}
> +
> +static void rkcsi_unregister(struct rkcsi_device *csi_dev)
> +{
> +	struct v4l2_subdev *sd = &csi_dev->sd;
> +
> +	v4l2_async_unregister_subdev(sd);
> +	v4l2_subdev_cleanup(sd);
> +	media_entity_cleanup(&sd->entity);
> +	v4l2_async_nf_unregister(&csi_dev->notifier);
> +	v4l2_async_nf_cleanup(&csi_dev->notifier);
> +}
> +
> +static const struct of_device_id rkcsi_of_match[] = {
> +	{
> +		.compatible = "rockchip,rk3568-mipi-csi",
> +	},
> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, rkcsi_of_match);
> +
> +static int rkcsi_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct rkcsi_device *csi_dev;
> +	int ret;
> +
> +	csi_dev = devm_kzalloc(dev, sizeof(*csi_dev), GFP_KERNEL);
> +	if (!csi_dev)
> +		return -ENOMEM;
> +	csi_dev->dev = dev;
> +	dev_set_drvdata(dev, csi_dev);
> +
> +	csi_dev->base_addr = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(csi_dev->base_addr))
> +		return PTR_ERR(csi_dev->base_addr);
> +
> +	ret = devm_clk_bulk_get_all(dev, &csi_dev->clks);
> +	if (ret != RKCSI_CLKS_MAX)
> +		return dev_err_probe(dev, -ENODEV, "failed to get clocks\n");
> +	csi_dev->clks_num = ret;
> +
> +	csi_dev->phy = devm_phy_get(dev, NULL);
> +	if (IS_ERR(csi_dev->phy))
> +		return dev_err_probe(dev, PTR_ERR(csi_dev->phy),
> +				     "failed to get MIPI CSI PHY\n");
> +
> +	csi_dev->reset = devm_reset_control_get_exclusive(dev, NULL);
> +	if (IS_ERR(csi_dev->reset))
> +		return dev_err_probe(dev, PTR_ERR(csi_dev->reset),
> +				     "failed to get reset\n");
> +
> +	csi_dev->formats = formats;
> +	csi_dev->formats_num = ARRAY_SIZE(formats);
> +
> +	pm_runtime_enable(dev);
> +
> +	ret = phy_init(csi_dev->phy);
> +	if (ret) {
> +		ret = dev_err_probe(dev, ret,
> +				    "failed to initialize MIPI CSI PHY\n");
> +		goto err_pm_runtime_disable;
> +	}
> +
> +	ret = rkcsi_register(csi_dev);
> +	if (ret)
> +		goto err_phy_exit;
> +
> +	return 0;
> +
> +err_phy_exit:
> +	phy_exit(csi_dev->phy);
> +err_pm_runtime_disable:
> +	pm_runtime_disable(dev);
> +	return ret;
> +}
> +
> +static void rkcsi_remove(struct platform_device *pdev)
> +{
> +	struct rkcsi_device *csi_dev = platform_get_drvdata(pdev);
> +	struct device *dev = &pdev->dev;
> +
> +	rkcsi_unregister(csi_dev);
> +	phy_exit(csi_dev->phy);
> +	pm_runtime_disable(dev);
> +}
> +
> +static int rkcsi_runtime_suspend(struct device *dev)
> +{
> +	struct rkcsi_device *csi_dev = dev_get_drvdata(dev);
> +
> +	clk_bulk_disable_unprepare(csi_dev->clks_num, csi_dev->clks);
> +
> +	return 0;
> +}
> +
> +static int rkcsi_runtime_resume(struct device *dev)
> +{
> +	struct rkcsi_device *csi_dev = dev_get_drvdata(dev);
> +	int ret;
> +
> +	reset_control_assert(csi_dev->reset);
> +	udelay(5);
> +	reset_control_deassert(csi_dev->reset);
> +
> +	ret = clk_bulk_prepare_enable(csi_dev->clks_num, csi_dev->clks);
> +	if (ret) {
> +		dev_err(dev, "failed to enable clocks\n");
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static const struct dev_pm_ops rkcsi_pm_ops = {
> +	.runtime_suspend = rkcsi_runtime_suspend,
> +	.runtime_resume = rkcsi_runtime_resume,
> +};
> +
> +static struct platform_driver rkcsi_drv = {
> +	.driver = {
> +		   .name = "rockchip-mipi-csi",
> +		   .of_match_table = rkcsi_of_match,
> +		   .pm = &rkcsi_pm_ops,
> +	},
> +	.probe = rkcsi_probe,
> +	.remove = rkcsi_remove,
> +};
> +module_platform_driver(rkcsi_drv);
> +
> +MODULE_DESCRIPTION("Rockchip MIPI CSI-2 Receiver platform driver");
> +MODULE_LICENSE("GPL");
>
> --
> 2.39.5
>
>


From helgaas at kernel.org  Tue Nov 18 09:50:10 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 18 Nov 2025 11:50:10 -0600
Subject: [RFC v1 1/5] PCI: rockchip: Fix Link Control register offset and
 enable ASPM/CLKREQ
In-Reply-To: <20251117181023.482138-2-linux.amoon@gmail.com>
Message-ID: <20251118175010.GA2540980@bhelgaas>

On Mon, Nov 17, 2025 at 11:40:09PM +0530, Anand Moon wrote:
> As per the RK3399 TRM (Part 2, 17.6.6.1.31), the Link Control register
> (RC_CONFIG_LC) resides at an offset of 0xd0 within the Root Complex (RC)
> configuration space, not at the offset of the PCI Express Capability List
> (0xc0). Following changes correct the register offset to use
> PCIE_RC_CONFIG_LC (0xd0) to configure link control.
> 
> Additionally, this commit explicitly enables ASPM (Active State Power
> Management) control and the CLKREQ# (Clock Request) mechanism as part of
> the Link Control register programming when enabling bandwidth
> notifications.

Don't do two things at once in the same patch.  Fix the register
offset in one patch.  Actually, as I mentioned at [1], there's a lot
of fixing to do there, and I'm not even going to consider other
changes until the #define mess is cleaned up.

What I'd really like to see is at least two patches here: one that
clearly makes no functional change -- don't try to fix anything, just
make it 100% obvious that all the offsets stay the same.  Then make a
separate patch that *only* changes any of the offsets that are wrong.

I don't think there should even be an ASPM change.  The PCI core
should be enabling L0s and L1 itself for DT systems like this.  And
ASPM needs to be enabled only when both ends of the link support it,
and only in a specific order.  The PCI core pays attention to that,
but this patch does not.

Bjorn

[1] https://lore.kernel.org/r/20251118005056.GA2541796 at bhelgaas


From jgg at nvidia.com  Tue Nov 18 10:57:07 2025
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue, 18 Nov 2025 14:57:07 -0400
Subject: [PATCH v2 2/3] iommu/amd: Don't call report_iommu_fault()
In-Reply-To: <93fd05cd-b227-42ab-8d96-7873a830e6be@amd.com>
References: <2-v2-25fc75484cab+ab-iommu_set_fault_jgg@nvidia.com>
 <93fd05cd-b227-42ab-8d96-7873a830e6be@amd.com>
Message-ID: <20251118185707.GP10864@nvidia.com>

On Sat, Nov 08, 2025 at 04:47:02PM +0530, Vasant Hegde wrote:
> > @@ -854,13 +854,6 @@ static void amd_iommu_report_page_fault(struct amd_iommu *iommu,
> >  						   PCI_FUNC(devid), domain_id);
> >  				goto out;
> >  			}
> 
> If you're planning to respin this series, could you please update the comment
> above the if condition?

Done

Thanks,
Jason


From jgg at nvidia.com  Tue Nov 18 10:58:31 2025
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue, 18 Nov 2025 14:58:31 -0400
Subject: [PATCH v2 2/3] iommu/amd: Don't call report_iommu_fault()
In-Reply-To: <BN9PR11MB5276EFE7D236FF918A79263C8CC9A@BN9PR11MB5276.namprd11.prod.outlook.com>
References: <0-v2-25fc75484cab+ab-iommu_set_fault_jgg@nvidia.com>
 <2-v2-25fc75484cab+ab-iommu_set_fault_jgg@nvidia.com>
 <BN9PR11MB5276EFE7D236FF918A79263C8CC9A@BN9PR11MB5276.namprd11.prod.outlook.com>
Message-ID: <20251118185831.GQ10864@nvidia.com>

On Mon, Nov 17, 2025 at 06:38:51AM +0000, Tian, Kevin wrote:
> > From: Jason Gunthorpe <jgg at nvidia.com>
> > Sent: Friday, November 7, 2025 4:35 AM
> > 
> > This old style API is only used by drivers/gpu/drm/msm,
> > drivers/remoteproc/omap_remoteproc.c, and
> > drivers/remoteproc/qcom_q6v5_adsp.c none are used on x86 HW.
> > 
> > Remove the dead code to discourage new users.
> > 
> > Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> > ---
> >  drivers/iommu/amd/iommu.c | 7 -------
> >  1 file changed, 7 deletions(-)
> > 
> > diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
> > index 2e1865daa1cee8..d4d9a5dbfa6333 100644
> > --- a/drivers/iommu/amd/iommu.c
> > +++ b/drivers/iommu/amd/iommu.c
> > @@ -854,13 +854,6 @@ static void amd_iommu_report_page_fault(struct
> > amd_iommu *iommu,
> >  						   PCI_FUNC(devid),
> > domain_id);
> >  				goto out;
> >  			}
> > -
> > -			if (!report_iommu_fault(&dev_data->domain-
> > >domain,
> > -						&pdev->dev, address,
> > -						IS_WRITE_REQUEST(flags) ?
> > -
> > 	IOMMU_FAULT_WRITE :
> > -
> > 	IOMMU_FAULT_READ))
> > -				goto out;
> >  		}
> > 
> >  		if (__ratelimit(&dev_data->rs)) {
> 
> Remove amd_iommu_report_page_fault() too?

I don't understand this remark?

amd_iommu_report_page_fault() generates the dmesg logging on iommu
faults?

Jason


From helgaas at kernel.org  Tue Nov 18 10:59:17 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 18 Nov 2025 12:59:17 -0600
Subject: [PATCH 2/4] PCI: tegra194: Remove unnecessary L1SS disable code
In-Reply-To: <aRRFYEgBigYDlfQh@ryzen>
Message-ID: <20251118185917.GA2583698@bhelgaas>

On Wed, Nov 12, 2025 at 09:29:20AM +0100, Niklas Cassel wrote:
> On Tue, Nov 11, 2025 at 04:16:09PM -0600, Bjorn Helgaas wrote:
> > From: Bjorn Helgaas <bhelgaas at google.com>
> > 
> > The DWC core clears the L1 Substates Supported bits unless the driver sets
> > the "dw_pcie.l1ss_support" flag.
> > 
> > The tegra194 init_host_aspm() sets "dw_pcie.l1ss_support" if the platform
> > has the "supports-clkreq" DT property.  If "supports-clkreq" is absent,
> > "dw_pcie.l1ss_support" is not set, and the DWC core will clear the L1
> > Substates Supported bits.
> > 
> > The tegra194 code to clear the L1 Substates Supported bits is unnecessary,
> > so remove it.
> > 
> > Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
> > ---
> 
> Since init_host_aspm() is now the only place using struct tegra_pcie_dw
> struct member cfg_link_cap_l1sub, I think that you can remove this struct
> member, and instead make this a local variable in init_host_aspm().

It looks like tegra_pcie_ep_irq_thread() also uses it, although I'm
dubious about that.

It's odd that software would be responsible for sending LTR messages,
but I guess this only happens for tegra194_pcie_dw_ep_of_data, and
apparently it's fixed (".has_ltr_req_fix" for tegra234.

And odd that we would read the capability register on every interrupt
even though this driver is the only thing that can change it, so we
should be able to cache the value in init_host_aspm().


From michael.riesch at collabora.com  Tue Nov 18 10:59:14 2025
From: michael.riesch at collabora.com (Michael Riesch)
Date: Tue, 18 Nov 2025 19:59:14 +0100
Subject: [PATCH v2 2/3] media: rockchip: add driver for the rockchip mipi
 csi-2 receiver
In-Reply-To: <aRyplYZOrGsSxSlp@lizhi-Precision-Tower-5810>
References: <20251114-rockchip-mipi-receiver-v2-0-eb9b43377fc4@collabora.com>
 <20251114-rockchip-mipi-receiver-v2-2-eb9b43377fc4@collabora.com>
 <aRyplYZOrGsSxSlp@lizhi-Precision-Tower-5810>
Message-ID: <554971e1-6fde-4b2c-a2de-fe178358a4e3@collabora.com>

Hi Frank,

On 11/18/25 18:15, Frank Li wrote:
> On Tue, Nov 18, 2025 at 12:12:26PM +0100, Michael Riesch via B4 Relay wrote:
>> From: Michael Riesch <michael.riesch at collabora.com>
>>
>>[...]
>> +#define CSI2HOST_N_LANES     0x04
>> +#define CSI2HOST_CSI2_RESETN 0x10
>> +#define CSI2HOST_PHY_STATE   0x14
>> +#define CSI2HOST_ERR1	     0x20
>> +#define CSI2HOST_ERR2	     0x24
>> +#define CSI2HOST_MSK1	     0x28
>> +#define CSI2HOST_MSK2	     0x2c
>> +#define CSI2HOST_CONTROL     0x40
> 
> Look like that is designware CSI2 controller, can we build common library
> for all dwc csi2 controller, instead of every vendor create individual one.
> 
> First try at
> https://lore.kernel.org/linux-media/20250821-95_cam-v3-21-c9286fbb34b9 at nxp.com/
> 
> Toshiba have similar patch
> https://lore.kernel.org/linux-media/aPZd39riAxqfw3mT at lizhi-Precision-Tower-5810/
> 
> Frank

This has been discussed already a while ago:
https://lore.kernel.org/all/20250507083837.GA11152 at pendragon.ideasonboard.com/

Bottom line from Laurent:

"Let's keep this driver Rockchip-specific then. Thanks for checking."

>  [...]
Best regards,
Michael


From jgg at nvidia.com  Tue Nov 18 11:00:21 2025
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Tue, 18 Nov 2025 15:00:21 -0400
Subject: [PATCH v2 3/3] iommu: Allow drivers to say if they use
 report_iommu_fault()
In-Reply-To: <26019e39-d36a-4290-ac80-c8b0b09104c8@rock-chips.com>
References: <3-v2-25fc75484cab+ab-iommu_set_fault_jgg@nvidia.com>
 <26019e39-d36a-4290-ac80-c8b0b09104c8@rock-chips.com>
Message-ID: <20251118190021.GR10864@nvidia.com>

On Tue, Nov 18, 2025 at 09:30:29AM +0800, Chaoyi Chen wrote:
> Hello Jason,
> 
> On 11/7/2025 4:34 AM, Jason Gunthorpe wrote:
> > report_iommu_fault() is an older API that has been superseded by
> > iommu_report_device_fault() which is capable to support PRI.
> > 
> > Only two external drivers consume this, drivers/remoteproc and
> > drivers/gpu/drm/msm. Ideally they would move over to the new APIs, but for
> > now protect against accidentally mix and matching the wrong components.
> > 
> > The iommu drivers support either the old iommu_set_fault_handler() via the
> > driver calling report_iommu_fault(), or they are newer server focused
> > drivers that call iommu_report_device_fault().
> > 
> > Include a flag in the iommu_ops if the driver calls report_iommu_fault()
> > and block iommu_set_fault_handler() for domain's of iommu drivers that
> > can't support it.
> > 
> > Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
> > Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> > Reviewed-by: Vasant Hegde <vasant.hegde at amd.com>
> > Reviewed-by: Kevin Tian <kevin.tian at intel.com>
> 
> Sorry for the noise. Sometimes non-IOMMU drivers, such as DRM
> devices, also want to handle IOMMU fault events, so they might use
> iommu_set_fault_handler() before. What API should they use as an
> alternative now?

The new flow is through iommu_report_device_fault() which an end user
can access by setting domain->iopf_handler currently.

Jason


From helgaas at kernel.org  Tue Nov 18 11:48:03 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 18 Nov 2025 13:48:03 -0600
Subject: [PATCH 1/4] PCI: dwc: Advertise L1 PM Substates only if driver
 requests it
In-Reply-To: <79a8c3cc-2b60-4bce-b1ba-7ab5f033f924@rock-chips.com>
Message-ID: <20251118194803.GA2586265@bhelgaas>

On Wed, Nov 12, 2025 at 09:03:38AM +0800, Shawn Lin wrote:
> ? 2025/11/12 ??? 6:16, Bjorn Helgaas ??:
> > From: Bjorn Helgaas <bhelgaas at google.com>
> > 
> > L1 PM Substates require the CLKREF# signal and may also require
> > device-specific support.  If CLKREF# is not supported or driver support is
> > lacking, enabling L1.1 or L1.2 may cause errors when accessing devices,
> > e.g.,
> > 
> >    nvme nvme0: controller is down; will reset: CSTS=0xffffffff, PCI_STATUS=0x10
> > 
> > If the kernel is built with CONFIG_PCIEASPM_POWER_SUPERSAVE=y or users
> > enable L1.x via sysfs, users may trip over these errors even if L1
> > Substates haven't been enabled by firmware or the driver.
> > 
> > To prevent such errors, disable advertising the L1 PM Substates unless the
> > driver sets "dw_pcie.l1ss_support" to indicate that it knows CLKREF# is
> > present and any device-specific configuration has been done.
> > 
> > Set "dw_pcie.l1ss_support" in tegra194 (if DT includes the
> > "supports-clkreq' property) and qcom (for 2.7.0 controllers) so they can
> > continue to use L1 Substates.
> > 
> > Based on Niklas's patch:
> > https://patch.msgid.link/20251017163252.598812-2-cassel at kernel.org
> 
> 
> Except the issue Fank pointed out, the commit msg says CLKREF# 3 times
> which seems not a term from spec. Should it be CLKREQ# ?

Yes!  Thank you, fixed locally.

> Otherwise,
> Reviewed-by: Shawn Lin <shawn.lin at rock-chips.com>
> 
> > 
> > Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
> > ---
> >   .../pci/controller/dwc/pcie-designware-ep.c   |  2 ++
> >   .../pci/controller/dwc/pcie-designware-host.c |  2 ++
> >   drivers/pci/controller/dwc/pcie-designware.c  | 24 +++++++++++++++++++
> >   drivers/pci/controller/dwc/pcie-designware.h  |  2 ++
> >   drivers/pci/controller/dwc/pcie-qcom.c        |  2 ++
> >   drivers/pci/controller/dwc/pcie-tegra194.c    |  3 +++
> >   6 files changed, 35 insertions(+)
> > 
> > diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
> > index 7f2112c2fb21..c94cff6eeb01 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> > @@ -966,6 +966,8 @@ int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)
> >   	if (ep->ops->init)
> >   		ep->ops->init(ep);
> > +	dw_pcie_config_l1ss(pci);
> > +
> >   	ptm_cap_base = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_PTM);
> >   	/*
> > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> > index 20c9333bcb1c..f1d5b45a3214 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > @@ -1060,6 +1060,8 @@ int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
> >   		PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
> >   	dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
> > +	dw_pcie_config_l1ss(pci);
> > +
> >   	dw_pcie_config_presets(pp);
> >   	/*
> >   	 * If the platform provides its own child bus config accesses, it means
> > diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
> > index c644216995f6..ede686623fad 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware.c
> > @@ -1081,6 +1081,30 @@ void dw_pcie_edma_remove(struct dw_pcie *pci)
> >   	dw_edma_remove(&pci->edma);
> >   }
> > +void dw_pcie_config_l1ss(struct dw_pcie *pci)
> > +{
> > +	u16 l1ss;
> > +	u32 l1ss_cap;
> > +
> > +	if (!pci->l1ss_support)
> > +		return;
> > +
> > +	l1ss = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_L1SS);
> > +	if (!l1ss)
> > +		return;
> > +
> > +	/*
> > +	 * Unless the driver claims "l1ss_support", don't advertise L1 PM
> > +	 * Substates because they require CLKREF# and possibly other
> > +	 * device-specific configuration.
> > +	 */
> > +	l1ss_cap = dw_pcie_readl_dbi(pci, l1ss + PCI_L1SS_CAP);
> > +	l1ss_cap &= ~(PCI_L1SS_CAP_PCIPM_L1_1 | PCI_L1SS_CAP_ASPM_L1_1 |
> > +		      PCI_L1SS_CAP_PCIPM_L1_2 | PCI_L1SS_CAP_ASPM_L1_2 |
> > +		      PCI_L1SS_CAP_L1_PM_SS);
> > +	dw_pcie_writel_dbi(pci, l1ss + PCI_L1SS_CAP, l1ss_cap);
> > +}
> > +
> >   void dw_pcie_setup(struct dw_pcie *pci)
> >   {
> >   	u32 val;
> > diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> > index e995f692a1ec..8d14b1fe2280 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware.h
> > +++ b/drivers/pci/controller/dwc/pcie-designware.h
> > @@ -516,6 +516,7 @@ struct dw_pcie {
> >   	int			max_link_speed;
> >   	u8			n_fts[2];
> >   	struct dw_edma_chip	edma;
> > +	bool			l1ss_support;	/* L1 PM Substates support */
> >   	struct clk_bulk_data	app_clks[DW_PCIE_NUM_APP_CLKS];
> >   	struct clk_bulk_data	core_clks[DW_PCIE_NUM_CORE_CLKS];
> >   	struct reset_control_bulk_data	app_rsts[DW_PCIE_NUM_APP_RSTS];
> > @@ -573,6 +574,7 @@ int dw_pcie_prog_ep_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
> >   				int type, u64 parent_bus_addr,
> >   				u8 bar, size_t size);
> >   void dw_pcie_disable_atu(struct dw_pcie *pci, u32 dir, int index);
> > +void dw_pcie_config_l1ss(struct dw_pcie *pci);
> >   void dw_pcie_setup(struct dw_pcie *pci);
> >   void dw_pcie_iatu_detect(struct dw_pcie *pci);
> >   int dw_pcie_edma_detect(struct dw_pcie *pci);
> > diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
> > index 805edbbfe7eb..61c2f4e2f74d 100644
> > --- a/drivers/pci/controller/dwc/pcie-qcom.c
> > +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> > @@ -1067,6 +1067,8 @@ static int qcom_pcie_init_2_7_0(struct qcom_pcie *pcie)
> >   	val &= ~REQ_NOT_ENTR_L1;
> >   	writel(val, pcie->parf + PARF_PM_CTRL);
> > +	pci->l1ss_support = true;
> > +
> >   	val = readl(pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
> >   	val |= EN;
> >   	writel(val, pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
> > diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
> > index 10e74458e667..3934757baa30 100644
> > --- a/drivers/pci/controller/dwc/pcie-tegra194.c
> > +++ b/drivers/pci/controller/dwc/pcie-tegra194.c
> > @@ -703,6 +703,9 @@ static void init_host_aspm(struct tegra_pcie_dw *pcie)
> >   	val |= (pcie->aspm_pwr_on_t << 19);
> >   	dw_pcie_writel_dbi(pci, pcie->cfg_link_cap_l1sub, val);
> > +	if (pcie->supports_clkreq)
> > +		pci->l1ss_support = true;
> > +
> >   	/* Program L0s and L1 entrance latencies */
> >   	val = dw_pcie_readl_dbi(pci, PCIE_PORT_AFR);
> >   	val &= ~PORT_AFR_L0S_ENTRANCE_LAT_MASK;
> 
> 
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip


From michael.opdenacker at rootcommit.com  Tue Nov 18 11:57:23 2025
From: michael.opdenacker at rootcommit.com (Michael Opdenacker)
Date: Tue, 18 Nov 2025 19:57:23 +0000 (UTC)
Subject: [PATCH v3 1/2] dt-bindings: arm: rockchip: Add Asus Tinker Board
 3/3S
In-Reply-To: <e134902e-e298-45d0-b94f-77748bb948c4@kernel.org>
References: <20251118-tinker3-v3-0-2903693f2ebb@rootcommit.com>
 <20251118-tinker3-v3-1-2903693f2ebb@rootcommit.com>
 <e134902e-e298-45d0-b94f-77748bb948c4@kernel.org>
Message-ID: <4e7bb5f5-30bb-4ed5-bb32-3008caa1826a@rootcommit.com>

Hi Krzysztof

Thanks for the new review!

On 11/18/25 17:31, Krzysztof Kozlowski wrote:
> On 18/11/2025 16:56, Michael Opdenacker wrote:
>> Document the compatible strings for Asus Tinker Board 3 [1] and 3S [2],
>> which are SBCs based on the Rockchip 3566 SoC.
>>
>> The "3S" version ("S" for "storage") just adds a 16 GB eMMC
>> and a "mask ROM" DIP switch to the "3" version.
>>
>> [1] https://tinker-board.asus.com/series/tinker-board-3.html
>> [2] https://tinker-board.asus.com/series/tinker-board-3s.html
>>
>> Signed-off-by: Michael Opdenacker <michael.opdenacker at rootcommit.com>
>>
>> ---
>>
>> Changes in V3:
>>
>> - Remove this Acked-by as the binding code changed substantially:
>>    Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> Above commit msg and DTS suggests they are pretty compatible with each
> other, so I don't quite get why this changed. Your changelog says
> "unexpectedly turns out to be compatible with 3 but not 3S.", but is
> this real or are you just guessing? I think you were tricked to change
> correct code into this.

I was just guessing.? The likelihood that something working on 3 doesn't 
work on 3s looks very small indeed, but I'm not the manufacturer to 
completely rule this out.
>
> Anyway, however odd this is, I don't care enough to stop this patchset, so:
>
> Acked-by: Krzysztof Kozlowski <krzk at kernel.org>

Thanks again!
Cheers
Michael.

-- 
Michael Opdenacker
Root Commit
Yocto Project and OpenEmbedded Training course - Learn by doing:
https://rootcommit.com/training/yocto/



From cristian.ciocaltea at collabora.com  Tue Nov 18 12:00:08 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 18 Nov 2025 22:00:08 +0200
Subject: [PATCH v4 05/10] drm/bridge: dw-hdmi-qp: Set bridge
 supported_formats
In-Reply-To: <20251117-color-format-v4-5-0ded72bd1b00@collabora.com>
References: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
 <20251117-color-format-v4-5-0ded72bd1b00@collabora.com>
Message-ID: <3863e0e5-677b-4225-9854-3ee420828275@collabora.com>

Hi Nicolas,

On 11/17/25 9:11 PM, Nicolas Frattaroli wrote:
> The drm_bridge "supported_formats" member stores a bitmask of supported
> HDMI output formats if the bridge is in fact an HDMI bridge.
> 
> However, until now, the synopsys dw-hdmi-qp driver did not set this
> member in the bridge it creates.
> 
> Set it based on the platform data's supported_formats member, and
> default to BIT(HDMI_COLORSPACE_RGB) if it's absent, which preserves the
> previous behaviour.
> 
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
> index fe4c026280f0..cf888236bd65 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
> @@ -1269,6 +1269,11 @@ struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev,
>  		dev_warn(dev, "Set ref_clk_rate to vendor default\n");
>  	}
>  
> +	if (plat_data->supported_formats)
> +		hdmi->bridge.supported_formats = plat_data->supported_formats;

This duplicates a change already introduced via commit 1ff27c5929ab
("drm/bridge: dw-hdmi-qp: Handle platform supported formats and color depth").

> +	else
> +		hdmi->bridge.supported_formats = BIT(HDMI_COLORSPACE_RGB);

And this one looks redundant as well, since RGB is supposed to be mandatory:
supported_formats defaults to RGB in drm_bridge_connector_init() if there's no
HDMI bridge in the pipeline overriding it, while drmm_connector_hdmi_init()
errors out if supported_formats is unset or doesn't advertise RGB.

Hence I think this patch can be dropped.

Regards,
Cristian



From cassel at kernel.org  Tue Nov 18 12:06:08 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Tue, 18 Nov 2025 21:06:08 +0100
Subject: [PATCH 2/4] PCI: tegra194: Remove unnecessary L1SS disable code
In-Reply-To: <20251118185917.GA2583698@bhelgaas>
References: <aRRFYEgBigYDlfQh@ryzen>
 <20251118185917.GA2583698@bhelgaas>
Message-ID: <aRzRsFKkVouJDRRs@ryzen>

On Tue, Nov 18, 2025 at 12:59:17PM -0600, Bjorn Helgaas wrote:
> On Wed, Nov 12, 2025 at 09:29:20AM +0100, Niklas Cassel wrote:
> > On Tue, Nov 11, 2025 at 04:16:09PM -0600, Bjorn Helgaas wrote:
> > > From: Bjorn Helgaas <bhelgaas at google.com>
> > >
> > > The DWC core clears the L1 Substates Supported bits unless the driver sets
> > > the "dw_pcie.l1ss_support" flag.
> > >
> > > The tegra194 init_host_aspm() sets "dw_pcie.l1ss_support" if the platform
> > > has the "supports-clkreq" DT property.  If "supports-clkreq" is absent,
> > > "dw_pcie.l1ss_support" is not set, and the DWC core will clear the L1
> > > Substates Supported bits.
> > >
> > > The tegra194 code to clear the L1 Substates Supported bits is unnecessary,
> > > so remove it.
> > >
> > > Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
> > > ---
> >
> > Since init_host_aspm() is now the only place using struct tegra_pcie_dw
> > struct member cfg_link_cap_l1sub, I think that you can remove this struct
> > member, and instead make this a local variable in init_host_aspm().
>
> It looks like tegra_pcie_ep_irq_thread() also uses it, although I'm
> dubious about that.
>
> It's odd that software would be responsible for sending LTR messages,
> but I guess this only happens for tegra194_pcie_dw_ep_of_data, and
> apparently it's fixed (".has_ltr_req_fix" for tegra234.
>
> And odd that we would read the capability register on every interrupt
> even though this driver is the only thing that can change it, so we
> should be able to cache the value in init_host_aspm().

Yes, sorry, my thinking was that this code in tegra_pcie_ep_irq_thread():

	/* If EP doesn't advertise L1SS, just return */
	val = dw_pcie_readl_dbi(pci, pcie->cfg_link_cap_l1sub);
	if (!(val & (PCI_L1SS_CAP_ASPM_L1_1 | PCI_L1SS_CAP_ASPM_L1_2)))
		return IRQ_HANDLED;


after your patch can be replaced with:

	/* If EP doesn't advertise L1SS, just return */
	if (!pci->l1ss_support)
		return IRQ_HANDLED;


Since we already know that if !pci->l1ss_support,
these bits will be cleared by DWC common code.


So, after that, we could replace the struct tegra_pcie_dw
struct member cfg_link_cap_l1sub with a local variable in
init_host_aspm().


Kind regards,
Niklas


From cristian.ciocaltea at collabora.com  Tue Nov 18 12:14:31 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Tue, 18 Nov 2025 22:14:31 +0200
Subject: [PATCH v4 06/10] drm/rockchip: dw_hdmi_qp: Set supported_formats
 platdata
In-Reply-To: <20251117-color-format-v4-6-0ded72bd1b00@collabora.com>
References: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
 <20251117-color-format-v4-6-0ded72bd1b00@collabora.com>
Message-ID: <edc12051-6e50-4ef6-98cf-713abb49dd90@collabora.com>

On 11/17/25 9:11 PM, Nicolas Frattaroli wrote:
> With the introduction of the supported_formats member in the
> dw-hdmi-qp platform data struct, drivers that have access to this
> information should now set it.
> 
> Set it in the rockchip dw_hdmi_qp glue driver, where such a bitmask of
> supported color formats already exists. It just needs to be converted to
> the appropriate HDMI_COLORSPACE_ mask.
> 
> This allows this information to be passed down to the dw-hdmi-qp core,
> which sets it in the bridge it creates, and consequently will allow the
> common HDMI bridge code to act on it.
> 
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
> ---
>  drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 24 ++++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
> 
> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
> index c9fe6aa3e3e3..7c294751de19 100644
> --- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
> @@ -468,6 +468,28 @@ static const struct of_device_id dw_hdmi_qp_rockchip_dt_ids[] = {
>  };
>  MODULE_DEVICE_TABLE(of, dw_hdmi_qp_rockchip_dt_ids);
>  
> +static const u32 supported_colorformats = DRM_COLOR_FORMAT_AUTO |
> +					  DRM_COLOR_FORMAT_RGB444 |
> +					  DRM_COLOR_FORMAT_YCBCR444;
> +
> +static unsigned int __pure drm_to_hdmi_fmts(const u32 fmt)
> +{
> +	unsigned int res = 0;
> +
> +	if (fmt & DRM_COLOR_FORMAT_AUTO)
> +		res |= BIT(HDMI_COLORSPACE_RGB);
> +	if (fmt & DRM_COLOR_FORMAT_RGB444)
> +		res |= BIT(HDMI_COLORSPACE_RGB);
> +	if (fmt & DRM_COLOR_FORMAT_YCBCR444)
> +		res |= BIT(HDMI_COLORSPACE_YUV444);
> +	if (fmt & DRM_COLOR_FORMAT_YCBCR422)
> +		res |= BIT(HDMI_COLORSPACE_YUV422);
> +	if (fmt & DRM_COLOR_FORMAT_YCBCR420)
> +		res |= BIT(HDMI_COLORSPACE_YUV420);
> +
> +	return res;
> +}
> +
>  static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
>  				    void *data)
>  {
> @@ -521,6 +543,8 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
>  	plat_data.phy_data = hdmi;
>  	plat_data.max_bpc = 10;
>  
> +	plat_data.supported_formats = drm_to_hdmi_fmts(supported_colorformats);

Any reason why this cannot be simply set as

  BIT(HDMI_COLORSPACE_RGB) | BIT(HDMI_COLORSPACE_YUV444) | BIT(HDMI_COLORSPACE_YUV422)

and get rid of the unnecessary conversion?

> +
>  	encoder = &hdmi->encoder.encoder;
>  	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
>  
> 



From helgaas at kernel.org  Tue Nov 18 12:22:10 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 18 Nov 2025 14:22:10 -0600
Subject: [PATCH 1/4] PCI: dwc: Advertise L1 PM Substates only if driver
 requests it
In-Reply-To: <22srj63j7fzmsebwxwjnnxnpmdn2iwxo36gkrl36gdm7ge2xif@dmrdbfgu3hn3>
Message-ID: <20251118202210.GA2586610@bhelgaas>

On Wed, Nov 12, 2025 at 11:21:07PM +0530, Manivannan Sadhasivam wrote:
> On Wed, Nov 12, 2025 at 09:22:36AM +0100, Niklas Cassel wrote:
> > On Tue, Nov 11, 2025 at 04:16:08PM -0600, Bjorn Helgaas wrote:
> > > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > > @@ -1060,6 +1060,8 @@ int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
> > >  		PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
> > >  	dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
> > >  
> > > +	dw_pcie_config_l1ss(pci);

> > > --- a/drivers/pci/controller/dwc/pcie-qcom.c
> > > +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> > > @@ -1067,6 +1067,8 @@ static int qcom_pcie_init_2_7_0(struct qcom_pcie *pcie)
> > >  	val &= ~REQ_NOT_ENTR_L1;
> > >  	writel(val, pcie->parf + PARF_PM_CTRL);
> > >  
> > > +	pci->l1ss_support = true;
> > > +
> > >  	val = readl(pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
> > >  	val |= EN;
> > >  	writel(val, pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
> > 
> > While it seems like ops_2_7_0 is the only type that explicitly does a
> > register write to enable L1ss, other versions might have the register
> > as enabled by default, so it would be nice if Mani could confirm exactly
> > which versions that should set l1ss_support = true.
> > 
> 
> Yes, on the rest of the platforms, this bit is supposed to be enabled by
> default. AFAIK, all Qcom platforms should support L1SS, atleast the
> non-IPQ/APQ ones.
> 
> We should set it for below cfgs:
> 
> cfg_fw_managed
> cfg_sc8280xp
> cfg_1_34_0
> cfg_1_9_0
> cfg_2_7_0

Except for cfg_fw_managed, the above are all covered by
qcom_pcie_init_2_7_0(), either via ops_2_7_0, ops_1_9_0, or
ops_1_21_0.

cfg_fw_managed is harder because we don't use dw_pcie_host_init() or
dw_pcie_setup_rc().

We do allocate a struct dw_pcie (where l1ss_support is) in
qcom_pcie_ecam_host_init(), but only so we can call
dw_pcie_msi_host_init() and dw_pcie_msi_init().

Neither of those seems like a logical place to fiddle with L1SS
support.

Open to suggestions.

Bjorn


From helgaas at kernel.org  Tue Nov 18 12:31:21 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 18 Nov 2025 14:31:21 -0600
Subject: [PATCH 2/4] PCI: tegra194: Remove unnecessary L1SS disable code
In-Reply-To: <aRzRsFKkVouJDRRs@ryzen>
Message-ID: <20251118203121.GA2590423@bhelgaas>

On Tue, Nov 18, 2025 at 09:06:08PM +0100, Niklas Cassel wrote:
> On Tue, Nov 18, 2025 at 12:59:17PM -0600, Bjorn Helgaas wrote:
> > On Wed, Nov 12, 2025 at 09:29:20AM +0100, Niklas Cassel wrote:
> > > On Tue, Nov 11, 2025 at 04:16:09PM -0600, Bjorn Helgaas wrote:
> > > > From: Bjorn Helgaas <bhelgaas at google.com>
> > > >
> > > > The DWC core clears the L1 Substates Supported bits unless the driver sets
> > > > the "dw_pcie.l1ss_support" flag.
> > > >
> > > > The tegra194 init_host_aspm() sets "dw_pcie.l1ss_support" if the platform
> > > > has the "supports-clkreq" DT property.  If "supports-clkreq" is absent,
> > > > "dw_pcie.l1ss_support" is not set, and the DWC core will clear the L1
> > > > Substates Supported bits.
> > > >
> > > > The tegra194 code to clear the L1 Substates Supported bits is unnecessary,
> > > > so remove it.
> > > >
> > > > Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
> > > > ---
> > >
> > > Since init_host_aspm() is now the only place using struct tegra_pcie_dw
> > > struct member cfg_link_cap_l1sub, I think that you can remove this struct
> > > member, and instead make this a local variable in init_host_aspm().
> >
> > It looks like tegra_pcie_ep_irq_thread() also uses it, although I'm
> > dubious about that.
> >
> > It's odd that software would be responsible for sending LTR messages,
> > but I guess this only happens for tegra194_pcie_dw_ep_of_data, and
> > apparently it's fixed (".has_ltr_req_fix" for tegra234.
> >
> > And odd that we would read the capability register on every interrupt
> > even though this driver is the only thing that can change it, so we
> > should be able to cache the value in init_host_aspm().
> 
> Yes, sorry, my thinking was that this code in tegra_pcie_ep_irq_thread():
> 
> 	/* If EP doesn't advertise L1SS, just return */
> 	val = dw_pcie_readl_dbi(pci, pcie->cfg_link_cap_l1sub);
> 	if (!(val & (PCI_L1SS_CAP_ASPM_L1_1 | PCI_L1SS_CAP_ASPM_L1_2)))
> 		return IRQ_HANDLED;
> 
> 
> after your patch can be replaced with:
> 
> 	/* If EP doesn't advertise L1SS, just return */
> 	if (!pci->l1ss_support)
> 		return IRQ_HANDLED;
> 
> 
> Since we already know that if !pci->l1ss_support,
> these bits will be cleared by DWC common code.
> 
> 
> So, after that, we could replace the struct tegra_pcie_dw
> struct member cfg_link_cap_l1sub with a local variable in
> init_host_aspm().

Oh, of course, thanks!


From macromorgan at hotmail.com  Tue Nov 18 12:36:09 2025
From: macromorgan at hotmail.com (Chris Morgan)
Date: Tue, 18 Nov 2025 14:36:09 -0600
Subject: [PATCH v2 2/3] drm/bridge: dw-hdmi-qp: Add support for missing
 HPD
In-Reply-To: <avdnpwnxs6cql7eyckdt37szpcf5ztgxlc7juwu6tqj5xxu56a@nrwljig2p67i>
References: <20251113192939.30031-1-macroalpha82@gmail.com>
 <20251113192939.30031-3-macroalpha82@gmail.com>
 <avdnpwnxs6cql7eyckdt37szpcf5ztgxlc7juwu6tqj5xxu56a@nrwljig2p67i>
Message-ID: <SN6PR1901MB46548ED8D4BA1184E0EA7DC3A5D6A@SN6PR1901MB4654.namprd19.prod.outlook.com>

On Tue, Nov 18, 2025 at 09:46:04AM +0100, Maxime Ripard wrote:
> Hi,
> 
> On Thu, Nov 13, 2025 at 01:29:38PM -0600, Chris Morgan wrote:
> > From: Chris Morgan <macromorgan at hotmail.com>
> > 
> > Add support for the dw-hdmi-qp driver to handle devices with missing
> > HPD pins.
> > 
> > Since in this situation we are now polling for the EDID data via i2c
> > change the error message to a debug message when we are unable to
> > complete an i2c read, as a disconnected device would otherwise fill
> > dmesg with i2c read errors.
> > 
> > Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
> 
> You must also disable any mode using the scrambler when there's no
> hotplug interrupt available.

Is there a simple way to do that? I'm not seeing any references to
scrambling in the current driver.

Should I just limit the rate to HDMI14_MAX_TMDSCLK (340000000)  under
dw_hdmi_qp_bridge_tmds_char_rate_valid() if using EDID polling? A
document I found online from Synopsys [1] claims that scrambling is
used by default at rates above 340 (if I'm reading it right) and used
opportunistically at rates below 340.

Thank you,
Chris

[1] https://www.synopsys.com/blogs/chip-design/hdmi-scrambling-higher-data-rates.html

> 
> Maxime




From helgaas at kernel.org  Tue Nov 18 12:36:38 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 18 Nov 2025 14:36:38 -0600
Subject: [PATCH 1/4] PCI: dwc: Advertise L1 PM Substates only if driver
 requests it
In-Reply-To: <aRRDzKFVTFTIuvvh@ryzen>
Message-ID: <20251118203638.GA2591575@bhelgaas>

On Wed, Nov 12, 2025 at 09:22:36AM +0100, Niklas Cassel wrote:
> On Tue, Nov 11, 2025 at 04:16:08PM -0600, Bjorn Helgaas wrote:
> > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > @@ -1060,6 +1060,8 @@ int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
> >  		PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
> >  	dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
> >  
> > +	dw_pcie_config_l1ss(pci);
> 
> The name dw_pcie_config_l1ss() sounds like we are enabling l1ss.
> 
> I know naming is hard.
> 
> Perhaps dw_pcie_disable_unsupported_l1ss() ?
> 
> Or something similar.

"disable" sounds like something we do with a control register, and
here we want to remove the advertised support from the capabilities
register.

Maybe dw_pcie_hide_unsupported_l1ss()?

Bjorn


From cassel at kernel.org  Tue Nov 18 12:45:30 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Tue, 18 Nov 2025 21:45:30 +0100
Subject: [PATCH 1/4] PCI: dwc: Advertise L1 PM Substates only if driver
 requests it
In-Reply-To: <20251118203638.GA2591575@bhelgaas>
References: <aRRDzKFVTFTIuvvh@ryzen>
 <20251118203638.GA2591575@bhelgaas>
Message-ID: <aRza6quobL4obC58@ryzen>

On Tue, Nov 18, 2025 at 02:36:38PM -0600, Bjorn Helgaas wrote:
> On Wed, Nov 12, 2025 at 09:22:36AM +0100, Niklas Cassel wrote:
> > On Tue, Nov 11, 2025 at 04:16:08PM -0600, Bjorn Helgaas wrote:
> > > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > > @@ -1060,6 +1060,8 @@ int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
> > >  		PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
> > >  	dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
> > >  
> > > +	dw_pcie_config_l1ss(pci);
> > 
> > The name dw_pcie_config_l1ss() sounds like we are enabling l1ss.
> > 
> > I know naming is hard.
> > 
> > Perhaps dw_pcie_disable_unsupported_l1ss() ?
> > 
> > Or something similar.
> 
> "disable" sounds like something we do with a control register, and
> here we want to remove the advertised support from the capabilities
> register.
> 
> Maybe dw_pcie_hide_unsupported_l1ss()?

Sounds good to me :)


Kind regards,
Niklas


From helgaas at kernel.org  Tue Nov 18 13:42:14 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 18 Nov 2025 15:42:14 -0600
Subject: [PATCH v2 0/4] PCI: dwc: Advertise L1 PM Substates only if driver requests it
Message-ID: <20251118214312.2598220-1-helgaas@kernel.org>

From: Bjorn Helgaas <bhelgaas at google.com>

This is a follow-up to Niklas's patch at
https://lore.kernel.org/r/20251017163252.598812-2-cassel at kernel.org.  That
patch clears the L1 PM Substate Supported bits for the dw-rockchip driver,
which doesn't yet do the device configuration to support the L1 Substates.

This series does the same thing, but in the DWC core so it applies to all
DWC-based drivers.  Drivers that do support L1 Substates (currently
tegra194 and qcom) indicate that by setting "dw_pcie.l1ss_support", and the
DWC core will leave the L1 PM Substate Supported bits alone.

This also includes Shawn's patches to add the dw-rockchip support for L1
Substates.

The problem this fixes is that users are currently able to enable L1
Substates, e.g., by

  - building with with CONFIG_PCIEASPM_POWER_SUPERSAVE=y
  - booting with "pcie_aspm.policy=powersupersave"
  - echo powersupersave > /sys/module/pcie_aspm/parameters/policy
  - echo 1 > /sys/bus/pci/devices/.../link/l1_1_aspm

but this breaks devices if the platform doesn't support CLKREQ# or lacks
Root Port configuration.  This series avoids that problem by preventing the
kernel from enabling L1.x in the first place.


Bjorn Helgaas (2):
  PCI: dwc: Advertise L1 PM Substates only if driver requests it
  PCI: tegra194: Remove unnecessary L1SS disable code

Shawn Lin (2):
  PCI: dw-rockchip: Configure L1SS support
  arm64: dts: rockchip: Add PCIe clkreq stuff for RK3588 EVB1

 .../boot/dts/rockchip/rk3588-evb1-v10.dts     |  7 ++-
 .../pci/controller/dwc/pcie-designware-ep.c   |  2 +
 .../pci/controller/dwc/pcie-designware-host.c |  2 +
 drivers/pci/controller/dwc/pcie-designware.c  | 24 ++++++++++
 drivers/pci/controller/dwc/pcie-designware.h  |  2 +
 drivers/pci/controller/dwc/pcie-dw-rockchip.c | 40 ++++++++++++++++
 drivers/pci/controller/dwc/pcie-qcom.c        |  2 +
 drivers/pci/controller/dwc/pcie-tegra194.c    | 48 ++++---------------
 8 files changed, 85 insertions(+), 42 deletions(-)

-- 
2.43.0



From helgaas at kernel.org  Tue Nov 18 13:42:15 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 18 Nov 2025 15:42:15 -0600
Subject: [PATCH v2 1/4] PCI: dwc: Advertise L1 PM Substates only if driver requests it
In-Reply-To: <20251118214312.2598220-1-helgaas@kernel.org>
References: <20251118214312.2598220-1-helgaas@kernel.org>
Message-ID: <20251118214312.2598220-2-helgaas@kernel.org>

From: Bjorn Helgaas <bhelgaas at google.com>

L1 PM Substates require the CLKREQ# signal and may also require
device-specific support.  If CLKREQ# is not supported or driver support is
lacking, enabling L1.1 or L1.2 may cause errors when accessing devices,
e.g.,

  nvme nvme0: controller is down; will reset: CSTS=0xffffffff, PCI_STATUS=0x10

If the kernel is built with CONFIG_PCIEASPM_POWER_SUPERSAVE=y or users
enable L1.x via sysfs, users may trip over these errors even if L1
Substates haven't been enabled by firmware or the driver.

To prevent such errors, disable advertising the L1 PM Substates unless the
driver sets "dw_pcie.l1ss_support" to indicate that it knows CLKREQ# is
present and any device-specific configuration has been done.

Set "dw_pcie.l1ss_support" in tegra194 (if DT includes the
"supports-clkreq' property) and qcom (for cfg_2_7_0, cfg_1_9_0, cfg_1_34_0,
and cfg_sc8280xp controllers) so they can continue to use L1 Substates.

Based on Niklas's patch:
https://patch.msgid.link/20251017163252.598812-2-cassel at kernel.org

Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
---
 .../pci/controller/dwc/pcie-designware-ep.c   |  2 ++
 .../pci/controller/dwc/pcie-designware-host.c |  2 ++
 drivers/pci/controller/dwc/pcie-designware.c  | 24 +++++++++++++++++++
 drivers/pci/controller/dwc/pcie-designware.h  |  2 ++
 drivers/pci/controller/dwc/pcie-qcom.c        |  2 ++
 drivers/pci/controller/dwc/pcie-tegra194.c    |  3 +++
 6 files changed, 35 insertions(+)

diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index 7f2112c2fb21..ad6c0fd67a65 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -966,6 +966,8 @@ int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)
 	if (ep->ops->init)
 		ep->ops->init(ep);
 
+	dw_pcie_hide_unsupported_l1ss(pci);
+
 	ptm_cap_base = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_PTM);
 
 	/*
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index 20c9333bcb1c..7abeb771e32d 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -1060,6 +1060,8 @@ int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
 		PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
 	dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
 
+	dw_pcie_hide_unsupported_l1ss(pci);
+
 	dw_pcie_config_presets(pp);
 	/*
 	 * If the platform provides its own child bus config accesses, it means
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
index c644216995f6..6e6a0dac5b53 100644
--- a/drivers/pci/controller/dwc/pcie-designware.c
+++ b/drivers/pci/controller/dwc/pcie-designware.c
@@ -1081,6 +1081,30 @@ void dw_pcie_edma_remove(struct dw_pcie *pci)
 	dw_edma_remove(&pci->edma);
 }
 
+void dw_pcie_hide_unsupported_l1ss(struct dw_pcie *pci)
+{
+	u16 l1ss;
+	u32 l1ss_cap;
+
+	if (pci->l1ss_support)
+		return;
+
+	l1ss = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_L1SS);
+	if (!l1ss)
+		return;
+
+	/*
+	 * Unless the driver claims "l1ss_support", don't advertise L1 PM
+	 * Substates because they require CLKREQ# and possibly other
+	 * device-specific configuration.
+	 */
+	l1ss_cap = dw_pcie_readl_dbi(pci, l1ss + PCI_L1SS_CAP);
+	l1ss_cap &= ~(PCI_L1SS_CAP_PCIPM_L1_1 | PCI_L1SS_CAP_ASPM_L1_1 |
+		      PCI_L1SS_CAP_PCIPM_L1_2 | PCI_L1SS_CAP_ASPM_L1_2 |
+		      PCI_L1SS_CAP_L1_PM_SS);
+	dw_pcie_writel_dbi(pci, l1ss + PCI_L1SS_CAP, l1ss_cap);
+}
+
 void dw_pcie_setup(struct dw_pcie *pci)
 {
 	u32 val;
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index e995f692a1ec..a68eea47d451 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -516,6 +516,7 @@ struct dw_pcie {
 	int			max_link_speed;
 	u8			n_fts[2];
 	struct dw_edma_chip	edma;
+	bool			l1ss_support;	/* L1 PM Substates support */
 	struct clk_bulk_data	app_clks[DW_PCIE_NUM_APP_CLKS];
 	struct clk_bulk_data	core_clks[DW_PCIE_NUM_CORE_CLKS];
 	struct reset_control_bulk_data	app_rsts[DW_PCIE_NUM_APP_RSTS];
@@ -573,6 +574,7 @@ int dw_pcie_prog_ep_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
 				int type, u64 parent_bus_addr,
 				u8 bar, size_t size);
 void dw_pcie_disable_atu(struct dw_pcie *pci, u32 dir, int index);
+void dw_pcie_hide_unsupported_l1ss(struct dw_pcie *pci);
 void dw_pcie_setup(struct dw_pcie *pci);
 void dw_pcie_iatu_detect(struct dw_pcie *pci);
 int dw_pcie_edma_detect(struct dw_pcie *pci);
diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index 805edbbfe7eb..61c2f4e2f74d 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -1067,6 +1067,8 @@ static int qcom_pcie_init_2_7_0(struct qcom_pcie *pcie)
 	val &= ~REQ_NOT_ENTR_L1;
 	writel(val, pcie->parf + PARF_PM_CTRL);
 
+	pci->l1ss_support = true;
+
 	val = readl(pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
 	val |= EN;
 	writel(val, pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
index 10e74458e667..3934757baa30 100644
--- a/drivers/pci/controller/dwc/pcie-tegra194.c
+++ b/drivers/pci/controller/dwc/pcie-tegra194.c
@@ -703,6 +703,9 @@ static void init_host_aspm(struct tegra_pcie_dw *pcie)
 	val |= (pcie->aspm_pwr_on_t << 19);
 	dw_pcie_writel_dbi(pci, pcie->cfg_link_cap_l1sub, val);
 
+	if (pcie->supports_clkreq)
+		pci->l1ss_support = true;
+
 	/* Program L0s and L1 entrance latencies */
 	val = dw_pcie_readl_dbi(pci, PCIE_PORT_AFR);
 	val &= ~PORT_AFR_L0S_ENTRANCE_LAT_MASK;
-- 
2.43.0



From helgaas at kernel.org  Tue Nov 18 13:42:16 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 18 Nov 2025 15:42:16 -0600
Subject: [PATCH v2 2/4] PCI: tegra194: Remove unnecessary L1SS disable code
In-Reply-To: <20251118214312.2598220-1-helgaas@kernel.org>
References: <20251118214312.2598220-1-helgaas@kernel.org>
Message-ID: <20251118214312.2598220-3-helgaas@kernel.org>

From: Bjorn Helgaas <bhelgaas at google.com>

The DWC core clears the L1 Substates Supported bits unless the driver sets
the "dw_pcie.l1ss_support" flag.

The tegra194 init_host_aspm() sets "dw_pcie.l1ss_support" if the platform
has the "supports-clkreq" DT property.  If "supports-clkreq" is absent,
"dw_pcie.l1ss_support" is not set, and the DWC core will clear the L1
Substates Supported bits.

The tegra194 code to clear the L1 Substates Supported bits is unnecessary,
so remove it.

Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
---
 drivers/pci/controller/dwc/pcie-tegra194.c | 45 +++-------------------
 1 file changed, 5 insertions(+), 40 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
index 3934757baa30..0ddeef70726d 100644
--- a/drivers/pci/controller/dwc/pcie-tegra194.c
+++ b/drivers/pci/controller/dwc/pcie-tegra194.c
@@ -260,7 +260,6 @@ struct tegra_pcie_dw {
 	u32 msi_ctrl_int;
 	u32 num_lanes;
 	u32 cid;
-	u32 cfg_link_cap_l1sub;
 	u32 ras_des_cap;
 	u32 pcie_cap_base;
 	u32 aspm_cmrt;
@@ -475,8 +474,7 @@ static irqreturn_t tegra_pcie_ep_irq_thread(int irq, void *arg)
 		return IRQ_HANDLED;
 
 	/* If EP doesn't advertise L1SS, just return */
-	val = dw_pcie_readl_dbi(pci, pcie->cfg_link_cap_l1sub);
-	if (!(val & (PCI_L1SS_CAP_ASPM_L1_1 | PCI_L1SS_CAP_ASPM_L1_2)))
+	if (!pci->l1ss_support)
 		return IRQ_HANDLED;
 
 	/* Check if BME is set to '1' */
@@ -608,24 +606,6 @@ static struct pci_ops tegra_pci_ops = {
 };
 
 #if defined(CONFIG_PCIEASPM)
-static void disable_aspm_l11(struct tegra_pcie_dw *pcie)
-{
-	u32 val;
-
-	val = dw_pcie_readl_dbi(&pcie->pci, pcie->cfg_link_cap_l1sub);
-	val &= ~PCI_L1SS_CAP_ASPM_L1_1;
-	dw_pcie_writel_dbi(&pcie->pci, pcie->cfg_link_cap_l1sub, val);
-}
-
-static void disable_aspm_l12(struct tegra_pcie_dw *pcie)
-{
-	u32 val;
-
-	val = dw_pcie_readl_dbi(&pcie->pci, pcie->cfg_link_cap_l1sub);
-	val &= ~PCI_L1SS_CAP_ASPM_L1_2;
-	dw_pcie_writel_dbi(&pcie->pci, pcie->cfg_link_cap_l1sub, val);
-}
-
 static inline u32 event_counter_prog(struct tegra_pcie_dw *pcie, u32 event)
 {
 	u32 val;
@@ -682,10 +662,9 @@ static int aspm_state_cnt(struct seq_file *s, void *data)
 static void init_host_aspm(struct tegra_pcie_dw *pcie)
 {
 	struct dw_pcie *pci = &pcie->pci;
-	u32 val;
+	u32 l1ss, val;
 
-	val = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_L1SS);
-	pcie->cfg_link_cap_l1sub = val + PCI_L1SS_CAP;
+	l1ss = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_L1SS);
 
 	pcie->ras_des_cap = dw_pcie_find_ext_capability(&pcie->pci,
 							PCI_EXT_CAP_ID_VNDR);
@@ -697,11 +676,11 @@ static void init_host_aspm(struct tegra_pcie_dw *pcie)
 			   PCIE_RAS_DES_EVENT_COUNTER_CONTROL, val);
 
 	/* Program T_cmrt and T_pwr_on values */
-	val = dw_pcie_readl_dbi(pci, pcie->cfg_link_cap_l1sub);
+	val = dw_pcie_readl_dbi(pci, l1ss + PCI_L1SS_CAP);
 	val &= ~(PCI_L1SS_CAP_CM_RESTORE_TIME | PCI_L1SS_CAP_P_PWR_ON_VALUE);
 	val |= (pcie->aspm_cmrt << 8);
 	val |= (pcie->aspm_pwr_on_t << 19);
-	dw_pcie_writel_dbi(pci, pcie->cfg_link_cap_l1sub, val);
+	dw_pcie_writel_dbi(pci, l1ss + PCI_L1SS_CAP, val);
 
 	if (pcie->supports_clkreq)
 		pci->l1ss_support = true;
@@ -729,8 +708,6 @@ static void init_debugfs(struct tegra_pcie_dw *pcie)
 				    aspm_state_cnt);
 }
 #else
-static inline void disable_aspm_l12(struct tegra_pcie_dw *pcie) { return; }
-static inline void disable_aspm_l11(struct tegra_pcie_dw *pcie) { return; }
 static inline void init_host_aspm(struct tegra_pcie_dw *pcie) { return; }
 static inline void init_debugfs(struct tegra_pcie_dw *pcie) { return; }
 #endif
@@ -934,12 +911,6 @@ static int tegra_pcie_dw_host_init(struct dw_pcie_rp *pp)
 
 	init_host_aspm(pcie);
 
-	/* Disable ASPM-L1SS advertisement if there is no CLKREQ routing */
-	if (!pcie->supports_clkreq) {
-		disable_aspm_l11(pcie);
-		disable_aspm_l12(pcie);
-	}
-
 	if (!pcie->of_data->has_l1ss_exit_fix) {
 		val = dw_pcie_readl_dbi(pci, GEN3_RELATED_OFF);
 		val &= ~GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL;
@@ -1874,12 +1845,6 @@ static void pex_ep_event_pex_rst_deassert(struct tegra_pcie_dw *pcie)
 
 	init_host_aspm(pcie);
 
-	/* Disable ASPM-L1SS advertisement if there is no CLKREQ routing */
-	if (!pcie->supports_clkreq) {
-		disable_aspm_l11(pcie);
-		disable_aspm_l12(pcie);
-	}
-
 	if (!pcie->of_data->has_l1ss_exit_fix) {
 		val = dw_pcie_readl_dbi(pci, GEN3_RELATED_OFF);
 		val &= ~GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL;
-- 
2.43.0



From helgaas at kernel.org  Tue Nov 18 13:42:17 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 18 Nov 2025 15:42:17 -0600
Subject: [PATCH v2 3/4] PCI: dw-rockchip: Configure L1SS support
In-Reply-To: <20251118214312.2598220-1-helgaas@kernel.org>
References: <20251118214312.2598220-1-helgaas@kernel.org>
Message-ID: <20251118214312.2598220-4-helgaas@kernel.org>

From: Shawn Lin <shawn.lin at rock-chips.com>

L1 PM Substates for RC mode require support in the dw-rockchip driver
including proper handling of the CLKREQ# sideband signal. It is mostly
handled by hardware, but software still needs to set the clkreq fields
in the PCIE_CLIENT_POWER_CON register to match the hardware implementation.

For more details, see section '18.6.6.4 L1 Substate' in the RK3568 TRM 1.1
Part 2, or section '11.6.6.4 L1 Substate' in the RK3588 TRM 1.0 Part2.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
[bhelgaas: set pci->l1ss_support so DWC core preserves L1SS Capability bits;
drop corresponding code here, include updates from
https://lore.kernel.org/r/aRRG8wv13HxOCqgA at ryzen]
Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
Link: https://patch.msgid.link/1761187883-150120-1-git-send-email-shawn.lin at rock-chips.com
---
 drivers/pci/controller/dwc/pcie-dw-rockchip.c | 40 +++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
index 3e2752c7dd09..bcd3a28da650 100644
--- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
+++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
@@ -62,6 +62,12 @@
 /* Interrupt Mask Register Related to Miscellaneous Operation */
 #define PCIE_CLIENT_INTR_MASK_MISC	0x24
 
+/* Power Management Control Register */
+#define PCIE_CLIENT_POWER_CON		0x2c
+#define  PCIE_CLKREQ_READY		FIELD_PREP_WM16(BIT(0), 1)
+#define  PCIE_CLKREQ_NOT_READY		FIELD_PREP_WM16(BIT(0), 0)
+#define  PCIE_CLKREQ_PULL_DOWN		FIELD_PREP_WM16(GENMASK(13, 12), 1)
+
 /* Hot Reset Control Register */
 #define PCIE_CLIENT_HOT_RESET_CTRL	0x180
 #define  PCIE_LTSSM_APP_DLY2_EN		BIT(1)
@@ -85,6 +91,7 @@ struct rockchip_pcie {
 	struct regulator *vpcie3v3;
 	struct irq_domain *irq_domain;
 	const struct rockchip_pcie_of_data *data;
+	bool supports_clkreq;
 };
 
 struct rockchip_pcie_of_data {
@@ -200,6 +207,35 @@ static bool rockchip_pcie_link_up(struct dw_pcie *pci)
 	return FIELD_GET(PCIE_LINKUP_MASK, val) == PCIE_LINKUP;
 }
 
+/*
+ * See e.g. section '11.6.6.4 L1 Substate' in the RK3588 TRM V1.0 for the steps
+ * needed to support L1 substates. Currently, just enable L1 substates for RC
+ * mode if CLKREQ# is properly connected and supports-clkreq is present in DT.
+ * For EP mode, there are more things should be done to actually save power in
+ * L1 substates, so disable L1 substates until there is proper support.
+ */
+static void rockchip_pcie_configure_l1ss(struct dw_pcie *pci)
+{
+	struct rockchip_pcie *rockchip = to_rockchip_pcie(pci);
+
+	/* Enable L1 substates if CLKREQ# is properly connected */
+	if (rockchip->supports_clkreq) {
+		rockchip_pcie_writel_apb(rockchip, PCIE_CLKREQ_READY,
+					 PCIE_CLIENT_POWER_CON);
+		pci->l1ss_support = true;
+		return;
+	}
+
+	/*
+	 * Otherwise, assert CLKREQ# unconditionally.  Since
+	 * pci->l1ss_support is not set, the DWC core will prevent L1
+	 * Substates support from being advertised.
+	 */
+	rockchip_pcie_writel_apb(rockchip,
+				 PCIE_CLKREQ_PULL_DOWN | PCIE_CLKREQ_NOT_READY,
+				 PCIE_CLIENT_POWER_CON);
+}
+
 static void rockchip_pcie_enable_l0s(struct dw_pcie *pci)
 {
 	u32 cap, lnkcap;
@@ -264,6 +300,7 @@ static int rockchip_pcie_host_init(struct dw_pcie_rp *pp)
 	irq_set_chained_handler_and_data(irq, rockchip_pcie_intx_handler,
 					 rockchip);
 
+	rockchip_pcie_configure_l1ss(pci);
 	rockchip_pcie_enable_l0s(pci);
 
 	return 0;
@@ -412,6 +449,9 @@ static int rockchip_pcie_resource_get(struct platform_device *pdev,
 		return dev_err_probe(&pdev->dev, PTR_ERR(rockchip->rst),
 				     "failed to get reset lines\n");
 
+	rockchip->supports_clkreq = of_property_read_bool(pdev->dev.of_node,
+							  "supports-clkreq");
+
 	return 0;
 }
 
-- 
2.43.0



From helgaas at kernel.org  Tue Nov 18 13:42:18 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 18 Nov 2025 15:42:18 -0600
Subject: [PATCH v2 4/4] arm64: dts: rockchip: Add PCIe clkreq stuff for RK3588 EVB1
In-Reply-To: <20251118214312.2598220-1-helgaas@kernel.org>
References: <20251118214312.2598220-1-helgaas@kernel.org>
Message-ID: <20251118214312.2598220-5-helgaas@kernel.org>

From: Shawn Lin <shawn.lin at rock-chips.com>

Add supports-clkreq and pinmux for PCIe ASPM L1 substates.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
Reviewed-by: Hans Zhang <hans.zhang at cixtech.com>
Acked-by: Manivannan Sadhasivam <mani at kernel.org>
Link: https://patch.msgid.link/1761187883-150120-2-git-send-email-shawn.lin at rock-chips.com
---
 arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
index ff1ba5ed56ef..c9d284cb738b 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
@@ -522,6 +522,7 @@ &pcie2x1l0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pcie2_0_rst>, <&pcie2_0_wake>, <&pcie2_0_clkreq>, <&wifi_host_wake_irq>;
 	reset-gpios = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>;
+	supports-clkreq;
 	vpcie3v3-supply = <&vcc3v3_wlan>;
 	status = "okay";
 
@@ -545,7 +546,8 @@ wifi: wifi at 0,0 {
 &pcie2x1l1 {
 	reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
 	pinctrl-names = "default";
-	pinctrl-0 = <&pcie2_1_rst>, <&rtl8111_isolate>;
+	pinctrl-0 = <&pcie2_1_rst>, <&rtl8111_isolate>, <&pcie30x1m1_1_clkreqn>;
+	supports-clkreq;
 	status = "okay";
 };
 
@@ -555,7 +557,8 @@ &pcie30phy {
 
 &pcie3x4 {
 	pinctrl-names = "default";
-	pinctrl-0 = <&pcie3_reset>;
+	pinctrl-0 = <&pcie3_reset>, <&pcie30x4m1_clkreqn>;
+	supports-clkreq;
 	reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
 	vpcie3v3-supply = <&vcc3v3_pcie30>;
 	status = "okay";
-- 
2.43.0



From Frank.li at nxp.com  Tue Nov 18 14:08:47 2025
From: Frank.li at nxp.com (Frank Li)
Date: Tue, 18 Nov 2025 17:08:47 -0500
Subject: [PATCH v2 2/3] media: rockchip: add driver for the rockchip mipi
 csi-2 receiver
In-Reply-To: <554971e1-6fde-4b2c-a2de-fe178358a4e3@collabora.com>
References: <20251114-rockchip-mipi-receiver-v2-0-eb9b43377fc4@collabora.com>
 <20251114-rockchip-mipi-receiver-v2-2-eb9b43377fc4@collabora.com>
 <aRyplYZOrGsSxSlp@lizhi-Precision-Tower-5810>
 <554971e1-6fde-4b2c-a2de-fe178358a4e3@collabora.com>
Message-ID: <aRzub5Ak6DZpO5f/@lizhi-Precision-Tower-5810>

On Tue, Nov 18, 2025 at 07:59:14PM +0100, Michael Riesch wrote:
> Hi Frank,
>
> On 11/18/25 18:15, Frank Li wrote:
> > On Tue, Nov 18, 2025 at 12:12:26PM +0100, Michael Riesch via B4 Relay wrote:
> >> From: Michael Riesch <michael.riesch at collabora.com>
> >>
> >>[...]
> >> +#define CSI2HOST_N_LANES     0x04
> >> +#define CSI2HOST_CSI2_RESETN 0x10
> >> +#define CSI2HOST_PHY_STATE   0x14
> >> +#define CSI2HOST_ERR1	     0x20
> >> +#define CSI2HOST_ERR2	     0x24
> >> +#define CSI2HOST_MSK1	     0x28
> >> +#define CSI2HOST_MSK2	     0x2c
> >> +#define CSI2HOST_CONTROL     0x40
> >
> > Look like that is designware CSI2 controller, can we build common library
> > for all dwc csi2 controller, instead of every vendor create individual one.
> >
> > First try at
> > https://lore.kernel.org/linux-media/20250821-95_cam-v3-21-c9286fbb34b9 at nxp.com/
> >
> > Toshiba have similar patch
> > https://lore.kernel.org/linux-media/aPZd39riAxqfw3mT at lizhi-Precision-Tower-5810/
> >
> > Frank
>
> This has been discussed already a while ago:
> https://lore.kernel.org/all/20250507083837.GA11152 at pendragon.ideasonboard.com/

https://lore.kernel.org/all/20250702093806.GF16835 at pendragon.ideasonboard.com/

Laurent Pinchart prevent imx93 DWC CSI2 driver at Jul, your discussion at
May, I think Laurent Pinchart change the mind.

We can choose not base on imx6, but we should create a standard dwc2 under
drivers/media/platform/synopsys/

Laurent Pinchart:

	Can you provide direction?

Frank

>
> Bottom line from Laurent:
>
> "Let's keep this driver Rockchip-specific then. Thanks for checking."
>
> >  [...]
> Best regards,
> Michael


From Frank.li at nxp.com  Tue Nov 18 14:20:36 2025
From: Frank.li at nxp.com (Frank Li)
Date: Tue, 18 Nov 2025 17:20:36 -0500
Subject: [PATCH v2 1/4] PCI: dwc: Advertise L1 PM Substates only if
 driver requests it
In-Reply-To: <20251118214312.2598220-2-helgaas@kernel.org>
References: <20251118214312.2598220-1-helgaas@kernel.org>
 <20251118214312.2598220-2-helgaas@kernel.org>
Message-ID: <aRzxNMJ+byxZiF3i@lizhi-Precision-Tower-5810>

On Tue, Nov 18, 2025 at 03:42:15PM -0600, Bjorn Helgaas wrote:
> From: Bjorn Helgaas <bhelgaas at google.com>
>
> L1 PM Substates require the CLKREQ# signal and may also require
> device-specific support.  If CLKREQ# is not supported or driver support is
> lacking, enabling L1.1 or L1.2 may cause errors when accessing devices,
> e.g.,
>
>   nvme nvme0: controller is down; will reset: CSTS=0xffffffff, PCI_STATUS=0x10
>
> If the kernel is built with CONFIG_PCIEASPM_POWER_SUPERSAVE=y or users
> enable L1.x via sysfs, users may trip over these errors even if L1
> Substates haven't been enabled by firmware or the driver.
>
> To prevent such errors, disable advertising the L1 PM Substates unless the
> driver sets "dw_pcie.l1ss_support" to indicate that it knows CLKREQ# is
> present and any device-specific configuration has been done.
>
> Set "dw_pcie.l1ss_support" in tegra194 (if DT includes the
> "supports-clkreq' property) and qcom (for cfg_2_7_0, cfg_1_9_0, cfg_1_34_0,
> and cfg_sc8280xp controllers) so they can continue to use L1 Substates.
>
> Based on Niklas's patch:
> https://patch.msgid.link/20251017163252.598812-2-cassel at kernel.org
>
> Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
> ---
>  .../pci/controller/dwc/pcie-designware-ep.c   |  2 ++
>  .../pci/controller/dwc/pcie-designware-host.c |  2 ++
>  drivers/pci/controller/dwc/pcie-designware.c  | 24 +++++++++++++++++++
>  drivers/pci/controller/dwc/pcie-designware.h  |  2 ++
>  drivers/pci/controller/dwc/pcie-qcom.c        |  2 ++
>  drivers/pci/controller/dwc/pcie-tegra194.c    |  3 +++
>  6 files changed, 35 insertions(+)
>
> diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
> index 7f2112c2fb21..ad6c0fd67a65 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> @@ -966,6 +966,8 @@ int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)
>  	if (ep->ops->init)
>  		ep->ops->init(ep);
>
> +	dw_pcie_hide_unsupported_l1ss(pci);
> +

Need call dw_pcie_dbi_ro_wr_en(pci) to access PCI_L1SS_CAP.

just ref below code

	/*
         * PTM responder capability can be disabled only after disabling
         * PTM root capability.
         */
        if (ptm_cap_base) {
                dw_pcie_dbi_ro_wr_en(pci);
                reg = dw_pcie_readl_dbi(pci, ptm_cap_base + PCI_PTM_CAP);
                reg &= ~PCI_PTM_CAP_ROOT;
                dw_pcie_writel_dbi(pci, ptm_cap_base + PCI_PTM_CAP, reg);

                reg = dw_pcie_readl_dbi(pci, ptm_cap_base + PCI_PTM_CAP);
                reg &= ~(PCI_PTM_CAP_RES | PCI_PTM_GRANULARITY_MASK);
                dw_pcie_writel_dbi(pci, ptm_cap_base + PCI_PTM_CAP, reg);
                dw_pcie_dbi_ro_wr_dis(pci);
        }

Frank


>  	ptm_cap_base = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_PTM);
>
>  	/*
> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> index 20c9333bcb1c..7abeb771e32d 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -1060,6 +1060,8 @@ int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
>  		PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
>  	dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
>
> +	dw_pcie_hide_unsupported_l1ss(pci);
> +
>  	dw_pcie_config_presets(pp);
>  	/*
>  	 * If the platform provides its own child bus config accesses, it means
> diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
> index c644216995f6..6e6a0dac5b53 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.c
> +++ b/drivers/pci/controller/dwc/pcie-designware.c
> @@ -1081,6 +1081,30 @@ void dw_pcie_edma_remove(struct dw_pcie *pci)
>  	dw_edma_remove(&pci->edma);
>  }
>
> +void dw_pcie_hide_unsupported_l1ss(struct dw_pcie *pci)
> +{
> +	u16 l1ss;
> +	u32 l1ss_cap;
> +
> +	if (pci->l1ss_support)
> +		return;
> +
> +	l1ss = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_L1SS);
> +	if (!l1ss)
> +		return;
> +
> +	/*
> +	 * Unless the driver claims "l1ss_support", don't advertise L1 PM
> +	 * Substates because they require CLKREQ# and possibly other
> +	 * device-specific configuration.
> +	 */
> +	l1ss_cap = dw_pcie_readl_dbi(pci, l1ss + PCI_L1SS_CAP);
> +	l1ss_cap &= ~(PCI_L1SS_CAP_PCIPM_L1_1 | PCI_L1SS_CAP_ASPM_L1_1 |
> +		      PCI_L1SS_CAP_PCIPM_L1_2 | PCI_L1SS_CAP_ASPM_L1_2 |
> +		      PCI_L1SS_CAP_L1_PM_SS);
> +	dw_pcie_writel_dbi(pci, l1ss + PCI_L1SS_CAP, l1ss_cap);
> +}
> +
>  void dw_pcie_setup(struct dw_pcie *pci)
>  {
>  	u32 val;
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> index e995f692a1ec..a68eea47d451 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -516,6 +516,7 @@ struct dw_pcie {
>  	int			max_link_speed;
>  	u8			n_fts[2];
>  	struct dw_edma_chip	edma;
> +	bool			l1ss_support;	/* L1 PM Substates support */
>  	struct clk_bulk_data	app_clks[DW_PCIE_NUM_APP_CLKS];
>  	struct clk_bulk_data	core_clks[DW_PCIE_NUM_CORE_CLKS];
>  	struct reset_control_bulk_data	app_rsts[DW_PCIE_NUM_APP_RSTS];
> @@ -573,6 +574,7 @@ int dw_pcie_prog_ep_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
>  				int type, u64 parent_bus_addr,
>  				u8 bar, size_t size);
>  void dw_pcie_disable_atu(struct dw_pcie *pci, u32 dir, int index);
> +void dw_pcie_hide_unsupported_l1ss(struct dw_pcie *pci);
>  void dw_pcie_setup(struct dw_pcie *pci);
>  void dw_pcie_iatu_detect(struct dw_pcie *pci);
>  int dw_pcie_edma_detect(struct dw_pcie *pci);
> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
> index 805edbbfe7eb..61c2f4e2f74d 100644
> --- a/drivers/pci/controller/dwc/pcie-qcom.c
> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> @@ -1067,6 +1067,8 @@ static int qcom_pcie_init_2_7_0(struct qcom_pcie *pcie)
>  	val &= ~REQ_NOT_ENTR_L1;
>  	writel(val, pcie->parf + PARF_PM_CTRL);
>
> +	pci->l1ss_support = true;
> +
>  	val = readl(pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
>  	val |= EN;
>  	writel(val, pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
> diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
> index 10e74458e667..3934757baa30 100644
> --- a/drivers/pci/controller/dwc/pcie-tegra194.c
> +++ b/drivers/pci/controller/dwc/pcie-tegra194.c
> @@ -703,6 +703,9 @@ static void init_host_aspm(struct tegra_pcie_dw *pcie)
>  	val |= (pcie->aspm_pwr_on_t << 19);
>  	dw_pcie_writel_dbi(pci, pcie->cfg_link_cap_l1sub, val);
>
> +	if (pcie->supports_clkreq)
> +		pci->l1ss_support = true;
> +
>  	/* Program L0s and L1 entrance latencies */
>  	val = dw_pcie_readl_dbi(pci, PCIE_PORT_AFR);
>  	val &= ~PORT_AFR_L0S_ENTRANCE_LAT_MASK;
> --
> 2.43.0
>


From macroalpha82 at gmail.com  Tue Nov 18 14:30:44 2025
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Tue, 18 Nov 2025 16:30:44 -0600
Subject: [PATCH V2 0/4] Indiedroid Nova Devicetree Updates
Message-ID: <20251118223048.4531-1-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

This series fixes up a few remaining issues with the devicetree for the
Indiedroid Nova. Namely it adds or updates a few pinctrl definitions,
it removes a few workarounds that no longer appear to be necessary for
eMMC and bluetooth, it adds support for the NPU, and it sets the device
type as embedded.

Changes since V1:
 - The device type addition, NPU enablement, HS400 enablement, and DMA
   fixes for bluetooth were accepted as a subset and have been removed
   from this series.
 - The individual changes from the pinctrl fixes have been broken out
   into a series of separate patches.

Chris Morgan (4):
  arm64: dts: rockchip: Add clk32k_in for Indiedroid Nova
  arm64: dts: rockchip: Define regulator for pcie2x1l2
  arm64: dts: rockchip: Correct pinctrl for pcie for Indiedroid Nova
  arm64: dts: rockchip: Add host wake pin for wifi on Indiedroid Nova

 .../dts/rockchip/rk3588s-indiedroid-nova.dts  | 43 ++++++++++++-------
 1 file changed, 28 insertions(+), 15 deletions(-)

-- 
2.43.0



From macroalpha82 at gmail.com  Tue Nov 18 14:30:45 2025
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Tue, 18 Nov 2025 16:30:45 -0600
Subject: [PATCH V2 1/4] arm64: dts: rockchip: Add clk32k_in for Indiedroid Nova
In-Reply-To: <20251118223048.4531-1-macroalpha82@gmail.com>
References: <20251118223048.4531-1-macroalpha82@gmail.com>
Message-ID: <20251118223048.4531-2-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

The clk32k_in pin of the SoC is connected to the real time clock
according to the schematics. Set the pin definition on the real
time clock to reflect this.

Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
---
 arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
index 769f4a7adf0a..d1cef48bcce5 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
@@ -430,7 +430,7 @@ rtc_hym8563: rtc at 51 {
 		clock-output-names = "hym8563";
 		interrupt-parent = <&gpio0>;
 		interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>;
-		pinctrl-0 = <&hym8563_int>;
+		pinctrl-0 = <&hym8563_int>, <&clk32k_in>;
 		pinctrl-names = "default";
 		wakeup-source;
 	};
-- 
2.43.0



From macroalpha82 at gmail.com  Tue Nov 18 14:30:46 2025
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Tue, 18 Nov 2025 16:30:46 -0600
Subject: [PATCH V2 2/4] arm64: dts: rockchip: Define regulator for pcie2x1l2
In-Reply-To: <20251118223048.4531-1-macroalpha82@gmail.com>
References: <20251118223048.4531-1-macroalpha82@gmail.com>
Message-ID: <20251118223048.4531-3-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

Add the correct regulator defined per the schematics to the PCIE
interface for the Indiedroid Nova.

Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
---
 arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
index d1cef48bcce5..1562d02e85d6 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
@@ -485,6 +485,7 @@ &i2s5_8ch {
 &pcie2x1l2 {
 	pinctrl-0 = <&rtl8111_perstb>;
 	pinctrl-names = "default";
+	vpcie3v3-supply = <&vcc_3v3_s3>;
 	status = "okay";
 };
 
-- 
2.43.0



From macroalpha82 at gmail.com  Tue Nov 18 14:30:47 2025
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Tue, 18 Nov 2025 16:30:47 -0600
Subject: [PATCH V2 3/4] arm64: dts: rockchip: Correct pinctrl for pcie for Indiedroid Nova
In-Reply-To: <20251118223048.4531-1-macroalpha82@gmail.com>
References: <20251118223048.4531-1-macroalpha82@gmail.com>
Message-ID: <20251118223048.4531-4-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

Correct the pin definitions of the PCIE controller on the Indiedroid
Nova according to the schematics. Since GPIO3 D1 is already defined
as a reset pin in the rk3588-base-pinctrl.dtsi file we do not need
a custom definition anymore.

Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
---
 .../boot/dts/rockchip/rk3588s-indiedroid-nova.dts      | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
index 1562d02e85d6..7233e290d0cf 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
@@ -483,8 +483,10 @@ &i2s5_8ch {
 };
 
 &pcie2x1l2 {
-	pinctrl-0 = <&rtl8111_perstb>;
+	pinctrl-0 = <&pcie20x1m0_perstn>, <&pcie20x1m0_clkreqn>,
+		    <&pcie20x1m0_waken>;
 	pinctrl-names = "default";
+	reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
 	vpcie3v3-supply = <&vcc_3v3_s3>;
 	status = "okay";
 };
@@ -515,12 +517,6 @@ bt_wake_host: bt-wake-host {
 		};
 	};
 
-	ethernet-pins {
-		rtl8111_perstb: rtl8111-perstb {
-			rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_up>;
-		};
-	};
-
 	hym8563 {
 
 		hym8563_int: hym8563-int {
-- 
2.43.0



From macroalpha82 at gmail.com  Tue Nov 18 14:30:48 2025
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Tue, 18 Nov 2025 16:30:48 -0600
Subject: [PATCH V2 4/4] arm64: dts: rockchip: Add host wake pin for wifi on Indiedroid Nova
In-Reply-To: <20251118223048.4531-1-macroalpha82@gmail.com>
References: <20251118223048.4531-1-macroalpha82@gmail.com>
Message-ID: <20251118223048.4531-5-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

Add the pin definition for the host wake interrupt on the Indiedroid
Nova. This necessitates adding a node for the wifi controller to
properly define the interrupt. Additionally, we can consolidate both
pinctrl definitions under a wifi node to note their common functionality.

Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
---
 .../dts/rockchip/rk3588s-indiedroid-nova.dts  | 30 ++++++++++++++-----
 1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
index 7233e290d0cf..174d299cc6bb 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
@@ -525,13 +525,6 @@ hym8563_int: hym8563-int {
 		};
 	};
 
-	sdio-pwrseq {
-		wifi_enable_h: wifi-enable-h {
-			rockchip,pins =
-				<0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>;
-		};
-	};
-
 	usb-typec {
 		usbc0_int: usbc0-int {
 			rockchip,pins =
@@ -543,6 +536,18 @@ typec5v_pwren: typec5v-pwren {
 				<4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
 		};
 	};
+
+	wifi {
+		wifi_enable_h: wifi-enable-h {
+			rockchip,pins =
+				<0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		wifi_host_wake_irq: wifi-host-wake-irq {
+			rockchip,pins =
+				<0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+	};
 };
 
 &rknn_core_0 {
@@ -593,6 +598,7 @@ &sdhci {
 };
 
 &sdio {
+	#address-cells = <1>;
 	bus-width = <4>;
 	cap-sd-highspeed;
 	cap-sdio-irq;
@@ -604,9 +610,19 @@ &sdio {
 	no-sd;
 	non-removable;
 	sd-uhs-sdr104;
+	#size-cells = <0>;
 	vmmc-supply = <&vcc_3v3_s3>;
 	vqmmc-supply = <&vcc_1v8_s3>;
 	status = "okay";
+
+	sdio_wifi: wifi at 1 {
+		reg = <1>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PA0 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-names = "host-wake";
+		pinctrl-0 = <&wifi_host_wake_irq>;
+		pinctrl-names = "default";
+	};
 };
 
 &sdmmc {
-- 
2.43.0



From Frank.li at nxp.com  Tue Nov 18 14:34:18 2025
From: Frank.li at nxp.com (Frank Li)
Date: Tue, 18 Nov 2025 17:34:18 -0500
Subject: [PATCH v2 1/4] PCI: dwc: Advertise L1 PM Substates only if
 driver requests it
In-Reply-To: <20251118214312.2598220-2-helgaas@kernel.org>
References: <20251118214312.2598220-1-helgaas@kernel.org>
 <20251118214312.2598220-2-helgaas@kernel.org>
Message-ID: <aRz0ak6onKzZs2lY@lizhi-Precision-Tower-5810>

On Tue, Nov 18, 2025 at 03:42:15PM -0600, Bjorn Helgaas wrote:
> From: Bjorn Helgaas <bhelgaas at google.com>
>
> L1 PM Substates require the CLKREQ# signal and may also require
> device-specific support.  If CLKREQ# is not supported or driver support is
> lacking, enabling L1.1 or L1.2 may cause errors when accessing devices,
> e.g.,
>
>   nvme nvme0: controller is down; will reset: CSTS=0xffffffff, PCI_STATUS=0x10
>
> If the kernel is built with CONFIG_PCIEASPM_POWER_SUPERSAVE=y or users
> enable L1.x via sysfs, users may trip over these errors even if L1
> Substates haven't been enabled by firmware or the driver.
>
> To prevent such errors, disable advertising the L1 PM Substates unless the
> driver sets "dw_pcie.l1ss_support" to indicate that it knows CLKREQ# is
> present and any device-specific configuration has been done.
>
> Set "dw_pcie.l1ss_support" in tegra194 (if DT includes the
> "supports-clkreq' property) and qcom (for cfg_2_7_0, cfg_1_9_0, cfg_1_34_0,
> and cfg_sc8280xp controllers) so they can continue to use L1 Substates.
>
> Based on Niklas's patch:
> https://patch.msgid.link/20251017163252.598812-2-cassel at kernel.org
>
> Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
> ---
>  .../pci/controller/dwc/pcie-designware-ep.c   |  2 ++
>  .../pci/controller/dwc/pcie-designware-host.c |  2 ++
>  drivers/pci/controller/dwc/pcie-designware.c  | 24 +++++++++++++++++++
>  drivers/pci/controller/dwc/pcie-designware.h  |  2 ++
>  drivers/pci/controller/dwc/pcie-qcom.c        |  2 ++
>  drivers/pci/controller/dwc/pcie-tegra194.c    |  3 +++
>  6 files changed, 35 insertions(+)
>
> diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
> index 7f2112c2fb21..ad6c0fd67a65 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> @@ -966,6 +966,8 @@ int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)
>  	if (ep->ops->init)
>  		ep->ops->init(ep);
>
> +	dw_pcie_hide_unsupported_l1ss(pci);
> +

And, I don't think EP need clean L1SS CAP flags. If EP don't support L1SS,
it should be force pull down #clkreq.

EP don't know if #clkreq connected in host boards, assume EP with same
software, which can run at two difference host system, one host system
connect #clkreq, the other system have not connect #clkreq.

otherwords, support-clkreq property should be only for RC side. not EP
side. EP side l1ss support should depend on specific epf function and
controller's capablity.

Frank

>  	ptm_cap_base = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_PTM);
>
>  	/*
> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> index 20c9333bcb1c..7abeb771e32d 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -1060,6 +1060,8 @@ int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
>  		PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
>  	dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
>
> +	dw_pcie_hide_unsupported_l1ss(pci);
> +
>  	dw_pcie_config_presets(pp);
>  	/*
>  	 * If the platform provides its own child bus config accesses, it means
> diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
> index c644216995f6..6e6a0dac5b53 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.c
> +++ b/drivers/pci/controller/dwc/pcie-designware.c
> @@ -1081,6 +1081,30 @@ void dw_pcie_edma_remove(struct dw_pcie *pci)
>  	dw_edma_remove(&pci->edma);
>  }
>
> +void dw_pcie_hide_unsupported_l1ss(struct dw_pcie *pci)
> +{
> +	u16 l1ss;
> +	u32 l1ss_cap;
> +
> +	if (pci->l1ss_support)
> +		return;
> +
> +	l1ss = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_L1SS);
> +	if (!l1ss)
> +		return;
> +
> +	/*
> +	 * Unless the driver claims "l1ss_support", don't advertise L1 PM
> +	 * Substates because they require CLKREQ# and possibly other
> +	 * device-specific configuration.
> +	 */
> +	l1ss_cap = dw_pcie_readl_dbi(pci, l1ss + PCI_L1SS_CAP);
> +	l1ss_cap &= ~(PCI_L1SS_CAP_PCIPM_L1_1 | PCI_L1SS_CAP_ASPM_L1_1 |
> +		      PCI_L1SS_CAP_PCIPM_L1_2 | PCI_L1SS_CAP_ASPM_L1_2 |
> +		      PCI_L1SS_CAP_L1_PM_SS);
> +	dw_pcie_writel_dbi(pci, l1ss + PCI_L1SS_CAP, l1ss_cap);
> +}
> +
>  void dw_pcie_setup(struct dw_pcie *pci)
>  {
>  	u32 val;
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> index e995f692a1ec..a68eea47d451 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -516,6 +516,7 @@ struct dw_pcie {
>  	int			max_link_speed;
>  	u8			n_fts[2];
>  	struct dw_edma_chip	edma;
> +	bool			l1ss_support;	/* L1 PM Substates support */
>  	struct clk_bulk_data	app_clks[DW_PCIE_NUM_APP_CLKS];
>  	struct clk_bulk_data	core_clks[DW_PCIE_NUM_CORE_CLKS];
>  	struct reset_control_bulk_data	app_rsts[DW_PCIE_NUM_APP_RSTS];
> @@ -573,6 +574,7 @@ int dw_pcie_prog_ep_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
>  				int type, u64 parent_bus_addr,
>  				u8 bar, size_t size);
>  void dw_pcie_disable_atu(struct dw_pcie *pci, u32 dir, int index);
> +void dw_pcie_hide_unsupported_l1ss(struct dw_pcie *pci);
>  void dw_pcie_setup(struct dw_pcie *pci);
>  void dw_pcie_iatu_detect(struct dw_pcie *pci);
>  int dw_pcie_edma_detect(struct dw_pcie *pci);
> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
> index 805edbbfe7eb..61c2f4e2f74d 100644
> --- a/drivers/pci/controller/dwc/pcie-qcom.c
> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> @@ -1067,6 +1067,8 @@ static int qcom_pcie_init_2_7_0(struct qcom_pcie *pcie)
>  	val &= ~REQ_NOT_ENTR_L1;
>  	writel(val, pcie->parf + PARF_PM_CTRL);
>
> +	pci->l1ss_support = true;
> +
>  	val = readl(pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
>  	val |= EN;
>  	writel(val, pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
> diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
> index 10e74458e667..3934757baa30 100644
> --- a/drivers/pci/controller/dwc/pcie-tegra194.c
> +++ b/drivers/pci/controller/dwc/pcie-tegra194.c
> @@ -703,6 +703,9 @@ static void init_host_aspm(struct tegra_pcie_dw *pcie)
>  	val |= (pcie->aspm_pwr_on_t << 19);
>  	dw_pcie_writel_dbi(pci, pcie->cfg_link_cap_l1sub, val);
>
> +	if (pcie->supports_clkreq)
> +		pci->l1ss_support = true;
> +
>  	/* Program L0s and L1 entrance latencies */
>  	val = dw_pcie_readl_dbi(pci, PCIE_PORT_AFR);
>  	val &= ~PORT_AFR_L0S_ENTRANCE_LAT_MASK;
> --
> 2.43.0
>


From cassel at kernel.org  Tue Nov 18 14:45:46 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Tue, 18 Nov 2025 23:45:46 +0100
Subject: [PATCH v2 1/4] PCI: dwc: Advertise L1 PM Substates only if
 driver requests it
In-Reply-To: <aRzxNMJ+byxZiF3i@lizhi-Precision-Tower-5810>
References: <20251118214312.2598220-1-helgaas@kernel.org>
 <20251118214312.2598220-2-helgaas@kernel.org>
 <aRzxNMJ+byxZiF3i@lizhi-Precision-Tower-5810>
Message-ID: <aRz3Gnw-0IRtUj9f@ryzen>

Hello Frank,

On Tue, Nov 18, 2025 at 05:20:36PM -0500, Frank Li wrote:
> >
> > +	dw_pcie_hide_unsupported_l1ss(pci);
> > +
> 
> Need call dw_pcie_dbi_ro_wr_en(pci) to access PCI_L1SS_CAP.

I disagree.

At least when checking two different versions of the databook
(one very old and one more recent), the register fields that we
are touching are all marked as:

Dbi: R/W (sticky)


There are some other register fields in PCI_L1SS_CAP, e.g.
NEXT_OFFSET, CAP_VERSION, and EXTENDED_CAP_ID that are marked as:

Dbi: if (DBI_RO_WR_EN == 1) then R/W(sticky) else R(sticky)
Note: This register field is sticky.


But since we are not touching any of those register fields,
the current code should be good as is.


Perhaps your version of the databook says differently than the
two versions I have, but considering that they seem to have
intentionally made these R/W without the need for DBI_RO_WR_EN,
I don't see a reason why they would want to change it even in
the absolute newest IP version.


Kind regards,
Niklas


From kevin.tian at intel.com  Tue Nov 18 15:58:39 2025
From: kevin.tian at intel.com (Tian, Kevin)
Date: Tue, 18 Nov 2025 23:58:39 +0000
Subject: [PATCH v2 2/3] iommu/amd: Don't call report_iommu_fault()
In-Reply-To: <20251118185831.GQ10864@nvidia.com>
References: <0-v2-25fc75484cab+ab-iommu_set_fault_jgg@nvidia.com>
 <2-v2-25fc75484cab+ab-iommu_set_fault_jgg@nvidia.com>
 <BN9PR11MB5276EFE7D236FF918A79263C8CC9A@BN9PR11MB5276.namprd11.prod.outlook.com>
 <20251118185831.GQ10864@nvidia.com>
Message-ID: <BN9PR11MB5276858062B57F944A7EBE778CD6A@BN9PR11MB5276.namprd11.prod.outlook.com>

> From: Jason Gunthorpe <jgg at nvidia.com>
> Sent: Wednesday, November 19, 2025 2:59 AM
> 
> On Mon, Nov 17, 2025 at 06:38:51AM +0000, Tian, Kevin wrote:
> > > From: Jason Gunthorpe <jgg at nvidia.com>
> > > Sent: Friday, November 7, 2025 4:35 AM
> > >
> > > This old style API is only used by drivers/gpu/drm/msm,
> > > drivers/remoteproc/omap_remoteproc.c, and
> > > drivers/remoteproc/qcom_q6v5_adsp.c none are used on x86 HW.
> > >
> > > Remove the dead code to discourage new users.
> > >
> > > Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> > > ---
> > >  drivers/iommu/amd/iommu.c | 7 -------
> > >  1 file changed, 7 deletions(-)
> > >
> > > diff --git a/drivers/iommu/amd/iommu.c
> b/drivers/iommu/amd/iommu.c
> > > index 2e1865daa1cee8..d4d9a5dbfa6333 100644
> > > --- a/drivers/iommu/amd/iommu.c
> > > +++ b/drivers/iommu/amd/iommu.c
> > > @@ -854,13 +854,6 @@ static void
> amd_iommu_report_page_fault(struct
> > > amd_iommu *iommu,
> > >  						   PCI_FUNC(devid),
> > > domain_id);
> > >  				goto out;
> > >  			}
> > > -
> > > -			if (!report_iommu_fault(&dev_data->domain-
> > > >domain,
> > > -						&pdev->dev, address,
> > > -						IS_WRITE_REQUEST(flags) ?
> > > -
> > > 	IOMMU_FAULT_WRITE :
> > > -
> > > 	IOMMU_FAULT_READ))
> > > -				goto out;
> > >  		}
> > >
> > >  		if (__ratelimit(&dev_data->rs)) {
> >
> > Remove amd_iommu_report_page_fault() too?
> 
> I don't understand this remark?
> 
> amd_iommu_report_page_fault() generates the dmesg logging on iommu
> faults?
> 

sorry I meant generating the dmesg logging same as other error
types in iommu_print_event(). No need for a separate function.


From naoki at radxa.com  Tue Nov 18 16:12:37 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Wed, 19 Nov 2025 09:12:37 +0900
Subject: [PATCH v2 4/4] arm64: dts: rockchip: Make eeprom read-only for
 Radxa ROCK 3C/5A/5C
In-Reply-To: <20251113140020.919159-1-amadeus@jmu.edu.cn>
References: <20251112035133.28753-5-naoki@radxa.com>
 <20251113140020.919159-1-amadeus@jmu.edu.cn>
Message-ID: <77B4456916875131+5e15cfc7-61ef-4277-885e-f28f3f33380c@radxa.com>

Hi Chukun,

On 11/13/25 23:00, Chukun Pan wrote:
> Hi,
> 
>> Make the BL24C16 EEPROM chips found on Radxa ROCK 3C, 5A and 5C SBCs
>> read-only, [1] [2] [3] because they contain factory-programmed data
>> that isn't supposed to be modified by the end users. [4]
> 
> Is this true? I confirmed that the EEPROM was empty when I submitted
> the ROCK 3C support. Based on the Radxa boards I purchased, it seems
> that only the "Network Computer" series SBC (E20C, E24C, E52C, E54C)
> have production information in their EEPROM.

I have confirmed with the Radxa internal team, and it is clear that for 
"all" products, the EEPROM (regardless of whether data has been written 
or not) is designated as: "The EEPROM is for factory data; users can 
read it, but they are not expected to write to it." This confirms that 
defining a read-only property is appropriate.

I will be submitting a series of patches to add eeprom nodes for several 
Radxa boards, and all of them will include the read-only property.

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> Thanks,
> Chukun
> 



From Frank.li at nxp.com  Tue Nov 18 16:45:21 2025
From: Frank.li at nxp.com (Frank Li)
Date: Tue, 18 Nov 2025 19:45:21 -0500
Subject: [PATCH v2 1/4] PCI: dwc: Advertise L1 PM Substates only if
 driver requests it
In-Reply-To: <aRz3Gnw-0IRtUj9f@ryzen>
References: <20251118214312.2598220-1-helgaas@kernel.org>
 <20251118214312.2598220-2-helgaas@kernel.org>
 <aRzxNMJ+byxZiF3i@lizhi-Precision-Tower-5810>
 <aRz3Gnw-0IRtUj9f@ryzen>
Message-ID: <aR0TIeJ6CWeB4YmT@lizhi-Precision-Tower-5810>

On Tue, Nov 18, 2025 at 11:45:46PM +0100, Niklas Cassel wrote:
> Hello Frank,
>
> On Tue, Nov 18, 2025 at 05:20:36PM -0500, Frank Li wrote:
> > >
> > > +	dw_pcie_hide_unsupported_l1ss(pci);
> > > +
> >
> > Need call dw_pcie_dbi_ro_wr_en(pci) to access PCI_L1SS_CAP.
>
> I disagree.
>
> At least when checking two different versions of the databook
> (one very old and one more recent), the register fields that we
> are touching are all marked as:
>
> Dbi: R/W (sticky)
>

Yes, you are right. Sorry for noise.

Frank

>
> There are some other register fields in PCI_L1SS_CAP, e.g.
> NEXT_OFFSET, CAP_VERSION, and EXTENDED_CAP_ID that are marked as:
>
> Dbi: if (DBI_RO_WR_EN == 1) then R/W(sticky) else R(sticky)
> Note: This register field is sticky.
>
>
> But since we are not touching any of those register fields,
> the current code should be good as is.
>
>
> Perhaps your version of the databook says differently than the
> two versions I have, but considering that they seem to have
> intentionally made these R/W without the need for DBI_RO_WR_EN,
> I don't see a reason why they would want to change it even in
> the absolute newest IP version.
>
>
> Kind regards,
> Niklas


From laurent.pinchart at ideasonboard.com  Tue Nov 18 20:15:32 2025
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Wed, 19 Nov 2025 13:15:32 +0900
Subject: [PATCH v4 02/10] drm: Add new general DRM property "color format"
In-Reply-To: <20251117-color-format-v4-2-0ded72bd1b00@collabora.com>
References: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
 <20251117-color-format-v4-2-0ded72bd1b00@collabora.com>
Message-ID: <20251119041532.GB10711@pendragon.ideasonboard.com>

On Mon, Nov 17, 2025 at 08:11:46PM +0100, Nicolas Frattaroli wrote:
> From: Andri Yngvason <andri at yngvason.is>
> 
> Adds a new general DRM property named "color format" which can be used by

s/Adds/Add/

> userspace to force the display driver output a particular color format.
> 
> Possible options are:
>     - auto (setup by default, driver internally picks the color format)
>     - rgb
>     - ycbcr444
>     - ycbcr422
>     - ycbcr420
> 
> Drivers should advertise from this list the formats which they support.
> Together with this list and EDID data from the sink we should be able
> to relay a list of usable color formats to users to pick from.
> 
> Signed-off-by: Werner Sembach <wse at tuxedocomputers.com>
> Signed-off-by: Andri Yngvason <andri at yngvason.is>
> Signed-off-by: Marius Vlad <marius.vlad at collabora.com>
> ---
>  drivers/gpu/drm/drm_atomic_helper.c |   5 +
>  drivers/gpu/drm/drm_atomic_uapi.c   |   4 +
>  drivers/gpu/drm/drm_connector.c     | 180 ++++++++++++++++++++++++++++++++++++
>  include/drm/drm_connector.h         |  54 ++++++++++-
>  4 files changed, 238 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index e641fcf8c568..25f354b2cc0d 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -736,6 +736,11 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
>  			if (old_connector_state->max_requested_bpc !=
>  			    new_connector_state->max_requested_bpc)
>  				new_crtc_state->connectors_changed = true;
> +
> +			if (old_connector_state->color_format !=
> +			    new_connector_state->color_format)
> +				new_crtc_state->connectors_changed = true;
> +
>  		}
>  
>  		if (funcs->atomic_check)
> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
> index b2cb5ae5a139..2f093b0d1628 100644
> --- a/drivers/gpu/drm/drm_atomic_uapi.c
> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
> @@ -784,6 +784,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
>  		state->privacy_screen_sw_state = val;
>  	} else if (property == connector->broadcast_rgb_property) {
>  		state->hdmi.broadcast_rgb = val;
> +	} else if (property == connector->color_format_property) {
> +		state->color_format = drm_color_format_enum_to_color_format(val);
>  	} else if (connector->funcs->atomic_set_property) {
>  		return connector->funcs->atomic_set_property(connector,
>  				state, property, val);
> @@ -869,6 +871,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
>  		*val = state->privacy_screen_sw_state;
>  	} else if (property == connector->broadcast_rgb_property) {
>  		*val = state->hdmi.broadcast_rgb;
> +	} else if (property == connector->color_format_property) {
> +		*val = drm_color_format_to_color_format_enum(state->color_format);
>  	} else if (connector->funcs->atomic_get_property) {
>  		return connector->funcs->atomic_get_property(connector,
>  				state, property, val);
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index 272d6254ea47..0ad7be0a2d09 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -1348,6 +1348,55 @@ static const char * const colorspace_names[] = {
>  	[DRM_MODE_COLORIMETRY_BT601_YCC] = "BT601_YCC",
>  };
>  
> +u32
> +drm_color_format_to_color_format_enum(enum drm_color_format fmt)
> +{
> +	switch (fmt) {
> +	default:
> +	case DRM_COLOR_FORMAT_AUTO:
> +		return DRM_MODE_COLOR_FORMAT_AUTO;
> +	case DRM_COLOR_FORMAT_RGB444:
> +		return DRM_MODE_COLOR_FORMAT_RGB444;
> +	case DRM_COLOR_FORMAT_YCBCR444:
> +		return DRM_MODE_COLOR_FORMAT_YCBCR444;
> +	case DRM_COLOR_FORMAT_YCBCR422:
> +		return DRM_MODE_COLOR_FORMAT_YCBCR422;
> +	case DRM_COLOR_FORMAT_YCBCR420:
> +		return DRM_MODE_COLOR_FORMAT_YCBCR420;
> +	}
> +}
> +
> +u32
> +drm_color_format_enum_to_color_format(enum drm_color_format_enum fmt_enum)
> +{
> +	switch (fmt_enum) {
> +	default:
> +	case DRM_MODE_COLOR_FORMAT_RGB444:
> +		return DRM_COLOR_FORMAT_RGB444;
> +	case DRM_MODE_COLOR_FORMAT_AUTO:
> +		return DRM_COLOR_FORMAT_AUTO;
> +	case DRM_MODE_COLOR_FORMAT_YCBCR444:
> +		return DRM_COLOR_FORMAT_YCBCR444;
> +	case DRM_MODE_COLOR_FORMAT_YCBCR422:
> +		return DRM_COLOR_FORMAT_YCBCR422;
> +	case DRM_MODE_COLOR_FORMAT_YCBCR420:
> +		return DRM_COLOR_FORMAT_YCBCR420;
> +	}

It seems this could be simplified to

	return BIT(fmt_enum);

The above function could also be simplified by using ffs().

> +}
> +
> +/**
> + * drm_get_color_format_name - return a string for color format
> + * @colorspace: color format to compute name of

s/colorspace/color_fmt/

Please make sure to compile the documentation and check for warnings in
the next iteration.

> + *
> + */
> +const char *drm_get_color_format_name(enum drm_color_format color_fmt)
> +{
> +	u32 conv_color_fmt = drm_color_format_to_color_format_enum(color_fmt);
> +
> +	return drm_hdmi_connector_get_output_format_name(conv_color_fmt);
> +}
> +EXPORT_SYMBOL(drm_get_color_format_name);

Could we flip that and make drm_hdmi_connector_get_output_format_name()
a wrapper around drm_get_color_format_name() ?

> +
>  /**
>   * drm_get_colorspace_name - return a string for color encoding
>   * @colorspace: color space to compute name of
> @@ -1377,6 +1426,22 @@ static const u32 hdmi_colorspaces =
>  	BIT(DRM_MODE_COLORIMETRY_DCI_P3_RGB_D65) |
>  	BIT(DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER);
>  
> +/* already bit-shifted */
> +static const u32 hdmi_colorformats =
> +	DRM_COLOR_FORMAT_AUTO |
> +	DRM_COLOR_FORMAT_RGB444 |
> +	DRM_COLOR_FORMAT_YCBCR444 |
> +	DRM_COLOR_FORMAT_YCBCR422 |
> +	DRM_COLOR_FORMAT_YCBCR420;
> +
> +/* already bit-shifted */
> +static const u32 dp_colorformats =
> +	DRM_COLOR_FORMAT_AUTO |
> +	DRM_COLOR_FORMAT_RGB444 |
> +	DRM_COLOR_FORMAT_YCBCR444 |
> +	DRM_COLOR_FORMAT_YCBCR422 |
> +	DRM_COLOR_FORMAT_YCBCR420;
> +
>  /*
>   * As per DP 1.4a spec, 2.2.5.7.5 VSC SDP Payload for Pixel Encoding/Colorimetry
>   * Format Table 2-120
> @@ -2628,6 +2693,101 @@ int drm_mode_create_hdmi_colorspace_property(struct drm_connector *connector,
>  }
>  EXPORT_SYMBOL(drm_mode_create_hdmi_colorspace_property);
>  
> +static int drm_mode_create_color_format_property(struct drm_connector *connector,
> +						 u32 supported_color_formats)
> +{
> +	struct drm_device *dev = connector->dev;
> +	struct drm_prop_enum_list enum_list[DRM_MODE_COLOR_FORMAT_COUNT];
> +	int i, len;

Neither can be negative, you can use unsigned int.

> +
> +	if (connector->color_format_property)
> +		return 0;
> +
> +	if (!supported_color_formats) {
> +		drm_err(dev, "No supported color formats provded on [CONNECTOR:%d:%s]\n",

s/provded/provided/

> +			    connector->base.id, connector->name);

Incorrect alignment.

> +		return -EINVAL;
> +	}
> +
> +	if ((supported_color_formats & -BIT(DRM_MODE_COLOR_FORMAT_COUNT)) != 0) {

GENMASK(DRM_MODE_COLOR_FORMAT_COUNT - 1, 0)

would be clearer than

-BIT(DRM_MODE_COLOR_FORMAT_COUNT)

> +		drm_err(dev, "Unknown colorspace provded on [CONNECTOR:%d:%s]\n",

s/colorspace/color format/
s/provded/provided/

> +			    connector->base.id, connector->name);
> +		return -EINVAL;
> +	}
> +
> +	len = 0;
> +	for (i = 0; i < DRM_MODE_COLOR_FORMAT_COUNT; i++) {
> +		if (!(supported_color_formats & BIT(i)))
> +			continue;
> +
> +		enum_list[len].type = i;
> +		if (i != DRM_MODE_COLOR_FORMAT_AUTO)
> +			enum_list[len].name = output_format_str[i];
> +		else
> +			enum_list[len].name = "AUTO";
> +		len++;
> +	}
> +
> +	connector->color_format_property =
> +		drm_property_create_enum(dev, DRM_MODE_PROP_ENUM, "color format",
> +					enum_list, len);
> +
> +	if (!connector->color_format_property)
> +		return -ENOMEM;
> +
> +	return 0;
> +}
> +
> +/**
> + * drm_mode_create_hdmi_color_format_property - create hdmi color format property
> + * @connector: connector to create the color format property on.
> + * @supported_color_formats: bitmap of supported color formats

You don't document that supported_color_formats can be 0. I think I'd
actually drop that possibility, it's not used by drivers in this series,
and it seems to be error-prone. If a later version of HDMI or DP adds
support for more color formats, those would get automatically advertised
while not supported by drivers.

> + *
> + * Called by a driver the first time it's needed, must be attached to desired
> + * HDMI connectors.
> + *
> + * Returns:
> + * Zero on success, negative errno on failure.
> + */
> +int drm_mode_create_hdmi_color_format_property(struct drm_connector *connector,
> +					       u32 supported_color_formats)
> +{
> +	u32 color_formats;
> +
> +	if (supported_color_formats)
> +		color_formats = supported_color_formats & hdmi_colorformats;
> +	else
> +		color_formats = hdmi_colorformats;
> +
> +	return drm_mode_create_color_format_property(connector, color_formats);
> +}
> +EXPORT_SYMBOL(drm_mode_create_hdmi_color_format_property);

I think we could simplify the API here by picking the defaults based on
the connector type:

int drm_mode_create_color_format_property(struct drm_connector *connector,
					  u32 supported_color_formats)
{
	struct drm_device *dev = connector->dev;
	struct drm_prop_enum_list enum_list[DRM_MODE_COLOR_FORMAT_COUNT];
	unsigned int i, len;

	if (connector->color_format_property)
		return 0;

	switch (connector->type) {
	case DRM_MODE_CONNECTOR_HDMIA:
	case DRM_MODE_CONNECTOR_HDMIB:
		supported_color_formats &= hdmi_colorformats;
		break;

	case DRM_MODE_CONNECTOR_DisplayPort:
	case DRM_MODE_CONNECTOR_eDP:
		supported_color_formats &= dp_colorformats;
		break;

	default:
		drm_err(dev, ...);
		return -EINVAL;
	}

	if (!supported_color_formats) {
		drm_err(dev, "No supported color formats provided on [CONNECTOR:%d:%s]\n",
			connector->base.id, connector->name);
		return -EINVAL;
	}

	...
}

> +
> +/**
> + * drm_mode_create_dp_color_format_property - create dp color format property
> + * @connector: connector to create the Colorspace property on.
> + * @supported_color_formats: bitmap of supported color formats
> + *
> + * Called by a driver the first time it's needed, must be attached to desired
> + * DP connectors.
> + *
> + * Returns:
> + * Zero on success, negative errno on failure.
> + */
> +int drm_mode_create_dp_color_format_property(struct drm_connector *connector,
> +					     u32 supported_color_formats)
> +{
> +	u32 color_formats;
> +
> +	if (supported_color_formats)
> +		color_formats = supported_color_formats & dp_colorformats;
> +	else
> +		color_formats = dp_colorformats;
> +
> +	return drm_mode_create_color_format_property(connector, color_formats);
> +}
> +EXPORT_SYMBOL(drm_mode_create_dp_color_format_property);
> +
>  /**
>   * drm_mode_create_dp_colorspace_property - create dp colorspace property
>   * @connector: connector to create the Colorspace property on.
> @@ -2845,6 +3005,26 @@ int drm_connector_attach_max_bpc_property(struct drm_connector *connector,
>  }
>  EXPORT_SYMBOL(drm_connector_attach_max_bpc_property);
>  
> +/**
> + * drm_connector_attach_color_format_property - attach "force color format" property
> + * @connector: connector to attach force color format property on.
> + *
> + * This is used to add support for selecting a color format on a connector.
> + *
> + * Returns:
> + * Zero on success, negative errno on failure.
> + */
> +int drm_connector_attach_color_format_property(struct drm_connector *connector)
> +{
> +	struct drm_property *prop = connector->color_format_property;
> +
> +	drm_object_attach_property(&connector->base, prop, DRM_COLOR_FORMAT_AUTO);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(drm_connector_attach_color_format_property);
> +
> +
>  /**
>   * drm_connector_attach_hdr_output_metadata_property - attach "HDR_OUTPUT_METADA" property
>   * @connector: connector to attach the property on.
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index 8f34f4b8183d..a071079fd3ad 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -556,6 +556,26 @@ enum drm_colorspace {
>  	DRM_MODE_COLORIMETRY_COUNT
>  };
>  
> +enum drm_color_format_enum {

Please document this.

> +	DRM_MODE_COLOR_FORMAT_RGB444		= HDMI_COLORSPACE_RGB,
> +	DRM_MODE_COLOR_FORMAT_YCBCR422		= HDMI_COLORSPACE_YUV422,
> +	DRM_MODE_COLOR_FORMAT_YCBCR444		= HDMI_COLORSPACE_YUV444,
> +	DRM_MODE_COLOR_FORMAT_YCBCR420		= HDMI_COLORSPACE_YUV420,
> +	/* auto case, driver will set the color_format */
> +	DRM_MODE_COLOR_FORMAT_AUTO,
> +	DRM_MODE_COLOR_FORMAT_COUNT
> +};
> +
> +enum drm_color_format {
> +	DRM_COLOR_FORMAT_NONE			= 0,
> +	DRM_COLOR_FORMAT_RGB444			= (1 << 0),
> +	DRM_COLOR_FORMAT_YCBCR422		= (1 << 1),
> +	DRM_COLOR_FORMAT_YCBCR444		= (1 << 2),
> +	DRM_COLOR_FORMAT_YCBCR420		= (1 << 3),
> +	/* auto case, driver will set the color_format */
> +	DRM_COLOR_FORMAT_AUTO			= (1 << 4),
> +};

It would be nicer to have a single enum, and use
BIT(DRM_MODE_COLOR_FORMAT_*) wherever a mask is used.

> +
>  /**
>   * enum drm_bus_flags - bus_flags info for &drm_display_info
>   *
> @@ -699,11 +719,6 @@ struct drm_display_info {
>  	 */
>  	enum subpixel_order subpixel_order;
>  
> -#define DRM_COLOR_FORMAT_RGB444		(1<<0)
> -#define DRM_COLOR_FORMAT_YCBCR444	(1<<1)
> -#define DRM_COLOR_FORMAT_YCBCR422	(1<<2)
> -#define DRM_COLOR_FORMAT_YCBCR420	(1<<3)
> -
>  	/**
>  	 * @panel_orientation: Read only connector property for built-in panels,
>  	 * indicating the orientation of the panel vs the device's casing.
> @@ -1107,6 +1122,13 @@ struct drm_connector_state {
>  	 */
>  	enum drm_colorspace colorspace;
>  
> +	/**
> +	 * @color_format: State variable for Connector property to request
> +	 * color format change on Sink. This is most commonly used to switch
> +	 * between RGB to YUV and vice-versa.
> +	 */
> +	enum drm_color_format color_format;
> +
>  	/**
>  	 * @writeback_job: Writeback job for writeback connectors
>  	 *
> @@ -2060,6 +2082,12 @@ struct drm_connector {
>  	 */
>  	struct drm_property *colorspace_property;
>  
> +	/**
> +	 * @color_format_property: Connector property to set the suitable
> +	 * color format supported by the sink.
> +	 */
> +	struct drm_property *color_format_property;
> +
>  	/**
>  	 * @path_blob_ptr:
>  	 *
> @@ -2461,6 +2489,12 @@ int drm_mode_create_dp_colorspace_property(struct drm_connector *connector,
>  int drm_mode_create_content_type_property(struct drm_device *dev);
>  int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
>  
> +int drm_mode_create_hdmi_color_format_property(struct drm_connector *connector,
> +					       u32 supported_color_formats);
> +
> +int drm_mode_create_dp_color_format_property(struct drm_connector *connector,
> +					     u32 supported_color_formats);
> +
>  int drm_connector_set_path_property(struct drm_connector *connector,
>  				    const char *path);
>  int drm_connector_set_tile_property(struct drm_connector *connector);
> @@ -2542,6 +2576,16 @@ bool drm_connector_has_possible_encoder(struct drm_connector *connector,
>  					struct drm_encoder *encoder);
>  const char *drm_get_colorspace_name(enum drm_colorspace colorspace);
>  
> +int drm_connector_attach_color_format_property(struct drm_connector *connector);
> +
> +const char *drm_get_color_format_name(enum drm_color_format color_fmt);
> +
> +u32
> +drm_color_format_to_color_format_enum(enum drm_color_format fmt);

This holds on a single line.

> +
> +u32
> +drm_color_format_enum_to_color_format(enum drm_color_format_enum fmt_enum);

I'd avoid the line break here too.

> +
>  /**
>   * drm_for_each_connector_iter - connector_list iterator macro
>   * @connector: &struct drm_connector pointer used as cursor

-- 
Regards,

Laurent Pinchart


From laurent.pinchart at ideasonboard.com  Tue Nov 18 20:16:48 2025
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Wed, 19 Nov 2025 13:16:48 +0900
Subject: [PATCH v4 03/10] drm: Add enum conversion from/to
 HDMI_COLORSPACE to DRM_COLOR_FORMAT
In-Reply-To: <20251117-color-format-v4-3-0ded72bd1b00@collabora.com>
References: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
 <20251117-color-format-v4-3-0ded72bd1b00@collabora.com>
Message-ID: <20251119041648.GD10711@pendragon.ideasonboard.com>

On Mon, Nov 17, 2025 at 08:11:47PM +0100, Nicolas Frattaroli wrote:
> From: Marius Vlad <marius.vlad at collabora.com>
> 
> This would please the compiler to have a enum transformation from one to
> another even though the values are the same. It should also make things

The hdmi_colorspace enumerators are defined as (with comments added to
make the values explicit)

enum hdmi_colorspace {
	HDMI_COLORSPACE_RGB,			/* 0 */
	HDMI_COLORSPACE_YUV422,			/* 1 */
	HDMI_COLORSPACE_YUV444,			/* 2 */
	HDMI_COLORSPACE_YUV420,			/* 3 */
	HDMI_COLORSPACE_RESERVED4,		/* 4 */
	HDMI_COLORSPACE_RESERVED5,		/* 5 */
	HDMI_COLORSPACE_RESERVED6,		/* 6 */
	HDMI_COLORSPACE_IDO_DEFINED,		/* 7 */
};

and the DRM color formats as (after patch 02/10)

enum drm_color_format {
	DRM_COLOR_FORMAT_NONE			= 0,		/* 0 */
	DRM_COLOR_FORMAT_RGB444			= (1 << 0),	/* 1 */
	DRM_COLOR_FORMAT_YCBCR422		= (1 << 1),	/* 2 */
	DRM_COLOR_FORMAT_YCBCR444		= (1 << 2),	/* 4 */
	DRM_COLOR_FORMAT_YCBCR420		= (1 << 3),	/* 8 */
	/* auto case, driver will set the color_format */
	DRM_COLOR_FORMAT_AUTO			= (1 << 4),	/* 16 */
};

Contrary to what is stated in the commit message, the values are not the
same. Maybe you confused DRM_COLOR_FORMAT_* with DRM_MODE_COLOR_FORMAT_*
?

> obvious that we use different enums.
> 
> Signed-off-by: Marius Vlad <marius.vlad at collabora.com>
> ---
>  drivers/gpu/drm/drm_connector.c | 18 ++++++++++++++++++
>  include/drm/drm_connector.h     |  3 +++
>  2 files changed, 21 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index 0ad7be0a2d09..61c077b67ac3 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -1384,6 +1384,24 @@ drm_color_format_enum_to_color_format(enum drm_color_format_enum fmt_enum)
>  	}
>  }
>  
> +enum hdmi_colorspace
> +color_format_to_hdmi_colorspace(enum drm_color_format fmt)
> +{
> +	switch (fmt) {
> +	default:
> +	case DRM_COLOR_FORMAT_AUTO:
> +	case DRM_COLOR_FORMAT_RGB444:
> +		return HDMI_COLORSPACE_RGB;
> +	case DRM_COLOR_FORMAT_YCBCR444:
> +		return HDMI_COLORSPACE_YUV444;
> +	case DRM_COLOR_FORMAT_YCBCR422:
> +		return HDMI_COLORSPACE_YUV422;
> +	case DRM_COLOR_FORMAT_YCBCR420:
> +		return HDMI_COLORSPACE_YUV420;
> +	}
> +}
> +EXPORT_SYMBOL(color_format_to_hdmi_colorspace);
> +
>  /**
>   * drm_get_color_format_name - return a string for color format
>   * @colorspace: color format to compute name of
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index a071079fd3ad..e044976c8d76 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -2586,6 +2586,9 @@ drm_color_format_to_color_format_enum(enum drm_color_format fmt);
>  u32
>  drm_color_format_enum_to_color_format(enum drm_color_format_enum fmt_enum);
>  
> +enum hdmi_colorspace
> +color_format_to_hdmi_colorspace(enum drm_color_format fmt);
> +
>  /**
>   * drm_for_each_connector_iter - connector_list iterator macro
>   * @connector: &struct drm_connector pointer used as cursor

-- 
Regards,

Laurent Pinchart


From laurent.pinchart at ideasonboard.com  Tue Nov 18 20:17:26 2025
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Wed, 19 Nov 2025 13:17:26 +0900
Subject: [PATCH v4 05/10] drm/bridge: dw-hdmi-qp: Set bridge
 supported_formats
In-Reply-To: <20251117-color-format-v4-5-0ded72bd1b00@collabora.com>
References: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
 <20251117-color-format-v4-5-0ded72bd1b00@collabora.com>
Message-ID: <20251119041726.GE10711@pendragon.ideasonboard.com>

On Mon, Nov 17, 2025 at 08:11:49PM +0100, Nicolas Frattaroli wrote:
> The drm_bridge "supported_formats" member stores a bitmask of supported
> HDMI output formats if the bridge is in fact an HDMI bridge.

It would be nice to convert the supported_formats field to a bitmask of
DRM_MODE_COLOR_FORMAT_* values.

> 
> However, until now, the synopsys dw-hdmi-qp driver did not set this
> member in the bridge it creates.
> 
> Set it based on the platform data's supported_formats member, and
> default to BIT(HDMI_COLORSPACE_RGB) if it's absent, which preserves the
> previous behaviour.
> 
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
> index fe4c026280f0..cf888236bd65 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
> @@ -1269,6 +1269,11 @@ struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev,
>  		dev_warn(dev, "Set ref_clk_rate to vendor default\n");
>  	}
>  
> +	if (plat_data->supported_formats)
> +		hdmi->bridge.supported_formats = plat_data->supported_formats;
> +	else
> +		hdmi->bridge.supported_formats = BIT(HDMI_COLORSPACE_RGB);
> +
>  	dw_hdmi_qp_init_hw(hdmi);
>  
>  	ret = devm_request_threaded_irq(dev, plat_data->main_irq,

-- 
Regards,

Laurent Pinchart


From laurent.pinchart at ideasonboard.com  Tue Nov 18 20:17:47 2025
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Wed, 19 Nov 2025 13:17:47 +0900
Subject: [PATCH v4 06/10] drm/rockchip: dw_hdmi_qp: Set supported_formats
 platdata
In-Reply-To: <20251117-color-format-v4-6-0ded72bd1b00@collabora.com>
References: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
 <20251117-color-format-v4-6-0ded72bd1b00@collabora.com>
Message-ID: <20251119041747.GF10711@pendragon.ideasonboard.com>

On Mon, Nov 17, 2025 at 08:11:50PM +0100, Nicolas Frattaroli wrote:
> With the introduction of the supported_formats member in the
> dw-hdmi-qp platform data struct, drivers that have access to this
> information should now set it.
> 
> Set it in the rockchip dw_hdmi_qp glue driver, where such a bitmask of
> supported color formats already exists. It just needs to be converted to
> the appropriate HDMI_COLORSPACE_ mask.
> 
> This allows this information to be passed down to the dw-hdmi-qp core,
> which sets it in the bridge it creates, and consequently will allow the
> common HDMI bridge code to act on it.
> 
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
> ---
>  drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 24 ++++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
> 
> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
> index c9fe6aa3e3e3..7c294751de19 100644
> --- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
> @@ -468,6 +468,28 @@ static const struct of_device_id dw_hdmi_qp_rockchip_dt_ids[] = {
>  };
>  MODULE_DEVICE_TABLE(of, dw_hdmi_qp_rockchip_dt_ids);
>  
> +static const u32 supported_colorformats = DRM_COLOR_FORMAT_AUTO |
> +					  DRM_COLOR_FORMAT_RGB444 |
> +					  DRM_COLOR_FORMAT_YCBCR444;
> +
> +static unsigned int __pure drm_to_hdmi_fmts(const u32 fmt)
> +{
> +	unsigned int res = 0;
> +
> +	if (fmt & DRM_COLOR_FORMAT_AUTO)
> +		res |= BIT(HDMI_COLORSPACE_RGB);
> +	if (fmt & DRM_COLOR_FORMAT_RGB444)
> +		res |= BIT(HDMI_COLORSPACE_RGB);
> +	if (fmt & DRM_COLOR_FORMAT_YCBCR444)
> +		res |= BIT(HDMI_COLORSPACE_YUV444);
> +	if (fmt & DRM_COLOR_FORMAT_YCBCR422)
> +		res |= BIT(HDMI_COLORSPACE_YUV422);
> +	if (fmt & DRM_COLOR_FORMAT_YCBCR420)
> +		res |= BIT(HDMI_COLORSPACE_YUV420);
> +
> +	return res;
> +}
> +

This would be greatly simplified by turning supported_formats into a
bitmask of DRM_MODE_COLOR_FORMAT_* values, as suggested in 05/10.

>  static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
>  				    void *data)
>  {
> @@ -521,6 +543,8 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
>  	plat_data.phy_data = hdmi;
>  	plat_data.max_bpc = 10;
>  
> +	plat_data.supported_formats = drm_to_hdmi_fmts(supported_colorformats);
> +
>  	encoder = &hdmi->encoder.encoder;
>  	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
>  

-- 
Regards,

Laurent Pinchart


From laurent.pinchart at ideasonboard.com  Tue Nov 18 20:32:46 2025
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Wed, 19 Nov 2025 13:32:46 +0900
Subject: [PATCH v4 04/10] drm/bridge: Act on the DRM color format property
In-Reply-To: <20251117-color-format-v4-4-0ded72bd1b00@collabora.com>
References: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
 <20251117-color-format-v4-4-0ded72bd1b00@collabora.com>
Message-ID: <20251119043246.GY10711@pendragon.ideasonboard.com>

On Mon, Nov 17, 2025 at 08:11:48PM +0100, Nicolas Frattaroli wrote:
> The new DRM color format property allows userspace to request a specific
> color format on a connector. In turn, this fills the connector state's
> color_format member to switch color formats.
> 
> Make drm_bridges consider the color_format set in the connector state
> during the atomic bridge check. Specifically, reject any output bus
> formats that do not correspond to the requested color format.
> 
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
> ---
>  drivers/gpu/drm/drm_bridge.c | 57 ++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 57 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
> index 8f355df883d8..b7df5cbad832 100644
> --- a/drivers/gpu/drm/drm_bridge.c
> +++ b/drivers/gpu/drm/drm_bridge.c
> @@ -1052,6 +1052,59 @@ static int select_bus_fmt_recursive(struct drm_bridge *first_bridge,
>  	return ret;
>  }
>  
> +static bool __pure bus_format_is_color_fmt(u32 bus_fmt, enum drm_color_format fmt)
> +{
> +	if (bus_fmt == MEDIA_BUS_FMT_FIXED)
> +		return true;
> +
> +	switch (fmt) {
> +	case DRM_COLOR_FORMAT_NONE:
> +	case DRM_COLOR_FORMAT_AUTO:
> +		return true;
> +	case DRM_COLOR_FORMAT_RGB444:
> +		switch (bus_fmt) {
> +		case MEDIA_BUS_FMT_RGB888_1X24:
> +		case MEDIA_BUS_FMT_RGB101010_1X30:
> +		case MEDIA_BUS_FMT_RGB121212_1X36:
> +		case MEDIA_BUS_FMT_RGB161616_1X48:
> +			return true;
> +		default:
> +			return false;
> +		}
> +	case DRM_COLOR_FORMAT_YCBCR444:
> +		switch (bus_fmt) {
> +		case MEDIA_BUS_FMT_YUV8_1X24:
> +		case MEDIA_BUS_FMT_YUV10_1X30:
> +		case MEDIA_BUS_FMT_YUV12_1X36:
> +		case MEDIA_BUS_FMT_YUV16_1X48:
> +			return true;
> +		default:
> +			return false;
> +		}
> +	case DRM_COLOR_FORMAT_YCBCR422:
> +		switch (bus_fmt) {
> +		case MEDIA_BUS_FMT_UYVY8_1X16:
> +		case MEDIA_BUS_FMT_UYVY10_1X20:
> +		case MEDIA_BUS_FMT_UYVY12_1X24:
> +			return true;
> +		default:
> +			return false;
> +		}
> +	case DRM_COLOR_FORMAT_YCBCR420:
> +		switch (bus_fmt) {
> +		case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
> +		case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
> +		case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
> +		case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
> +			return true;
> +		default:
> +			return false;
> +		}
> +	}

I'd find this more readable:

	if (fmt == DRM_COLOR_FORMAT_NONE || fmt == DRM_COLOR_FORMAT_AUTO)
		return true;

	switch (bus_fmt) {
	case MEDIA_BUS_FMT_RGB888_1X24:
	case MEDIA_BUS_FMT_RGB101010_1X30:
	case MEDIA_BUS_FMT_RGB121212_1X36:
	case MEDIA_BUS_FMT_RGB161616_1X48:
		return fmt == DRM_COLOR_FORMAT_RGB444:

	case MEDIA_BUS_FMT_YUV8_1X24:
	case MEDIA_BUS_FMT_YUV10_1X30:
	case MEDIA_BUS_FMT_YUV12_1X36:
	case MEDIA_BUS_FMT_YUV16_1X48:
		return fmt == DRM_COLOR_FORMAT_YCBCR444;

	case MEDIA_BUS_FMT_UYVY8_1X16:
	case MEDIA_BUS_FMT_UYVY10_1X20:
	case MEDIA_BUS_FMT_UYVY12_1X24:
		return fmt == DRM_COLOR_FORMAT_YCBCR422;

	case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
	case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
	case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
	case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
		return fmt == DRM_COLOR_FORMAT_YCBCR420;

	default:
		return false;
	}

but it could be a matter for personal preference ?

I'm also a bit concerned about the 

	if (fmt == DRM_COLOR_FORMAT_NONE || fmt == DRM_COLOR_FORMAT_AUTO)

test. What's the difference between NONE and AUTO ? Is it meaningful, or
should the two enumerators be merged into a single one ?

> +
> +	return false;
> +}
> +
>  /*
>   * This function is called by &drm_atomic_bridge_chain_check() just before
>   * calling &drm_bridge_funcs.atomic_check() on all elements of the chain.
> @@ -1137,6 +1190,10 @@ drm_atomic_bridge_chain_select_bus_fmts(struct drm_bridge *bridge,
>  	}
>  
>  	for (i = 0; i < num_out_bus_fmts; i++) {
> +		if (!bus_format_is_color_fmt(out_bus_fmts[i], conn_state->color_format)) {
> +			ret = -ENOTSUPP;
> +			continue;
> +		}
>  		ret = select_bus_fmt_recursive(bridge, last_bridge, crtc_state,
>  					       conn_state, out_bus_fmts[i]);
>  		if (ret != -ENOTSUPP)

-- 
Regards,

Laurent Pinchart


From dsimic at manjaro.org  Tue Nov 18 22:47:20 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Wed, 19 Nov 2025 07:47:20 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v2 1/2] =?utf-8?q?dt-bindings=3A?=
 =?utf-8?q?_arm=3A?==?utf-8?q?_rockchip=3A?= Add Asus Tinker Board 3 and 3S
In-Reply-To: <0c224662-b3c2-4075-8b68-c0ae27421ba8@rootcommit.com>
References: <e4cd11d0-463c-e707-5110-6b92899b1ba3@manjaro.org> <0c224662-b3c2-4075-8b68-c0ae27421ba8@rootcommit.com>
Message-ID: <3c96ee6b-dca7-1a0a-792b-f8c165ec997d@manjaro.org>

Hello Michael,

On Tuesday, November 18, 2025 06:27 CET, Michael Opdenacker <michael.opdenacker at rootcommit.com> wrote:
> On 11/15/25 01:52, Dragan Simic wrote:
> > I'm sorry again for not mentioning it in my earlier responses,
> > but shouldn't this addition be specified like below:
> >
> >       - description: Asus Tinker Board 3/3S
> >         items:
> >           - enum:
> > 	          - asus,rk3566-tinker-board-3
> >             - asus,rk3566-tinker-board-3s
> >           - const: rockchip,rk3566
> >
> > ... because the introduced .dts files define the actual board DTs,
> > by descending from the common .dtsi file, while they're compatible
> > in the sense of the 3S board variant extending the 3 variant.
> 
> Actually, "make dtbs_check" fails if rk3566-tinker-board-3s.dts has:
> compatible = "asus,rk3566-tinker-board-3s", 
> "asus,rk3566-tinker-board-3", "rockchip,rk3566";
> 
> The failure is:
> arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3s.dtb: / 
> (asus,rk3566-tinker-board-3s): compatible: 'oneOf' conditional failed, 
> one must be fixed:
>  ? ? ['asus,rk3566-tinker-board-3s', 'asus,rk3566-tinker-board-3', 
> 'rockchip,rk3566'] is too long
>  ? ? ['asus,rk3566-tinker-board-3s', 'asus,rk3566-tinker-board-3', 
> 'rockchip,rk3566'] is too short

Oh, I missed that completely, thanks for running the checks.

> If I understand correctly, to keep the?rk3566-tinker-board-3s.dts file 
> as it is, you need Asus Tinker Board 3 and 3S to have two different 
> descriptions as in V2:
> 
> - description: Asus Tinker Board 3 items: - const: 
> asus,rk3566-tinker-board-3 - const: rockchip,rk3566 - description: Asus 
> Tinker Board 3S items: - const: asus,rk3566-tinker-board-3s - const: 
> asus,rk3566-tinker-board-3 - const: rockchip,rk3566
> 
> The other solution is to remove the "asus,rk3566-tinker-board-3" 
> compatible from?rk3566-tinker-board-3s.dts, which is not a big deal in 
> my opinion. In addition, if some code turns out to work only on 3 but 
> not on 3S, though that's not expected if 3S is indeed a superset of 3, 
> we won't be stuck.
> 
> I can submit a V3 along these lines.

This should let us keep the "asus,rk3566-tinker-board-3" compatible
in the new rk3566-tinker-board-3s.dts board dts while satisfying the
validation properly:

  - description: Asus Tinker Board 3/3S
    items:
    - enum:
        - asus,rk3566-tinker-board-3s
    - const: asus,rk3566-tinker-board-3
    - const: rockchip,rk3566

I'm quite busy at the moment, hence my delayed response, and I also
apologize for not running the checks on the above-proposed solution,
but I think it should work as expected.



From dsimic at manjaro.org  Tue Nov 18 23:00:50 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Wed, 19 Nov 2025 08:00:50 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v3 1/2] =?utf-8?q?dt-bindings=3A?=
 =?utf-8?q?_arm=3A?==?utf-8?q?_rockchip=3A?= Add Asus Tinker Board 3/3S
In-Reply-To: <20251118-tinker3-v3-1-2903693f2ebb@rootcommit.com>
References: <20251118-tinker3-v3-0-2903693f2ebb@rootcommit.com> <20251118-tinker3-v3-1-2903693f2ebb@rootcommit.com>
Message-ID: <155d3d05-49f8-a000-6939-1411917745bb@manjaro.org>

Hello Michael,

On Tuesday, November 18, 2025 16:56 CET, Michael Opdenacker <michael.opdenacker at rootcommit.com> wrote:
> Document the compatible strings for Asus Tinker Board 3 [1] and 3S [2],
> which are SBCs based on the Rockchip 3566 SoC.
> 
> The "3S" version ("S" for "storage") just adds a 16 GB eMMC
> and a "mask ROM" DIP switch to the "3" version.
> 
> [1] https://tinker-board.asus.com/series/tinker-board-3.html
> [2] https://tinker-board.asus.com/series/tinker-board-3s.html
> 
> Signed-off-by: Michael Opdenacker <michael.opdenacker at rootcommit.com>
> 
> ---
> 
> Changes in V3:
> 
> - Remove this Acked-by as the binding code changed substantially:
>   Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> ---
>  Documentation/devicetree/bindings/arm/rockchip.yaml | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
> index 6aceaa8acbb2..800c11323a4f 100644
> --- a/Documentation/devicetree/bindings/arm/rockchip.yaml
> +++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
> @@ -86,6 +86,13 @@ properties:
>            - const: asus,rk3288-tinker-s
>            - const: rockchip,rk3288
>  
> +      - description: Asus Tinker Board 3/3S
> +        items:
> +          - enum:
> +              - asus,rk3566-tinker-board-3
> +              - asus,rk3566-tinker-board-3s
> +          - const: rockchip,rk3566
> +
>        - description: Beelink A1
>          items:
>            - const: azw,beelink-a1

Please see my delayed response in the v2. [1]  I think that would be
a better approach.

[1] https://lore.kernel.org/linux-rockchip/3c96ee6b-dca7-1a0a-792b-f8c165ec997d at manjaro.org/



From krzk at kernel.org  Tue Nov 18 23:09:25 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 19 Nov 2025 08:09:25 +0100
Subject: [PATCH v3 1/2] dt-bindings: arm: rockchip: Add Asus Tinker Board
 3/3S
In-Reply-To: <155d3d05-49f8-a000-6939-1411917745bb@manjaro.org>
References: <20251118-tinker3-v3-0-2903693f2ebb@rootcommit.com>
 <20251118-tinker3-v3-1-2903693f2ebb@rootcommit.com>
 <155d3d05-49f8-a000-6939-1411917745bb@manjaro.org>
Message-ID: <e7417a6e-3824-48f7-af56-eaf4bf097cb9@kernel.org>

On 19/11/2025 08:00, Dragan Simic wrote:
> Hello Michael,
> 
> On Tuesday, November 18, 2025 16:56 CET, Michael Opdenacker <michael.opdenacker at rootcommit.com> wrote:
>> Document the compatible strings for Asus Tinker Board 3 [1] and 3S [2],
>> which are SBCs based on the Rockchip 3566 SoC.
>>
>> The "3S" version ("S" for "storage") just adds a 16 GB eMMC
>> and a "mask ROM" DIP switch to the "3" version.
>>
>> [1] https://tinker-board.asus.com/series/tinker-board-3.html
>> [2] https://tinker-board.asus.com/series/tinker-board-3s.html
>>
>> Signed-off-by: Michael Opdenacker <michael.opdenacker at rootcommit.com>
>>
>> ---
>>
>> Changes in V3:
>>
>> - Remove this Acked-by as the binding code changed substantially:
>>   Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
>> ---
>>  Documentation/devicetree/bindings/arm/rockchip.yaml | 7 +++++++
>>  1 file changed, 7 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
>> index 6aceaa8acbb2..800c11323a4f 100644
>> --- a/Documentation/devicetree/bindings/arm/rockchip.yaml
>> +++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
>> @@ -86,6 +86,13 @@ properties:
>>            - const: asus,rk3288-tinker-s
>>            - const: rockchip,rk3288
>>  
>> +      - description: Asus Tinker Board 3/3S
>> +        items:
>> +          - enum:
>> +              - asus,rk3566-tinker-board-3
>> +              - asus,rk3566-tinker-board-3s
>> +          - const: rockchip,rk3566
>> +
>>        - description: Beelink A1
>>          items:
>>            - const: azw,beelink-a1
> 
> Please see my delayed response in the v2. [1]  I think that would be
> a better approach.
> 
> [1] https://lore.kernel.org/linux-rockchip/3c96ee6b-dca7-1a0a-792b-f8c165ec997d at manjaro.org/
> 

Your reviews are not helpful. You nitpick irrelevant things and propose
solutions which later reverse leading to wasted effort on contributors side.

Michael implemented what you asked here:

https://lore.kernel.org/linux-rockchip/e4cd11d0-463c-e707-5110-6b92899b1ba3 at manjaro.org/

This patch implements exactly what you wanted. On v4 you will ask to
reverse back to v1?

Now you claim that you want back v2. Really, you are NOT HELPING. It is
clear you do not understand what you are proposing and this is not
helping ion the process. Please refrain from such confusing reviews.



Best regards,
Krzysztof


From dsimic at manjaro.org  Tue Nov 18 23:23:02 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Wed, 19 Nov 2025 08:23:02 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v3 1/2] =?utf-8?q?dt-bindings=3A?=
 =?utf-8?q?_arm=3A?==?utf-8?q?_rockchip=3A?= Add Asus Tinker Board 3/3S
In-Reply-To: <e7417a6e-3824-48f7-af56-eaf4bf097cb9@kernel.org>
References: <20251118-tinker3-v3-0-2903693f2ebb@rootcommit.com>
 <20251118-tinker3-v3-1-2903693f2ebb@rootcommit.com>
 <155d3d05-49f8-a000-6939-1411917745bb@manjaro.org> <e7417a6e-3824-48f7-af56-eaf4bf097cb9@kernel.org>
Message-ID: <b8e91b59-afb1-6d0d-4709-c7f76ded0e18@manjaro.org>

Hello Krzysztof,

On Wednesday, November 19, 2025 08:09 CET, Krzysztof Kozlowski <krzk at kernel.org> wrote:
> On 19/11/2025 08:00, Dragan Simic wrote:
> > On Tuesday, November 18, 2025 16:56 CET, Michael Opdenacker <michael.opdenacker at rootcommit.com> wrote:
> >> Document the compatible strings for Asus Tinker Board 3 [1] and 3S [2],
> >> which are SBCs based on the Rockchip 3566 SoC.
> >>
> >> The "3S" version ("S" for "storage") just adds a 16 GB eMMC
> >> and a "mask ROM" DIP switch to the "3" version.
> >>
> >> [1] https://tinker-board.asus.com/series/tinker-board-3.html
> >> [2] https://tinker-board.asus.com/series/tinker-board-3s.html
> >>
> >> Signed-off-by: Michael Opdenacker <michael.opdenacker at rootcommit.com>
> >>
> >> ---
> >>
> >> Changes in V3:
> >>
> >> - Remove this Acked-by as the binding code changed substantially:
> >>   Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> >> ---
> >>  Documentation/devicetree/bindings/arm/rockchip.yaml | 7 +++++++
> >>  1 file changed, 7 insertions(+)
> >>
> >> diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
> >> index 6aceaa8acbb2..800c11323a4f 100644
> >> --- a/Documentation/devicetree/bindings/arm/rockchip.yaml
> >> +++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
> >> @@ -86,6 +86,13 @@ properties:
> >>            - const: asus,rk3288-tinker-s
> >>            - const: rockchip,rk3288
> >>  
> >> +      - description: Asus Tinker Board 3/3S
> >> +        items:
> >> +          - enum:
> >> +              - asus,rk3566-tinker-board-3
> >> +              - asus,rk3566-tinker-board-3s
> >> +          - const: rockchip,rk3566
> >> +
> >>        - description: Beelink A1
> >>          items:
> >>            - const: azw,beelink-a1
> > 
> > Please see my delayed response in the v2. [1]  I think that would be
> > a better approach.
> > 
> > [1] https://lore.kernel.org/linux-rockchip/3c96ee6b-dca7-1a0a-792b-f8c165ec997d at manjaro.org/
> 
> Your reviews are not helpful. You nitpick irrelevant things and propose
> solutions which later reverse leading to wasted effort on contributors side.
> 
> Michael implemented what you asked here:
> 
> https://lore.kernel.org/linux-rockchip/e4cd11d0-463c-e707-5110-6b92899b1ba3 at manjaro.org/

Not exactly, because I didn't ask for any compatibles to be removed
from the new board dts files.

In this case, we could also say that it was Michael's fault not to
give enough time for the reviewers to respond.

> This patch implements exactly what you wanted. On v4 you will ask to
> reverse back to v1?

No, I will not, and please note this version doesn't exactly implement
what I suggested, as already explained above.

> Now you claim that you want back v2. Really, you are NOT HELPING. It is
> clear you do not understand what you are proposing and this is not
> helping ion the process. Please refrain from such confusing reviews.

No, I'm not suggesting that the series goes back to v2, but Michael
failed to give me enough time to respond.  If that were the case,
the v3 would've been in nicer shape, with, from my point of view, no
need for further adjustments.



From michael.opdenacker at rootcommit.com  Tue Nov 18 23:25:37 2025
From: michael.opdenacker at rootcommit.com (Michael Opdenacker)
Date: Wed, 19 Nov 2025 07:25:37 +0000 (UTC)
Subject: [PATCH v2 1/2] dt-bindings: arm: rockchip: Add Asus Tinker Board
 3 and 3S
In-Reply-To: <3c96ee6b-dca7-1a0a-792b-f8c165ec997d@manjaro.org>
References: <e4cd11d0-463c-e707-5110-6b92899b1ba3@manjaro.org>
 <0c224662-b3c2-4075-8b68-c0ae27421ba8@rootcommit.com>
 <3c96ee6b-dca7-1a0a-792b-f8c165ec997d@manjaro.org>
Message-ID: <8fce39e0-62f7-4a79-83b8-e3a63af10e2f@rootcommit.com>

Hi Dragan

Thanks for your reviews in busy times!

> This should let us keep the "asus,rk3566-tinker-board-3" compatible
> in the new rk3566-tinker-board-3s.dts board dts while satisfying the
> validation properly:
>
>    - description: Asus Tinker Board 3/3S
>      items:
>      - enum:
>          - asus,rk3566-tinker-board-3s
>      - const: asus,rk3566-tinker-board-3
>      - const: rockchip,rk3566
>
> I'm quite busy at the moment, hence my delayed response, and I also
> apologize for not running the checks on the above-proposed solution,
> but I think it should work as expected.

I actually already tried this, but it doesn't pass "make dtbs_check":

arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3.dtb: / 
(asus,rk3566-tinker-board-3): compatible: 'oneOf' conditional failed, 
one must be fixed:
 ? ? ['asus,rk3566-tinker-board-3', 'rockchip,rk3566'] is too short

The "enum" statement seems to mean that there is at least one of the 
items, which is not the case for rk3566-tinker-board-3.dts that doesn't 
have it.

So, my V3 seems like the way to go if we don't want to duplicate entries 
in rockchip.yaml.
Cheers
Michael.

-- 
Michael Opdenacker
Root Commit
Yocto Project and OpenEmbedded Training course - Learn by doing:
https://rootcommit.com/training/yocto/



From dsimic at manjaro.org  Tue Nov 18 23:28:43 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Wed, 19 Nov 2025 08:28:43 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v2 1/2] =?utf-8?q?dt-bindings=3A?=
 =?utf-8?q?_arm=3A?==?utf-8?q?_rockchip=3A?= Add Asus Tinker Board 3 and 3S
In-Reply-To: <8fce39e0-62f7-4a79-83b8-e3a63af10e2f@rootcommit.com>
References: <e4cd11d0-463c-e707-5110-6b92899b1ba3@manjaro.org>
 <0c224662-b3c2-4075-8b68-c0ae27421ba8@rootcommit.com>
 <3c96ee6b-dca7-1a0a-792b-f8c165ec997d@manjaro.org> <8fce39e0-62f7-4a79-83b8-e3a63af10e2f@rootcommit.com>
Message-ID: <3d5ed2bc-038c-0808-56f3-411652b5ed6d@manjaro.org>

On Wednesday, November 19, 2025 08:25 CET, Michael Opdenacker <michael.opdenacker at rootcommit.com> wrote:
> > This should let us keep the "asus,rk3566-tinker-board-3" compatible
> > in the new rk3566-tinker-board-3s.dts board dts while satisfying the
> > validation properly:
> >
> >    - description: Asus Tinker Board 3/3S
> >      items:
> >      - enum:
> >          - asus,rk3566-tinker-board-3s
> >      - const: asus,rk3566-tinker-board-3
> >      - const: rockchip,rk3566
> >
> > I'm quite busy at the moment, hence my delayed response, and I also
> > apologize for not running the checks on the above-proposed solution,
> > but I think it should work as expected.
> 
> I actually already tried this, but it doesn't pass "make dtbs_check":
> 
> arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3.dtb: / 
> (asus,rk3566-tinker-board-3): compatible: 'oneOf' conditional failed, 
> one must be fixed:
>  ? ? ['asus,rk3566-tinker-board-3', 'rockchip,rk3566'] is too short
> 
> The "enum" statement seems to mean that there is at least one of the 
> items, which is not the case for rk3566-tinker-board-3.dts that doesn't 
> have it.
> 
> So, my V3 seems like the way to go if we don't want to duplicate entries 
> in rockchip.yaml.

I see, thanks for the clarification.  Then the v3 is the way to go.



From krzk at kernel.org  Tue Nov 18 23:31:25 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 19 Nov 2025 08:31:25 +0100
Subject: [PATCH v3 1/2] dt-bindings: arm: rockchip: Add Asus Tinker Board
 3/3S
In-Reply-To: <b8e91b59-afb1-6d0d-4709-c7f76ded0e18@manjaro.org>
References: <20251118-tinker3-v3-0-2903693f2ebb@rootcommit.com>
 <20251118-tinker3-v3-1-2903693f2ebb@rootcommit.com>
 <155d3d05-49f8-a000-6939-1411917745bb@manjaro.org>
 <e7417a6e-3824-48f7-af56-eaf4bf097cb9@kernel.org>
 <b8e91b59-afb1-6d0d-4709-c7f76ded0e18@manjaro.org>
Message-ID: <5bc642d3-fe05-4654-88c3-11c6534c5aa4@kernel.org>

On 19/11/2025 08:23, Dragan Simic wrote:
> Hello Krzysztof,
> 
> On Wednesday, November 19, 2025 08:09 CET, Krzysztof Kozlowski <krzk at kernel.org> wrote:
>> On 19/11/2025 08:00, Dragan Simic wrote:
>>> On Tuesday, November 18, 2025 16:56 CET, Michael Opdenacker <michael.opdenacker at rootcommit.com> wrote:
>>>> Document the compatible strings for Asus Tinker Board 3 [1] and 3S [2],
>>>> which are SBCs based on the Rockchip 3566 SoC.
>>>>
>>>> The "3S" version ("S" for "storage") just adds a 16 GB eMMC
>>>> and a "mask ROM" DIP switch to the "3" version.
>>>>
>>>> [1] https://tinker-board.asus.com/series/tinker-board-3.html
>>>> [2] https://tinker-board.asus.com/series/tinker-board-3s.html
>>>>
>>>> Signed-off-by: Michael Opdenacker <michael.opdenacker at rootcommit.com>
>>>>
>>>> ---
>>>>
>>>> Changes in V3:
>>>>
>>>> - Remove this Acked-by as the binding code changed substantially:
>>>>   Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
>>>> ---
>>>>  Documentation/devicetree/bindings/arm/rockchip.yaml | 7 +++++++
>>>>  1 file changed, 7 insertions(+)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
>>>> index 6aceaa8acbb2..800c11323a4f 100644
>>>> --- a/Documentation/devicetree/bindings/arm/rockchip.yaml
>>>> +++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
>>>> @@ -86,6 +86,13 @@ properties:
>>>>            - const: asus,rk3288-tinker-s
>>>>            - const: rockchip,rk3288
>>>>  
>>>> +      - description: Asus Tinker Board 3/3S
>>>> +        items:
>>>> +          - enum:
>>>> +              - asus,rk3566-tinker-board-3
>>>> +              - asus,rk3566-tinker-board-3s
>>>> +          - const: rockchip,rk3566
>>>> +
>>>>        - description: Beelink A1
>>>>          items:
>>>>            - const: azw,beelink-a1
>>>
>>> Please see my delayed response in the v2. [1]  I think that would be
>>> a better approach.
>>>
>>> [1] https://lore.kernel.org/linux-rockchip/3c96ee6b-dca7-1a0a-792b-f8c165ec997d at manjaro.org/
>>
>> Your reviews are not helpful. You nitpick irrelevant things and propose
>> solutions which later reverse leading to wasted effort on contributors side.
>>
>> Michael implemented what you asked here:
>>
>> https://lore.kernel.org/linux-rockchip/e4cd11d0-463c-e707-5110-6b92899b1ba3 at manjaro.org/
> 
> Not exactly, because I didn't ask for any compatibles to be removed
> from the new board dts files.

Read your answer again. You wanted ENTIRE bindings, to be like this:

     - description: Asus Tinker Board 3/3S
       items:
         - enum:
	   - asus,rk3566-tinker-board-3
           - asus,rk3566-tinker-board-3s
         - const: rockchip,rk3566

(skipping obvious indentation fixup)
There are exactly like this.

> 
> In this case, we could also say that it was Michael's fault not to
> give enough time for the reviewers to respond.

Michael implemented EXACTLY what you asked. Now, you ask to change it to
what Michael did BEFORE.

Your reviews are completely irresponsible and incorrect.

Best regards,
Krzysztof


From michael.opdenacker at rootcommit.com  Tue Nov 18 23:32:57 2025
From: michael.opdenacker at rootcommit.com (Michael Opdenacker)
Date: Wed, 19 Nov 2025 07:32:57 +0000 (UTC)
Subject: [PATCH v3 1/2] dt-bindings: arm: rockchip: Add Asus Tinker Board
 3/3S
In-Reply-To: <b8e91b59-afb1-6d0d-4709-c7f76ded0e18@manjaro.org>
References: <20251118-tinker3-v3-0-2903693f2ebb@rootcommit.com>
 <20251118-tinker3-v3-1-2903693f2ebb@rootcommit.com>
 <155d3d05-49f8-a000-6939-1411917745bb@manjaro.org>
 <e7417a6e-3824-48f7-af56-eaf4bf097cb9@kernel.org>
 <b8e91b59-afb1-6d0d-4709-c7f76ded0e18@manjaro.org>
Message-ID: <d6b3ca5a-e036-4019-8f4f-428d4d132f2f@rootcommit.com>


On 11/19/25 08:23, Dragan Simic wrote:
> No, I'm not suggesting that the series goes back to v2, but Michael
> failed to give me enough time to respond.  If that were the case,
> the v3 would've been in nicer shape, with, from my point of view, no
> need for further adjustments.

I'm sorry if I caused trouble.

I agree I didn't leave you much time to react to my reply to your 
review. What happens is that I'm new to this subsystem and I was feeling 
some pressure to avoid missing the launch window for 6.19, which I don't 
know exactly when it will be.

Michael.

-- 
Michael Opdenacker
Root Commit
Yocto Project and OpenEmbedded Training course - Learn by doing:
https://rootcommit.com/training/yocto/



From dsimic at manjaro.org  Tue Nov 18 23:33:31 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Wed, 19 Nov 2025 08:33:31 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v3 1/2] =?utf-8?q?dt-bindings=3A?=
 =?utf-8?q?_arm=3A?==?utf-8?q?_rockchip=3A?= Add Asus Tinker Board 3/3S
In-Reply-To: <e7417a6e-3824-48f7-af56-eaf4bf097cb9@kernel.org>
References: <20251118-tinker3-v3-0-2903693f2ebb@rootcommit.com>
 <20251118-tinker3-v3-1-2903693f2ebb@rootcommit.com>
 <155d3d05-49f8-a000-6939-1411917745bb@manjaro.org> <e7417a6e-3824-48f7-af56-eaf4bf097cb9@kernel.org>
Message-ID: <1417577e-10da-7101-5f78-c0299efba587@manjaro.org>

On Wednesday, November 19, 2025 08:09 CET, Krzysztof Kozlowski <krzk at kernel.org> wrote:
> Now you claim that you want back v2. Really, you are NOT HELPING. It is
> clear you do not understand what you are proposing and this is not
> helping ion the process. Please refrain from such confusing reviews.
> 
> Best regards,
> Krzysztof

Oh, i forgot to mention that it certainly may be that I don't
know everything when it comes to DT bindings and definitions, but
you also may not know how to handle communication with people in
a polite and friendly way.

Thus, I'd suggest that you replace "Best regards" in your signature
with "No regards".



From dsimic at manjaro.org  Tue Nov 18 23:40:09 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Wed, 19 Nov 2025 08:40:09 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v3 1/2] =?utf-8?q?dt-bindings=3A?=
 =?utf-8?q?_arm=3A?==?utf-8?q?_rockchip=3A?= Add Asus Tinker Board 3/3S
In-Reply-To: <5bc642d3-fe05-4654-88c3-11c6534c5aa4@kernel.org>
References: <20251118-tinker3-v3-0-2903693f2ebb@rootcommit.com>
 <20251118-tinker3-v3-1-2903693f2ebb@rootcommit.com>
 <155d3d05-49f8-a000-6939-1411917745bb@manjaro.org>
 <e7417a6e-3824-48f7-af56-eaf4bf097cb9@kernel.org>
 <b8e91b59-afb1-6d0d-4709-c7f76ded0e18@manjaro.org> <5bc642d3-fe05-4654-88c3-11c6534c5aa4@kernel.org>
Message-ID: <b98e53ce-9c8c-c505-6097-0d22d0416e8e@manjaro.org>

On Wednesday, November 19, 2025 08:31 CET, Krzysztof Kozlowski <krzk at kernel.org> wrote:
> On 19/11/2025 08:23, Dragan Simic wrote:
> > On Wednesday, November 19, 2025 08:09 CET, Krzysztof Kozlowski <krzk at kernel.org> wrote:
> >> On 19/11/2025 08:00, Dragan Simic wrote:
> >>> On Tuesday, November 18, 2025 16:56 CET, Michael Opdenacker <michael.opdenacker at rootcommit.com> wrote:
> >>>> Document the compatible strings for Asus Tinker Board 3 [1] and 3S [2],
> >>>> which are SBCs based on the Rockchip 3566 SoC.
> >>>>
> >>>> The "3S" version ("S" for "storage") just adds a 16 GB eMMC
> >>>> and a "mask ROM" DIP switch to the "3" version.
> >>>>
> >>>> [1] https://tinker-board.asus.com/series/tinker-board-3.html
> >>>> [2] https://tinker-board.asus.com/series/tinker-board-3s.html
> >>>>
> >>>> Signed-off-by: Michael Opdenacker <michael.opdenacker at rootcommit.com>
> >>>>
> >>>> ---
> >>>>
> >>>> Changes in V3:
> >>>>
> >>>> - Remove this Acked-by as the binding code changed substantially:
> >>>>   Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> >>>> ---
> >>>>  Documentation/devicetree/bindings/arm/rockchip.yaml | 7 +++++++
> >>>>  1 file changed, 7 insertions(+)
> >>>>
> >>>> diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
> >>>> index 6aceaa8acbb2..800c11323a4f 100644
> >>>> --- a/Documentation/devicetree/bindings/arm/rockchip.yaml
> >>>> +++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
> >>>> @@ -86,6 +86,13 @@ properties:
> >>>>            - const: asus,rk3288-tinker-s
> >>>>            - const: rockchip,rk3288
> >>>>  
> >>>> +      - description: Asus Tinker Board 3/3S
> >>>> +        items:
> >>>> +          - enum:
> >>>> +              - asus,rk3566-tinker-board-3
> >>>> +              - asus,rk3566-tinker-board-3s
> >>>> +          - const: rockchip,rk3566
> >>>> +
> >>>>        - description: Beelink A1
> >>>>          items:
> >>>>            - const: azw,beelink-a1
> >>>
> >>> Please see my delayed response in the v2. [1]  I think that would be
> >>> a better approach.
> >>>
> >>> [1] https://lore.kernel.org/linux-rockchip/3c96ee6b-dca7-1a0a-792b-f8c165ec997d at manjaro.org/
> >>
> >> Your reviews are not helpful. You nitpick irrelevant things and propose
> >> solutions which later reverse leading to wasted effort on contributors side.
> >>
> >> Michael implemented what you asked here:
> >>
> >> https://lore.kernel.org/linux-rockchip/e4cd11d0-463c-e707-5110-6b92899b1ba3 at manjaro.org/
> > 
> > Not exactly, because I didn't ask for any compatibles to be removed
> > from the new board dts files.
> 
> Read your answer again. You wanted ENTIRE bindings, to be like this:
> 
>      - description: Asus Tinker Board 3/3S
>        items:
>          - enum:
> 	   - asus,rk3566-tinker-board-3
>            - asus,rk3566-tinker-board-3s
>          - const: rockchip,rk3566
> 
> (skipping obvious indentation fixup)
> There are exactly like this.
> 
> > 
> > In this case, we could also say that it was Michael's fault not to
> > give enough time for the reviewers to respond.
> 
> Michael implemented EXACTLY what you asked. Now, you ask to change it to
> what Michael did BEFORE.

Not really, because it wasn't some kind of a request from my side,
but merely a suggestion that was intended to be discussed further
so the best possible solution is reached before v3 is submitted.

> Your reviews are completely irresponsible and incorrect.

Calling my reviews irresponsible hurts me a lot, really, but I'm
unfortunately already used to hear hurtful things from your side.



From krzk at kernel.org  Tue Nov 18 23:48:18 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 19 Nov 2025 08:48:18 +0100
Subject: [PATCH v3 1/2] dt-bindings: arm: rockchip: Add Asus Tinker Board
 3/3S
In-Reply-To: <b98e53ce-9c8c-c505-6097-0d22d0416e8e@manjaro.org>
References: <20251118-tinker3-v3-0-2903693f2ebb@rootcommit.com>
 <20251118-tinker3-v3-1-2903693f2ebb@rootcommit.com>
 <155d3d05-49f8-a000-6939-1411917745bb@manjaro.org>
 <e7417a6e-3824-48f7-af56-eaf4bf097cb9@kernel.org>
 <b8e91b59-afb1-6d0d-4709-c7f76ded0e18@manjaro.org>
 <5bc642d3-fe05-4654-88c3-11c6534c5aa4@kernel.org>
 <b98e53ce-9c8c-c505-6097-0d22d0416e8e@manjaro.org>
Message-ID: <e1598abe-7a66-4808-82c7-2389ee2ea279@kernel.org>

On 19/11/2025 08:40, Dragan Simic wrote:
> On Wednesday, November 19, 2025 08:31 CET, Krzysztof Kozlowski <krzk at kernel.org> wrote:
>> On 19/11/2025 08:23, Dragan Simic wrote:
>>> On Wednesday, November 19, 2025 08:09 CET, Krzysztof Kozlowski <krzk at kernel.org> wrote:
>>>> On 19/11/2025 08:00, Dragan Simic wrote:
>>>>> On Tuesday, November 18, 2025 16:56 CET, Michael Opdenacker <michael.opdenacker at rootcommit.com> wrote:
>>>>>> Document the compatible strings for Asus Tinker Board 3 [1] and 3S [2],
>>>>>> which are SBCs based on the Rockchip 3566 SoC.
>>>>>>
>>>>>> The "3S" version ("S" for "storage") just adds a 16 GB eMMC
>>>>>> and a "mask ROM" DIP switch to the "3" version.
>>>>>>
>>>>>> [1] https://tinker-board.asus.com/series/tinker-board-3.html
>>>>>> [2] https://tinker-board.asus.com/series/tinker-board-3s.html
>>>>>>
>>>>>> Signed-off-by: Michael Opdenacker <michael.opdenacker at rootcommit.com>
>>>>>>
>>>>>> ---
>>>>>>
>>>>>> Changes in V3:
>>>>>>
>>>>>> - Remove this Acked-by as the binding code changed substantially:
>>>>>>   Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
>>>>>> ---
>>>>>>  Documentation/devicetree/bindings/arm/rockchip.yaml | 7 +++++++
>>>>>>  1 file changed, 7 insertions(+)
>>>>>>
>>>>>> diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
>>>>>> index 6aceaa8acbb2..800c11323a4f 100644
>>>>>> --- a/Documentation/devicetree/bindings/arm/rockchip.yaml
>>>>>> +++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
>>>>>> @@ -86,6 +86,13 @@ properties:
>>>>>>            - const: asus,rk3288-tinker-s
>>>>>>            - const: rockchip,rk3288
>>>>>>  
>>>>>> +      - description: Asus Tinker Board 3/3S
>>>>>> +        items:
>>>>>> +          - enum:
>>>>>> +              - asus,rk3566-tinker-board-3
>>>>>> +              - asus,rk3566-tinker-board-3s
>>>>>> +          - const: rockchip,rk3566
>>>>>> +
>>>>>>        - description: Beelink A1
>>>>>>          items:
>>>>>>            - const: azw,beelink-a1
>>>>>
>>>>> Please see my delayed response in the v2. [1]  I think that would be
>>>>> a better approach.
>>>>>
>>>>> [1] https://lore.kernel.org/linux-rockchip/3c96ee6b-dca7-1a0a-792b-f8c165ec997d at manjaro.org/
>>>>
>>>> Your reviews are not helpful. You nitpick irrelevant things and propose
>>>> solutions which later reverse leading to wasted effort on contributors side.
>>>>
>>>> Michael implemented what you asked here:
>>>>
>>>> https://lore.kernel.org/linux-rockchip/e4cd11d0-463c-e707-5110-6b92899b1ba3 at manjaro.org/
>>>
>>> Not exactly, because I didn't ask for any compatibles to be removed
>>> from the new board dts files.
>>
>> Read your answer again. You wanted ENTIRE bindings, to be like this:
>>
>>      - description: Asus Tinker Board 3/3S
>>        items:
>>          - enum:
>> 	   - asus,rk3566-tinker-board-3
>>            - asus,rk3566-tinker-board-3s
>>          - const: rockchip,rk3566
>>
>> (skipping obvious indentation fixup)
>> There are exactly like this.
>>
>>>
>>> In this case, we could also say that it was Michael's fault not to
>>> give enough time for the reviewers to respond.
>>
>> Michael implemented EXACTLY what you asked. Now, you ask to change it to
>> what Michael did BEFORE.
> 
> Not really, because it wasn't some kind of a request from my side,
> but merely a suggestion that was intended to be discussed further
> so the best possible solution is reached before v3 is submitted.
> 
>> Your reviews are completely irresponsible and incorrect.
> 
> Calling my reviews irresponsible hurts me a lot, really, but I'm
> unfortunately already used to hear hurtful things from your side.

You do not bear the cost of your reviews, so maybe that's why you think
nitpicking, poking around, pin pointing irrelevant things and adding 2
cents is okay, but that leads to additional effort on contributors and
reviewers. And not respecting total effort is irresponsible.


Best regards,
Krzysztof


From dsimic at manjaro.org  Tue Nov 18 23:54:10 2025
From: dsimic at manjaro.org (Dragan Simic)
Date: Wed, 19 Nov 2025 08:54:10 +0100
Subject: =?utf-8?q?Re=3A?= [PATCH v3 1/2] =?utf-8?q?dt-bindings=3A?=
 =?utf-8?q?_arm=3A?==?utf-8?q?_rockchip=3A?= Add Asus Tinker Board 3/3S
In-Reply-To: <e1598abe-7a66-4808-82c7-2389ee2ea279@kernel.org>
References: <20251118-tinker3-v3-0-2903693f2ebb@rootcommit.com>
 <20251118-tinker3-v3-1-2903693f2ebb@rootcommit.com>
 <155d3d05-49f8-a000-6939-1411917745bb@manjaro.org>
 <e7417a6e-3824-48f7-af56-eaf4bf097cb9@kernel.org>
 <b8e91b59-afb1-6d0d-4709-c7f76ded0e18@manjaro.org>
 <5bc642d3-fe05-4654-88c3-11c6534c5aa4@kernel.org>
 <b98e53ce-9c8c-c505-6097-0d22d0416e8e@manjaro.org> <e1598abe-7a66-4808-82c7-2389ee2ea279@kernel.org>
Message-ID: <69de292c-af43-d202-72da-c7d3769d1799@manjaro.org>

On Wednesday, November 19, 2025 08:48 CET, Krzysztof Kozlowski <krzk at kernel.org> wrote:
> On 19/11/2025 08:40, Dragan Simic wrote:
> > On Wednesday, November 19, 2025 08:31 CET, Krzysztof Kozlowski <krzk at kernel.org> wrote:
> >> On 19/11/2025 08:23, Dragan Simic wrote:
> >>> On Wednesday, November 19, 2025 08:09 CET, Krzysztof Kozlowski <krzk at kernel.org> wrote:
> >>>> Your reviews are not helpful. You nitpick irrelevant things and propose
> >>>> solutions which later reverse leading to wasted effort on contributors side.
> >>>>
> >>>> Michael implemented what you asked here:
> >>>>
> >>>> https://lore.kernel.org/linux-rockchip/e4cd11d0-463c-e707-5110-6b92899b1ba3 at manjaro.org/
> >>>
> >>> Not exactly, because I didn't ask for any compatibles to be removed
> >>> from the new board dts files.
> >>
> >> Read your answer again. You wanted ENTIRE bindings, to be like this:
> >>
> >>      - description: Asus Tinker Board 3/3S
> >>        items:
> >>          - enum:
> >> 	   - asus,rk3566-tinker-board-3
> >>            - asus,rk3566-tinker-board-3s
> >>          - const: rockchip,rk3566
> >>
> >> (skipping obvious indentation fixup)
> >> There are exactly like this.
> >>>
> >>> In this case, we could also say that it was Michael's fault not to
> >>> give enough time for the reviewers to respond.
> >>
> >> Michael implemented EXACTLY what you asked. Now, you ask to change it to
> >> what Michael did BEFORE.
> > 
> > Not really, because it wasn't some kind of a request from my side,
> > but merely a suggestion that was intended to be discussed further
> > so the best possible solution is reached before v3 is submitted.
> > 
> >> Your reviews are completely irresponsible and incorrect.
> > 
> > Calling my reviews irresponsible hurts me a lot, really, but I'm
> > unfortunately already used to hear hurtful things from your side.
> 
> You do not bear the cost of your reviews, so maybe that's why you think
> nitpicking, poking around, pin pointing irrelevant things and adding 2
> cents is okay, but that leads to additional effort on contributors and
> reviewers. And not respecting total effort is irresponsible.

Thank you very much for finding additional ways to hurt my feelings.
However, please think about how your unfriendly approach may or may
not contribute to the overall effort.



From dan.carpenter at linaro.org  Wed Nov 19 00:09:54 2025
From: dan.carpenter at linaro.org (Dan Carpenter)
Date: Wed, 19 Nov 2025 11:09:54 +0300
Subject: [PATCH next] media: rockchip: rkcif: fix off by one bugs
Message-ID: <aR17UkYsfAxCZ4fe@stanley.mountain>

Change these comparisons from > vs >= to avoid accessing one element
beyond the end of the arrays.

Fixes: 1f2353f5a1af ("media: rockchip: rkcif: add support for rk3568 vicap mipi capture")
Signed-off-by: Dan Carpenter <dan.carpenter at linaro.org>
---
 .../media/platform/rockchip/rkcif/rkcif-capture-mipi.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.c b/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.c
index 1b81bcc067ef..a933df682acc 100644
--- a/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.c
+++ b/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.c
@@ -489,8 +489,8 @@ static inline unsigned int rkcif_mipi_get_reg(struct rkcif_interface *interface,
 
 	block = interface->index - RKCIF_MIPI_BASE;
 
-	if (WARN_ON_ONCE(block > RKCIF_MIPI_MAX - RKCIF_MIPI_BASE) ||
-	    WARN_ON_ONCE(index > RKCIF_MIPI_REGISTER_MAX))
+	if (WARN_ON_ONCE(block >= RKCIF_MIPI_MAX - RKCIF_MIPI_BASE) ||
+	    WARN_ON_ONCE(index >= RKCIF_MIPI_REGISTER_MAX))
 		return RKCIF_REGISTER_NOTSUPPORTED;
 
 	offset = rkcif->match_data->mipi->blocks[block].offset;
@@ -510,9 +510,9 @@ static inline unsigned int rkcif_mipi_id_get_reg(struct rkcif_stream *stream,
 	block = stream->interface->index - RKCIF_MIPI_BASE;
 	id = stream->id;
 
-	if (WARN_ON_ONCE(block > RKCIF_MIPI_MAX - RKCIF_MIPI_BASE) ||
-	    WARN_ON_ONCE(id > RKCIF_ID_MAX) ||
-	    WARN_ON_ONCE(index > RKCIF_MIPI_ID_REGISTER_MAX))
+	if (WARN_ON_ONCE(block >= RKCIF_MIPI_MAX - RKCIF_MIPI_BASE) ||
+	    WARN_ON_ONCE(id >= RKCIF_ID_MAX) ||
+	    WARN_ON_ONCE(index >= RKCIF_MIPI_ID_REGISTER_MAX))
 		return RKCIF_REGISTER_NOTSUPPORTED;
 
 	offset = rkcif->match_data->mipi->blocks[block].offset;
-- 
2.51.0



From neil.armstrong at linaro.org  Wed Nov 19 00:25:35 2025
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Wed, 19 Nov 2025 09:25:35 +0100
Subject: [PATCH RESEND 0/3] Fixes for phy-rockchip-samsung-hdptx
In-Reply-To: <20251028-phy-hdptx-fixes-v1-0-ecc642a59d94@collabora.com>
References: <20251028-phy-hdptx-fixes-v1-0-ecc642a59d94@collabora.com>
Message-ID: <25e9e2ae-d280-4022-8c8a-41df5009011a@linaro.org>

On 10/28/25 09:00, Cristian Ciocaltea wrote:
> These patches were initially part of the HDMI 2.1 FRL support series [1]
> aiming to provide a few fixes for the Samsung HDMI/eDP Transmitter Combo
> PHY.
> 
> I'm sending this as a distinct series right now, since the FRL part
> might require additional time for review.
> 
> [1] https://lore.kernel.org/r/20250818-phy-hdptx-frl-v3-0-c79997d8bb2b at collabora.com
> 
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
> ---
> Cristian Ciocaltea (3):
>        phy: rockchip: samsung-hdptx: Fix reported clock rate in high bpc mode
>        phy: rockchip: samsung-hdptx: Reduce ROPLL loop bandwidth
>        phy: rockchip: samsung-hdptx: Prevent Inter-Pair Skew from exceeding the limits
> 
>   drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 27 +++++++++++++----------
>   1 file changed, 15 insertions(+), 12 deletions(-)
> ---
> base-commit: 33bcf93b9a6b028758105680f8b538a31bc563cf
> change-id: 20250902-phy-hdptx-fixes-7308ffea4c6a

For the serie:
Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From marek.poradecki at novencio.pl  Wed Nov 19 01:01:03 2025
From: marek.poradecki at novencio.pl (Marek Poradecki)
Date: Wed, 19 Nov 2025 09:01:03 GMT
Subject: =?UTF-8?Q?Wiadomo=C5=9B=C4=87_z_ksi=C4=99gowo=C5=9Bci?=
Message-ID: <20251119074742-0.1.5y.z4kd.0.139j60of30@novencio.pl>

Dzie? dobry,

pomagamy przedsi?biorcom wprowadzi? model wymiany walut, kt?ry minimalizuje wahania koszt?w przy rozliczeniach mi?dzynarodowych.

Kiedyv mo?emy um?wi? si? na 15-minutow? rozmow?, aby zaprezentowa?, jak taki model m?g?by dzia?a? w Pa?stwa firmie - z gwarancj? indywidualnych kurs?w i pe?nym uproszczeniem p?atno?ci? Prosz? o propozycj? dogodnego terminu.


Pozdrawiam
Marek Poradecki


From mripard at kernel.org  Wed Nov 19 01:02:23 2025
From: mripard at kernel.org (Maxime Ripard)
Date: Wed, 19 Nov 2025 10:02:23 +0100
Subject: [PATCH v2 2/3] drm/bridge: dw-hdmi-qp: Add support for missing
 HPD
In-Reply-To: <SN6PR1901MB46548ED8D4BA1184E0EA7DC3A5D6A@SN6PR1901MB4654.namprd19.prod.outlook.com>
References: <20251113192939.30031-1-macroalpha82@gmail.com>
 <20251113192939.30031-3-macroalpha82@gmail.com>
 <avdnpwnxs6cql7eyckdt37szpcf5ztgxlc7juwu6tqj5xxu56a@nrwljig2p67i>
 <SN6PR1901MB46548ED8D4BA1184E0EA7DC3A5D6A@SN6PR1901MB4654.namprd19.prod.outlook.com>
Message-ID: <hgwfztkwk4qgvefwo2cdedzas3rzlhx6yek6dgldkgaq2jskvw@exxqujjpa6bl>

On Tue, Nov 18, 2025 at 02:36:09PM -0600, Chris Morgan wrote:
> On Tue, Nov 18, 2025 at 09:46:04AM +0100, Maxime Ripard wrote:
> > Hi,
> > 
> > On Thu, Nov 13, 2025 at 01:29:38PM -0600, Chris Morgan wrote:
> > > From: Chris Morgan <macromorgan at hotmail.com>
> > > 
> > > Add support for the dw-hdmi-qp driver to handle devices with missing
> > > HPD pins.
> > > 
> > > Since in this situation we are now polling for the EDID data via i2c
> > > change the error message to a debug message when we are unable to
> > > complete an i2c read, as a disconnected device would otherwise fill
> > > dmesg with i2c read errors.
> > > 
> > > Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
> > 
> > You must also disable any mode using the scrambler when there's no
> > hotplug interrupt available.
> 
> Is there a simple way to do that? I'm not seeing any references to
> scrambling in the current driver.
> 
> Should I just limit the rate to HDMI14_MAX_TMDSCLK (340000000)  under
> dw_hdmi_qp_bridge_tmds_char_rate_valid() if using EDID polling? A
> document I found online from Synopsys [1] claims that scrambling is
> used by default at rates above 340 (if I'm reading it right) and used
> opportunistically at rates below 340.

Yep, that's what you should be testing for :)

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 273 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251119/93bb5054/attachment-0001.sig>

From mripard at kernel.org  Wed Nov 19 01:09:12 2025
From: mripard at kernel.org (Maxime Ripard)
Date: Wed, 19 Nov 2025 10:09:12 +0100
Subject: [PATCH v4 07/10] drm/display: hdmi-state-helper: Act on color
 format DRM property
In-Reply-To: <20251117-color-format-v4-7-0ded72bd1b00@collabora.com>
References: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
 <20251117-color-format-v4-7-0ded72bd1b00@collabora.com>
Message-ID: <4wt5dbvseauo2bvi66ohtk445zsfjtpjwgvochwwlyk4uugcmy@5ubwtkxyy2ax>

Hi,

On Mon, Nov 17, 2025 at 08:11:51PM +0100, Nicolas Frattaroli wrote:
> With the introduction of the "color format" DRM property, which allows
> userspace to request a specific color format, the HDMI state helper
> should implement this.
> 
> Implement it by checking whether the property is set and set to
> something other than auto. If so, pass the requested color format, and
> otherwise set RGB.
> 
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
> ---
>  drivers/gpu/drm/display/drm_hdmi_state_helper.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> index a561f124be99..add0d51fce33 100644
> --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> @@ -650,9 +650,15 @@ hdmi_compute_config(const struct drm_connector *connector,
>  				       conn_state->max_bpc,
>  				       8, connector->max_bpc);
>  	int ret;
> +	enum hdmi_colorspace hdmi_colorspace;
> +
> +	if (conn_state->color_format && conn_state->color_format != DRM_COLOR_FORMAT_AUTO)
> +		hdmi_colorspace = color_format_to_hdmi_colorspace(conn_state->color_format);
> +	else
> +		hdmi_colorspace = HDMI_COLORSPACE_RGB;
>  
>  	ret = hdmi_compute_format_bpc(connector, conn_state, mode, max_bpc,
> -				      HDMI_COLORSPACE_RGB);
> +				      hdmi_colorspace);

I don't think we want the fallback to yuv420 for anything but auto, so
I'd rather have something like

if (conn_state->color_format != DRM_COLOR_FORMAT_AUTO)
   return hdmi_compute_format_bpc(connector, conn_state, mode, max_bpc,
                                  color_format_to_hdmi_colorspace(conn_state->color_format))

We'll also need unit tests.

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 273 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251119/efa458bb/attachment.sig>

From mripard at kernel.org  Wed Nov 19 01:10:26 2025
From: mripard at kernel.org (Maxime Ripard)
Date: Wed, 19 Nov 2025 10:10:26 +0100
Subject: [PATCH v4 10/10] drm/rockchip: Implement "color format" DRM
 property
In-Reply-To: <20251117-color-format-v4-10-0ded72bd1b00@collabora.com>
References: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
 <20251117-color-format-v4-10-0ded72bd1b00@collabora.com>
Message-ID: <irl64vwqiwdgxwwvim62qm55fc36p6fyduxlnc23zkotsr6726@4zswp4rjdtu4>

On Mon, Nov 17, 2025 at 08:11:54PM +0100, Nicolas Frattaroli wrote:
> From: Derek Foreman <derek.foreman at collabora.com>
> 
> Register the color format property in the dw_hdmi_qp-rockchip driver,
> and act on requested format changes as part of the connector state in
> the vop2 video output driver.
> 
> Signed-off-by: Derek Foreman <derek.foreman at collabora.com>
> Signed-off-by: Marius Vlad <marius.vlad at collabora.com>
> Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
> ---
>  drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c |  3 ++
>  drivers/gpu/drm/rockchip/rockchip_drm_vop2.c   | 46 ++++++++++++++++++++++++++
>  drivers/gpu/drm/rockchip/rockchip_drm_vop2.h   |  2 ++
>  3 files changed, 51 insertions(+)
> 
> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
> index 7c294751de19..7028166fdace 100644
> --- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
> @@ -635,6 +635,9 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
>  		return dev_err_probe(hdmi->dev, PTR_ERR(connector),
>  				     "Failed to init bridge connector\n");
>  
> +	if (!drm_mode_create_hdmi_color_format_property(connector, supported_colorformats))
> +		drm_connector_attach_color_format_property(connector);
> +

Why shouldn't we register the property in drmm_connector_hdmi_init directly?

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 273 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251119/b02780c4/attachment.sig>

From michael.opdenacker at rootcommit.com  Wed Nov 19 01:22:38 2025
From: michael.opdenacker at rootcommit.com (Michael Opdenacker)
Date: Wed, 19 Nov 2025 09:22:38 +0000 (UTC)
Subject: [PATCH] dt-bindings: arm: rockchip: merge Asus Tinker and Tinker S
Message-ID: <20251119-merge-tinker-bindings-v1-1-4072b55750c1@rootcommit.com>

Merge sections for Asus Tinker Board and Asus Tinker Board S.

Asus Tinker Board S (Storage) is just a variant of Tinker Board
with an added eMMC chip.

Signed-off-by: Michael Opdenacker <michael.opdenacker at rootcommit.com>
---
 Documentation/devicetree/bindings/arm/rockchip.yaml | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
index 6aceaa8acbb2..784089f1e245 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.yaml
+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
@@ -78,12 +78,9 @@ properties:
 
       - description: Asus Tinker board
         items:
-          - const: asus,rk3288-tinker
-          - const: rockchip,rk3288
-
-      - description: Asus Tinker board S
-        items:
-          - const: asus,rk3288-tinker-s
+          - enum:
+              - asus,rk3288-tinker
+              - asus,rk3288-tinker-s
           - const: rockchip,rk3288
 
       - description: Beelink A1

---
base-commit: e7c375b181600caf135cfd03eadbc45eb530f2cb
change-id: 20251119-merge-tinker-bindings-f49b05d71fe4

Best regards,
-- 
Michael Opdenacker <michael.opdenacker at rootcommit.com>



From linux at armlinux.org.uk  Wed Nov 19 02:02:56 2025
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 19 Nov 2025 10:02:56 +0000
Subject: [PATCH net-next 0/3] net: stmmac: pass struct device to init/exit
Message-ID: <aR2V0Kib7j0L4FNN@shell.armlinux.org.uk>

Rather than passing the platform device to the ->init() and ->exit()
methods, make these methods useful for other devices by passing the
struct device instead. Update the implementations appropriately for
this change.

Move the calls for these methods into the core driver's probe and
remove methods from the stmmac_platform layer.

Convert dwmac-rk to use ->init() and ->exit().

 .../net/ethernet/stmicro/stmmac/dwmac-anarion.c    |  4 +-
 .../net/ethernet/stmicro/stmmac/dwmac-eic7700.c    |  4 +-
 .../net/ethernet/stmicro/stmmac/dwmac-loongson1.c  | 12 +++---
 .../ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c  |  4 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c     | 47 +++++++++-------------
 drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c    | 14 +++----
 .../net/ethernet/stmicro/stmmac/dwmac-socfpga.c    |  2 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c    |  4 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c  | 10 ++---
 drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c  |  4 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac-thead.c  |  2 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  | 47 ++++++++++++++++------
 .../net/ethernet/stmicro/stmmac/stmmac_platform.c  | 35 +++++-----------
 include/linux/stmmac.h                             |  4 +-
 14 files changed, 94 insertions(+), 99 deletions(-)

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!


From rmk+kernel at armlinux.org.uk  Wed Nov 19 02:03:55 2025
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 19 Nov 2025 10:03:55 +0000
Subject: [PATCH net-next 2/3] net: stmmac: move probe/remove calling of
 init/exit
In-Reply-To: <aR2V0Kib7j0L4FNN@shell.armlinux.org.uk>
References: <aR2V0Kib7j0L4FNN@shell.armlinux.org.uk>
Message-ID: <E1vLf2Z-0000000FMNH-0xPV@rmk-PC.armlinux.org.uk>

Move the probe/remove time calling of the init()/exit() methods in
the platform data to the main driver probe/remove functions. This
allows them to be used by non-platform_device based drivers.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 .../net/ethernet/stmicro/stmmac/stmmac_main.c | 47 ++++++++++++++-----
 .../ethernet/stmicro/stmmac/stmmac_platform.c | 23 +--------
 2 files changed, 36 insertions(+), 34 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 644dccb29f75..aac8188248ff 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -7593,19 +7593,9 @@ struct plat_stmmacenet_data *stmmac_plat_dat_alloc(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(stmmac_plat_dat_alloc);
 
-/**
- * stmmac_dvr_probe
- * @device: device pointer
- * @plat_dat: platform data pointer
- * @res: stmmac resource pointer
- * Description: this is the main probe function used to
- * call the alloc_etherdev, allocate the priv structure.
- * Return:
- * returns 0 on success, otherwise errno.
- */
-int stmmac_dvr_probe(struct device *device,
-		     struct plat_stmmacenet_data *plat_dat,
-		     struct stmmac_resources *res)
+static int __stmmac_dvr_probe(struct device *device,
+			      struct plat_stmmacenet_data *plat_dat,
+			      struct stmmac_resources *res)
 {
 	struct net_device *ndev = NULL;
 	struct stmmac_priv *priv;
@@ -7912,6 +7902,34 @@ int stmmac_dvr_probe(struct device *device,
 
 	return ret;
 }
+
+/**
+ * stmmac_dvr_probe
+ * @dev: device pointer
+ * @plat_dat: platform data pointer
+ * @res: stmmac resource pointer
+ * Description: this is the main probe function used to
+ * call the alloc_etherdev, allocate the priv structure.
+ * Return:
+ * returns 0 on success, otherwise errno.
+ */
+int stmmac_dvr_probe(struct device *dev, struct plat_stmmacenet_data *plat_dat,
+		     struct stmmac_resources *res)
+{
+	int ret;
+
+	if (plat_dat->init) {
+		ret = plat_dat->init(dev, plat_dat->bsp_priv);
+		if (ret)
+			return ret;
+	}
+
+	ret = __stmmac_dvr_probe(dev, plat_dat, res);
+	if (ret && plat_dat->exit)
+		plat_dat->exit(dev, plat_dat->bsp_priv);
+
+	return ret;
+}
 EXPORT_SYMBOL_GPL(stmmac_dvr_probe);
 
 /**
@@ -7950,6 +7968,9 @@ void stmmac_dvr_remove(struct device *dev)
 
 	pm_runtime_disable(dev);
 	pm_runtime_put_noidle(dev);
+
+	if (priv->plat->exit)
+		priv->plat->exit(dev, priv->plat->bsp_priv);
 }
 EXPORT_SYMBOL_GPL(stmmac_dvr_remove);
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index feccb8a3e7e8..9015b7f80d1b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -804,25 +804,12 @@ int stmmac_pltfr_probe(struct platform_device *pdev,
 		       struct plat_stmmacenet_data *plat,
 		       struct stmmac_resources *res)
 {
-	struct device *dev = &pdev->dev;
-	int ret;
-
 	if (!plat->suspend && plat->exit)
 		plat->suspend = stmmac_plat_suspend;
 	if (!plat->resume && plat->init)
 		plat->resume = stmmac_plat_resume;
 
-	ret = stmmac_pltfr_init(dev, plat);
-	if (ret)
-		return ret;
-
-	ret = stmmac_dvr_probe(dev, plat, res);
-	if (ret) {
-		stmmac_pltfr_exit(dev, plat);
-		return ret;
-	}
-
-	return ret;
+	return stmmac_dvr_probe(&pdev->dev, plat, res);
 }
 EXPORT_SYMBOL_GPL(stmmac_pltfr_probe);
 
@@ -864,13 +851,7 @@ EXPORT_SYMBOL_GPL(devm_stmmac_pltfr_probe);
  */
 void stmmac_pltfr_remove(struct platform_device *pdev)
 {
-	struct net_device *ndev = platform_get_drvdata(pdev);
-	struct stmmac_priv *priv = netdev_priv(ndev);
-	struct plat_stmmacenet_data *plat = priv->plat;
-	struct device *dev = &pdev->dev;
-
-	stmmac_dvr_remove(dev);
-	stmmac_pltfr_exit(dev, plat);
+	stmmac_dvr_remove(&pdev->dev);
 }
 EXPORT_SYMBOL_GPL(stmmac_pltfr_remove);
 
-- 
2.47.3



From rmk+kernel at armlinux.org.uk  Wed Nov 19 02:04:00 2025
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 19 Nov 2025 10:04:00 +0000
Subject: [PATCH net-next 3/3] net: stmmac: rk: convert to init()/exit()
 methods
In-Reply-To: <aR2V0Kib7j0L4FNN@shell.armlinux.org.uk>
References: <aR2V0Kib7j0L4FNN@shell.armlinux.org.uk>
Message-ID: <E1vLf2e-0000000FMNN-1Xnh@rmk-PC.armlinux.org.uk>

Convert rk to use the init() and exit() methods for powering up and
down the device. This allows us to use the pltfr versions of probe()
and remove().

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 .../net/ethernet/stmicro/stmmac/dwmac-rk.c    | 47 ++++++++-----------
 1 file changed, 19 insertions(+), 28 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 6e75da577af5..6bfe82d7001a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -1763,6 +1763,22 @@ static int rk_gmac_resume(struct device *dev, void *bsp_priv_)
 	return 0;
 }
 
+static int rk_gmac_init(struct device *dev, void *bsp_priv)
+{
+	return rk_gmac_powerup(bsp_priv);
+}
+
+static void rk_gmac_exit(struct device *dev, void *bsp_priv_)
+{
+	struct stmmac_priv *priv = netdev_priv(dev_get_drvdata(dev));
+	struct rk_priv_data *bsp_priv = bsp_priv_;
+
+	rk_gmac_powerdown(bsp_priv);
+
+	if (priv->plat->phy_node && bsp_priv->integrated_phy)
+		clk_put(bsp_priv->clk_phy);
+}
+
 static int rk_gmac_probe(struct platform_device *pdev)
 {
 	struct plat_stmmacenet_data *plat_dat;
@@ -1795,6 +1811,8 @@ static int rk_gmac_probe(struct platform_device *pdev)
 
 	plat_dat->get_interfaces = rk_get_interfaces;
 	plat_dat->set_clk_tx_rate = rk_set_clk_tx_rate;
+	plat_dat->init = rk_gmac_init;
+	plat_dat->exit = rk_gmac_exit;
 	plat_dat->suspend = rk_gmac_suspend;
 	plat_dat->resume = rk_gmac_resume;
 
@@ -1806,33 +1824,7 @@ static int rk_gmac_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	ret = rk_gmac_powerup(plat_dat->bsp_priv);
-	if (ret)
-		return ret;
-
-	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
-	if (ret)
-		goto err_gmac_powerdown;
-
-	return 0;
-
-err_gmac_powerdown:
-	rk_gmac_powerdown(plat_dat->bsp_priv);
-
-	return ret;
-}
-
-static void rk_gmac_remove(struct platform_device *pdev)
-{
-	struct stmmac_priv *priv = netdev_priv(platform_get_drvdata(pdev));
-	struct rk_priv_data *bsp_priv = priv->plat->bsp_priv;
-
-	stmmac_dvr_remove(&pdev->dev);
-
-	rk_gmac_powerdown(bsp_priv);
-
-	if (priv->plat->phy_node && bsp_priv->integrated_phy)
-		clk_put(bsp_priv->clk_phy);
+	return devm_stmmac_pltfr_probe(pdev, plat_dat, &stmmac_res);
 }
 
 static const struct of_device_id rk_gmac_dwmac_match[] = {
@@ -1858,7 +1850,6 @@ MODULE_DEVICE_TABLE(of, rk_gmac_dwmac_match);
 
 static struct platform_driver rk_gmac_dwmac_driver = {
 	.probe  = rk_gmac_probe,
-	.remove = rk_gmac_remove,
 	.driver = {
 		.name           = "rk_gmac-dwmac",
 		.pm		= &stmmac_simple_pm_ops,
-- 
2.47.3



From rmk+kernel at armlinux.org.uk  Wed Nov 19 02:03:50 2025
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 19 Nov 2025 10:03:50 +0000
Subject: [PATCH net-next 1/3] net: stmmac: pass struct device to init()/exit()
 methods
In-Reply-To: <aR2V0Kib7j0L4FNN@shell.armlinux.org.uk>
References: <aR2V0Kib7j0L4FNN@shell.armlinux.org.uk>
Message-ID: <E1vLf2U-0000000FMN2-0SLg@rmk-PC.armlinux.org.uk>

As struct plat_stmmacenet_data is not platform_device specific, pass
a struct device into the init() and exit() methods to allow them to
become independent of the underlying device.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 .../ethernet/stmicro/stmmac/dwmac-anarion.c   |  4 +--
 .../ethernet/stmicro/stmmac/dwmac-eic7700.c   |  4 +--
 .../ethernet/stmicro/stmmac/dwmac-loongson1.c | 12 ++++----
 .../stmicro/stmmac/dwmac-renesas-gbeth.c      |  4 +--
 .../net/ethernet/stmicro/stmmac/dwmac-s32.c   | 14 +++++-----
 .../ethernet/stmicro/stmmac/dwmac-socfpga.c   |  2 +-
 .../net/ethernet/stmicro/stmmac/dwmac-sti.c   |  4 +--
 .../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 10 +++----
 .../net/ethernet/stmicro/stmmac/dwmac-sunxi.c |  4 +--
 .../net/ethernet/stmicro/stmmac/dwmac-thead.c |  2 +-
 .../ethernet/stmicro/stmmac/stmmac_platform.c | 28 ++++++++++---------
 include/linux/stmmac.h                        |  4 +--
 12 files changed, 47 insertions(+), 45 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c
index 84072c8ed741..5e0fc31762d9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c
@@ -34,7 +34,7 @@ static void gmac_write_reg(struct anarion_gmac *gmac, uint8_t reg, uint32_t val)
 	writel(val, gmac->ctl_block + reg);
 }
 
-static int anarion_gmac_init(struct platform_device *pdev, void *priv)
+static int anarion_gmac_init(struct device *dev, void *priv)
 {
 	uint32_t sw_config;
 	struct anarion_gmac *gmac = priv;
@@ -52,7 +52,7 @@ static int anarion_gmac_init(struct platform_device *pdev, void *priv)
 	return 0;
 }
 
-static void anarion_gmac_exit(struct platform_device *pdev, void *priv)
+static void anarion_gmac_exit(struct device *dev, void *priv)
 {
 	struct anarion_gmac *gmac = priv;
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-eic7700.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-eic7700.c
index 1dcf2037001e..bcb8e000e720 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-eic7700.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-eic7700.c
@@ -58,14 +58,14 @@ static int eic7700_clks_config(void *priv, bool enabled)
 	return ret;
 }
 
-static int eic7700_dwmac_init(struct platform_device *pdev, void *priv)
+static int eic7700_dwmac_init(struct device *dev, void *priv)
 {
 	struct eic7700_qos_priv *dwc = priv;
 
 	return eic7700_clks_config(dwc, true);
 }
 
-static void eic7700_dwmac_exit(struct platform_device *pdev, void *priv)
+static void eic7700_dwmac_exit(struct device *dev, void *priv)
 {
 	struct eic7700_qos_priv *dwc = priv;
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson1.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson1.c
index 894ee66f5c9b..de9aba756aac 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson1.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson1.c
@@ -48,7 +48,7 @@ struct ls1x_dwmac {
 struct ls1x_data {
 	int (*setup)(struct platform_device *pdev,
 		     struct plat_stmmacenet_data *plat_dat);
-	int (*init)(struct platform_device *pdev, void *bsp_priv);
+	int (*init)(struct device *dev, void *bsp_priv);
 };
 
 static int ls1b_dwmac_setup(struct platform_device *pdev,
@@ -79,7 +79,7 @@ static int ls1b_dwmac_setup(struct platform_device *pdev,
 	return 0;
 }
 
-static int ls1b_dwmac_syscon_init(struct platform_device *pdev, void *priv)
+static int ls1b_dwmac_syscon_init(struct device *dev, void *priv)
 {
 	struct ls1x_dwmac *dwmac = priv;
 	struct plat_stmmacenet_data *plat = dwmac->plat_dat;
@@ -98,7 +98,7 @@ static int ls1b_dwmac_syscon_init(struct platform_device *pdev, void *priv)
 					   GMAC0_USE_TXCLK | GMAC0_USE_PWM01);
 			break;
 		default:
-			dev_err(&pdev->dev, "Unsupported PHY mode %u\n",
+			dev_err(dev, "Unsupported PHY mode %u\n",
 				plat->phy_interface);
 			return -EOPNOTSUPP;
 		}
@@ -122,7 +122,7 @@ static int ls1b_dwmac_syscon_init(struct platform_device *pdev, void *priv)
 					   GMAC1_USE_TXCLK | GMAC1_USE_PWM23);
 			break;
 		default:
-			dev_err(&pdev->dev, "Unsupported PHY mode %u\n",
+			dev_err(dev, "Unsupported PHY mode %u\n",
 				plat->phy_interface);
 			return -EOPNOTSUPP;
 		}
@@ -133,7 +133,7 @@ static int ls1b_dwmac_syscon_init(struct platform_device *pdev, void *priv)
 	return 0;
 }
 
-static int ls1c_dwmac_syscon_init(struct platform_device *pdev, void *priv)
+static int ls1c_dwmac_syscon_init(struct device *dev, void *priv)
 {
 	struct ls1x_dwmac *dwmac = priv;
 	struct plat_stmmacenet_data *plat = dwmac->plat_dat;
@@ -143,7 +143,7 @@ static int ls1c_dwmac_syscon_init(struct platform_device *pdev, void *priv)
 	phy_intf_sel = stmmac_get_phy_intf_sel(plat->phy_interface);
 	if (phy_intf_sel != PHY_INTF_SEL_GMII_MII &&
 	    phy_intf_sel != PHY_INTF_SEL_RMII) {
-		dev_err(&pdev->dev, "Unsupported PHY-mode %u\n",
+		dev_err(dev, "Unsupported PHY-mode %u\n",
 			plat->phy_interface);
 		return -EOPNOTSUPP;
 	}
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c
index bc7bb975803c..be7f5eb2cdcf 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c
@@ -91,7 +91,7 @@ static struct phylink_pcs *renesas_gmac_select_pcs(struct stmmac_priv *priv,
 	return priv->hw->phylink_pcs;
 }
 
-static int renesas_gbeth_init(struct platform_device *pdev, void *priv)
+static int renesas_gbeth_init(struct device *dev, void *priv)
 {
 	struct plat_stmmacenet_data *plat_dat;
 	struct renesas_gbeth *gbeth = priv;
@@ -113,7 +113,7 @@ static int renesas_gbeth_init(struct platform_device *pdev, void *priv)
 	return ret;
 }
 
-static void renesas_gbeth_exit(struct platform_device *pdev, void *priv)
+static void renesas_gbeth_exit(struct device *dev, void *priv)
 {
 	struct plat_stmmacenet_data *plat_dat;
 	struct renesas_gbeth *gbeth = priv;
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c
index 2b7ad64bfdf7..5a485ee98fa7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c
@@ -47,7 +47,7 @@ static int s32_gmac_write_phy_intf_select(struct s32_priv_data *gmac)
 	return 0;
 }
 
-static int s32_gmac_init(struct platform_device *pdev, void *priv)
+static int s32_gmac_init(struct device *dev, void *priv)
 {
 	struct s32_priv_data *gmac = priv;
 	int ret;
@@ -55,31 +55,31 @@ static int s32_gmac_init(struct platform_device *pdev, void *priv)
 	/* Set initial TX interface clock */
 	ret = clk_prepare_enable(gmac->tx_clk);
 	if (ret) {
-		dev_err(&pdev->dev, "Can't enable tx clock\n");
+		dev_err(dev, "Can't enable tx clock\n");
 		return ret;
 	}
 	ret = clk_set_rate(gmac->tx_clk, GMAC_INTF_RATE_125M);
 	if (ret) {
-		dev_err(&pdev->dev, "Can't set tx clock\n");
+		dev_err(dev, "Can't set tx clock\n");
 		goto err_tx_disable;
 	}
 
 	/* Set initial RX interface clock */
 	ret = clk_prepare_enable(gmac->rx_clk);
 	if (ret) {
-		dev_err(&pdev->dev, "Can't enable rx clock\n");
+		dev_err(dev, "Can't enable rx clock\n");
 		goto err_tx_disable;
 	}
 	ret = clk_set_rate(gmac->rx_clk, GMAC_INTF_RATE_125M);
 	if (ret) {
-		dev_err(&pdev->dev, "Can't set rx clock\n");
+		dev_err(dev, "Can't set rx clock\n");
 		goto err_txrx_disable;
 	}
 
 	/* Set interface mode */
 	ret = s32_gmac_write_phy_intf_select(gmac);
 	if (ret) {
-		dev_err(&pdev->dev, "Can't set PHY interface mode\n");
+		dev_err(dev, "Can't set PHY interface mode\n");
 		goto err_txrx_disable;
 	}
 
@@ -92,7 +92,7 @@ static int s32_gmac_init(struct platform_device *pdev, void *priv)
 	return ret;
 }
 
-static void s32_gmac_exit(struct platform_device *pdev, void *priv)
+static void s32_gmac_exit(struct device *dev, void *priv)
 {
 	struct s32_priv_data *gmac = priv;
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
index 49d651948e2b..a2b52d2c4eb6 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
@@ -551,7 +551,7 @@ static struct phylink_pcs *socfpga_dwmac_select_pcs(struct stmmac_priv *priv,
 	return priv->hw->phylink_pcs;
 }
 
-static int socfpga_dwmac_init(struct platform_device *pdev, void *bsp_priv)
+static int socfpga_dwmac_init(struct device *dev, void *bsp_priv)
 {
 	struct socfpga_dwmac *dwmac = bsp_priv;
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
index b0509ab6b31c..f50547b67fbc 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
@@ -229,14 +229,14 @@ static int sti_dwmac_parse_data(struct sti_dwmac *dwmac,
 	return 0;
 }
 
-static int sti_dwmac_init(struct platform_device *pdev, void *bsp_priv)
+static int sti_dwmac_init(struct device *dev, void *bsp_priv)
 {
 	struct sti_dwmac *dwmac = bsp_priv;
 
 	return clk_prepare_enable(dwmac->clk);
 }
 
-static void sti_dwmac_exit(struct platform_device *pdev, void *bsp_priv)
+static void sti_dwmac_exit(struct device *dev, void *bsp_priv)
 {
 	struct sti_dwmac *dwmac = bsp_priv;
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
index 7434d4bbb526..8aa496ac85cc 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -571,16 +571,16 @@ static const struct stmmac_dma_ops sun8i_dwmac_dma_ops = {
 
 static int sun8i_dwmac_power_internal_phy(struct stmmac_priv *priv);
 
-static int sun8i_dwmac_init(struct platform_device *pdev, void *priv)
+static int sun8i_dwmac_init(struct device *dev, void *priv)
 {
-	struct net_device *ndev = platform_get_drvdata(pdev);
+	struct net_device *ndev = dev_get_drvdata(dev);
 	struct sunxi_priv_data *gmac = priv;
 	int ret;
 
 	if (gmac->regulator) {
 		ret = regulator_enable(gmac->regulator);
 		if (ret) {
-			dev_err(&pdev->dev, "Fail to enable regulator\n");
+			dev_err(dev, "Fail to enable regulator\n");
 			return ret;
 		}
 	}
@@ -1005,7 +1005,7 @@ static void sun8i_dwmac_unset_syscon(struct sunxi_priv_data *gmac)
 				   (H3_EPHY_SHUTDOWN | H3_EPHY_SELECT));
 }
 
-static void sun8i_dwmac_exit(struct platform_device *pdev, void *priv)
+static void sun8i_dwmac_exit(struct device *dev, void *priv)
 {
 	struct sunxi_priv_data *gmac = priv;
 
@@ -1265,7 +1265,7 @@ static void sun8i_dwmac_shutdown(struct platform_device *pdev)
 	struct stmmac_priv *priv = netdev_priv(ndev);
 	struct sunxi_priv_data *gmac = priv->plat->bsp_priv;
 
-	sun8i_dwmac_exit(pdev, gmac);
+	sun8i_dwmac_exit(&pdev->dev, gmac);
 }
 
 static const struct of_device_id sun8i_dwmac_match[] = {
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
index 7f560d78209d..52593ba3a3a3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
@@ -27,7 +27,7 @@ struct sunxi_priv_data {
 #define SUN7I_GMAC_GMII_RGMII_RATE	125000000
 #define SUN7I_GMAC_MII_RATE		25000000
 
-static int sun7i_gmac_init(struct platform_device *pdev, void *priv)
+static int sun7i_gmac_init(struct device *dev, void *priv)
 {
 	struct sunxi_priv_data *gmac = priv;
 	int ret = 0;
@@ -58,7 +58,7 @@ static int sun7i_gmac_init(struct platform_device *pdev, void *priv)
 	return ret;
 }
 
-static void sun7i_gmac_exit(struct platform_device *pdev, void *priv)
+static void sun7i_gmac_exit(struct device *dev, void *priv)
 {
 	struct sunxi_priv_data *gmac = priv;
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-thead.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-thead.c
index a3378046b061..e291028ba56e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-thead.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-thead.c
@@ -186,7 +186,7 @@ static int thead_dwmac_enable_clk(struct plat_stmmacenet_data *plat)
 	return 0;
 }
 
-static int thead_dwmac_init(struct platform_device *pdev, void *priv)
+static int thead_dwmac_init(struct device *dev, void *priv)
 {
 	struct thead_dwmac *dwmac = priv;
 	unsigned int reg;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 1fefa6c55db1..feccb8a3e7e8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -747,40 +747,40 @@ EXPORT_SYMBOL_GPL(stmmac_get_platform_resources);
 
 /**
  * stmmac_pltfr_init
- * @pdev: pointer to the platform device
+ * @dev: pointer to the device structure
  * @plat: driver data platform structure
  * Description: Call the platform's init callback (if any) and propagate
  * the return value.
  */
-static int stmmac_pltfr_init(struct platform_device *pdev,
+static int stmmac_pltfr_init(struct device *dev,
 			     struct plat_stmmacenet_data *plat)
 {
 	int ret = 0;
 
 	if (plat->init)
-		ret = plat->init(pdev, plat->bsp_priv);
+		ret = plat->init(dev, plat->bsp_priv);
 
 	return ret;
 }
 
 /**
  * stmmac_pltfr_exit
- * @pdev: pointer to the platform device
+ * @dev: pointer to the device structure
  * @plat: driver data platform structure
  * Description: Call the platform's exit callback (if any).
  */
-static void stmmac_pltfr_exit(struct platform_device *pdev,
+static void stmmac_pltfr_exit(struct device *dev,
 			      struct plat_stmmacenet_data *plat)
 {
 	if (plat->exit)
-		plat->exit(pdev, plat->bsp_priv);
+		plat->exit(dev, plat->bsp_priv);
 }
 
 static int stmmac_plat_suspend(struct device *dev, void *bsp_priv)
 {
 	struct stmmac_priv *priv = netdev_priv(dev_get_drvdata(dev));
 
-	stmmac_pltfr_exit(to_platform_device(dev), priv->plat);
+	stmmac_pltfr_exit(dev, priv->plat);
 
 	return 0;
 }
@@ -789,7 +789,7 @@ static int stmmac_plat_resume(struct device *dev, void *bsp_priv)
 {
 	struct stmmac_priv *priv = netdev_priv(dev_get_drvdata(dev));
 
-	return stmmac_pltfr_init(to_platform_device(dev), priv->plat);
+	return stmmac_pltfr_init(dev, priv->plat);
 }
 
 /**
@@ -804,6 +804,7 @@ int stmmac_pltfr_probe(struct platform_device *pdev,
 		       struct plat_stmmacenet_data *plat,
 		       struct stmmac_resources *res)
 {
+	struct device *dev = &pdev->dev;
 	int ret;
 
 	if (!plat->suspend && plat->exit)
@@ -811,13 +812,13 @@ int stmmac_pltfr_probe(struct platform_device *pdev,
 	if (!plat->resume && plat->init)
 		plat->resume = stmmac_plat_resume;
 
-	ret = stmmac_pltfr_init(pdev, plat);
+	ret = stmmac_pltfr_init(dev, plat);
 	if (ret)
 		return ret;
 
-	ret = stmmac_dvr_probe(&pdev->dev, plat, res);
+	ret = stmmac_dvr_probe(dev, plat, res);
 	if (ret) {
-		stmmac_pltfr_exit(pdev, plat);
+		stmmac_pltfr_exit(dev, plat);
 		return ret;
 	}
 
@@ -866,9 +867,10 @@ void stmmac_pltfr_remove(struct platform_device *pdev)
 	struct net_device *ndev = platform_get_drvdata(pdev);
 	struct stmmac_priv *priv = netdev_priv(ndev);
 	struct plat_stmmacenet_data *plat = priv->plat;
+	struct device *dev = &pdev->dev;
 
-	stmmac_dvr_remove(&pdev->dev);
-	stmmac_pltfr_exit(pdev, plat);
+	stmmac_dvr_remove(dev);
+	stmmac_pltfr_exit(dev, plat);
 }
 EXPORT_SYMBOL_GPL(stmmac_pltfr_remove);
 
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index 4f70a6551e68..673b068fdadf 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -264,8 +264,8 @@ struct plat_stmmacenet_data {
 			  unsigned int mode,
 			  phy_interface_t interface);
 	void (*ptp_clk_freq_config)(struct stmmac_priv *priv);
-	int (*init)(struct platform_device *pdev, void *priv);
-	void (*exit)(struct platform_device *pdev, void *priv);
+	int (*init)(struct device *dev, void *priv);
+	void (*exit)(struct device *dev, void *priv);
 	int (*suspend)(struct device *dev, void *priv);
 	int (*resume)(struct device *dev, void *priv);
 	int (*mac_setup)(void *priv, struct mac_device_info *mac);
-- 
2.47.3



From krzk at kernel.org  Wed Nov 19 02:11:51 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Wed, 19 Nov 2025 11:11:51 +0100
Subject: [PATCH] dt-bindings: arm: rockchip: merge Asus Tinker and Tinker
 S
In-Reply-To: <20251119-merge-tinker-bindings-v1-1-4072b55750c1@rootcommit.com>
References: <20251119-merge-tinker-bindings-v1-1-4072b55750c1@rootcommit.com>
Message-ID: <ae967667-26db-41fd-8aec-bdb1f2cdffc8@kernel.org>

On 19/11/2025 10:22, Michael Opdenacker wrote:
> Merge sections for Asus Tinker Board and Asus Tinker Board S.
> 
> Asus Tinker Board S (Storage) is just a variant of Tinker Board
> with an added eMMC chip.
> 
> Signed-off-by: Michael Opdenacker <michael.opdenacker at rootcommit.com>
> ---


Acked-by: Krzysztof Kozlowski <krzk at kernel.org>

Best regards,
Krzysztof


From cassel at kernel.org  Wed Nov 19 03:08:41 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Wed, 19 Nov 2025 12:08:41 +0100
Subject: [PATCH v2 1/4] PCI: dwc: Advertise L1 PM Substates only if
 driver requests it
In-Reply-To: <aRz0ak6onKzZs2lY@lizhi-Precision-Tower-5810>
References: <20251118214312.2598220-1-helgaas@kernel.org>
 <20251118214312.2598220-2-helgaas@kernel.org>
 <aRz0ak6onKzZs2lY@lizhi-Precision-Tower-5810>
Message-ID: <aR2lOZDBEdGVd9On@ryzen>

On Tue, Nov 18, 2025 at 05:34:18PM -0500, Frank Li wrote:
> On Tue, Nov 18, 2025 at 03:42:15PM -0600, Bjorn Helgaas wrote:
> > From: Bjorn Helgaas <bhelgaas at google.com>
> >
> > L1 PM Substates require the CLKREQ# signal and may also require
> > device-specific support.  If CLKREQ# is not supported or driver support is
> > lacking, enabling L1.1 or L1.2 may cause errors when accessing devices,
> > e.g.,
> >
> >   nvme nvme0: controller is down; will reset: CSTS=0xffffffff, PCI_STATUS=0x10
> >
> > If the kernel is built with CONFIG_PCIEASPM_POWER_SUPERSAVE=y or users
> > enable L1.x via sysfs, users may trip over these errors even if L1
> > Substates haven't been enabled by firmware or the driver.
> >
> > To prevent such errors, disable advertising the L1 PM Substates unless the
> > driver sets "dw_pcie.l1ss_support" to indicate that it knows CLKREQ# is
> > present and any device-specific configuration has been done.
> >
> > Set "dw_pcie.l1ss_support" in tegra194 (if DT includes the
> > "supports-clkreq' property) and qcom (for cfg_2_7_0, cfg_1_9_0, cfg_1_34_0,
> > and cfg_sc8280xp controllers) so they can continue to use L1 Substates.
> >
> > Based on Niklas's patch:
> > https://patch.msgid.link/20251017163252.598812-2-cassel at kernel.org
> >
> > Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
> > ---
> >  .../pci/controller/dwc/pcie-designware-ep.c   |  2 ++
> >  .../pci/controller/dwc/pcie-designware-host.c |  2 ++
> >  drivers/pci/controller/dwc/pcie-designware.c  | 24 +++++++++++++++++++
> >  drivers/pci/controller/dwc/pcie-designware.h  |  2 ++
> >  drivers/pci/controller/dwc/pcie-qcom.c        |  2 ++
> >  drivers/pci/controller/dwc/pcie-tegra194.c    |  3 +++
> >  6 files changed, 35 insertions(+)
> >
> > diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
> > index 7f2112c2fb21..ad6c0fd67a65 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> > @@ -966,6 +966,8 @@ int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)
> >  	if (ep->ops->init)
> >  		ep->ops->init(ep);
> >
> > +	dw_pcie_hide_unsupported_l1ss(pci);
> > +
> 
> And, I don't think EP need clean L1SS CAP flags. If EP don't support L1SS,
> it should be force pull down #clkreq.

I think the problem is that we cannot force pull down CLKREQ# in a generic
DWC function. That would have to be done in glue driver specific callbacks.

Bjorn, perhaps we should simply drop the dw_pcie_hide_unsupported_l1ss()
call from dw_pcie_ep_init_registers(), and consider hiding L1ss for EPs to
be out of scope for this series.

That way, we could still queue this series up for 6.19.

Thoughts from everyone?



Kind regards,
Niklas


From rmk+kernel at armlinux.org.uk  Wed Nov 19 03:29:16 2025
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 19 Nov 2025 11:29:16 +0000
Subject: [PATCH net-next] net: stmmac: rk: use phylink's interface mode for
 set_clk_tx_rate()
Message-ID: <E1vLgNA-0000000FMjN-0DSS@rmk-PC.armlinux.org.uk>

rk_set_clk_tx_rate() is passed the interface mode from phylink which
will be the same as bsp_priv->phy_iface. Use the passed-in interface
mode rather than bsp_priv->phy_iface.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 6bfe82d7001a..0a95f54e725e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -1735,8 +1735,7 @@ static int rk_set_clk_tx_rate(void *bsp_priv_, struct clk *clk_tx_i,
 	struct rk_priv_data *bsp_priv = bsp_priv_;
 
 	if (bsp_priv->ops->set_speed)
-		return bsp_priv->ops->set_speed(bsp_priv, bsp_priv->phy_iface,
-						speed);
+		return bsp_priv->ops->set_speed(bsp_priv, interface, speed);
 
 	return -EINVAL;
 }
-- 
2.47.3



From xakep.amatop at gmail.com  Wed Nov 19 03:35:43 2025
From: xakep.amatop at gmail.com (Mykola Kvach)
Date: Wed, 19 Nov 2025 13:35:43 +0200
Subject: [PATCH v3] arm64: dts: rockchip: orangepi-5: fix PCIe 3.3V
 regulator voltage
In-Reply-To: <176307584246.496508.12079514999315183214.b4-ty@sntech.de>
References: <cf6e08dfdfbf1c540685d12388baab1326f95d2c.1762165324.git.xakep.amatop@gmail.com>
 <176307584246.496508.12079514999315183214.b4-ty@sntech.de>
Message-ID: <CAGeoDV_R8GBSs9qjY4772ymU=LsLiP=LTTx2-4uBLkB2PAuVhQ@mail.gmail.com>

On Fri, Nov 14, 2025 at 1:18?AM Heiko Stuebner <heiko at sntech.de> wrote:
>
>
> On Mon, 03 Nov 2025 12:27:40 +0200, Mykola Kvach wrote:
> > The vcc3v3_pcie20 fixed regulator powers the PCIe device-side 3.3V rail
> > for pcie2x1l2 via vpcie3v3-supply. The DTS mistakenly set its
> > regulator-min/max-microvolt to 1800000 (1.8 V). Correct both to 3300000
> > (3.3 V) to match the rail name, the PCIe/M.2 power requirement, and the
> > actual hardware wiring on Orange Pi 5.
> >
> >
> > [...]
>
> Applied, thanks!
>
> [1/1] arm64: dts: rockchip: orangepi-5: fix PCIe 3.3V regulator voltage
>       commit: b5414520793e68d266fdd97a84989d9831156aad
>
> Please start new threads when sending version x+1 and don't append
> that new patch to the old thread (less confusing for tooling like b4).

Got it, thanks for the explanation.

>
> Best regards,
> --
> Heiko Stuebner <heiko at sntech.de>

Best regards,
Mykola


From nicolas.frattaroli at collabora.com  Wed Nov 19 04:41:18 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Wed, 19 Nov 2025 13:41:18 +0100
Subject: [PATCH v4 07/10] drm/display: hdmi-state-helper: Act on color format DRM
 property
In-Reply-To: <4wt5dbvseauo2bvi66ohtk445zsfjtpjwgvochwwlyk4uugcmy@5ubwtkxyy2ax>
References: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
 <20251117-color-format-v4-7-0ded72bd1b00@collabora.com>
 <4wt5dbvseauo2bvi66ohtk445zsfjtpjwgvochwwlyk4uugcmy@5ubwtkxyy2ax>
Message-ID: <7179523.lOV4Wx5bFT@workhorse>

On Wednesday, 19 November 2025 10:09:12 Central European Standard Time Maxime Ripard wrote:
> Hi,
> 
> On Mon, Nov 17, 2025 at 08:11:51PM +0100, Nicolas Frattaroli wrote:
> > With the introduction of the "color format" DRM property, which allows
> > userspace to request a specific color format, the HDMI state helper
> > should implement this.
> > 
> > Implement it by checking whether the property is set and set to
> > something other than auto. If so, pass the requested color format, and
> > otherwise set RGB.
> > 
> > Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
> > ---
> >  drivers/gpu/drm/display/drm_hdmi_state_helper.c | 8 +++++++-
> >  1 file changed, 7 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> > index a561f124be99..add0d51fce33 100644
> > --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> > +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> > @@ -650,9 +650,15 @@ hdmi_compute_config(const struct drm_connector *connector,
> >  				       conn_state->max_bpc,
> >  				       8, connector->max_bpc);
> >  	int ret;
> > +	enum hdmi_colorspace hdmi_colorspace;
> > +
> > +	if (conn_state->color_format && conn_state->color_format != DRM_COLOR_FORMAT_AUTO)
> > +		hdmi_colorspace = color_format_to_hdmi_colorspace(conn_state->color_format);
> > +	else
> > +		hdmi_colorspace = HDMI_COLORSPACE_RGB;
> >  
> >  	ret = hdmi_compute_format_bpc(connector, conn_state, mode, max_bpc,
> > -				      HDMI_COLORSPACE_RGB);
> > +				      hdmi_colorspace);
> 
> I don't think we want the fallback to yuv420 for anything but auto, so

Okay. Changing all the non-hdmi-state-helper drivers (amdgpu, i915)
to do this as well would require some more work however, especially
in the case of amdgpu where the code flow is not always obvious.

> I'd rather have something like
> 
> if (conn_state->color_format != DRM_COLOR_FORMAT_AUTO)
>    return hdmi_compute_format_bpc(connector, conn_state, mode, max_bpc,
>                                   color_format_to_hdmi_colorspace(conn_state->color_format))
> 
> We'll also need unit tests.

Sure, am I guessing correctly that they'd go in
drm_hdmi_state_helper_test.c?

> Maxime
> 






From nicolas.frattaroli at collabora.com  Wed Nov 19 04:48:13 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Wed, 19 Nov 2025 13:48:13 +0100
Subject: [PATCH v4 03/10] drm: Add enum conversion from/to HDMI_COLORSPACE to
 DRM_COLOR_FORMAT
In-Reply-To: <20251119041648.GD10711@pendragon.ideasonboard.com>
References: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
 <20251117-color-format-v4-3-0ded72bd1b00@collabora.com>
 <20251119041648.GD10711@pendragon.ideasonboard.com>
Message-ID: <3356228.ElGaqSPkdT@workhorse>

On Wednesday, 19 November 2025 05:16:48 Central European Standard Time Laurent Pinchart wrote:
> On Mon, Nov 17, 2025 at 08:11:47PM +0100, Nicolas Frattaroli wrote:
> > From: Marius Vlad <marius.vlad at collabora.com>
> > 
> > This would please the compiler to have a enum transformation from one to
> > another even though the values are the same. It should also make things
> 
> The hdmi_colorspace enumerators are defined as (with comments added to
> make the values explicit)
> 
> enum hdmi_colorspace {
> 	HDMI_COLORSPACE_RGB,			/* 0 */
> 	HDMI_COLORSPACE_YUV422,			/* 1 */
> 	HDMI_COLORSPACE_YUV444,			/* 2 */
> 	HDMI_COLORSPACE_YUV420,			/* 3 */
> 	HDMI_COLORSPACE_RESERVED4,		/* 4 */
> 	HDMI_COLORSPACE_RESERVED5,		/* 5 */
> 	HDMI_COLORSPACE_RESERVED6,		/* 6 */
> 	HDMI_COLORSPACE_IDO_DEFINED,		/* 7 */
> };
> 
> and the DRM color formats as (after patch 02/10)
> 
> enum drm_color_format {
> 	DRM_COLOR_FORMAT_NONE			= 0,		/* 0 */
> 	DRM_COLOR_FORMAT_RGB444			= (1 << 0),	/* 1 */
> 	DRM_COLOR_FORMAT_YCBCR422		= (1 << 1),	/* 2 */
> 	DRM_COLOR_FORMAT_YCBCR444		= (1 << 2),	/* 4 */
> 	DRM_COLOR_FORMAT_YCBCR420		= (1 << 3),	/* 8 */
> 	/* auto case, driver will set the color_format */
> 	DRM_COLOR_FORMAT_AUTO			= (1 << 4),	/* 16 */
> };
> 
> Contrary to what is stated in the commit message, the values are not the
> same. Maybe you confused DRM_COLOR_FORMAT_* with DRM_MODE_COLOR_FORMAT_*
> ?

It's possible the equality got lost during my refactor, but I think
the needless enum conversions between like 4 different things should
be minimised anyway, so I'll look into getting rid of as much of this
as possible.

> 
> > obvious that we use different enums.
> > 
> > Signed-off-by: Marius Vlad <marius.vlad at collabora.com>
> > ---
> >  drivers/gpu/drm/drm_connector.c | 18 ++++++++++++++++++
> >  include/drm/drm_connector.h     |  3 +++
> >  2 files changed, 21 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> > index 0ad7be0a2d09..61c077b67ac3 100644
> > --- a/drivers/gpu/drm/drm_connector.c
> > +++ b/drivers/gpu/drm/drm_connector.c
> > @@ -1384,6 +1384,24 @@ drm_color_format_enum_to_color_format(enum drm_color_format_enum fmt_enum)
> >  	}
> >  }
> >  
> > +enum hdmi_colorspace
> > +color_format_to_hdmi_colorspace(enum drm_color_format fmt)
> > +{
> > +	switch (fmt) {
> > +	default:
> > +	case DRM_COLOR_FORMAT_AUTO:
> > +	case DRM_COLOR_FORMAT_RGB444:
> > +		return HDMI_COLORSPACE_RGB;
> > +	case DRM_COLOR_FORMAT_YCBCR444:
> > +		return HDMI_COLORSPACE_YUV444;
> > +	case DRM_COLOR_FORMAT_YCBCR422:
> > +		return HDMI_COLORSPACE_YUV422;
> > +	case DRM_COLOR_FORMAT_YCBCR420:
> > +		return HDMI_COLORSPACE_YUV420;
> > +	}
> > +}
> > +EXPORT_SYMBOL(color_format_to_hdmi_colorspace);
> > +
> >  /**
> >   * drm_get_color_format_name - return a string for color format
> >   * @colorspace: color format to compute name of
> > diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> > index a071079fd3ad..e044976c8d76 100644
> > --- a/include/drm/drm_connector.h
> > +++ b/include/drm/drm_connector.h
> > @@ -2586,6 +2586,9 @@ drm_color_format_to_color_format_enum(enum drm_color_format fmt);
> >  u32
> >  drm_color_format_enum_to_color_format(enum drm_color_format_enum fmt_enum);
> >  
> > +enum hdmi_colorspace
> > +color_format_to_hdmi_colorspace(enum drm_color_format fmt);
> > +
> >  /**
> >   * drm_for_each_connector_iter - connector_list iterator macro
> >   * @connector: &struct drm_connector pointer used as cursor
> 
> 






From nicolas.frattaroli at collabora.com  Wed Nov 19 04:50:51 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Wed, 19 Nov 2025 13:50:51 +0100
Subject: [PATCH v4 04/10] drm/bridge: Act on the DRM color format property
In-Reply-To: <20251119043246.GY10711@pendragon.ideasonboard.com>
References: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
 <20251117-color-format-v4-4-0ded72bd1b00@collabora.com>
 <20251119043246.GY10711@pendragon.ideasonboard.com>
Message-ID: <3210678.irdbgypaU6@workhorse>

On Wednesday, 19 November 2025 05:32:46 Central European Standard Time Laurent Pinchart wrote:
> On Mon, Nov 17, 2025 at 08:11:48PM +0100, Nicolas Frattaroli wrote:
> > The new DRM color format property allows userspace to request a specific
> > color format on a connector. In turn, this fills the connector state's
> > color_format member to switch color formats.
> > 
> > Make drm_bridges consider the color_format set in the connector state
> > during the atomic bridge check. Specifically, reject any output bus
> > formats that do not correspond to the requested color format.
> > 
> > Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
> > ---
> >  drivers/gpu/drm/drm_bridge.c | 57 ++++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 57 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
> > index 8f355df883d8..b7df5cbad832 100644
> > --- a/drivers/gpu/drm/drm_bridge.c
> > +++ b/drivers/gpu/drm/drm_bridge.c
> > @@ -1052,6 +1052,59 @@ static int select_bus_fmt_recursive(struct drm_bridge *first_bridge,
> >  	return ret;
> >  }
> >  
> > +static bool __pure bus_format_is_color_fmt(u32 bus_fmt, enum drm_color_format fmt)
> > +{
> > +	if (bus_fmt == MEDIA_BUS_FMT_FIXED)
> > +		return true;
> > +
> > +	switch (fmt) {
> > +	case DRM_COLOR_FORMAT_NONE:
> > +	case DRM_COLOR_FORMAT_AUTO:
> > +		return true;
> > +	case DRM_COLOR_FORMAT_RGB444:
> > +		switch (bus_fmt) {
> > +		case MEDIA_BUS_FMT_RGB888_1X24:
> > +		case MEDIA_BUS_FMT_RGB101010_1X30:
> > +		case MEDIA_BUS_FMT_RGB121212_1X36:
> > +		case MEDIA_BUS_FMT_RGB161616_1X48:
> > +			return true;
> > +		default:
> > +			return false;
> > +		}
> > +	case DRM_COLOR_FORMAT_YCBCR444:
> > +		switch (bus_fmt) {
> > +		case MEDIA_BUS_FMT_YUV8_1X24:
> > +		case MEDIA_BUS_FMT_YUV10_1X30:
> > +		case MEDIA_BUS_FMT_YUV12_1X36:
> > +		case MEDIA_BUS_FMT_YUV16_1X48:
> > +			return true;
> > +		default:
> > +			return false;
> > +		}
> > +	case DRM_COLOR_FORMAT_YCBCR422:
> > +		switch (bus_fmt) {
> > +		case MEDIA_BUS_FMT_UYVY8_1X16:
> > +		case MEDIA_BUS_FMT_UYVY10_1X20:
> > +		case MEDIA_BUS_FMT_UYVY12_1X24:
> > +			return true;
> > +		default:
> > +			return false;
> > +		}
> > +	case DRM_COLOR_FORMAT_YCBCR420:
> > +		switch (bus_fmt) {
> > +		case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
> > +		case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
> > +		case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
> > +		case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
> > +			return true;
> > +		default:
> > +			return false;
> > +		}
> > +	}
> 
> I'd find this more readable:
> 
> 	if (fmt == DRM_COLOR_FORMAT_NONE || fmt == DRM_COLOR_FORMAT_AUTO)
> 		return true;
> 
> 	switch (bus_fmt) {
> 	case MEDIA_BUS_FMT_RGB888_1X24:
> 	case MEDIA_BUS_FMT_RGB101010_1X30:
> 	case MEDIA_BUS_FMT_RGB121212_1X36:
> 	case MEDIA_BUS_FMT_RGB161616_1X48:
> 		return fmt == DRM_COLOR_FORMAT_RGB444:
> 
> 	case MEDIA_BUS_FMT_YUV8_1X24:
> 	case MEDIA_BUS_FMT_YUV10_1X30:
> 	case MEDIA_BUS_FMT_YUV12_1X36:
> 	case MEDIA_BUS_FMT_YUV16_1X48:
> 		return fmt == DRM_COLOR_FORMAT_YCBCR444;
> 
> 	case MEDIA_BUS_FMT_UYVY8_1X16:
> 	case MEDIA_BUS_FMT_UYVY10_1X20:
> 	case MEDIA_BUS_FMT_UYVY12_1X24:
> 		return fmt == DRM_COLOR_FORMAT_YCBCR422;
> 
> 	case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
> 	case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
> 	case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
> 	case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
> 		return fmt == DRM_COLOR_FORMAT_YCBCR420;
> 
> 	default:
> 		return false;
> 	}
> 
> but it could be a matter for personal preference ?

I agree, that is nicer.

> 
> I'm also a bit concerned about the 
> 
> 	if (fmt == DRM_COLOR_FORMAT_NONE || fmt == DRM_COLOR_FORMAT_AUTO)
> 
> test. What's the difference between NONE and AUTO ? Is it meaningful, or
> should the two enumerators be merged into a single one ?

I've noticed that as well but didn't act on it before sending out v4.
I think we should try to make them the same yes. I don't see a valid
reason why anything would ever set "NONE" when it means "AUTO". If
there is a non-AUTO "NONE" case to describe an invalid format, then
this code is wrong anyways. I'll do some digging.

> > +
> > +	return false;
> > +}
> > +
> >  /*
> >   * This function is called by &drm_atomic_bridge_chain_check() just before
> >   * calling &drm_bridge_funcs.atomic_check() on all elements of the chain.
> > @@ -1137,6 +1190,10 @@ drm_atomic_bridge_chain_select_bus_fmts(struct drm_bridge *bridge,
> >  	}
> >  
> >  	for (i = 0; i < num_out_bus_fmts; i++) {
> > +		if (!bus_format_is_color_fmt(out_bus_fmts[i], conn_state->color_format)) {
> > +			ret = -ENOTSUPP;
> > +			continue;
> > +		}
> >  		ret = select_bus_fmt_recursive(bridge, last_bridge, crtc_state,
> >  					       conn_state, out_bus_fmts[i]);
> >  		if (ret != -ENOTSUPP)
> 
> 






From kamil.konieczny at linux.intel.com  Wed Nov 19 05:21:49 2025
From: kamil.konieczny at linux.intel.com (Kamil Konieczny)
Date: Wed, 19 Nov 2025 14:21:49 +0100
Subject: [PATCH i-g-t] tests: (Re)add kms_crtc_background_color test
In-Reply-To: <20251110-crtc-bgcolor-v1-1-28669b692970@collabora.com>
References: <20251110-crtc-bgcolor-v1-1-28669b692970@collabora.com>
Message-ID: <20251119132149.spbl5k3dmj2lwzon@kamilkon-DESK.igk.intel.com>

Hi Cristian,
On 2025-11-10 at 15:18:05 +0200, Cristian Ciocaltea wrote:
> Provide test to verify the behavior of BACKGROUND_COLOR DRM CRTC
> property.
> 
> This is done by filling a full-screen primary plane with a given color
> and comparing the resulting CRC with the one obtained after turning off
> all planes while having the CRTC background set to the same color.
> 
> It's worth noting this is a reworked version of the test that has been
> dropped over 5 years ago via commit 33f07391e5f6 ("tests: Remove
> kms_crtc_background_color test"), as the required kernel changes never
> landed because of missing userspace support.
> 
+cc J-P, Karthik, Swati
Cc: Juha-Pekka Heikkila <juhapekka.heikkila at gmail.com>
Cc: Juha-Pekka Heikkila <juha-pekka.heikkila at intel.com>
Cc: Karthik B S <karthik.b.s at intel.com>
Cc: Swati Sharma <swati2.sharma at intel.com>

I have few nits, see below.

> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
> ---
> This has been tested on a Radxa ROCK 5B board which is based on Rockchip
> RK3588 SoC.  It relies on the kernel series [1] introducing the
> BACKGROUND_COLOR CRTC property and a few additional patches from [2]
> enabling the required CRC functionality for the Rockchip platform (still
> require a bit more work before sending those upstream).
> 
> It's worth noting CRC is only supported by the display controller (VOP2)
> present in the RK3576 SoC variant.  However, the computation is done by
> the hardware before applying the background color, hence it has limited
> usage in IGT testing.
> 
> Luckily, the frame CRCs can be captured through DPCD, i.e. at
> DisplayPort AUX channel level, hence I used the USB-C DP AltMode capable
> port of the aforementioned board to perform the actual validation.
> 
> [1] https://lore.kernel.org/all/20251013-rk3588-bgcolor-v2-0-25cc3810ba8c at collabora.com/
> [2] https://gitlab.collabora.com/hardware-enablement/rockchip-3588/linux/-/commits/cristicc/rk3588-vop2-crc
> 
> root at rock5b$ cat /sys/kernel/debug/dri/1/vop2/summary
> 
> cat /sys/kernel/debug/dri/1/vop2/summary
> Video Port0: DISABLED
> Video Port1: DISABLED
> Video Port2: ACTIVE
>     Connector: DP-1
> 	bus_format[1018]: RGB101010_1X30
> 	output_mode[f] color_space[0]
> 	background color (10bpc): r=0x0 g=0x0 b=0x0
>     Display mode: 3840x2160p60
> 	clk[594000] real_clk[594000] type[48] flag[9]
> 	H: 3840 4016 4104 4400
> 	V: 2160 2164 2174 2250
>     Cluster2-win0: ACTIVE
> 	win_id: 2
> 	format: XR24 little-endian (0x34325258) glb_alpha[0xff]
> 	rotate: xmirror: 0 ymirror: 0 rotate_90: 0 rotate_270: 0
> 	zpos: 0
> 	src: pos[0, 0] rect[3840 x 2160]
> 	dst: pos[0, 0] rect[3840 x 2160]
> 	buf[0]: addr: 0x0000000000000000 pitch: 15360 offset: 0
> 
> root at rock5b$ ./kms_crtc_background_color --device drm:/dev/dri/card1
> 
> IGT-Version: 2.2-g3e4ec308e (aarch64) (Linux: 6.18.0-rc1 aarch64)
> Using IGT_SRANDOM=1762774806 for randomisation
> Opened device: /dev/dri/card1
> Starting subtest: background-color-red
> Starting dynamic subtest: pipe-C-DP-1
> Dynamic subtest pipe-C-DP-1: SUCCESS (0.491s)
> Subtest background-color-red: SUCCESS (0.493s)
> Starting subtest: background-color-green
> Starting dynamic subtest: pipe-C-DP-1
> Dynamic subtest pipe-C-DP-1: SUCCESS (0.533s)
> Subtest background-color-green: SUCCESS (0.535s)
> Starting subtest: background-color-blue
> Starting dynamic subtest: pipe-C-DP-1
> Dynamic subtest pipe-C-DP-1: SUCCESS (0.541s)
> Subtest background-color-blue: SUCCESS (0.544s)
> Starting subtest: background-color-yellow
> Starting dynamic subtest: pipe-C-DP-1
> Dynamic subtest pipe-C-DP-1: SUCCESS (0.535s)
> Subtest background-color-yellow: SUCCESS (0.537s)
> Starting subtest: background-color-purple
> Starting dynamic subtest: pipe-C-DP-1
> Dynamic subtest pipe-C-DP-1: SUCCESS (0.536s)
> Subtest background-color-purple: SUCCESS (0.538s)
> Starting subtest: background-color-cyan
> Starting dynamic subtest: pipe-C-DP-1
> Dynamic subtest pipe-C-DP-1: SUCCESS (0.539s)
> Subtest background-color-cyan: SUCCESS (0.541s)
> Starting subtest: background-color-black
> Starting dynamic subtest: pipe-C-DP-1
> (kms_crtc_background_color:744) igt_pipe_crc-WARNING: Warning on condition all_zero in function crc_sanity_checks, file ../lib/igt_pipe_crc.c:475
> (kms_crtc_background_color:744) igt_pipe_crc-WARNING: Suspicious CRC: All values are 0.
> (kms_crtc_background_color:744) igt_pipe_crc-WARNING: Warning on condition all_zero in function crc_sanity_checks, file ../lib/igt_pipe_crc.c:475
> (kms_crtc_background_color:744) igt_pipe_crc-WARNING: Suspicious CRC: All values are 0.
> Dynamic subtest pipe-C-DP-1: SUCCESS (0.535s)
> Subtest background-color-black: SUCCESS (0.537s)
> Starting subtest: background-color-white
> Starting dynamic subtest: pipe-C-DP-1
> Dynamic subtest pipe-C-DP-1: SUCCESS (0.540s)
> Subtest background-color-white: SUCCESS (0.542s)
> ---
>  lib/igt_kms.c                     |   1 +
>  lib/igt_kms.h                     |   3 +-
>  tests/kms_crtc_background_color.c | 139 ++++++++++++++++++++++++++++++++++++++
>  tests/meson.build                 |   1 +
>  4 files changed, 143 insertions(+), 1 deletion(-)
> 
> diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> index 9208c8dbfc86..7c0848865038 100644
> --- a/lib/igt_kms.c
> +++ b/lib/igt_kms.c
> @@ -705,6 +705,7 @@ const char * const igt_plane_prop_names[IGT_NUM_PLANE_PROPS] = {
>  };
>  
>  const char * const igt_crtc_prop_names[IGT_NUM_CRTC_PROPS] = {
> +	[IGT_CRTC_BACKGROUND] = "BACKGROUND_COLOR",
>  	[IGT_CRTC_CTM] = "CTM",
>  	[IGT_CRTC_GAMMA_LUT] = "GAMMA_LUT",
>  	[IGT_CRTC_GAMMA_LUT_SIZE] = "GAMMA_LUT_SIZE",
> diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> index eff76f0de0b3..a19f8d126a8d 100644
> --- a/lib/igt_kms.h
> +++ b/lib/igt_kms.h
> @@ -156,7 +156,8 @@ void kmstest_restore_vt_mode(void);
>  void kmstest_set_vt_text_mode(void);
>  
>  enum igt_atomic_crtc_properties {
> -       IGT_CRTC_CTM = 0,
> +       IGT_CRTC_BACKGROUND = 0,
> +       IGT_CRTC_CTM,
>         IGT_CRTC_GAMMA_LUT,
>         IGT_CRTC_GAMMA_LUT_SIZE,
>         IGT_CRTC_DEGAMMA_LUT,
> diff --git a/tests/kms_crtc_background_color.c b/tests/kms_crtc_background_color.c
> new file mode 100644
> index 000000000000..4e6d183b736d
> --- /dev/null
> +++ b/tests/kms_crtc_background_color.c
> @@ -0,0 +1,139 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright ? 2013,2014 Intel Corporation
> + * Copyright ? 2025 Collabora, Ltd.
> + */
> +

Please add here:

/**
 * TEST: crtc background color
 * Category: Display
 * Description: Test background color feature with CRC at CRTC
 * Driver requirement: i915, xe
 * Mega feature: General Display Features
 */

Feel free to correct me with name and/or description.
Karthik or Swati, please also correct this if I made any
mistake here.

> +#include "igt.h"
> +
> +IGT_TEST_DESCRIPTION("Test crtc background color feature");
> +
> +typedef struct {
> +	int drm_fd;
> +	int debugfs;
> +	igt_display_t display;
> +} data_t;
> +
> +#define __DRM_ARGB64_PREP(c, shift, bpc)			\
> +	(((__u64)(c) << (16 - (bpc)) & 0xffffU) << (shift))
> +
> +#define DRM_ARGB64_PREP_BPC(alpha, red, green, blue, bpc)	\
> +	(__DRM_ARGB64_PREP(alpha, 48, bpc) |			\
> +	 __DRM_ARGB64_PREP(red,   32, bpc) |			\
> +	 __DRM_ARGB64_PREP(green, 16, bpc) |			\
> +	 __DRM_ARGB64_PREP(blue,   0, bpc))
> +
> +static void test_background(data_t *data, enum pipe pipe, igt_output_t *output,
> +			    __u16 red, __u16 green, __u16 blue)
> +{
> +	igt_display_t *display = &data->display;
> +	igt_crc_t plane_crc, bg_crc;
> +	igt_pipe_crc_t *pipe_crc;
> +	igt_plane_t *plane;
> +	drmModeModeInfo *mode;
> +	struct igt_fb fb;
> +
> +	igt_display_reset(display);
> +
> +	igt_output_set_pipe(output, pipe);
> +	mode = igt_output_get_mode(output);
> +
> +	plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
> +
> +	/* Fill the primary plane and set the background to the same color */
> +	igt_create_color_fb(data->drm_fd,
> +			    mode->hdisplay, mode->vdisplay,
> +			    DRM_FORMAT_XRGB8888,
> +			    DRM_FORMAT_MOD_NONE,
> +			    (double)red / 0xffff,
> +			    (double)green / 0xffff,
> +			    (double)blue / 0xffff,
> +			    &fb);
> +
> +	igt_plane_set_fb(plane, &fb);
> +	igt_pipe_set_prop_value(&data->display, pipe, IGT_CRTC_BACKGROUND,
> +				DRM_ARGB64_PREP_BPC(0xffff, red, green, blue, 8));
> +	igt_display_commit2(&data->display, COMMIT_ATOMIC);
> +
> +	pipe_crc = igt_pipe_crc_new(data->drm_fd, pipe, IGT_PIPE_CRC_SOURCE_AUTO);
> +	igt_pipe_crc_collect_crc(pipe_crc, &plane_crc);
> +
> +	/* Turn off the primary plane so that only the background is visible */
> +	igt_plane_set_fb(plane, NULL);
> +	igt_display_commit2(&data->display, COMMIT_ATOMIC);
> +	igt_pipe_crc_collect_crc(pipe_crc, &bg_crc);
> +
> +	/*
> +	 * The test assumes hardware is able to generate valid CRCs when setting
> +	 * the background color. Some platforms, e.g. Intel, might require at
> +	 * least one plane to be visible before reading the pipe-level ("dmux")
> +	 * CRC. Other platforms, e.g. Rockchip, do not take background color
> +	 * into account when computing CRC at CRTC level.
> +	 * A possible workaround would be to use alternative CRC sources, e.g.
> +	 * where computation is performed at encoder or sink level.
> +	 */
> +	igt_assert_crc_equal(&plane_crc, &bg_crc);
> +
> +	/* Clean-up */
> +	igt_pipe_set_prop_value(&data->display, pipe, IGT_CRTC_BACKGROUND,
> +				DRM_ARGB64_PREP_BPC(0xffff, 0, 0, 0, 8));
> +	igt_pipe_crc_free(pipe_crc);
> +	igt_output_set_pipe(output, PIPE_NONE);
> +	igt_display_commit(display);
> +	igt_remove_fb(data->drm_fd, &fb);
> +}
> +

Add here:

/**
 * SUBTEST: background-color-%s
 * Description: Tests %arg[1] in background color
 *
 * arg[1]:
 *
 * @red:      red
 * @green:    green
 * @blue:     blue
 * @yellow:   yellow
 * @purple:   purple
 * @cyan:     cyan
 * @black:    black
 * @white:    white
 */

With this it will compile and will be tested by Intel CI.

Regards,
Kamil

> +igt_main
> +{
> +	igt_output_t *output;
> +	data_t data = {};
> +	enum pipe pipe;
> +	int i;
> +
> +	struct {
> +		const char *color;
> +		__u16 red;
> +		__u16 green;
> +		__u16 blue;
> +	} tests[] = {
> +		{ "red",    0xffff, 0x0000, 0x0000, },
> +		{ "green",  0x0000, 0xffff, 0x0000, },
> +		{ "blue",   0x0000, 0x0000, 0xffff, },
> +		{ "yellow", 0xffff, 0xffff, 0x0000, },
> +		{ "purple", 0xffff, 0x0000, 0xffff, },
> +		{ "cyan",   0x0000, 0xffff, 0xffff, },
> +		{ "black",  0x0000, 0x0000, 0x0000, },
> +		{ "white",  0xffff, 0xffff, 0xffff, },
> +	};
> +
> +	igt_fixture {
> +		data.drm_fd = drm_open_driver_master(DRIVER_ANY);
> +
> +		kmstest_set_vt_graphics_mode();
> +
> +		igt_display_require(&data.display, data.drm_fd);
> +		igt_display_require_output(&data.display);
> +		igt_require_pipe_crc(data.drm_fd);
> +
> +		data.debugfs = igt_debugfs_dir(data.drm_fd);
> +	}
> +
> +	for (i = 0; i < ARRAY_SIZE(tests); i++) {
> +		igt_describe_f("Test crtc background color %s", tests[i].color);
> +		igt_subtest_with_dynamic_f("background-color-%s", tests[i].color) {
> +			for_each_pipe_with_single_output(&data.display, pipe, output) {
> +				igt_require(igt_pipe_has_prop(&data.display, pipe,
> +							      IGT_CRTC_BACKGROUND));
> +
> +				igt_dynamic_f("pipe-%s-%s", kmstest_pipe_name(pipe), output->name)
> +					test_background(&data, pipe, output, tests[i].red,
> +							tests[i].green, tests[i].blue);
> +			}
> +		}
> +	}
> +
> +	igt_fixture {
> +		igt_display_fini(&data.display);
> +		drm_close_driver(data.drm_fd);
> +	}
> +}
> diff --git a/tests/meson.build b/tests/meson.build
> index 9736f2338507..06827b41a00c 100644
> --- a/tests/meson.build
> +++ b/tests/meson.build
> @@ -27,6 +27,7 @@ test_progs = [
>  	'kms_color',
>  	'kms_concurrent',
>  	'kms_content_protection',
> +	'kms_crtc_background_color',
>  	'kms_cursor_crc',
>  	'kms_cursor_edge_walk',
>  	'kms_cursor_legacy',
> 
> ---
> base-commit: 862eb176244feac8ee711f381fe1be1fdc6a7ede
> change-id: 20251110-crtc-bgcolor-f6ed9a58e0bf
> 


From nicolas.frattaroli at collabora.com  Wed Nov 19 05:32:45 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Wed, 19 Nov 2025 14:32:45 +0100
Subject: [PATCH v4 05/10] drm/bridge: dw-hdmi-qp: Set bridge supported_formats
In-Reply-To: <3863e0e5-677b-4225-9854-3ee420828275@collabora.com>
References: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
 <20251117-color-format-v4-5-0ded72bd1b00@collabora.com>
 <3863e0e5-677b-4225-9854-3ee420828275@collabora.com>
Message-ID: <4348284.aeNJFYEL58@workhorse>

On Tuesday, 18 November 2025 21:00:08 Central European Standard Time Cristian Ciocaltea wrote:
> Hi Nicolas,
> 
> On 11/17/25 9:11 PM, Nicolas Frattaroli wrote:
> > The drm_bridge "supported_formats" member stores a bitmask of supported
> > HDMI output formats if the bridge is in fact an HDMI bridge.
> > 
> > However, until now, the synopsys dw-hdmi-qp driver did not set this
> > member in the bridge it creates.
> > 
> > Set it based on the platform data's supported_formats member, and
> > default to BIT(HDMI_COLORSPACE_RGB) if it's absent, which preserves the
> > previous behaviour.
> > 
> > Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
> > ---
> >  drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 5 +++++
> >  1 file changed, 5 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
> > index fe4c026280f0..cf888236bd65 100644
> > --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
> > +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
> > @@ -1269,6 +1269,11 @@ struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev,
> >  		dev_warn(dev, "Set ref_clk_rate to vendor default\n");
> >  	}
> >  
> > +	if (plat_data->supported_formats)
> > +		hdmi->bridge.supported_formats = plat_data->supported_formats;
> 
> This duplicates a change already introduced via commit 1ff27c5929ab
> ("drm/bridge: dw-hdmi-qp: Handle platform supported formats and color depth").

Hmm, looks like I didn't notice that when rebasing onto next-20251117.

(Aside note, that commit is once again lacking from next-20251119,
did it get dropped for some reason or did DRM as a whole not get
pulled into that next version due to a conflict?)

> 
> > +	else
> > +		hdmi->bridge.supported_formats = BIT(HDMI_COLORSPACE_RGB);
> 
> And this one looks redundant as well, since RGB is supposed to be mandatory:
> supported_formats defaults to RGB in drm_bridge_connector_init() if there's no
> HDMI bridge in the pipeline overriding it, while drmm_connector_hdmi_init()
> errors out if supported_formats is unset or doesn't advertise RGB.

Oops, yeah you're right

> 
> Hence I think this patch can be dropped.

Will do! Thanks for the quick review

> 
> Regards,
> Cristian
> 
> 






From nicolas.frattaroli at collabora.com  Wed Nov 19 05:37:51 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Wed, 19 Nov 2025 14:37:51 +0100
Subject: [PATCH v4 06/10] drm/rockchip: dw_hdmi_qp: Set supported_formats platdata
In-Reply-To: <edc12051-6e50-4ef6-98cf-713abb49dd90@collabora.com>
References: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
 <20251117-color-format-v4-6-0ded72bd1b00@collabora.com>
 <edc12051-6e50-4ef6-98cf-713abb49dd90@collabora.com>
Message-ID: <11723230.nUPlyArG6x@workhorse>

On Tuesday, 18 November 2025 21:14:31 Central European Standard Time Cristian Ciocaltea wrote:
> On 11/17/25 9:11 PM, Nicolas Frattaroli wrote:
> > With the introduction of the supported_formats member in the
> > dw-hdmi-qp platform data struct, drivers that have access to this
> > information should now set it.
> > 
> > Set it in the rockchip dw_hdmi_qp glue driver, where such a bitmask of
> > supported color formats already exists. It just needs to be converted to
> > the appropriate HDMI_COLORSPACE_ mask.
> > 
> > This allows this information to be passed down to the dw-hdmi-qp core,
> > which sets it in the bridge it creates, and consequently will allow the
> > common HDMI bridge code to act on it.
> > 
> > Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
> > ---
> >  drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 24 ++++++++++++++++++++++++
> >  1 file changed, 24 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
> > index c9fe6aa3e3e3..7c294751de19 100644
> > --- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
> > +++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
> > @@ -468,6 +468,28 @@ static const struct of_device_id dw_hdmi_qp_rockchip_dt_ids[] = {
> >  };
> >  MODULE_DEVICE_TABLE(of, dw_hdmi_qp_rockchip_dt_ids);
> >  
> > +static const u32 supported_colorformats = DRM_COLOR_FORMAT_AUTO |
> > +					  DRM_COLOR_FORMAT_RGB444 |
> > +					  DRM_COLOR_FORMAT_YCBCR444;
> > +
> > +static unsigned int __pure drm_to_hdmi_fmts(const u32 fmt)
> > +{
> > +	unsigned int res = 0;
> > +
> > +	if (fmt & DRM_COLOR_FORMAT_AUTO)
> > +		res |= BIT(HDMI_COLORSPACE_RGB);
> > +	if (fmt & DRM_COLOR_FORMAT_RGB444)
> > +		res |= BIT(HDMI_COLORSPACE_RGB);
> > +	if (fmt & DRM_COLOR_FORMAT_YCBCR444)
> > +		res |= BIT(HDMI_COLORSPACE_YUV444);
> > +	if (fmt & DRM_COLOR_FORMAT_YCBCR422)
> > +		res |= BIT(HDMI_COLORSPACE_YUV422);
> > +	if (fmt & DRM_COLOR_FORMAT_YCBCR420)
> > +		res |= BIT(HDMI_COLORSPACE_YUV420);
> > +
> > +	return res;
> > +}
> > +
> >  static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
> >  				    void *data)
> >  {
> > @@ -521,6 +543,8 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
> >  	plat_data.phy_data = hdmi;
> >  	plat_data.max_bpc = 10;
> >  
> > +	plat_data.supported_formats = drm_to_hdmi_fmts(supported_colorformats);
> 
> Any reason why this cannot be simply set as
> 
>   BIT(HDMI_COLORSPACE_RGB) | BIT(HDMI_COLORSPACE_YUV444) | BIT(HDMI_COLORSPACE_YUV422)
> 
> and get rid of the unnecessary conversion?

My gut feeling lead me towards trying to have a single source of
truth for the supported color formats, but upon further reflection
this is indeed way too verbose and lead me to move the
supported_colorformats definition into this patch rather than the
one where it's needed for registering the property.

So I agree with you here and will simplify this by just setting
these as you described.

Kind regards,
Nicolas Frattaroli

> 
> > +
> >  	encoder = &hdmi->encoder.encoder;
> >  	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
> >  
> > 
> 
> 






From linux.amoon at gmail.com  Wed Nov 19 06:19:06 2025
From: linux.amoon at gmail.com (Anand Moon)
Date: Wed, 19 Nov 2025 19:49:06 +0530
Subject: [RFC v1 1/5] PCI: rockchip: Fix Link Control register offset and
 enable ASPM/CLKREQ
In-Reply-To: <20251118175010.GA2540980@bhelgaas>
References: <20251117181023.482138-2-linux.amoon@gmail.com> <20251118175010.GA2540980@bhelgaas>
Message-ID: <CANAwSgRHuwoQjr95sXp-X97=L-X3vqUPxjR5=2jNtFZA+4gnwQ@mail.gmail.com>

Hi Bjorn / Shwan

Thanks for your review comments.

On Tue, 18 Nov 2025 at 23:20, Bjorn Helgaas <helgaas at kernel.org> wrote:
>
> On Mon, Nov 17, 2025 at 11:40:09PM +0530, Anand Moon wrote:
> > As per the RK3399 TRM (Part 2, 17.6.6.1.31), the Link Control register
> > (RC_CONFIG_LC) resides at an offset of 0xd0 within the Root Complex (RC)
> > configuration space, not at the offset of the PCI Express Capability List
> > (0xc0). Following changes correct the register offset to use
> > PCIE_RC_CONFIG_LC (0xd0) to configure link control.
> >
> > Additionally, this commit explicitly enables ASPM (Active State Power
> > Management) control and the CLKREQ# (Clock Request) mechanism as part of
> > the Link Control register programming when enabling bandwidth
> > notifications.
>
> Don't do two things at once in the same patch.  Fix the register
> offset in one patch.  Actually, as I mentioned at [1], there's a lot
> of fixing to do there, and I'm not even going to consider other
> changes until the #define mess is cleaned up.
>
Ok, got that.
> What I'd really like to see is at least two patches here: one that
> clearly makes no functional change -- don't try to fix anything, just
> make it 100% obvious that all the offsets stay the same.  Then make a
> separate patch that *only* changes any of the offsets that are wrong.
>
Ok, understood.
> I don't think there should even be an ASPM change.  The PCI core
> should be enabling L0s and L1 itself for DT systems like this.  And
> ASPM needs to be enabled only when both ends of the link support it,
> and only in a specific order.  The PCI core pays attention to that,
> but this patch does not.
>
Ok, I get it.

> Bjorn
>
> [1] https://lore.kernel.org/r/20251118005056.GA2541796 at bhelgaas

According to the RK3399 Technical Reference Manual (TRM), and pci_regs.h
already includes the correct, pre-defined offsets for all PCI Express
device types
and their capabilities registers. To avoid overlapping register mappings,
we should explicitly remove the addition of manual offsets within the code.

Thanks
-Anand

Here is the example. Is this the correct approach?
---
 drivers/pci/controller/pcie-rockchip-host.c | 12 ++++++------
 drivers/pci/controller/pcie-rockchip.h      |  2 ++
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/pci/controller/pcie-rockchip-host.c
b/drivers/pci/controller/pcie-rockchip-host.c
index ee1822ca01db..af438d59e788 100644
--- a/drivers/pci/controller/pcie-rockchip-host.c
+++ b/drivers/pci/controller/pcie-rockchip-host.c
@@ -32,18 +32,18 @@ static void rockchip_pcie_enable_bw_int(struct
rockchip_pcie *rockchip)
 {
        u32 status;

-       status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_CR +
PCI_EXP_LNKCTL);
+       status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LC);
        status |= (PCI_EXP_LNKCTL_LBMIE | PCI_EXP_LNKCTL_LABIE);
-       rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_CR +
PCI_EXP_LNKCTL);
+       rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LC);
 }

 static void rockchip_pcie_clr_bw_int(struct rockchip_pcie *rockchip)
 {
        u32 status;

-       status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_CR +
PCI_EXP_LNKCTL);
+       status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LC);
        status |= (PCI_EXP_LNKSTA_LBMS | PCI_EXP_LNKSTA_LABS) << 16;
-       rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_CR +
PCI_EXP_LNKCTL);
+       rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LC);
 }

 static void rockchip_pcie_update_txcredit_mui(struct rockchip_pcie *rockchip)
@@ -306,9 +306,9 @@ static int rockchip_pcie_host_init_port(struct
rockchip_pcie *rockchip)
        rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_CR +
PCI_EXP_LNKCTL);

        /* Set RC's RCB to 128 */
-       status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_CR +
PCI_EXP_LNKCTL);
+       status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LC);
        status |= PCI_EXP_LNKCTL_RCB;
-       rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_CR +
PCI_EXP_LNKCTL);
+       rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LC);

        /* Enable Gen1 training */
        rockchip_pcie_write(rockchip, PCIE_CLIENT_LINK_TRAIN_ENABLE,
diff --git a/drivers/pci/controller/pcie-rockchip.h
b/drivers/pci/controller/pcie-rockchip.h
index 3e82a69b9c00..3313cd8c585f 100644
--- a/drivers/pci/controller/pcie-rockchip.h
+++ b/drivers/pci/controller/pcie-rockchip.h
@@ -157,6 +157,8 @@
 #define PCIE_EP_CONFIG_LCS             (PCIE_EP_CONFIG_BASE + 0xd0)
 #define PCIE_RC_CONFIG_RID_CCR         (PCIE_RC_CONFIG_BASE + 0x08)
 #define PCIE_RC_CONFIG_CR              (PCIE_RC_CONFIG_BASE + 0xc0)
+/* Link Control and Status Register */
+#define PCIE_RC_CONFIG_LC              (PCIE_RC_CONFIG_BASE + 0xd0)
 #define PCIE_RC_CONFIG_L1_SUBSTATE_CTRL2 (PCIE_RC_CONFIG_BASE + 0x90c)
 #define PCIE_RC_CONFIG_THP_CAP         (PCIE_RC_CONFIG_BASE + 0x274)
 #define   PCIE_RC_CONFIG_THP_CAP_NEXT_MASK     GENMASK(31, 20)


From wens at csie.org  Wed Nov 19 06:43:18 2025
From: wens at csie.org (Chen-Yu Tsai)
Date: Wed, 19 Nov 2025 22:43:18 +0800
Subject: [PATCH net-next 1/3] net: stmmac: pass struct device to
 init()/exit() methods
In-Reply-To: <E1vLf2U-0000000FMN2-0SLg@rmk-PC.armlinux.org.uk>
References: <aR2V0Kib7j0L4FNN@shell.armlinux.org.uk> <E1vLf2U-0000000FMN2-0SLg@rmk-PC.armlinux.org.uk>
Message-ID: <CAGb2v65syu47YAy8-24LDXt1MC2K7r+weOyCWn5fZzRgSFhnDA@mail.gmail.com>

On Wed, Nov 19, 2025 at 6:04?PM Russell King (Oracle)
<rmk+kernel at armlinux.org.uk> wrote:
>
> As struct plat_stmmacenet_data is not platform_device specific, pass
> a struct device into the init() and exit() methods to allow them to
> become independent of the underlying device.
>
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> ---
>  .../ethernet/stmicro/stmmac/dwmac-anarion.c   |  4 +--
>  .../ethernet/stmicro/stmmac/dwmac-eic7700.c   |  4 +--
>  .../ethernet/stmicro/stmmac/dwmac-loongson1.c | 12 ++++----
>  .../stmicro/stmmac/dwmac-renesas-gbeth.c      |  4 +--
>  .../net/ethernet/stmicro/stmmac/dwmac-s32.c   | 14 +++++-----
>  .../ethernet/stmicro/stmmac/dwmac-socfpga.c   |  2 +-
>  .../net/ethernet/stmicro/stmmac/dwmac-sti.c   |  4 +--


>  .../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 10 +++----
>  .../net/ethernet/stmicro/stmmac/dwmac-sunxi.c |  4 +--

For sun8i / sunxi,

Acked-by: Chen-Yu Tsai <wens at kernel.org>

>  .../net/ethernet/stmicro/stmmac/dwmac-thead.c |  2 +-
>  .../ethernet/stmicro/stmmac/stmmac_platform.c | 28 ++++++++++---------
>  include/linux/stmmac.h                        |  4 +--
>  12 files changed, 47 insertions(+), 45 deletions(-)


From maxime.chevallier at bootlin.com  Wed Nov 19 07:03:56 2025
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Wed, 19 Nov 2025 16:03:56 +0100
Subject: [PATCH net-next 1/3] net: stmmac: pass struct device to
 init()/exit() methods
In-Reply-To: <E1vLf2U-0000000FMN2-0SLg@rmk-PC.armlinux.org.uk>
References: <aR2V0Kib7j0L4FNN@shell.armlinux.org.uk>
 <E1vLf2U-0000000FMN2-0SLg@rmk-PC.armlinux.org.uk>
Message-ID: <62213fae-1141-4361-90f9-b03b48c8abfc@bootlin.com>



On 19/11/2025 11:03, Russell King (Oracle) wrote:
> As struct plat_stmmacenet_data is not platform_device specific, pass
> a struct device into the init() and exit() methods to allow them to
> become independent of the underlying device.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Reviewed-by: Maxime Chevallier <maxime.chevallier at bootlin.com>

Maxime

> ---
>  .../ethernet/stmicro/stmmac/dwmac-anarion.c   |  4 +--
>  .../ethernet/stmicro/stmmac/dwmac-eic7700.c   |  4 +--
>  .../ethernet/stmicro/stmmac/dwmac-loongson1.c | 12 ++++----
>  .../stmicro/stmmac/dwmac-renesas-gbeth.c      |  4 +--
>  .../net/ethernet/stmicro/stmmac/dwmac-s32.c   | 14 +++++-----
>  .../ethernet/stmicro/stmmac/dwmac-socfpga.c   |  2 +-
>  .../net/ethernet/stmicro/stmmac/dwmac-sti.c   |  4 +--
>  .../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 10 +++----
>  .../net/ethernet/stmicro/stmmac/dwmac-sunxi.c |  4 +--
>  .../net/ethernet/stmicro/stmmac/dwmac-thead.c |  2 +-
>  .../ethernet/stmicro/stmmac/stmmac_platform.c | 28 ++++++++++---------
>  include/linux/stmmac.h                        |  4 +--
>  12 files changed, 47 insertions(+), 45 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c
> index 84072c8ed741..5e0fc31762d9 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c
> @@ -34,7 +34,7 @@ static void gmac_write_reg(struct anarion_gmac *gmac, uint8_t reg, uint32_t val)
>  	writel(val, gmac->ctl_block + reg);
>  }
>  
> -static int anarion_gmac_init(struct platform_device *pdev, void *priv)
> +static int anarion_gmac_init(struct device *dev, void *priv)
>  {
>  	uint32_t sw_config;
>  	struct anarion_gmac *gmac = priv;
> @@ -52,7 +52,7 @@ static int anarion_gmac_init(struct platform_device *pdev, void *priv)
>  	return 0;
>  }
>  
> -static void anarion_gmac_exit(struct platform_device *pdev, void *priv)
> +static void anarion_gmac_exit(struct device *dev, void *priv)
>  {
>  	struct anarion_gmac *gmac = priv;
>  
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-eic7700.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-eic7700.c
> index 1dcf2037001e..bcb8e000e720 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-eic7700.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-eic7700.c
> @@ -58,14 +58,14 @@ static int eic7700_clks_config(void *priv, bool enabled)
>  	return ret;
>  }
>  
> -static int eic7700_dwmac_init(struct platform_device *pdev, void *priv)
> +static int eic7700_dwmac_init(struct device *dev, void *priv)
>  {
>  	struct eic7700_qos_priv *dwc = priv;
>  
>  	return eic7700_clks_config(dwc, true);
>  }
>  
> -static void eic7700_dwmac_exit(struct platform_device *pdev, void *priv)
> +static void eic7700_dwmac_exit(struct device *dev, void *priv)
>  {
>  	struct eic7700_qos_priv *dwc = priv;
>  
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson1.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson1.c
> index 894ee66f5c9b..de9aba756aac 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson1.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson1.c
> @@ -48,7 +48,7 @@ struct ls1x_dwmac {
>  struct ls1x_data {
>  	int (*setup)(struct platform_device *pdev,
>  		     struct plat_stmmacenet_data *plat_dat);
> -	int (*init)(struct platform_device *pdev, void *bsp_priv);
> +	int (*init)(struct device *dev, void *bsp_priv);
>  };
>  
>  static int ls1b_dwmac_setup(struct platform_device *pdev,
> @@ -79,7 +79,7 @@ static int ls1b_dwmac_setup(struct platform_device *pdev,
>  	return 0;
>  }
>  
> -static int ls1b_dwmac_syscon_init(struct platform_device *pdev, void *priv)
> +static int ls1b_dwmac_syscon_init(struct device *dev, void *priv)
>  {
>  	struct ls1x_dwmac *dwmac = priv;
>  	struct plat_stmmacenet_data *plat = dwmac->plat_dat;
> @@ -98,7 +98,7 @@ static int ls1b_dwmac_syscon_init(struct platform_device *pdev, void *priv)
>  					   GMAC0_USE_TXCLK | GMAC0_USE_PWM01);
>  			break;
>  		default:
> -			dev_err(&pdev->dev, "Unsupported PHY mode %u\n",
> +			dev_err(dev, "Unsupported PHY mode %u\n",
>  				plat->phy_interface);
>  			return -EOPNOTSUPP;
>  		}
> @@ -122,7 +122,7 @@ static int ls1b_dwmac_syscon_init(struct platform_device *pdev, void *priv)
>  					   GMAC1_USE_TXCLK | GMAC1_USE_PWM23);
>  			break;
>  		default:
> -			dev_err(&pdev->dev, "Unsupported PHY mode %u\n",
> +			dev_err(dev, "Unsupported PHY mode %u\n",
>  				plat->phy_interface);
>  			return -EOPNOTSUPP;
>  		}
> @@ -133,7 +133,7 @@ static int ls1b_dwmac_syscon_init(struct platform_device *pdev, void *priv)
>  	return 0;
>  }
>  
> -static int ls1c_dwmac_syscon_init(struct platform_device *pdev, void *priv)
> +static int ls1c_dwmac_syscon_init(struct device *dev, void *priv)
>  {
>  	struct ls1x_dwmac *dwmac = priv;
>  	struct plat_stmmacenet_data *plat = dwmac->plat_dat;
> @@ -143,7 +143,7 @@ static int ls1c_dwmac_syscon_init(struct platform_device *pdev, void *priv)
>  	phy_intf_sel = stmmac_get_phy_intf_sel(plat->phy_interface);
>  	if (phy_intf_sel != PHY_INTF_SEL_GMII_MII &&
>  	    phy_intf_sel != PHY_INTF_SEL_RMII) {
> -		dev_err(&pdev->dev, "Unsupported PHY-mode %u\n",
> +		dev_err(dev, "Unsupported PHY-mode %u\n",
>  			plat->phy_interface);
>  		return -EOPNOTSUPP;
>  	}
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c
> index bc7bb975803c..be7f5eb2cdcf 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c
> @@ -91,7 +91,7 @@ static struct phylink_pcs *renesas_gmac_select_pcs(struct stmmac_priv *priv,
>  	return priv->hw->phylink_pcs;
>  }
>  
> -static int renesas_gbeth_init(struct platform_device *pdev, void *priv)
> +static int renesas_gbeth_init(struct device *dev, void *priv)
>  {
>  	struct plat_stmmacenet_data *plat_dat;
>  	struct renesas_gbeth *gbeth = priv;
> @@ -113,7 +113,7 @@ static int renesas_gbeth_init(struct platform_device *pdev, void *priv)
>  	return ret;
>  }
>  
> -static void renesas_gbeth_exit(struct platform_device *pdev, void *priv)
> +static void renesas_gbeth_exit(struct device *dev, void *priv)
>  {
>  	struct plat_stmmacenet_data *plat_dat;
>  	struct renesas_gbeth *gbeth = priv;
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c
> index 2b7ad64bfdf7..5a485ee98fa7 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c
> @@ -47,7 +47,7 @@ static int s32_gmac_write_phy_intf_select(struct s32_priv_data *gmac)
>  	return 0;
>  }
>  
> -static int s32_gmac_init(struct platform_device *pdev, void *priv)
> +static int s32_gmac_init(struct device *dev, void *priv)
>  {
>  	struct s32_priv_data *gmac = priv;
>  	int ret;
> @@ -55,31 +55,31 @@ static int s32_gmac_init(struct platform_device *pdev, void *priv)
>  	/* Set initial TX interface clock */
>  	ret = clk_prepare_enable(gmac->tx_clk);
>  	if (ret) {
> -		dev_err(&pdev->dev, "Can't enable tx clock\n");
> +		dev_err(dev, "Can't enable tx clock\n");
>  		return ret;
>  	}
>  	ret = clk_set_rate(gmac->tx_clk, GMAC_INTF_RATE_125M);
>  	if (ret) {
> -		dev_err(&pdev->dev, "Can't set tx clock\n");
> +		dev_err(dev, "Can't set tx clock\n");
>  		goto err_tx_disable;
>  	}
>  
>  	/* Set initial RX interface clock */
>  	ret = clk_prepare_enable(gmac->rx_clk);
>  	if (ret) {
> -		dev_err(&pdev->dev, "Can't enable rx clock\n");
> +		dev_err(dev, "Can't enable rx clock\n");
>  		goto err_tx_disable;
>  	}
>  	ret = clk_set_rate(gmac->rx_clk, GMAC_INTF_RATE_125M);
>  	if (ret) {
> -		dev_err(&pdev->dev, "Can't set rx clock\n");
> +		dev_err(dev, "Can't set rx clock\n");
>  		goto err_txrx_disable;
>  	}
>  
>  	/* Set interface mode */
>  	ret = s32_gmac_write_phy_intf_select(gmac);
>  	if (ret) {
> -		dev_err(&pdev->dev, "Can't set PHY interface mode\n");
> +		dev_err(dev, "Can't set PHY interface mode\n");
>  		goto err_txrx_disable;
>  	}
>  
> @@ -92,7 +92,7 @@ static int s32_gmac_init(struct platform_device *pdev, void *priv)
>  	return ret;
>  }
>  
> -static void s32_gmac_exit(struct platform_device *pdev, void *priv)
> +static void s32_gmac_exit(struct device *dev, void *priv)
>  {
>  	struct s32_priv_data *gmac = priv;
>  
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
> index 49d651948e2b..a2b52d2c4eb6 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
> @@ -551,7 +551,7 @@ static struct phylink_pcs *socfpga_dwmac_select_pcs(struct stmmac_priv *priv,
>  	return priv->hw->phylink_pcs;
>  }
>  
> -static int socfpga_dwmac_init(struct platform_device *pdev, void *bsp_priv)
> +static int socfpga_dwmac_init(struct device *dev, void *bsp_priv)
>  {
>  	struct socfpga_dwmac *dwmac = bsp_priv;
>  
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
> index b0509ab6b31c..f50547b67fbc 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
> @@ -229,14 +229,14 @@ static int sti_dwmac_parse_data(struct sti_dwmac *dwmac,
>  	return 0;
>  }
>  
> -static int sti_dwmac_init(struct platform_device *pdev, void *bsp_priv)
> +static int sti_dwmac_init(struct device *dev, void *bsp_priv)
>  {
>  	struct sti_dwmac *dwmac = bsp_priv;
>  
>  	return clk_prepare_enable(dwmac->clk);
>  }
>  
> -static void sti_dwmac_exit(struct platform_device *pdev, void *bsp_priv)
> +static void sti_dwmac_exit(struct device *dev, void *bsp_priv)
>  {
>  	struct sti_dwmac *dwmac = bsp_priv;
>  
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
> index 7434d4bbb526..8aa496ac85cc 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
> @@ -571,16 +571,16 @@ static const struct stmmac_dma_ops sun8i_dwmac_dma_ops = {
>  
>  static int sun8i_dwmac_power_internal_phy(struct stmmac_priv *priv);
>  
> -static int sun8i_dwmac_init(struct platform_device *pdev, void *priv)
> +static int sun8i_dwmac_init(struct device *dev, void *priv)
>  {
> -	struct net_device *ndev = platform_get_drvdata(pdev);
> +	struct net_device *ndev = dev_get_drvdata(dev);
>  	struct sunxi_priv_data *gmac = priv;
>  	int ret;
>  
>  	if (gmac->regulator) {
>  		ret = regulator_enable(gmac->regulator);
>  		if (ret) {
> -			dev_err(&pdev->dev, "Fail to enable regulator\n");
> +			dev_err(dev, "Fail to enable regulator\n");
>  			return ret;
>  		}
>  	}
> @@ -1005,7 +1005,7 @@ static void sun8i_dwmac_unset_syscon(struct sunxi_priv_data *gmac)
>  				   (H3_EPHY_SHUTDOWN | H3_EPHY_SELECT));
>  }
>  
> -static void sun8i_dwmac_exit(struct platform_device *pdev, void *priv)
> +static void sun8i_dwmac_exit(struct device *dev, void *priv)
>  {
>  	struct sunxi_priv_data *gmac = priv;
>  
> @@ -1265,7 +1265,7 @@ static void sun8i_dwmac_shutdown(struct platform_device *pdev)
>  	struct stmmac_priv *priv = netdev_priv(ndev);
>  	struct sunxi_priv_data *gmac = priv->plat->bsp_priv;
>  
> -	sun8i_dwmac_exit(pdev, gmac);
> +	sun8i_dwmac_exit(&pdev->dev, gmac);
>  }
>  
>  static const struct of_device_id sun8i_dwmac_match[] = {
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
> index 7f560d78209d..52593ba3a3a3 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
> @@ -27,7 +27,7 @@ struct sunxi_priv_data {
>  #define SUN7I_GMAC_GMII_RGMII_RATE	125000000
>  #define SUN7I_GMAC_MII_RATE		25000000
>  
> -static int sun7i_gmac_init(struct platform_device *pdev, void *priv)
> +static int sun7i_gmac_init(struct device *dev, void *priv)
>  {
>  	struct sunxi_priv_data *gmac = priv;
>  	int ret = 0;
> @@ -58,7 +58,7 @@ static int sun7i_gmac_init(struct platform_device *pdev, void *priv)
>  	return ret;
>  }
>  
> -static void sun7i_gmac_exit(struct platform_device *pdev, void *priv)
> +static void sun7i_gmac_exit(struct device *dev, void *priv)
>  {
>  	struct sunxi_priv_data *gmac = priv;
>  
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-thead.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-thead.c
> index a3378046b061..e291028ba56e 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-thead.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-thead.c
> @@ -186,7 +186,7 @@ static int thead_dwmac_enable_clk(struct plat_stmmacenet_data *plat)
>  	return 0;
>  }
>  
> -static int thead_dwmac_init(struct platform_device *pdev, void *priv)
> +static int thead_dwmac_init(struct device *dev, void *priv)
>  {
>  	struct thead_dwmac *dwmac = priv;
>  	unsigned int reg;
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
> index 1fefa6c55db1..feccb8a3e7e8 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
> @@ -747,40 +747,40 @@ EXPORT_SYMBOL_GPL(stmmac_get_platform_resources);
>  
>  /**
>   * stmmac_pltfr_init
> - * @pdev: pointer to the platform device
> + * @dev: pointer to the device structure
>   * @plat: driver data platform structure
>   * Description: Call the platform's init callback (if any) and propagate
>   * the return value.
>   */
> -static int stmmac_pltfr_init(struct platform_device *pdev,
> +static int stmmac_pltfr_init(struct device *dev,
>  			     struct plat_stmmacenet_data *plat)
>  {
>  	int ret = 0;
>  
>  	if (plat->init)
> -		ret = plat->init(pdev, plat->bsp_priv);
> +		ret = plat->init(dev, plat->bsp_priv);
>  
>  	return ret;
>  }
>  
>  /**
>   * stmmac_pltfr_exit
> - * @pdev: pointer to the platform device
> + * @dev: pointer to the device structure
>   * @plat: driver data platform structure
>   * Description: Call the platform's exit callback (if any).
>   */
> -static void stmmac_pltfr_exit(struct platform_device *pdev,
> +static void stmmac_pltfr_exit(struct device *dev,
>  			      struct plat_stmmacenet_data *plat)
>  {
>  	if (plat->exit)
> -		plat->exit(pdev, plat->bsp_priv);
> +		plat->exit(dev, plat->bsp_priv);
>  }
>  
>  static int stmmac_plat_suspend(struct device *dev, void *bsp_priv)
>  {
>  	struct stmmac_priv *priv = netdev_priv(dev_get_drvdata(dev));
>  
> -	stmmac_pltfr_exit(to_platform_device(dev), priv->plat);
> +	stmmac_pltfr_exit(dev, priv->plat);
>  
>  	return 0;
>  }
> @@ -789,7 +789,7 @@ static int stmmac_plat_resume(struct device *dev, void *bsp_priv)
>  {
>  	struct stmmac_priv *priv = netdev_priv(dev_get_drvdata(dev));
>  
> -	return stmmac_pltfr_init(to_platform_device(dev), priv->plat);
> +	return stmmac_pltfr_init(dev, priv->plat);
>  }
>  
>  /**
> @@ -804,6 +804,7 @@ int stmmac_pltfr_probe(struct platform_device *pdev,
>  		       struct plat_stmmacenet_data *plat,
>  		       struct stmmac_resources *res)
>  {
> +	struct device *dev = &pdev->dev;
>  	int ret;
>  
>  	if (!plat->suspend && plat->exit)
> @@ -811,13 +812,13 @@ int stmmac_pltfr_probe(struct platform_device *pdev,
>  	if (!plat->resume && plat->init)
>  		plat->resume = stmmac_plat_resume;
>  
> -	ret = stmmac_pltfr_init(pdev, plat);
> +	ret = stmmac_pltfr_init(dev, plat);
>  	if (ret)
>  		return ret;
>  
> -	ret = stmmac_dvr_probe(&pdev->dev, plat, res);
> +	ret = stmmac_dvr_probe(dev, plat, res);
>  	if (ret) {
> -		stmmac_pltfr_exit(pdev, plat);
> +		stmmac_pltfr_exit(dev, plat);
>  		return ret;
>  	}
>  
> @@ -866,9 +867,10 @@ void stmmac_pltfr_remove(struct platform_device *pdev)
>  	struct net_device *ndev = platform_get_drvdata(pdev);
>  	struct stmmac_priv *priv = netdev_priv(ndev);
>  	struct plat_stmmacenet_data *plat = priv->plat;
> +	struct device *dev = &pdev->dev;
>  
> -	stmmac_dvr_remove(&pdev->dev);
> -	stmmac_pltfr_exit(pdev, plat);
> +	stmmac_dvr_remove(dev);
> +	stmmac_pltfr_exit(dev, plat);
>  }
>  EXPORT_SYMBOL_GPL(stmmac_pltfr_remove);
>  
> diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
> index 4f70a6551e68..673b068fdadf 100644
> --- a/include/linux/stmmac.h
> +++ b/include/linux/stmmac.h
> @@ -264,8 +264,8 @@ struct plat_stmmacenet_data {
>  			  unsigned int mode,
>  			  phy_interface_t interface);
>  	void (*ptp_clk_freq_config)(struct stmmac_priv *priv);
> -	int (*init)(struct platform_device *pdev, void *priv);
> -	void (*exit)(struct platform_device *pdev, void *priv);
> +	int (*init)(struct device *dev, void *priv);
> +	void (*exit)(struct device *dev, void *priv);
>  	int (*suspend)(struct device *dev, void *priv);
>  	int (*resume)(struct device *dev, void *priv);
>  	int (*mac_setup)(void *priv, struct mac_device_info *mac);



From maxime.chevallier at bootlin.com  Wed Nov 19 07:04:23 2025
From: maxime.chevallier at bootlin.com (Maxime Chevallier)
Date: Wed, 19 Nov 2025 16:04:23 +0100
Subject: [PATCH net-next 2/3] net: stmmac: move probe/remove calling of
 init/exit
In-Reply-To: <E1vLf2Z-0000000FMNH-0xPV@rmk-PC.armlinux.org.uk>
References: <aR2V0Kib7j0L4FNN@shell.armlinux.org.uk>
 <E1vLf2Z-0000000FMNH-0xPV@rmk-PC.armlinux.org.uk>
Message-ID: <b04b1abe-c75b-4f59-b9a9-183df0c56d08@bootlin.com>



On 19/11/2025 11:03, Russell King (Oracle) wrote:
> Move the probe/remove time calling of the init()/exit() methods in
> the platform data to the main driver probe/remove functions. This
> allows them to be used by non-platform_device based drivers.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Reviewed-by: Maxime Chevallier <maxime.chevallier at bootlin.com>

Maxime

> ---
>  .../net/ethernet/stmicro/stmmac/stmmac_main.c | 47 ++++++++++++++-----
>  .../ethernet/stmicro/stmmac/stmmac_platform.c | 23 +--------
>  2 files changed, 36 insertions(+), 34 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index 644dccb29f75..aac8188248ff 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -7593,19 +7593,9 @@ struct plat_stmmacenet_data *stmmac_plat_dat_alloc(struct device *dev)
>  }
>  EXPORT_SYMBOL_GPL(stmmac_plat_dat_alloc);
>  
> -/**
> - * stmmac_dvr_probe
> - * @device: device pointer
> - * @plat_dat: platform data pointer
> - * @res: stmmac resource pointer
> - * Description: this is the main probe function used to
> - * call the alloc_etherdev, allocate the priv structure.
> - * Return:
> - * returns 0 on success, otherwise errno.
> - */
> -int stmmac_dvr_probe(struct device *device,
> -		     struct plat_stmmacenet_data *plat_dat,
> -		     struct stmmac_resources *res)
> +static int __stmmac_dvr_probe(struct device *device,
> +			      struct plat_stmmacenet_data *plat_dat,
> +			      struct stmmac_resources *res)
>  {
>  	struct net_device *ndev = NULL;
>  	struct stmmac_priv *priv;
> @@ -7912,6 +7902,34 @@ int stmmac_dvr_probe(struct device *device,
>  
>  	return ret;
>  }
> +
> +/**
> + * stmmac_dvr_probe
> + * @dev: device pointer
> + * @plat_dat: platform data pointer
> + * @res: stmmac resource pointer
> + * Description: this is the main probe function used to
> + * call the alloc_etherdev, allocate the priv structure.
> + * Return:
> + * returns 0 on success, otherwise errno.
> + */
> +int stmmac_dvr_probe(struct device *dev, struct plat_stmmacenet_data *plat_dat,
> +		     struct stmmac_resources *res)
> +{
> +	int ret;
> +
> +	if (plat_dat->init) {
> +		ret = plat_dat->init(dev, plat_dat->bsp_priv);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	ret = __stmmac_dvr_probe(dev, plat_dat, res);
> +	if (ret && plat_dat->exit)
> +		plat_dat->exit(dev, plat_dat->bsp_priv);
> +
> +	return ret;
> +}
>  EXPORT_SYMBOL_GPL(stmmac_dvr_probe);
>  
>  /**
> @@ -7950,6 +7968,9 @@ void stmmac_dvr_remove(struct device *dev)
>  
>  	pm_runtime_disable(dev);
>  	pm_runtime_put_noidle(dev);
> +
> +	if (priv->plat->exit)
> +		priv->plat->exit(dev, priv->plat->bsp_priv);
>  }
>  EXPORT_SYMBOL_GPL(stmmac_dvr_remove);
>  
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
> index feccb8a3e7e8..9015b7f80d1b 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
> @@ -804,25 +804,12 @@ int stmmac_pltfr_probe(struct platform_device *pdev,
>  		       struct plat_stmmacenet_data *plat,
>  		       struct stmmac_resources *res)
>  {
> -	struct device *dev = &pdev->dev;
> -	int ret;
> -
>  	if (!plat->suspend && plat->exit)
>  		plat->suspend = stmmac_plat_suspend;
>  	if (!plat->resume && plat->init)
>  		plat->resume = stmmac_plat_resume;
>  
> -	ret = stmmac_pltfr_init(dev, plat);
> -	if (ret)
> -		return ret;
> -
> -	ret = stmmac_dvr_probe(dev, plat, res);
> -	if (ret) {
> -		stmmac_pltfr_exit(dev, plat);
> -		return ret;
> -	}
> -
> -	return ret;
> +	return stmmac_dvr_probe(&pdev->dev, plat, res);
>  }
>  EXPORT_SYMBOL_GPL(stmmac_pltfr_probe);
>  
> @@ -864,13 +851,7 @@ EXPORT_SYMBOL_GPL(devm_stmmac_pltfr_probe);
>   */
>  void stmmac_pltfr_remove(struct platform_device *pdev)
>  {
> -	struct net_device *ndev = platform_get_drvdata(pdev);
> -	struct stmmac_priv *priv = netdev_priv(ndev);
> -	struct plat_stmmacenet_data *plat = priv->plat;
> -	struct device *dev = &pdev->dev;
> -
> -	stmmac_dvr_remove(dev);
> -	stmmac_pltfr_exit(dev, plat);
> +	stmmac_dvr_remove(&pdev->dev);
>  }
>  EXPORT_SYMBOL_GPL(stmmac_pltfr_remove);
>  



From Frank.li at nxp.com  Wed Nov 19 07:58:09 2025
From: Frank.li at nxp.com (Frank Li)
Date: Wed, 19 Nov 2025 10:58:09 -0500
Subject: [PATCH v2 1/4] PCI: dwc: Advertise L1 PM Substates only if
 driver requests it
In-Reply-To: <aR2lOZDBEdGVd9On@ryzen>
References: <20251118214312.2598220-1-helgaas@kernel.org>
 <20251118214312.2598220-2-helgaas@kernel.org>
 <aRz0ak6onKzZs2lY@lizhi-Precision-Tower-5810>
 <aR2lOZDBEdGVd9On@ryzen>
Message-ID: <aR3pEaJ4oTagaKU8@lizhi-Precision-Tower-5810>

On Wed, Nov 19, 2025 at 12:08:41PM +0100, Niklas Cassel wrote:
> On Tue, Nov 18, 2025 at 05:34:18PM -0500, Frank Li wrote:
> > On Tue, Nov 18, 2025 at 03:42:15PM -0600, Bjorn Helgaas wrote:
> > > From: Bjorn Helgaas <bhelgaas at google.com>
> > >
> > > L1 PM Substates require the CLKREQ# signal and may also require
> > > device-specific support.  If CLKREQ# is not supported or driver support is
> > > lacking, enabling L1.1 or L1.2 may cause errors when accessing devices,
> > > e.g.,
> > >
> > >   nvme nvme0: controller is down; will reset: CSTS=0xffffffff, PCI_STATUS=0x10
> > >
> > > If the kernel is built with CONFIG_PCIEASPM_POWER_SUPERSAVE=y or users
> > > enable L1.x via sysfs, users may trip over these errors even if L1
> > > Substates haven't been enabled by firmware or the driver.
> > >
> > > To prevent such errors, disable advertising the L1 PM Substates unless the
> > > driver sets "dw_pcie.l1ss_support" to indicate that it knows CLKREQ# is
> > > present and any device-specific configuration has been done.
> > >
> > > Set "dw_pcie.l1ss_support" in tegra194 (if DT includes the
> > > "supports-clkreq' property) and qcom (for cfg_2_7_0, cfg_1_9_0, cfg_1_34_0,
> > > and cfg_sc8280xp controllers) so they can continue to use L1 Substates.
> > >
> > > Based on Niklas's patch:
> > > https://patch.msgid.link/20251017163252.598812-2-cassel at kernel.org
> > >
> > > Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
> > > ---
> > >  .../pci/controller/dwc/pcie-designware-ep.c   |  2 ++
> > >  .../pci/controller/dwc/pcie-designware-host.c |  2 ++
> > >  drivers/pci/controller/dwc/pcie-designware.c  | 24 +++++++++++++++++++
> > >  drivers/pci/controller/dwc/pcie-designware.h  |  2 ++
> > >  drivers/pci/controller/dwc/pcie-qcom.c        |  2 ++
> > >  drivers/pci/controller/dwc/pcie-tegra194.c    |  3 +++
> > >  6 files changed, 35 insertions(+)
> > >
> > > diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
> > > index 7f2112c2fb21..ad6c0fd67a65 100644
> > > --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> > > +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> > > @@ -966,6 +966,8 @@ int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)
> > >  	if (ep->ops->init)
> > >  		ep->ops->init(ep);
> > >
> > > +	dw_pcie_hide_unsupported_l1ss(pci);
> > > +
> >
> > And, I don't think EP need clean L1SS CAP flags. If EP don't support L1SS,
> > it should be force pull down #clkreq.
>
> I think the problem is that we cannot force pull down CLKREQ# in a generic
> DWC function. That would have to be done in glue driver specific callbacks.
>
> Bjorn, perhaps we should simply drop the dw_pcie_hide_unsupported_l1ss()
> call from dw_pcie_ep_init_registers(), and consider hiding L1ss for EPs to
> be out of scope for this series.


Agree, we should consider EP later. When work at EP mode, #clkreq default
it is 0. RC should not turn L1SS if RC don't support. If RC side support,
it should be fine by turing on EP's L1SS because hardware already support
it.

Frank

>
> That way, we could still queue this series up for 6.19.
>
> Thoughts from everyone?
>
>
>
> Kind regards,
> Niklas


From macroalpha82 at gmail.com  Wed Nov 19 08:12:50 2025
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Wed, 19 Nov 2025 10:12:50 -0600
Subject: [PATCH] pmdomain: rockchip: quiet regulator error on -EPROBE_DEFER
Message-ID: <20251119161250.60885-1-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

Change the dev_err() to dev_err_probe() under rockchip_pd_power_on()
to prevent errors early in the boot process when the requested
regulator is not yet available. This converts errors like the following
to debug messages:

rockchip-pm-domain fd8d8000.power-management:power-controller: Failed to enable supply: -517

Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
---
 drivers/pmdomain/rockchip/pm-domains.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/pmdomain/rockchip/pm-domains.c b/drivers/pmdomain/rockchip/pm-domains.c
index 1955c6d453e4..3c84a65de1a5 100644
--- a/drivers/pmdomain/rockchip/pm-domains.c
+++ b/drivers/pmdomain/rockchip/pm-domains.c
@@ -688,7 +688,8 @@ static int rockchip_pd_power_on(struct generic_pm_domain *domain)
 
 	ret = rockchip_pd_regulator_enable(pd);
 	if (ret) {
-		dev_err(pd->pmu->dev, "Failed to enable supply: %d\n", ret);
+		dev_err_probe(pd->pmu->dev, ret,
+			      "Failed to enable supply: %d\n", ret);
 		return ret;
 	}
 
-- 
2.43.0



From macromorgan at hotmail.com  Wed Nov 19 08:24:57 2025
From: macromorgan at hotmail.com (Chris Morgan)
Date: Wed, 19 Nov 2025 10:24:57 -0600
Subject: [PATCH v2 2/3] drm/bridge: dw-hdmi-qp: Add support for missing
 HPD
In-Reply-To: <hgwfztkwk4qgvefwo2cdedzas3rzlhx6yek6dgldkgaq2jskvw@exxqujjpa6bl>
References: <20251113192939.30031-1-macroalpha82@gmail.com>
 <20251113192939.30031-3-macroalpha82@gmail.com>
 <avdnpwnxs6cql7eyckdt37szpcf5ztgxlc7juwu6tqj5xxu56a@nrwljig2p67i>
 <SN6PR1901MB46548ED8D4BA1184E0EA7DC3A5D6A@SN6PR1901MB4654.namprd19.prod.outlook.com>
 <hgwfztkwk4qgvefwo2cdedzas3rzlhx6yek6dgldkgaq2jskvw@exxqujjpa6bl>
Message-ID: <SN6PR1901MB46542ED12EF34220E3119460A5D7A@SN6PR1901MB4654.namprd19.prod.outlook.com>

On Wed, Nov 19, 2025 at 10:02:23AM +0100, Maxime Ripard wrote:
> On Tue, Nov 18, 2025 at 02:36:09PM -0600, Chris Morgan wrote:
> > On Tue, Nov 18, 2025 at 09:46:04AM +0100, Maxime Ripard wrote:
> > > Hi,
> > > 
> > > On Thu, Nov 13, 2025 at 01:29:38PM -0600, Chris Morgan wrote:
> > > > From: Chris Morgan <macromorgan at hotmail.com>
> > > > 
> > > > Add support for the dw-hdmi-qp driver to handle devices with missing
> > > > HPD pins.
> > > > 
> > > > Since in this situation we are now polling for the EDID data via i2c
> > > > change the error message to a debug message when we are unable to
> > > > complete an i2c read, as a disconnected device would otherwise fill
> > > > dmesg with i2c read errors.
> > > > 
> > > > Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
> > > 
> > > You must also disable any mode using the scrambler when there's no
> > > hotplug interrupt available.
> > 
> > Is there a simple way to do that? I'm not seeing any references to
> > scrambling in the current driver.
> > 
> > Should I just limit the rate to HDMI14_MAX_TMDSCLK (340000000)  under
> > dw_hdmi_qp_bridge_tmds_char_rate_valid() if using EDID polling? A
> > document I found online from Synopsys [1] claims that scrambling is
> > used by default at rates above 340 (if I'm reading it right) and used
> > opportunistically at rates below 340.
> 
> Yep, that's what you should be testing for :)
> 
> Maxime

Thanks, though now that I dig into it I'm a bit more confused on the
best way forward. It looks like for today the driver is hard-limited
to HDMI14_MAX_TMDSCLK because scrambling isn't supported. I'm assuming
it will be at some point, suggesting that we *will* need this in the
future. Is it sufficient to just add a comment there noting we need
to check, or should I add a check there (that does nothing today)
to ensure when we do support faster rates we are ready?

Thank you,
Chris


From neil.armstrong at linaro.org  Wed Nov 19 08:49:08 2025
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Wed, 19 Nov 2025 17:49:08 +0100
Subject: (subset) [PATCH 0/9] drm/rockchip: Introduce Rockchip RK3506
 VOP
In-Reply-To: <20251106020632.92-1-kernel@airkyi.com>
References: <20251106020632.92-1-kernel@airkyi.com>
Message-ID: <176357094817.280640.17849339974679922280.b4-ty@linaro.org>

Hi,

On Thu, 06 Nov 2025 10:06:23 +0800, Chaoyi Chen wrote:
> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> 
> The VOP on rk3506:
> - Support 2 lane MIPI DSI interface, 1.5Gbps/lane.
> - Support RGB interface.
> - Max output resolution is 1280x1280 at 60fps.
> - WIN1 layer support RGB888/ARGB8888/RGB565.
> - Support Gamma LUT.
> 
> [...]

Thanks, Applied to https://gitlab.freedesktop.org/drm/misc/kernel.git (drm-misc-next)

[1/9] dt-bindings: ili9881c: Add compatible string for Wanchanglong w552946aaa
      https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/15e794bcbc9527736d33c96412ce077bd817d9af
[5/9] drm/panel: ilitek-ili9881d: Add support for Wanchanglong W552946AAA panel
      https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/89b34ebed02ee39ae02069dcf2e5728aceec9deb

-- 
Neil



From cristian.ciocaltea at collabora.com  Wed Nov 19 09:49:23 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Wed, 19 Nov 2025 19:49:23 +0200
Subject: [PATCH v2 2/3] drm/bridge: dw-hdmi-qp: Add support for missing
 HPD
In-Reply-To: <SN6PR1901MB46542ED12EF34220E3119460A5D7A@SN6PR1901MB4654.namprd19.prod.outlook.com>
References: <20251113192939.30031-1-macroalpha82@gmail.com>
 <20251113192939.30031-3-macroalpha82@gmail.com>
 <avdnpwnxs6cql7eyckdt37szpcf5ztgxlc7juwu6tqj5xxu56a@nrwljig2p67i>
 <SN6PR1901MB46548ED8D4BA1184E0EA7DC3A5D6A@SN6PR1901MB4654.namprd19.prod.outlook.com>
 <hgwfztkwk4qgvefwo2cdedzas3rzlhx6yek6dgldkgaq2jskvw@exxqujjpa6bl>
 <SN6PR1901MB46542ED12EF34220E3119460A5D7A@SN6PR1901MB4654.namprd19.prod.outlook.com>
Message-ID: <485c4a78-c20b-492a-8c27-07ef63323735@collabora.com>

On 11/19/25 6:24 PM, Chris Morgan wrote:
> On Wed, Nov 19, 2025 at 10:02:23AM +0100, Maxime Ripard wrote:
>> On Tue, Nov 18, 2025 at 02:36:09PM -0600, Chris Morgan wrote:
>>> On Tue, Nov 18, 2025 at 09:46:04AM +0100, Maxime Ripard wrote:
>>>> Hi,
>>>>
>>>> On Thu, Nov 13, 2025 at 01:29:38PM -0600, Chris Morgan wrote:
>>>>> From: Chris Morgan <macromorgan at hotmail.com>
>>>>>
>>>>> Add support for the dw-hdmi-qp driver to handle devices with missing
>>>>> HPD pins.
>>>>>
>>>>> Since in this situation we are now polling for the EDID data via i2c
>>>>> change the error message to a debug message when we are unable to
>>>>> complete an i2c read, as a disconnected device would otherwise fill
>>>>> dmesg with i2c read errors.
>>>>>
>>>>> Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
>>>>
>>>> You must also disable any mode using the scrambler when there's no
>>>> hotplug interrupt available.
>>>
>>> Is there a simple way to do that? I'm not seeing any references to
>>> scrambling in the current driver.
>>>
>>> Should I just limit the rate to HDMI14_MAX_TMDSCLK (340000000)  under
>>> dw_hdmi_qp_bridge_tmds_char_rate_valid() if using EDID polling? A
>>> document I found online from Synopsys [1] claims that scrambling is
>>> used by default at rates above 340 (if I'm reading it right) and used
>>> opportunistically at rates below 340.
>>
>> Yep, that's what you should be testing for :)
>>
>> Maxime
> 
> Thanks, though now that I dig into it I'm a bit more confused on the
> best way forward. It looks like for today the driver is hard-limited
> to HDMI14_MAX_TMDSCLK because scrambling isn't supported. I'm assuming
> it will be at some point, suggesting that we *will* need this in the
> future. Is it sufficient to just add a comment there noting we need
> to check, or should I add a check there (that does nothing today)
> to ensure when we do support faster rates we are ready?

I plan to work on upstreaming the scrambling support soon.  Adding a TODO
comment would be enough for me to take care of the rest, but I'll still need
your help to get that tested, though. :-)

Cristian


From macromorgan at hotmail.com  Wed Nov 19 10:27:24 2025
From: macromorgan at hotmail.com (Chris Morgan)
Date: Wed, 19 Nov 2025 12:27:24 -0600
Subject: [PATCH v2 2/3] drm/bridge: dw-hdmi-qp: Add support for missing
 HPD
In-Reply-To: <485c4a78-c20b-492a-8c27-07ef63323735@collabora.com>
References: <20251113192939.30031-1-macroalpha82@gmail.com>
 <20251113192939.30031-3-macroalpha82@gmail.com>
 <avdnpwnxs6cql7eyckdt37szpcf5ztgxlc7juwu6tqj5xxu56a@nrwljig2p67i>
 <SN6PR1901MB46548ED8D4BA1184E0EA7DC3A5D6A@SN6PR1901MB4654.namprd19.prod.outlook.com>
 <hgwfztkwk4qgvefwo2cdedzas3rzlhx6yek6dgldkgaq2jskvw@exxqujjpa6bl>
 <SN6PR1901MB46542ED12EF34220E3119460A5D7A@SN6PR1901MB4654.namprd19.prod.outlook.com>
 <485c4a78-c20b-492a-8c27-07ef63323735@collabora.com>
Message-ID: <SN6PR1901MB4654C7B215573639E428B21BA5D7A@SN6PR1901MB4654.namprd19.prod.outlook.com>

On Wed, Nov 19, 2025 at 07:49:23PM +0200, Cristian Ciocaltea wrote:
> On 11/19/25 6:24 PM, Chris Morgan wrote:
> > On Wed, Nov 19, 2025 at 10:02:23AM +0100, Maxime Ripard wrote:
> >> On Tue, Nov 18, 2025 at 02:36:09PM -0600, Chris Morgan wrote:
> >>> On Tue, Nov 18, 2025 at 09:46:04AM +0100, Maxime Ripard wrote:
> >>>> Hi,
> >>>>
> >>>> On Thu, Nov 13, 2025 at 01:29:38PM -0600, Chris Morgan wrote:
> >>>>> From: Chris Morgan <macromorgan at hotmail.com>
> >>>>>
> >>>>> Add support for the dw-hdmi-qp driver to handle devices with missing
> >>>>> HPD pins.
> >>>>>
> >>>>> Since in this situation we are now polling for the EDID data via i2c
> >>>>> change the error message to a debug message when we are unable to
> >>>>> complete an i2c read, as a disconnected device would otherwise fill
> >>>>> dmesg with i2c read errors.
> >>>>>
> >>>>> Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
> >>>>
> >>>> You must also disable any mode using the scrambler when there's no
> >>>> hotplug interrupt available.
> >>>
> >>> Is there a simple way to do that? I'm not seeing any references to
> >>> scrambling in the current driver.
> >>>
> >>> Should I just limit the rate to HDMI14_MAX_TMDSCLK (340000000)  under
> >>> dw_hdmi_qp_bridge_tmds_char_rate_valid() if using EDID polling? A
> >>> document I found online from Synopsys [1] claims that scrambling is
> >>> used by default at rates above 340 (if I'm reading it right) and used
> >>> opportunistically at rates below 340.
> >>
> >> Yep, that's what you should be testing for :)
> >>
> >> Maxime
> > 
> > Thanks, though now that I dig into it I'm a bit more confused on the
> > best way forward. It looks like for today the driver is hard-limited
> > to HDMI14_MAX_TMDSCLK because scrambling isn't supported. I'm assuming
> > it will be at some point, suggesting that we *will* need this in the
> > future. Is it sufficient to just add a comment there noting we need
> > to check, or should I add a check there (that does nothing today)
> > to ensure when we do support faster rates we are ready?
> 
> I plan to work on upstreaming the scrambling support soon.  Adding a TODO
> comment would be enough for me to take care of the rest, but I'll still need
> your help to get that tested, though. :-)
> 
> Cristian

Okay, I'll add a TODO there to make sure that we put in special handling for
when we have scrambling enabled, then when you have patches ready I can test
it.

Thank you,
Chris


From luca.ceresoli at bootlin.com  Wed Nov 19 11:49:42 2025
From: luca.ceresoli at bootlin.com (Luca Ceresoli)
Date: Wed, 19 Nov 2025 20:49:42 +0100
Subject: [PATCH v9 08/10] drm/rockchip: cdn-dp: Add multiple bridges to
 support PHY port selection
In-Reply-To: <2ebace6f-d3c4-4516-b6cb-4951de06b6c8@rock-chips.com>
References: <20251111105040.94-1-kernel@airkyi.com>
 <20251111105040.94-9-kernel@airkyi.com>
 <DE5YP3AVGOG3.OHP68Z0F6KBU@bootlin.com>
 <b1a339e7-a011-4b4b-8988-2e3768753c85@rock-chips.com>
 <2ebace6f-d3c4-4516-b6cb-4951de06b6c8@rock-chips.com>
Message-ID: <DECXKE9A67HG.35AR5UZKKQ8A1@bootlin.com>

Hello Chaoyi,

On Mon Nov 17, 2025 at 2:33 AM CET, Chaoyi Chen wrote:
...
>>>> +??? /* One endpoint may correspond to one next bridge. */
>>>> +??? for_each_of_graph_port_endpoint(port, dp_ep) {
>>>> +??????? struct device_node *next_bridge_node __free(device_node) =
>>>> +??????????? of_graph_get_remote_port_parent(dp_ep);
>>>> +
>>>> +??????? bridge = of_drm_find_bridge(next_bridge_node);
>>>> +??????? if (!bridge) {
>>>> +??????????? ret = -EPROBE_DEFER;
>>>> +??????????? goto out;
>>>> +??????? }
>>>> +
>>>> +??????? dp->next_bridge_valid = true;
>>>> +??????? dp->next_bridge_list[count].bridge = bridge;
>>> You are storing a reference to a drm_bridge, so have to increment the
>>> refcount:
>>>
>>> ??????? dp->next_bridge_list[count].bridge = drm_bridge_get(bridge);
>>> ???????????????????????????????????????????? ^^^^^^^^^^^^^^
>>>
>>> FYI there is a plan to replace of_drm_find_bridge() with a function that
>>> increases the bridge refcount before returning the bridge, but it's not
>>> there yet. When that will happen, the explicit drm_bridge_get() won't be
>>> needed anymore and this code can be updated accordingly.
>
> Out of curiosity, I checked the callers of of_drm_find_bridge(), and it
> seems that the vast majority of them do not pay attention to the increase
> or decrease of reference counts.

They do not call drm_bridge_put() to decrease the refcount, and that's
"correct" because of_drm_find_bridge() does not increase it. This was
totally correct in the past because DRM bridge refcounting did not exist.

Refcounting has been added to support hot-pluggable bridges. If you want
more info, this presentation I gave at ELCE 2025 is a good summary, with
links to relevant patches:

 * Video (start at 19:30): https://www.youtube.com/watch?v=msmBQBSyZZ4
 * Slides (start at slide 27):
   https://bootlin.com/pub/conferences/2025/elce/ceresoli-hotplug-status.pdf

> Does this mean that even if we add reference counting in
> of_drm_find_bridge(), we still need to modify the corresponding functions
> of their callers and decrease the reference count at the appropriate
> time?

Exactly. I have explored that approach but it turned out being not
reasonably doable due to the large number of (direct + indirect) callers of
of_drm_find_bridge() as well as the trickiness of those involvingthe
panel_bridge. So Maxime proposed a different approach [0]: deprecate
of_drm_find_bridge() and replace it with a function that increments the
refcount, then let the various callers move to the new function over time.

Earlier today I sent a series doing that, and converting lots of users
[1]. If/when that approach will be accepted, you can update your driver to
use the new drm_of_fund_bridge() and take care of putting the reference
when appropriate. But you don't need to do anything until then.

[0] https://lore.kernel.org/dri-devel/20250319-stylish-lime-mongoose-0a18ad at houat/
[1] https://lore.kernel.org/lkml/20251119-drm-bridge-alloc-getput-drm_of_find_bridge-v1-0-0db98a7fe474 at bootlin.com/

> Thank you.

You're welcome. I hope it was a clear explanation.

Luca

--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From cristian.ciocaltea at collabora.com  Wed Nov 19 13:09:27 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Wed, 19 Nov 2025 23:09:27 +0200
Subject: [PATCH i-g-t] tests: (Re)add kms_crtc_background_color test
In-Reply-To: <20251119132149.spbl5k3dmj2lwzon@kamilkon-DESK.igk.intel.com>
References: <20251110-crtc-bgcolor-v1-1-28669b692970@collabora.com>
 <20251119132149.spbl5k3dmj2lwzon@kamilkon-DESK.igk.intel.com>
Message-ID: <dd1717b7-4e20-4ed7-ae08-7286713d4a71@collabora.com>

Hi Kamil,

On 11/19/25 3:21 PM, Kamil Konieczny wrote:
> Hi Cristian,
> On 2025-11-10 at 15:18:05 +0200, Cristian Ciocaltea wrote:
>> Provide test to verify the behavior of BACKGROUND_COLOR DRM CRTC
>> property.
>>
>> This is done by filling a full-screen primary plane with a given color
>> and comparing the resulting CRC with the one obtained after turning off
>> all planes while having the CRTC background set to the same color.
>>
>> It's worth noting this is a reworked version of the test that has been
>> dropped over 5 years ago via commit 33f07391e5f6 ("tests: Remove
>> kms_crtc_background_color test"), as the required kernel changes never
>> landed because of missing userspace support.
>>
> +cc J-P, Karthik, Swati
> Cc: Juha-Pekka Heikkila <juhapekka.heikkila at gmail.com>
> Cc: Juha-Pekka Heikkila <juha-pekka.heikkila at intel.com>
> Cc: Karthik B S <karthik.b.s at intel.com>
> Cc: Swati Sharma <swati2.sharma at intel.com>
> 
> I have few nits, see below.
> 
>> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
>> ---
>> This has been tested on a Radxa ROCK 5B board which is based on Rockchip
>> RK3588 SoC.  It relies on the kernel series [1] introducing the
>> BACKGROUND_COLOR CRTC property and a few additional patches from [2]
>> enabling the required CRC functionality for the Rockchip platform (still
>> require a bit more work before sending those upstream).
>>
>> It's worth noting CRC is only supported by the display controller (VOP2)
>> present in the RK3576 SoC variant.  However, the computation is done by
>> the hardware before applying the background color, hence it has limited
>> usage in IGT testing.
>>
>> Luckily, the frame CRCs can be captured through DPCD, i.e. at
>> DisplayPort AUX channel level, hence I used the USB-C DP AltMode capable
>> port of the aforementioned board to perform the actual validation.
>>
>> [1] https://lore.kernel.org/all/20251013-rk3588-bgcolor-v2-0-25cc3810ba8c at collabora.com/
>> [2] https://gitlab.collabora.com/hardware-enablement/rockchip-3588/linux/-/commits/cristicc/rk3588-vop2-crc
>>

[...]

> Please add here:
> 
> /**
>  * TEST: crtc background color
>  * Category: Display
>  * Description: Test background color feature with CRC at CRTC
>  * Driver requirement: i915, xe
>  * Mega feature: General Display Features
>  */
> 
> Feel free to correct me with name and/or description.

Ack.

> Karthik or Swati, please also correct this if I made any
> mistake here.
> 
>> +#include "igt.h"
>> +
>> +IGT_TEST_DESCRIPTION("Test crtc background color feature");
>> +
>> +typedef struct {
>> +	int drm_fd;
>> +	int debugfs;
>> +	igt_display_t display;
>> +} data_t;
>> +
>> +#define __DRM_ARGB64_PREP(c, shift, bpc)			\
>> +	(((__u64)(c) << (16 - (bpc)) & 0xffffU) << (shift))
>> +
>> +#define DRM_ARGB64_PREP_BPC(alpha, red, green, blue, bpc)	\
>> +	(__DRM_ARGB64_PREP(alpha, 48, bpc) |			\
>> +	 __DRM_ARGB64_PREP(red,   32, bpc) |			\
>> +	 __DRM_ARGB64_PREP(green, 16, bpc) |			\
>> +	 __DRM_ARGB64_PREP(blue,   0, bpc))
>> +
>> +static void test_background(data_t *data, enum pipe pipe, igt_output_t *output,
>> +			    __u16 red, __u16 green, __u16 blue)
>> +{
>> +	igt_display_t *display = &data->display;
>> +	igt_crc_t plane_crc, bg_crc;
>> +	igt_pipe_crc_t *pipe_crc;
>> +	igt_plane_t *plane;
>> +	drmModeModeInfo *mode;
>> +	struct igt_fb fb;
>> +
>> +	igt_display_reset(display);
>> +
>> +	igt_output_set_pipe(output, pipe);
>> +	mode = igt_output_get_mode(output);
>> +
>> +	plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
>> +
>> +	/* Fill the primary plane and set the background to the same color */
>> +	igt_create_color_fb(data->drm_fd,
>> +			    mode->hdisplay, mode->vdisplay,
>> +			    DRM_FORMAT_XRGB8888,
>> +			    DRM_FORMAT_MOD_NONE,
>> +			    (double)red / 0xffff,
>> +			    (double)green / 0xffff,
>> +			    (double)blue / 0xffff,
>> +			    &fb);
>> +
>> +	igt_plane_set_fb(plane, &fb);
>> +	igt_pipe_set_prop_value(&data->display, pipe, IGT_CRTC_BACKGROUND,
>> +				DRM_ARGB64_PREP_BPC(0xffff, red, green, blue, 8));
>> +	igt_display_commit2(&data->display, COMMIT_ATOMIC);
>> +
>> +	pipe_crc = igt_pipe_crc_new(data->drm_fd, pipe, IGT_PIPE_CRC_SOURCE_AUTO);
>> +	igt_pipe_crc_collect_crc(pipe_crc, &plane_crc);
>> +
>> +	/* Turn off the primary plane so that only the background is visible */
>> +	igt_plane_set_fb(plane, NULL);
>> +	igt_display_commit2(&data->display, COMMIT_ATOMIC);
>> +	igt_pipe_crc_collect_crc(pipe_crc, &bg_crc);
>> +
>> +	/*
>> +	 * The test assumes hardware is able to generate valid CRCs when setting
>> +	 * the background color. Some platforms, e.g. Intel, might require at
>> +	 * least one plane to be visible before reading the pipe-level ("dmux")
>> +	 * CRC. Other platforms, e.g. Rockchip, do not take background color
>> +	 * into account when computing CRC at CRTC level.
>> +	 * A possible workaround would be to use alternative CRC sources, e.g.
>> +	 * where computation is performed at encoder or sink level.
>> +	 */
>> +	igt_assert_crc_equal(&plane_crc, &bg_crc);
>> +
>> +	/* Clean-up */
>> +	igt_pipe_set_prop_value(&data->display, pipe, IGT_CRTC_BACKGROUND,
>> +				DRM_ARGB64_PREP_BPC(0xffff, 0, 0, 0, 8));
>> +	igt_pipe_crc_free(pipe_crc);
>> +	igt_output_set_pipe(output, PIPE_NONE);
>> +	igt_display_commit(display);
>> +	igt_remove_fb(data->drm_fd, &fb);
>> +}
>> +
> 
> Add here:
> 
> /**
>  * SUBTEST: background-color-%s
>  * Description: Tests %arg[1] in background color
>  *
>  * arg[1]:
>  *
>  * @red:      red
>  * @green:    green
>  * @blue:     blue
>  * @yellow:   yellow
>  * @purple:   purple
>  * @cyan:     cyan
>  * @black:    black
>  * @white:    white
>  */
> 
> With this it will compile and will be tested by Intel CI.

Great!  Please note there's already a 2nd revision [1] available which might
require adjusting your kernel driver due to the following change:

- Set the value of the CRTC background color property with 16bpc instead
  of 8bpc, to avoid CRC check failures because of framebuffer format
  precision mismatch - display controller drivers shall convert it back
  from 16bpc to their internal representation of the pixel color if
  necessary, e.g. VKMS already uses 16bpc, hence no conversion is
  required in that case

[1] https://lore.kernel.org/all/20251118-crtc-bgcolor-v2-1-dce4063f85a9 at collabora.com/


From macroalpha82 at gmail.com  Wed Nov 19 14:55:24 2025
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Wed, 19 Nov 2025 16:55:24 -0600
Subject: [PATCH V3 1/3] dt-bindings: display: rockchip: Add no-hpd for dw-hdmi-qp controller
In-Reply-To: <20251119225526.70588-1-macroalpha82@gmail.com>
References: <20251119225526.70588-1-macroalpha82@gmail.com>
Message-ID: <20251119225526.70588-2-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

Add an attribute of "no-hpd" for the Rockchip dw-hdmi-qp controller.
This is used to describe implementations where the HPD pin is not
connected or used for other purposes, such as in the RK3588S based
Gameforce Ace which repurposed the GPIO for an additional face
button.

The "no-hpd" option was chosen to be consistent with other devices
which already define this parameter for broken or missing hpd
functionality.

Acked-by: Conor Dooley <conor.dooley at microchip.com>
Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
---
 .../display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml        | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml
index 96b4b088eebe..07342838cd52 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3588-dw-hdmi-qp.yaml
@@ -69,6 +69,12 @@ properties:
       - const: main
       - const: hpd
 
+  no-hpd:
+    type: boolean
+    description:
+      The HPD pin is not present or used for another purpose, and the EDID
+      must be polled instead to determine if a device is attached.
+
   phys:
     maxItems: 1
     description: The HDMI/eDP PHY
-- 
2.43.0



From macroalpha82 at gmail.com  Wed Nov 19 14:55:23 2025
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Wed, 19 Nov 2025 16:55:23 -0600
Subject: [PATCH V3 0/3] Add HDMI for Gameforce Ace
Message-ID: <20251119225526.70588-1-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

Add support for the micro HDMI port for the Gameforce Ace. This port does
not have a HPD pin so it requires making changes to the HDMI controller
to support this configuration.

Changes since v1:
 - Simplified checking of no-hpd parameter and changed to
   device_property_read_bool() function.

Changes since v2:
 - Changed dev_dbg i2c read and write errors to i2c_dbg_ratelimited.
 - Added a TODO: note in an appropriate location to disable or limit
   the ability for this driver to enable scrambling when no_hpd = 1.
   Scrambling is not currently supported by this driver but the author
   expects that it will be soon.

Chris Morgan (3):
  dt-bindings: display: rockchip: Add no-hpd for dw-hdmi-qp controller
  drm/bridge: dw-hdmi-qp: Add support for missing HPD
  arm64: dts: rockchip: Add HDMI to Gameforce Ace

 .../rockchip/rockchip,rk3588-dw-hdmi-qp.yaml  |  6 ++
 .../dts/rockchip/rk3588s-gameforce-ace.dts    | 63 +++++++++++++++++++
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c  | 34 ++++++++--
 3 files changed, 99 insertions(+), 4 deletions(-)

-- 
2.43.0



From macroalpha82 at gmail.com  Wed Nov 19 14:55:25 2025
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Wed, 19 Nov 2025 16:55:25 -0600
Subject: [PATCH V3 2/3] drm/bridge: dw-hdmi-qp: Add support for missing HPD
In-Reply-To: <20251119225526.70588-1-macroalpha82@gmail.com>
References: <20251119225526.70588-1-macroalpha82@gmail.com>
Message-ID: <20251119225526.70588-3-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

Add support for the dw-hdmi-qp driver to handle devices with missing
HPD pins.

Since in this situation we are now polling for the EDID data via i2c
change the error message to a rate limited debug message when we are
unable to complete an i2c read, as a disconnected device would
otherwise fill dmesg with i2c read errors.

Reviewed-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 34 +++++++++++++++++---
 1 file changed, 30 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
index 39332c57f2c5..929b2e95a5c5 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
@@ -145,6 +145,7 @@ struct dw_hdmi_qp {
 	struct regmap *regm;
 
 	unsigned long tmds_char_rate;
+	bool no_hpd;
 };
 
 static void dw_hdmi_qp_write(struct dw_hdmi_qp *hdmi, unsigned int val,
@@ -535,14 +536,22 @@ static int dw_hdmi_qp_i2c_read(struct dw_hdmi_qp *hdmi,
 
 		stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10);
 		if (!stat) {
-			dev_err(hdmi->dev, "i2c read timed out\n");
+			if (hdmi->no_hpd)
+				dev_dbg_ratelimited(hdmi->dev,
+						    "i2c read timed out\n");
+			else
+				dev_err(hdmi->dev, "i2c read timed out\n");
 			dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0);
 			return -EAGAIN;
 		}
 
 		/* Check for error condition on the bus */
 		if (i2c->stat & I2CM_NACK_RCVD_IRQ) {
-			dev_err(hdmi->dev, "i2c read error\n");
+			if (hdmi->no_hpd)
+				dev_dbg_ratelimited(hdmi->dev,
+						    "i2c read error\n");
+			else
+				dev_err(hdmi->dev, "i2c read error\n");
 			dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0);
 			return -EIO;
 		}
@@ -879,6 +888,15 @@ static enum drm_connector_status
 dw_hdmi_qp_bridge_detect(struct drm_bridge *bridge, struct drm_connector *connector)
 {
 	struct dw_hdmi_qp *hdmi = bridge->driver_private;
+	const struct drm_edid *drm_edid;
+
+	if (hdmi->no_hpd) {
+		drm_edid = drm_edid_read_ddc(connector, bridge->ddc);
+		if (drm_edid)
+			return connector_status_connected;
+		else
+			return connector_status_disconnected;
+	}
 
 	return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
 }
@@ -904,6 +922,11 @@ dw_hdmi_qp_bridge_tmds_char_rate_valid(const struct drm_bridge *bridge,
 {
 	struct dw_hdmi_qp *hdmi = bridge->driver_private;
 
+	/*
+	 * TODO: when hdmi->no_hpd is 1 we must not support modes that
+	 * require scrambling, including every mode with a clock above
+	 * HDMI14_MAX_TMDSCLK.
+	 */
 	if (rate > HDMI14_MAX_TMDSCLK) {
 		dev_dbg(hdmi->dev, "Unsupported TMDS char rate: %lld\n", rate);
 		return MODE_CLOCK_HIGH;
@@ -1074,12 +1097,15 @@ struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev,
 	if (ret)
 		return ERR_PTR(ret);
 
+	hdmi->no_hpd = device_property_read_bool(dev, "no-hpd");
+
 	hdmi->bridge.driver_private = hdmi;
 	hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT |
 			   DRM_BRIDGE_OP_EDID |
 			   DRM_BRIDGE_OP_HDMI |
-			   DRM_BRIDGE_OP_HDMI_AUDIO |
-			   DRM_BRIDGE_OP_HPD;
+			   DRM_BRIDGE_OP_HDMI_AUDIO;
+	if (!hdmi->no_hpd)
+		hdmi->bridge.ops |= DRM_BRIDGE_OP_HPD;
 	hdmi->bridge.of_node = pdev->dev.of_node;
 	hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
 	hdmi->bridge.vendor = "Synopsys";
-- 
2.43.0



From macroalpha82 at gmail.com  Wed Nov 19 14:55:26 2025
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Wed, 19 Nov 2025 16:55:26 -0600
Subject: [PATCH V3 3/3] arm64: dts: rockchip: Add HDMI to Gameforce Ace
In-Reply-To: <20251119225526.70588-1-macroalpha82@gmail.com>
References: <20251119225526.70588-1-macroalpha82@gmail.com>
Message-ID: <20251119225526.70588-4-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

Add support for the HDMI port for the Gameforce Ace. The HDMI port
has no HPD pin present (the manufacturer's devicetree states the pin
is reused for an additional face button) so add the attribute of
no-hpd to poll for connected devices.

Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
---
 .../dts/rockchip/rk3588s-gameforce-ace.dts    | 63 +++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts b/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts
index f5894672fcbd..b98e1a3369dc 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts
@@ -300,6 +300,20 @@ amp_headphone: headphone-amplifier {
 		sound-name-prefix = "Headphones Amplifier";
 	};
 
+	hdmi0-con {
+		compatible = "hdmi-connector";
+		ddc-en-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_HIGH>;
+		pinctrl-0 = <&hdmi0_en>;
+		pinctrl-names = "default";
+		type = "d";
+
+		port {
+			hdmi0_con_in: endpoint {
+				remote-endpoint = <&hdmi0_out_con>;
+			};
+		};
+	};
+
 	pwm_fan: pwm-fan {
 		compatible = "pwm-fan";
 		#cooling-cells = <2>;
@@ -498,6 +512,34 @@ &gpu {
 	status = "okay";
 };
 
+&hdmi0 {
+	no-hpd;
+	pinctrl-0 = <&hdmim0_tx0_cec>, <&hdmim0_tx0_scl>,
+		    <&hdmim0_tx0_sda>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&hdmi0_in {
+	hdmi0_in_vp0: endpoint {
+		remote-endpoint = <&vp0_out_hdmi0>;
+	};
+};
+
+&hdmi0_out {
+	hdmi0_out_con: endpoint {
+		remote-endpoint = <&hdmi0_con_in>;
+	};
+};
+
+&hdmi0_sound {
+	status = "okay";
+};
+
+&hdptxphy0 {
+	status = "okay";
+};
+
 &i2c0 {
 	pinctrl-0 = <&i2c0m2_xfer>;
 	pinctrl-names = "default";
@@ -746,6 +788,10 @@ &i2s0_sdi0
 	status = "okay";
 };
 
+&i2s5_8ch {
+	status = "okay";
+};
+
 &mipidcphy0 {
 	status = "okay";
 };
@@ -842,6 +888,13 @@ charger_int_h: charger-int-h {
 		};
 	};
 
+	hdmi {
+		hdmi0_en: hdmi0-en {
+			rockchip,pins =
+				<4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
 	hym8563 {
 		hym8563_int: hym8563-int {
 			rockchip,pins =
@@ -1416,6 +1469,16 @@ &vop_mmu {
 	status = "okay";
 };
 
+&vp0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	vp0_out_hdmi0: endpoint at ROCKCHIP_VOP2_EP_HDMI0 {
+		reg = <ROCKCHIP_VOP2_EP_HDMI0>;
+		remote-endpoint = <&hdmi0_in_vp0>;
+	};
+};
+
 &vp3 {
 	#address-cells = <1>;
 	#size-cells = <0>;
-- 
2.43.0



From shawn.lin at rock-chips.com  Wed Nov 19 16:34:11 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Thu, 20 Nov 2025 08:34:11 +0800
Subject: [PATCH] pmdomain: rockchip: quiet regulator error on
 -EPROBE_DEFER
In-Reply-To: <20251119161250.60885-1-macroalpha82@gmail.com>
References: <20251119161250.60885-1-macroalpha82@gmail.com>
Message-ID: <1451d8b9-0751-4785-9644-9ce68230ed27@rock-chips.com>

? 2025/11/20 ??? 0:12, Chris Morgan ??:
> From: Chris Morgan <macromorgan at hotmail.com>
> 
> Change the dev_err() to dev_err_probe() under rockchip_pd_power_on()
> to prevent errors early in the boot process when the requested
> regulator is not yet available. This converts errors like the following
> to debug messages:
> 
> rockchip-pm-domain fd8d8000.power-management:power-controller: Failed to enable supply: -517
> 
> Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
> ---
>   drivers/pmdomain/rockchip/pm-domains.c | 3 ++-
>   1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pmdomain/rockchip/pm-domains.c b/drivers/pmdomain/rockchip/pm-domains.c
> index 1955c6d453e4..3c84a65de1a5 100644
> --- a/drivers/pmdomain/rockchip/pm-domains.c
> +++ b/drivers/pmdomain/rockchip/pm-domains.c
> @@ -688,7 +688,8 @@ static int rockchip_pd_power_on(struct generic_pm_domain *domain)
>   
>   	ret = rockchip_pd_regulator_enable(pd);
>   	if (ret) {
> -		dev_err(pd->pmu->dev, "Failed to enable supply: %d\n", ret);
> +		dev_err_probe(pd->pmu->dev, ret,
> +			      "Failed to enable supply: %d\n", ret);
>   		return ret;

return dev_err_probe(pd->pmu->dev, ret, "Failed to enable supply: %d\n", 
ret); ?

>   	}
>   



From shawn.lin at rock-chips.com  Wed Nov 19 16:53:38 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Thu, 20 Nov 2025 08:53:38 +0800
Subject: [PATCH v2 1/4] PCI: dwc: Advertise L1 PM Substates only if driver
 requests it
In-Reply-To: <aR3pEaJ4oTagaKU8@lizhi-Precision-Tower-5810>
References: <20251118214312.2598220-1-helgaas@kernel.org>
 <20251118214312.2598220-2-helgaas@kernel.org>
 <aRz0ak6onKzZs2lY@lizhi-Precision-Tower-5810> <aR2lOZDBEdGVd9On@ryzen>
 <aR3pEaJ4oTagaKU8@lizhi-Precision-Tower-5810>
Message-ID: <7608cf17-75cf-4b7b-a326-f3233771c662@rock-chips.com>

? 2025/11/19 ??? 23:58, Frank Li ??:
> On Wed, Nov 19, 2025 at 12:08:41PM +0100, Niklas Cassel wrote:
>> On Tue, Nov 18, 2025 at 05:34:18PM -0500, Frank Li wrote:
>>> On Tue, Nov 18, 2025 at 03:42:15PM -0600, Bjorn Helgaas wrote:
>>>> From: Bjorn Helgaas <bhelgaas at google.com>
>>>>
>>>> L1 PM Substates require the CLKREQ# signal and may also require
>>>> device-specific support.  If CLKREQ# is not supported or driver support is
>>>> lacking, enabling L1.1 or L1.2 may cause errors when accessing devices,
>>>> e.g.,
>>>>
>>>>    nvme nvme0: controller is down; will reset: CSTS=0xffffffff, PCI_STATUS=0x10
>>>>
>>>> If the kernel is built with CONFIG_PCIEASPM_POWER_SUPERSAVE=y or users
>>>> enable L1.x via sysfs, users may trip over these errors even if L1
>>>> Substates haven't been enabled by firmware or the driver.
>>>>
>>>> To prevent such errors, disable advertising the L1 PM Substates unless the
>>>> driver sets "dw_pcie.l1ss_support" to indicate that it knows CLKREQ# is
>>>> present and any device-specific configuration has been done.
>>>>
>>>> Set "dw_pcie.l1ss_support" in tegra194 (if DT includes the
>>>> "supports-clkreq' property) and qcom (for cfg_2_7_0, cfg_1_9_0, cfg_1_34_0,
>>>> and cfg_sc8280xp controllers) so they can continue to use L1 Substates.
>>>>
>>>> Based on Niklas's patch:
>>>> https://patch.msgid.link/20251017163252.598812-2-cassel at kernel.org
>>>>
>>>> Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
>>>> ---
>>>>   .../pci/controller/dwc/pcie-designware-ep.c   |  2 ++
>>>>   .../pci/controller/dwc/pcie-designware-host.c |  2 ++
>>>>   drivers/pci/controller/dwc/pcie-designware.c  | 24 +++++++++++++++++++
>>>>   drivers/pci/controller/dwc/pcie-designware.h  |  2 ++
>>>>   drivers/pci/controller/dwc/pcie-qcom.c        |  2 ++
>>>>   drivers/pci/controller/dwc/pcie-tegra194.c    |  3 +++
>>>>   6 files changed, 35 insertions(+)
>>>>
>>>> diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
>>>> index 7f2112c2fb21..ad6c0fd67a65 100644
>>>> --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
>>>> +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
>>>> @@ -966,6 +966,8 @@ int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)
>>>>   	if (ep->ops->init)
>>>>   		ep->ops->init(ep);
>>>>
>>>> +	dw_pcie_hide_unsupported_l1ss(pci);
>>>> +
>>>
>>> And, I don't think EP need clean L1SS CAP flags. If EP don't support L1SS,
>>> it should be force pull down #clkreq.
>>
>> I think the problem is that we cannot force pull down CLKREQ# in a generic
>> DWC function. That would have to be done in glue driver specific callbacks.
>>
>> Bjorn, perhaps we should simply drop the dw_pcie_hide_unsupported_l1ss()
>> call from dw_pcie_ep_init_registers(), and consider hiding L1ss for EPs to
>> be out of scope for this series.
> 
> 
> Agree, we should consider EP later. When work at EP mode, #clkreq default
> it is 0. RC should not turn L1SS if RC don't support. If RC side support,
> it should be fine by turing on EP's L1SS because hardware already support
> it.

I agree to drop it from dw_pcie_ep_init_registers, and queue it up for
6.19.

Don't get me wrong, but I just need clearly speak out the thought: I
think the idea behind is something like quirk that a variant controller
works on EP mode claiming L1ss available through *CAP* regs but actually
it doesn't. This is nothing related to RC side, even if it pulls down
CLKREQ# to reject negotiation for L1ss, it still looks wrong from lspci
view. So of course, we could leave it to the glue driver to explictly
eliminate L1SS capability later. If they want, just export
dw_pcie_hide_unsupported_l1ss() the call it.

> 
> Frank
> 
>>
>> That way, we could still queue this series up for 6.19.
>>
>> Thoughts from everyone?
>>
>>
>>
>> Kind regards,
>> Niklas
> 



From kernel at airkyi.com  Wed Nov 19 18:23:34 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Thu, 20 Nov 2025 10:23:34 +0800
Subject: [PATCH v10 02/11] usb: typec: Export all typec device types
In-Reply-To: <20251120022343.250-1-kernel@airkyi.com>
References: <20251120022343.250-1-kernel@airkyi.com>
Message-ID: <20251120022343.250-3-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

Export all typec device types for identification.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
Reviewed-by: Heikki Krogerus <heikki.krogerus at linux.intel.com>
---

(no changes since v9)

 drivers/usb/typec/class.c |  4 ++++
 drivers/usb/typec/class.h | 10 ----------
 include/linux/usb/typec.h | 10 ++++++++++
 3 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
index 1ccf5385d559..957add6b73e9 100644
--- a/drivers/usb/typec/class.c
+++ b/drivers/usb/typec/class.c
@@ -793,6 +793,7 @@ const struct device_type typec_partner_dev_type = {
 	.groups = typec_partner_groups,
 	.release = typec_partner_release,
 };
+EXPORT_SYMBOL_GPL(typec_partner_dev_type);
 
 static void typec_partner_link_device(struct typec_partner *partner, struct device *dev)
 {
@@ -1147,6 +1148,7 @@ const struct device_type typec_plug_dev_type = {
 	.groups = typec_plug_groups,
 	.release = typec_plug_release,
 };
+EXPORT_SYMBOL_GPL(typec_plug_dev_type);
 
 /**
  * typec_plug_set_num_altmodes - Set the number of available plug altmodes
@@ -1295,6 +1297,7 @@ const struct device_type typec_cable_dev_type = {
 	.groups = typec_cable_groups,
 	.release = typec_cable_release,
 };
+EXPORT_SYMBOL_GPL(typec_cable_dev_type);
 
 /**
  * typec_cable_get - Get a reference to the USB Type-C cable
@@ -2034,6 +2037,7 @@ const struct device_type typec_port_dev_type = {
 	.uevent = typec_uevent,
 	.release = typec_release,
 };
+EXPORT_SYMBOL_GPL(typec_port_dev_type);
 
 /* --------------------------------------- */
 /* Driver callbacks to report role updates */
diff --git a/drivers/usb/typec/class.h b/drivers/usb/typec/class.h
index db2fe96c48ff..f04f6987bed8 100644
--- a/drivers/usb/typec/class.h
+++ b/drivers/usb/typec/class.h
@@ -87,16 +87,6 @@ struct typec_port {
 #define to_typec_cable(_dev_) container_of(_dev_, struct typec_cable, dev)
 #define to_typec_partner(_dev_) container_of(_dev_, struct typec_partner, dev)
 
-extern const struct device_type typec_partner_dev_type;
-extern const struct device_type typec_cable_dev_type;
-extern const struct device_type typec_plug_dev_type;
-extern const struct device_type typec_port_dev_type;
-
-#define is_typec_partner(dev) ((dev)->type == &typec_partner_dev_type)
-#define is_typec_cable(dev) ((dev)->type == &typec_cable_dev_type)
-#define is_typec_plug(dev) ((dev)->type == &typec_plug_dev_type)
-#define is_typec_port(dev) ((dev)->type == &typec_port_dev_type)
-
 extern const struct class typec_mux_class;
 extern const struct class retimer_class;
 extern const struct class typec_class;
diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h
index 309251572e2e..02fed8293415 100644
--- a/include/linux/usb/typec.h
+++ b/include/linux/usb/typec.h
@@ -56,6 +56,16 @@ enum typec_role {
 	TYPEC_SOURCE,
 };
 
+extern const struct device_type typec_partner_dev_type;
+extern const struct device_type typec_cable_dev_type;
+extern const struct device_type typec_plug_dev_type;
+extern const struct device_type typec_port_dev_type;
+
+#define is_typec_partner(dev) ((dev)->type == &typec_partner_dev_type)
+#define is_typec_cable(dev) ((dev)->type == &typec_cable_dev_type)
+#define is_typec_plug(dev) ((dev)->type == &typec_plug_dev_type)
+#define is_typec_port(dev) ((dev)->type == &typec_port_dev_type)
+
 static inline int is_sink(enum typec_role role)
 {
 	return role == TYPEC_SINK;
-- 
2.51.1



From kernel at airkyi.com  Wed Nov 19 18:23:32 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Thu, 20 Nov 2025 10:23:32 +0800
Subject: [PATCH v10 00/11] Add Type-C DP support for RK3399 EVB IND board
Message-ID: <20251120022343.250-1-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

This series focuses on adding Type-C DP support for USBDP PHY and DP
driver. The USBDP PHY and DP will perceive the changes in cable status
based on the USB PD and Type-C state machines provided by TCPM. Before
this, the USBDP PHY and DP controller of RK3399 sensed cable state
changes through extcon, and devices such as the RK3399 Gru-Chromebook
rely on them. This series should not break them.

====
1. DisplayPort HPD status notify

Before v7, I implemented a variety of DP HPD status notify. However,
they all had various problems and it was difficult to become a generic
solution.

Under the guidance of Heikki and Dmitry, a decoupled notification
method between the TypeC and DRM subsystems was introduced in v7.
First, a notification is sent when TypeC registers a new altmode.
Then, a generic DP AUX HPD bridge is implemented on the DRM side.

That makes it redundant for each Type-C controller driver to implement
a similar DP AUX HPD bridge in embedded scenarios.

====
2. Altmode switching and orientation switching for USBDP PHY

For USB Type-C interfaces, an external Type-C controller chip assists
by detecting cable attachment, determining plug orientation, and
reporting USB PD message. The USB/DP combo PHY supports software
configurable pin mapping and DisplayPort lane assignment. Based on
these message, the combo PHY can perform both altmode switching and
orientation switching via software.

The RK3399 EVB IND board has a Type-C interface DisplayPort. It use
fusb302 chip as Type-C controller. The connection diagram is shown below:

fusb302 chip +---> USB2.0 PHY ----> DWC3 USB controller
             |
             +---> USB/DP PHY0 +--> CDN-DP controller
                               |
                               +--> DWC3 USB controller

====
3. Multiple bridge model for RK3399 CDN-DP

The RK3399 has two USB/DP combo PHY and one CDN-DP controller. And
the CDN-DP can be switched to output to one of the PHYs.

USB/DP PHY0 ---+
               | <----> CDN-DP controller
USB/DP PHY1 ---+

In previous versions, if both PHY ports were connected to DP,
the CDN-DP driver would select the first PHY port for output.

On Dmitry's suggestion, we introduced a multi-bridge model to support
flexible selection of the output PHY port. For each PHY port, a
separate encoder and bridge are registered.

The change is based on the DRM AUX HPD bridge, rather than the
extcon approach. This requires the DT to correctly describe the
connections between the first bridge in bridge chain and DP
controller. And Once the first bridge is obtained, we can get the
last bridge corresponding to the USB-C connector, and then set the
DRM connector's fwnode to the corresponding one to enable HPD
notification.

====
Patch1 add notifier functions for Type-C core.
Patch2 export all Type-C device types for identification.
Patch3 add generic USB Type-C DP HPD bridge.
Patch4 add new API drm_aux_bridge_register_from_node().
Patch5 add new Type-C mode switch for RK3399 USBDP phy binding.
Patch6 add typec_mux and typec_switch for RK3399 USBDP PHY.
Patch7 add DRM AUX bridge support for RK3399 USBDP PHY.
Patch8 drops CDN-DP's extcon dependency when Type-C is present.
Patch9 add multiple bridges to support PHY port selection.
Patch10 add missing dp_out port for RK3399 CDN-DP.
Patch11 add Type-C DP support for RK3399 EVB IND board.

Changes in v10:
- Link to V9: https://lore.kernel.org/all/20251111105040.94-1-kernel at airkyi.com/
- Notify TYPEC_ALTMODE_UNREGISTERED when altmode removed. 
- Add drm_aux_bridge_register_from_node().
- Fix refcount usage of drm_bridge.

Changes in v9:
- Link to V8: https://lore.kernel.org/all/20251029071435.88-1-kernel at airkyi.com/
- Remove the exposed DRM_AUX_HPD_BRIDGE option, and select
DRM_AUX_HPD_TYPEC_BRIDGE when it is available.
- Add usb role switch for Type-C.
- Remove USB2 PHY in Type-C connection.
- ...

Changes in v8:
- Link to V7: https://lore.kernel.org/all/20251023033009.90-1-kernel at airkyi.com/
- Export all typec device types for identification.
- Merge generic DP HPD bridge into one module.
- Fix coding style.

Changes in v7:
- Link to V6: https://lore.kernel.org/all/20251016022741.91-1-kernel at airkyi.com/
- Add notifier functions for Type-C core.
- Add generic USB Type-C DP HPD bridge.

Changes in v6:
- Link to V5: https://lore.kernel.org/all/20251011033233.97-1-kernel at airkyi.com/
- Fix depend in Kconfig.
- Check DP svid in tcphy_typec_mux_set().
- Remove mode setting in tcphy_orien_sw_set().
- Rename some variable names.
- Attach the DP bridge to the next bridge.

Changes in v5:
- Link to V4: https://lore.kernel.org/all/20250922012039.323-1-kernel at airkyi.com/
- Remove the calls related to `drm_aux_hpd_bridge_notify()`.
- Place the helper functions in the same compilation unit.
- Add more comments about parent device.
- Add DRM AUX bridge support for RK3399 USBDP PHY
- By parsing the HPD bridge chain, set the connector's of_node to the
of_node corresponding to the USB-C connector.
- Return EDID cache when other port is already enabled.

Changes in v4:
- Link to V3: https://lore.kernel.org/all/20250729090032.97-1-kernel at airkyi.com/
- Add default HPD device for DisplayPort altmode.
- Introduce multiple bridges for CDN-DP.
- ...

Changes in v3:
- Link to V2: https://lore.kernel.org/all/20250718062619.99-1-kernel at airkyi.com/
- Add more descriptions to clarify the role of the PHY in switching.
- Fix wrong vdo value.
- Fix port node in usb-c-connector.

Changes in v2:
- Link to V1: https://lore.kernel.org/all/20250715112456.101-1-kernel at airkyi.com/
- Reuse dp-port/usb3-port in rk3399-typec-phy binding.
- Fix compile error when CONFIG_TYPEC is not enabled.
- Notify DP HPD state by USB/DP PHY.
- Ignore duplicate HPD events.
- Add endpoint to link DP PHY and DP controller.
- Fix devicetree coding style.


Chaoyi Chen (11):
  usb: typec: Add notifier functions
  usb: typec: Export all typec device types
  drm/bridge: Implement generic USB Type-C DP HPD bridge
  drm/bridge: aux: Add drm_aux_bridge_register_from_node()
  dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode-switch
  phy: rockchip: phy-rockchip-typec: Add typec_mux/typec_switch support
  phy: rockchip: phy-rockchip-typec: Add DRM AUX bridge
  drm/rockchip: cdn-dp: Support handle lane info without extcon
  drm/rockchip: cdn-dp: Add multiple bridges to support PHY port
    selection
  arm64: dts: rockchip: Add missing dp_out port for RK3399 CDN-DP
  arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort

 .../phy/rockchip,rk3399-typec-phy.yaml        |   6 +
 arch/arm64/boot/dts/rockchip/rk3399-base.dtsi |  10 +-
 .../boot/dts/rockchip/rk3399-evb-ind.dts      | 147 +++++++
 drivers/gpu/drm/bridge/Kconfig                |  10 +
 drivers/gpu/drm/bridge/Makefile               |   1 +
 drivers/gpu/drm/bridge/aux-bridge.c           |  24 +-
 .../gpu/drm/bridge/aux-hpd-typec-dp-bridge.c  |  50 +++
 drivers/gpu/drm/rockchip/Kconfig              |   1 +
 drivers/gpu/drm/rockchip/cdn-dp-core.c        | 350 +++++++++++++---
 drivers/gpu/drm/rockchip/cdn-dp-core.h        |  18 +-
 drivers/phy/rockchip/Kconfig                  |   3 +
 drivers/phy/rockchip/phy-rockchip-typec.c     | 373 +++++++++++++++++-
 drivers/usb/typec/Makefile                    |   2 +-
 drivers/usb/typec/bus.h                       |   2 +
 drivers/usb/typec/class.c                     |   7 +
 drivers/usb/typec/class.h                     |  10 -
 drivers/usb/typec/notify.c                    |  23 ++
 include/drm/bridge/aux-bridge.h               |   6 +
 include/linux/usb/typec.h                     |  10 +
 include/linux/usb/typec_altmode.h             |   9 +
 20 files changed, 967 insertions(+), 95 deletions(-)
 create mode 100644 drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
 create mode 100644 drivers/usb/typec/notify.c

-- 
2.51.1



From kernel at airkyi.com  Wed Nov 19 18:23:33 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Thu, 20 Nov 2025 10:23:33 +0800
Subject: [PATCH v10 01/11] usb: typec: Add notifier functions
In-Reply-To: <20251120022343.250-1-kernel@airkyi.com>
References: <20251120022343.250-1-kernel@airkyi.com>
Message-ID: <20251120022343.250-2-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

Some other part of kernel may want to know the event of typec bus.

This patch add common notifier function to notify these event.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---

Changes in v10:
- Notify TYPEC_ALTMODE_UNREGISTERED when altmode removed. 

Changes in v9:
- Remove redundant header files.

Changes in v8:
- Fix coding style.

 drivers/usb/typec/Makefile        |  2 +-
 drivers/usb/typec/bus.h           |  2 ++
 drivers/usb/typec/class.c         |  3 +++
 drivers/usb/typec/notify.c        | 23 +++++++++++++++++++++++
 include/linux/usb/typec_altmode.h |  9 +++++++++
 5 files changed, 38 insertions(+), 1 deletion(-)
 create mode 100644 drivers/usb/typec/notify.c

diff --git a/drivers/usb/typec/Makefile b/drivers/usb/typec/Makefile
index 7a368fea61bc..20d09c5314d7 100644
--- a/drivers/usb/typec/Makefile
+++ b/drivers/usb/typec/Makefile
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_TYPEC)		+= typec.o
-typec-y				:= class.o mux.o bus.o pd.o retimer.o
+typec-y				:= class.o mux.o notify.o bus.o pd.o retimer.o
 typec-$(CONFIG_ACPI)		+= port-mapper.o
 obj-$(CONFIG_TYPEC)		+= altmodes/
 obj-$(CONFIG_TYPEC_TCPM)	+= tcpm/
diff --git a/drivers/usb/typec/bus.h b/drivers/usb/typec/bus.h
index 643b8c81786d..820b59b6d434 100644
--- a/drivers/usb/typec/bus.h
+++ b/drivers/usb/typec/bus.h
@@ -26,6 +26,8 @@ struct altmode {
 	struct altmode			*plug[2];
 };
 
+void typec_notify_event(unsigned long event, void *data);
+
 #define to_altmode(d) container_of(d, struct altmode, adev)
 
 extern const struct bus_type typec_bus;
diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
index 9b2647cb199b..1ccf5385d559 100644
--- a/drivers/usb/typec/class.c
+++ b/drivers/usb/typec/class.c
@@ -600,6 +600,8 @@ typec_register_altmode(struct device *parent,
 		return ERR_PTR(ret);
 	}
 
+	typec_notify_event(TYPEC_ALTMODE_REGISTERED, &alt->adev);
+
 	return &alt->adev;
 }
 
@@ -614,6 +616,7 @@ void typec_unregister_altmode(struct typec_altmode *adev)
 {
 	if (IS_ERR_OR_NULL(adev))
 		return;
+	typec_notify_event(TYPEC_ALTMODE_UNREGISTERED, adev);
 	typec_retimer_put(to_altmode(adev)->retimer);
 	typec_mux_put(to_altmode(adev)->mux);
 	device_unregister(&adev->dev);
diff --git a/drivers/usb/typec/notify.c b/drivers/usb/typec/notify.c
new file mode 100644
index 000000000000..9e50b54da359
--- /dev/null
+++ b/drivers/usb/typec/notify.c
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/notifier.h>
+
+#include "bus.h"
+
+static BLOCKING_NOTIFIER_HEAD(typec_notifier_list);
+
+int typec_altmode_register_notify(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_register(&typec_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(typec_altmode_register_notify);
+
+int typec_altmode_unregister_notify(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_unregister(&typec_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(typec_altmode_unregister_notify);
+
+void typec_notify_event(unsigned long event, void *data)
+{
+	blocking_notifier_call_chain(&typec_notifier_list, event, data);
+}
diff --git a/include/linux/usb/typec_altmode.h b/include/linux/usb/typec_altmode.h
index f7db3bd4c90e..59e20702504b 100644
--- a/include/linux/usb/typec_altmode.h
+++ b/include/linux/usb/typec_altmode.h
@@ -10,6 +10,7 @@
 #define MODE_DISCOVERY_MAX	6
 
 struct typec_altmode_ops;
+struct notifier_block;
 
 /**
  * struct typec_altmode - USB Type-C alternate mode device
@@ -77,6 +78,14 @@ int typec_altmode_notify(struct typec_altmode *altmode, unsigned long conf,
 const struct typec_altmode *
 typec_altmode_get_partner(struct typec_altmode *altmode);
 
+enum usb_typec_event {
+	TYPEC_ALTMODE_REGISTERED,
+	TYPEC_ALTMODE_UNREGISTERED,
+};
+
+int typec_altmode_register_notify(struct notifier_block *nb);
+int typec_altmode_unregister_notify(struct notifier_block *nb);
+
 /**
  * struct typec_cable_ops - Cable alternate mode operations vector
  * @enter: Operations to be executed with Enter Mode Command
-- 
2.51.1



From kernel at airkyi.com  Wed Nov 19 18:23:37 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Thu, 20 Nov 2025 10:23:37 +0800
Subject: [PATCH v10 05/11] dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode-switch
In-Reply-To: <20251120022343.250-1-kernel@airkyi.com>
References: <20251120022343.250-1-kernel@airkyi.com>
Message-ID: <20251120022343.250-6-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

The RK3399 SoC integrates two USB/DP combo PHYs, each of which
supports software-configurable pin mapping and DisplayPort lane
assignment. These capabilities enable the PHY itself to handle both
mode switching and orientation switching, based on the Type-C plug
orientation and USB PD negotiation results.

While an external Type-C controller is still required to detect cable
attachment and report USB PD events, the actual mode and orientation
switching is performed internally by the PHY through software
configuration. This allows the PHY to act as a Type-C multiplexer for
both data role and DP altmode configuration.

To reflect this hardware design, this patch introduces a new
"mode-switch" property for the dp-port node in the device tree bindings.
This property indicates that the connected PHY is capable of handling
Type-C mode switching itself.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---

(no changes since v5)

Changes in v4:
- Remove "|" in description.

Changes in v3:
- Add more descriptions to clarify the role of the PHY in switching.

Changes in v2:
- Reuse dp-port/usb3-port in rk3399-typec-phy binding.

 .../devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml  | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml
index 91c011f68cd0..83ebcde096ea 100644
--- a/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml
@@ -51,6 +51,12 @@ properties:
       '#phy-cells':
         const: 0
 
+      mode-switch:
+        description:
+          Indicates the PHY can handle altmode switching. In this case,
+          requires an external USB Type-C controller to report USB PD message.
+        type: boolean
+
       port:
         $ref: /schemas/graph.yaml#/properties/port
         description: Connection to USB Type-C connector
-- 
2.51.1



From kernel at airkyi.com  Wed Nov 19 18:23:35 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Thu, 20 Nov 2025 10:23:35 +0800
Subject: [PATCH v10 03/11] drm/bridge: Implement generic USB Type-C DP HPD bridge
In-Reply-To: <20251120022343.250-1-kernel@airkyi.com>
References: <20251120022343.250-1-kernel@airkyi.com>
Message-ID: <20251120022343.250-4-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

The HPD function of Type-C DP is implemented through
drm_connector_oob_hotplug_event(). For embedded DP, it is required
that the DRM connector fwnode corresponds to the Type-C port fwnode.

To describe the relationship between the DP controller and the Type-C
port device, we usually using drm_bridge to build a bridge chain.

Now several USB-C controller drivers have already implemented the DP
HPD bridge function provided by aux-hpd-bridge.c, it will build a DP
HPD bridge on USB-C connector port device.

But this requires the USB-C controller driver to manually register the
HPD bridge. If the driver does not implement this feature, the bridge
will not be create.

So this patch implements a generic DP HPD bridge based on
aux-hpd-bridge.c. It will monitor Type-C bus events, and when a
Type-C port device containing the DP svid is registered, it will
create an HPD bridge for it without the need for the USB-C controller
driver to implement it.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
Reviewed-by: Heikki Krogerus <heikki.krogerus at linux.intel.com>
---

(no changes since v10)

Changes in v9:
- Remove the exposed DRM_AUX_HPD_BRIDGE option, and select
DRM_AUX_HPD_TYPEC_BRIDGE when it is available.
- Add more commit comment about problem background.

Changes in v8:
- Merge generic DP HPD bridge into one module.

 drivers/gpu/drm/bridge/Kconfig                | 10 ++++
 drivers/gpu/drm/bridge/Makefile               |  1 +
 .../gpu/drm/bridge/aux-hpd-typec-dp-bridge.c  | 50 +++++++++++++++++++
 3 files changed, 61 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index a250afd8d662..559487aa09a9 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -30,6 +30,16 @@ config DRM_AUX_HPD_BRIDGE
 	  Simple bridge that terminates the bridge chain and provides HPD
 	  support.
 
+if DRM_AUX_HPD_BRIDGE
+config DRM_AUX_HPD_TYPEC_BRIDGE
+	tristate
+	depends on TYPEC || !TYPEC
+	default TYPEC
+	help
+	  Simple bridge that terminates the bridge chain and provides HPD
+	  support. It build bridge on each USB-C connector device node.
+endif
+
 menu "Display Interface Bridges"
 	depends on DRM && DRM_BRIDGE
 
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index c7dc03182e59..a3a0393d2e72 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_DRM_AUX_BRIDGE) += aux-bridge.o
 obj-$(CONFIG_DRM_AUX_HPD_BRIDGE) += aux-hpd-bridge.o
+obj-$(CONFIG_DRM_AUX_HPD_TYPEC_BRIDGE) += aux-hpd-typec-dp-bridge.o
 obj-$(CONFIG_DRM_CHIPONE_ICN6211) += chipone-icn6211.o
 obj-$(CONFIG_DRM_CHRONTEL_CH7033) += chrontel-ch7033.o
 obj-$(CONFIG_DRM_CROS_EC_ANX7688) += cros-ec-anx7688.o
diff --git a/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c b/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
new file mode 100644
index 000000000000..9cb6a0cb0f0a
--- /dev/null
+++ b/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0+
+#include <linux/of.h>
+#include <linux/usb/typec_altmode.h>
+#include <linux/usb/typec_dp.h>
+
+#include <drm/bridge/aux-bridge.h>
+
+static int drm_typec_bus_event(struct notifier_block *nb,
+			       unsigned long action, void *data)
+{
+	struct typec_altmode *alt = (struct typec_altmode *)data;
+
+	if (action != TYPEC_ALTMODE_REGISTERED)
+		goto done;
+
+	if (is_typec_partner(&alt->dev) || alt->svid != USB_TYPEC_DP_SID)
+		goto done;
+
+	/*
+	 * alt->dev.parent->parent : USB-C controller device
+	 * alt->dev.parent         : USB-C connector device
+	 */
+	drm_dp_hpd_bridge_register(alt->dev.parent->parent,
+				   to_of_node(alt->dev.parent->fwnode));
+
+done:
+	return NOTIFY_OK;
+}
+
+static struct notifier_block drm_typec_event_nb = {
+	.notifier_call = drm_typec_bus_event,
+};
+
+static void drm_aux_hpd_typec_dp_bridge_module_exit(void)
+{
+	typec_altmode_unregister_notify(&drm_typec_event_nb);
+}
+
+static int __init drm_aux_hpd_typec_dp_bridge_module_init(void)
+{
+	typec_altmode_register_notify(&drm_typec_event_nb);
+
+	return 0;
+}
+
+module_init(drm_aux_hpd_typec_dp_bridge_module_init);
+module_exit(drm_aux_hpd_typec_dp_bridge_module_exit);
+
+MODULE_DESCRIPTION("DRM TYPEC DP HPD BRIDGE");
+MODULE_LICENSE("GPL");
-- 
2.51.1



From kernel at airkyi.com  Wed Nov 19 18:23:39 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Thu, 20 Nov 2025 10:23:39 +0800
Subject: [PATCH v10 07/11] phy: rockchip: phy-rockchip-typec: Add DRM AUX bridge
In-Reply-To: <20251120022343.250-1-kernel@airkyi.com>
References: <20251120022343.250-1-kernel@airkyi.com>
Message-ID: <20251120022343.250-8-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

Using the DRM_AUX_BRIDGE helper to create the transparent DRM bridge
device.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---

Changes in v10:
- Use drm_aux_bridge_register_from_node() instead.

(no changes since v7)

Changes in v6:
- Fix depend in Kconfig. 

 drivers/phy/rockchip/Kconfig              | 2 ++
 drivers/phy/rockchip/phy-rockchip-typec.c | 5 +++++
 2 files changed, 7 insertions(+)

diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
index db4adc7c53da..bcb5476222fc 100644
--- a/drivers/phy/rockchip/Kconfig
+++ b/drivers/phy/rockchip/Kconfig
@@ -120,6 +120,8 @@ config PHY_ROCKCHIP_TYPEC
 	tristate "Rockchip TYPEC PHY Driver"
 	depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST)
 	depends on TYPEC || TYPEC=n
+	depends on DRM || DRM=n
+	select DRM_AUX_BRIDGE if DRM_BRIDGE
 	select EXTCON
 	select GENERIC_PHY
 	select RESET_CONTROLLER
diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c
index 1f5b4142cbe4..e31b778c3537 100644
--- a/drivers/phy/rockchip/phy-rockchip-typec.c
+++ b/drivers/phy/rockchip/phy-rockchip-typec.c
@@ -56,6 +56,7 @@
 #include <linux/phy/phy.h>
 #include <linux/usb/typec_dp.h>
 #include <linux/usb/typec_mux.h>
+#include <drm/bridge/aux-bridge.h>
 
 #define CMN_SSM_BANDGAP			(0x21 << 2)
 #define CMN_SSM_BIAS			(0x22 << 2)
@@ -1312,6 +1313,10 @@ static int tcphy_setup_typec_mux(struct rockchip_typec_phy *tcphy)
 	if (!of_property_read_bool(np, "mode-switch"))
 		goto put_np;
 
+	ret = drm_aux_bridge_register_from_node(tcphy->dev, np);
+	if (ret)
+		goto put_np;
+
 	mux_desc.drvdata = tcphy;
 	mux_desc.fwnode = device_get_named_child_node(tcphy->dev, "dp-port");
 	mux_desc.set = tcphy_typec_mux_set;
-- 
2.51.1



From kernel at airkyi.com  Wed Nov 19 18:23:38 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Thu, 20 Nov 2025 10:23:38 +0800
Subject: [PATCH v10 06/11] phy: rockchip: phy-rockchip-typec: Add typec_mux/typec_switch support
In-Reply-To: <20251120022343.250-1-kernel@airkyi.com>
References: <20251120022343.250-1-kernel@airkyi.com>
Message-ID: <20251120022343.250-7-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

This patch add support for Type-C Port Controller Manager. Each PHY
will register typec_mux and typec_switch when external Type-C
controller is present. Type-C events are handled by TCPM without
extcon.

The extcon device should still be supported.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---

(no changes since v7)

Changes in v6:
- Fix depend in Kconfig.
- Check DP svid in tcphy_typec_mux_set().
- Remove mode setting in tcphy_orien_sw_set().

(no changes since v5)

Changes in v4:
- Remove notify DP HPD state by USB/DP PHY.

(no changes since v3)

Changes in v2:
- Fix compile error when CONFIG_TYPEC is not enabled.
- Notify DP HPD state by USB/DP PHY.

 drivers/phy/rockchip/Kconfig              |   1 +
 drivers/phy/rockchip/phy-rockchip-typec.c | 368 +++++++++++++++++++++-
 2 files changed, 353 insertions(+), 16 deletions(-)

diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
index 14698571b607..db4adc7c53da 100644
--- a/drivers/phy/rockchip/Kconfig
+++ b/drivers/phy/rockchip/Kconfig
@@ -119,6 +119,7 @@ config PHY_ROCKCHIP_SNPS_PCIE3
 config PHY_ROCKCHIP_TYPEC
 	tristate "Rockchip TYPEC PHY Driver"
 	depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST)
+	depends on TYPEC || TYPEC=n
 	select EXTCON
 	select GENERIC_PHY
 	select RESET_CONTROLLER
diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c
index d9701b6106d5..1f5b4142cbe4 100644
--- a/drivers/phy/rockchip/phy-rockchip-typec.c
+++ b/drivers/phy/rockchip/phy-rockchip-typec.c
@@ -54,6 +54,8 @@
 
 #include <linux/mfd/syscon.h>
 #include <linux/phy/phy.h>
+#include <linux/usb/typec_dp.h>
+#include <linux/usb/typec_mux.h>
 
 #define CMN_SSM_BANDGAP			(0x21 << 2)
 #define CMN_SSM_BIAS			(0x22 << 2)
@@ -286,12 +288,23 @@
 #define RX_DIAG_SC2C_DELAY		(0x81e1 << 2)
 
 #define PMA_LANE_CFG			(0xc000 << 2)
+#define PMA_LANE3_DP_LANE_SEL(x)	(((x) & 0x3) << 14)
+#define PMA_LANE3_INTERFACE_SEL(x)	(((x) & 0x1) << 12)
+#define PMA_LANE2_DP_LANE_SEL(x)	(((x) & 0x3) << 10)
+#define PMA_LANE2_INTERFACE_SEL(x)	(((x) & 0x1) << 8)
+#define PMA_LANE1_DP_LANE_SEL(x)	(((x) & 0x3) << 6)
+#define PMA_LANE1_INTERFACE_SEL(x)	(((x) & 0x1) << 4)
+#define PMA_LANE0_DP_LANE_SEL(x)	(((x) & 0x3) << 2)
+#define PMA_LANE0_INTERFACE_SEL(x)	(((x) & 0x1) << 0)
 #define PIPE_CMN_CTRL1			(0xc001 << 2)
 #define PIPE_CMN_CTRL2			(0xc002 << 2)
 #define PIPE_COM_LOCK_CFG1		(0xc003 << 2)
 #define PIPE_COM_LOCK_CFG2		(0xc004 << 2)
 #define PIPE_RCV_DET_INH		(0xc005 << 2)
 #define DP_MODE_CTL			(0xc008 << 2)
+#define PHY_DP_POWER_STATE_ACK_MASK	GENMASK(7, 4)
+#define PHY_DP_POWER_STATE_ACK_SHIFT	4
+#define PHY_DP_POWER_STATE_MASK		GENMASK(3, 0)
 #define DP_CLK_CTL			(0xc009 << 2)
 #define STS				(0xc00F << 2)
 #define PHY_ISO_CMN_CTRL		(0xc010 << 2)
@@ -327,8 +340,15 @@
 
 #define DP_MODE_A0			BIT(4)
 #define DP_MODE_A2			BIT(6)
-#define DP_MODE_ENTER_A0		0xc101
-#define DP_MODE_ENTER_A2		0xc104
+
+#define DP_MODE_MASK			0xf
+#define DP_MODE_ENTER_A0		BIT(0)
+#define DP_MODE_ENTER_A2		BIT(2)
+#define DP_MODE_ENTER_A3		BIT(3)
+#define DP_MODE_A0_ACK			BIT(4)
+#define DP_MODE_A2_ACK			BIT(6)
+#define DP_MODE_A3_ACK			BIT(7)
+#define DP_LINK_RESET_DEASSERTED	BIT(8)
 
 #define PHY_MODE_SET_TIMEOUT		100000
 
@@ -340,6 +360,31 @@
 #define MODE_DFP_USB			BIT(1)
 #define MODE_DFP_DP			BIT(2)
 
+enum phy_dp_lane_num {
+	PHY_DP_LANE_0 = 0,
+	PHY_DP_LANE_1,
+	PHY_DP_LANE_2,
+	PHY_DP_LANE_3,
+};
+
+enum phy_pma_if {
+	PMA_IF_PIPE_PCS = 0,
+	PMA_IF_PHY_DP,
+};
+
+enum phy_typec_role {
+	TYPEC_PHY_USB = 0,
+	TYPEC_PHY_DP,
+	TYPEC_PHY_MAX,
+};
+
+enum phy_dp_power_state {
+	PHY_DP_POWER_STATE_A0 = 0,
+	PHY_DP_POWER_STATE_A1,
+	PHY_DP_POWER_STATE_A2,
+	PHY_DP_POWER_STATE_A3,
+};
+
 struct usb3phy_reg {
 	u32 offset;
 	u32 enable_bit;
@@ -372,18 +417,22 @@ struct rockchip_typec_phy {
 	struct device *dev;
 	void __iomem *base;
 	struct extcon_dev *extcon;
+	struct typec_mux_dev *mux;
+	struct typec_switch_dev *sw;
 	struct regmap *grf_regs;
 	struct clk *clk_core;
 	struct clk *clk_ref;
 	struct reset_control *uphy_rst;
 	struct reset_control *pipe_rst;
 	struct reset_control *tcphy_rst;
+	struct phy *phys[TYPEC_PHY_MAX];
 	const struct rockchip_usb3phy_port_cfg *port_cfgs;
 	/* mutex to protect access to individual PHYs */
 	struct mutex lock;
 
 	bool flip;
 	u8 mode;
+	u8 new_mode;
 };
 
 struct phy_reg {
@@ -454,6 +503,99 @@ static const struct rockchip_usb3phy_port_cfg rk3399_usb3phy_port_cfgs[] = {
 	{ /* sentinel */ }
 };
 
+static int tcphy_cfg_usb3_to_usb2_only(struct rockchip_typec_phy *tcphy,
+				       bool value);
+
+static int tcphy_dp_set_power_state(struct rockchip_typec_phy *tcphy,
+				    enum phy_dp_power_state state)
+{
+	u32 ack, reg, sts = BIT(state);
+	int ret;
+
+	/*
+	 * Power state changes must not be requested until after the cmn_ready
+	 * signal has gone active.
+	 */
+	reg = readl(tcphy->base + PMA_CMN_CTRL1);
+	if (!(reg & CMN_READY)) {
+		dev_err(tcphy->dev, "cmn_ready in the inactive state\n");
+		return -EINVAL;
+	}
+
+	reg = readl(tcphy->base + DP_MODE_CTL);
+	reg &= ~PHY_DP_POWER_STATE_MASK;
+	reg |= sts;
+	writel(reg, tcphy->base + DP_MODE_CTL);
+
+	ret = readl_poll_timeout(tcphy->base + DP_MODE_CTL,
+				 ack, (((ack & PHY_DP_POWER_STATE_ACK_MASK) >>
+				 PHY_DP_POWER_STATE_ACK_SHIFT) == sts), 10,
+				 PHY_MODE_SET_TIMEOUT);
+	if (ret < 0) {
+		dev_err(tcphy->dev, "failed to enter power state %d\n", state);
+		return ret;
+	}
+
+	return 0;
+}
+
+/*
+ * For the TypeC PHY, the 4 lanes are mapping to the USB TypeC receptacle pins
+ * as follows:
+ *   -------------------------------------------------------------------
+ *	PHY Lanes/Module Pins			TypeC Receptacle Pins
+ *   -------------------------------------------------------------------
+ *	Lane0 (tx_p/m_ln_0)			TX1+/TX1- (pins A2/A3)
+ *	Lane1 (tx_rx_p/m_ln_1)			RX1+/RX1- (pins B11/B10)
+ *	Lane2 (tx_rx_p/m_ln_2)			RX2+/RX2- (pins A11/A10)
+ *	Lane3 (tx_p/m_ln_3)			TX2+/TX2- (pins B2/B3)
+ *   -------------------------------------------------------------------
+ *
+ * USB and DP lanes mapping to TypeC PHY lanes for each of pin assignment
+ * options (normal connector orientation) described in the VESA DisplayPort
+ * Alt Mode on USB TypeC Standard as follows:
+ *
+ * ----------------------------------------------------------------------
+ *	PHY Lanes	A	B	C	D	E	F
+ * ----------------------------------------------------------------------
+ *	  0	       ML1     SSTX    ML2     SSTX    ML2     SSTX
+ *	  1	       ML3     SSRX    ML3     SSRX    ML3     SSRX
+ *	  2	       ML2     ML1     ML0     ML0     ML0     ML0
+ *	  3	       ML0     ML0     ML1     ML1     ML1     ML1
+ * ----------------------------------------------------------------------
+ */
+static void tcphy_set_lane_mapping(struct rockchip_typec_phy *tcphy, u8 mode)
+{
+	/*
+	 * The PMA_LANE_CFG register is used to select whether a PMA lane
+	 * is mapped for USB or PHY DP. The PMA_LANE_CFG register is
+	 * configured based on a normal connector orientation. Logic in the
+	 * PHY automatically handles the flipped connector case based on the
+	 * setting of orientation of TypeC PHY.
+	 */
+	if (mode == MODE_DFP_DP) {
+		/* This maps to VESA DP Alt Mode pin assignments C and E. */
+		writel(PMA_LANE3_DP_LANE_SEL(PHY_DP_LANE_1) |
+		       PMA_LANE3_INTERFACE_SEL(PMA_IF_PHY_DP) |
+		       PMA_LANE2_DP_LANE_SEL(PHY_DP_LANE_0) |
+		       PMA_LANE2_INTERFACE_SEL(PMA_IF_PHY_DP) |
+		       PMA_LANE1_DP_LANE_SEL(PHY_DP_LANE_3) |
+		       PMA_LANE1_INTERFACE_SEL(PMA_IF_PHY_DP) |
+		       PMA_LANE0_DP_LANE_SEL(PHY_DP_LANE_2) |
+		       PMA_LANE0_INTERFACE_SEL(PMA_IF_PHY_DP),
+		       tcphy->base + PMA_LANE_CFG);
+	} else {
+		/* This maps to VESA DP Alt Mode pin assignments D and F. */
+		writel(PMA_LANE3_DP_LANE_SEL(PHY_DP_LANE_1) |
+		       PMA_LANE3_INTERFACE_SEL(PMA_IF_PHY_DP) |
+		       PMA_LANE2_DP_LANE_SEL(PHY_DP_LANE_0) |
+		       PMA_LANE2_INTERFACE_SEL(PMA_IF_PHY_DP) |
+		       PMA_LANE1_INTERFACE_SEL(PMA_IF_PIPE_PCS) |
+		       PMA_LANE0_INTERFACE_SEL(PMA_IF_PIPE_PCS),
+		       tcphy->base + PMA_LANE_CFG);
+	}
+}
+
 static void tcphy_cfg_24m(struct rockchip_typec_phy *tcphy)
 {
 	u32 i, rdata;
@@ -743,8 +885,10 @@ static int tcphy_phy_init(struct rockchip_typec_phy *tcphy, u8 mode)
 	tcphy_dp_aux_set_flip(tcphy);
 
 	tcphy_cfg_24m(tcphy);
+	tcphy_set_lane_mapping(tcphy, mode);
 
 	if (mode == MODE_DFP_DP) {
+		tcphy_cfg_usb3_to_usb2_only(tcphy, true);
 		tcphy_cfg_dp_pll(tcphy);
 		for (i = 0; i < 4; i++)
 			tcphy_dp_cfg_lane(tcphy, i);
@@ -768,7 +912,10 @@ static int tcphy_phy_init(struct rockchip_typec_phy *tcphy, u8 mode)
 		writel(PIN_ASSIGN_D_F, tcphy->base + PMA_LANE_CFG);
 	}
 
-	writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL);
+	val = readl(tcphy->base + DP_MODE_CTL);
+	val &= ~DP_MODE_MASK;
+	val |= DP_MODE_ENTER_A2 | DP_LINK_RESET_DEASSERTED;
+	writel(val, tcphy->base + DP_MODE_CTL);
 
 	reset_control_deassert(tcphy->uphy_rst);
 
@@ -811,8 +958,9 @@ static int tcphy_get_mode(struct rockchip_typec_phy *tcphy)
 	u8 mode;
 	int ret, ufp, dp;
 
+	/* If extcon not exist, try to use tcpm mode */
 	if (!edev)
-		return MODE_DFP_USB;
+		return tcphy->new_mode;
 
 	ufp = extcon_get_state(edev, EXTCON_USB);
 	dp = extcon_get_state(edev, EXTCON_DISP_DP);
@@ -850,6 +998,71 @@ static int tcphy_get_mode(struct rockchip_typec_phy *tcphy)
 	return mode;
 }
 
+#if IS_ENABLED(CONFIG_TYPEC)
+static int tcphy_orien_sw_set(struct typec_switch_dev *sw,
+			      enum typec_orientation orien)
+{
+	struct rockchip_typec_phy *tcphy = typec_switch_get_drvdata(sw);
+
+	mutex_lock(&tcphy->lock);
+
+	if (orien == TYPEC_ORIENTATION_NONE) {
+		tcphy->new_mode = MODE_DISCONNECT;
+		goto unlock_ret;
+	}
+
+	tcphy->flip = (orien == TYPEC_ORIENTATION_REVERSE) ? true : false;
+
+unlock_ret:
+	mutex_unlock(&tcphy->lock);
+	return 0;
+}
+
+static void udphy_orien_switch_unregister(void *data)
+{
+	struct rockchip_typec_phy *tcphy = data;
+
+	typec_switch_unregister(tcphy->sw);
+}
+
+static int tcphy_setup_orien_switch(struct rockchip_typec_phy *tcphy)
+{
+	struct typec_switch_desc sw_desc = { };
+	struct device_node *np;
+	int ret = 0;
+
+	np = of_get_child_by_name(tcphy->dev->of_node, "usb3-port");
+	if (!np)
+		return 0;
+
+	if (!of_property_read_bool(np, "orientation-switch"))
+		goto put_np;
+
+	sw_desc.drvdata = tcphy;
+	sw_desc.fwnode = device_get_named_child_node(tcphy->dev, "usb3-port");
+	sw_desc.set = tcphy_orien_sw_set;
+
+	tcphy->sw = typec_switch_register(tcphy->dev, &sw_desc);
+	if (IS_ERR(tcphy->sw)) {
+		dev_err(tcphy->dev, "Error register typec orientation switch: %ld\n",
+			PTR_ERR(tcphy->sw));
+		ret = PTR_ERR(tcphy->sw);
+		goto put_np;
+	}
+
+	ret = devm_add_action_or_reset(tcphy->dev, udphy_orien_switch_unregister, tcphy);
+
+put_np:
+	of_node_put(np);
+	return ret;
+}
+#else
+static int tcphy_setup_orien_switch(struct rockchip_typec_phy *tcphy)
+{
+	return 0;
+}
+#endif
+
 static int tcphy_cfg_usb3_to_usb2_only(struct rockchip_typec_phy *tcphy,
 				       bool value)
 {
@@ -989,14 +1202,9 @@ static int rockchip_dp_phy_power_on(struct phy *phy)
 
 	tcphy_dp_aux_calibration(tcphy);
 
-	writel(DP_MODE_ENTER_A0, tcphy->base + DP_MODE_CTL);
-
-	ret = readx_poll_timeout(readl, tcphy->base + DP_MODE_CTL,
-				 val, val & DP_MODE_A0, 1000,
-				 PHY_MODE_SET_TIMEOUT);
-	if (ret < 0) {
-		writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL);
-		dev_err(tcphy->dev, "failed to wait TCPHY enter A0\n");
+	ret = tcphy_dp_set_power_state(tcphy, PHY_DP_POWER_STATE_A0);
+	if (ret) {
+		dev_err(tcphy->dev, "failed to enter A0 power state\n");
 		goto power_on_finish;
 	}
 
@@ -1013,6 +1221,7 @@ static int rockchip_dp_phy_power_on(struct phy *phy)
 static int rockchip_dp_phy_power_off(struct phy *phy)
 {
 	struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy);
+	int ret;
 
 	mutex_lock(&tcphy->lock);
 
@@ -1021,7 +1230,11 @@ static int rockchip_dp_phy_power_off(struct phy *phy)
 
 	tcphy->mode &= ~MODE_DFP_DP;
 
-	writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL);
+	ret = tcphy_dp_set_power_state(tcphy, PHY_DP_POWER_STATE_A2);
+	if (ret) {
+		dev_err(tcphy->dev, "failed to enter A2 power state\n");
+		goto unlock;
+	}
 
 	if (tcphy->mode == MODE_DISCONNECT)
 		tcphy_phy_deinit(tcphy);
@@ -1037,6 +1250,93 @@ static const struct phy_ops rockchip_dp_phy_ops = {
 	.owner		= THIS_MODULE,
 };
 
+#if IS_ENABLED(CONFIG_TYPEC)
+static int tcphy_typec_mux_set(struct typec_mux_dev *mux, struct typec_mux_state *state)
+{
+	struct rockchip_typec_phy *tcphy = typec_mux_get_drvdata(mux);
+	struct typec_displayport_data *data;
+	int hpd = 0;
+
+	mutex_lock(&tcphy->lock);
+
+	switch (state->mode) {
+	case TYPEC_STATE_SAFE:
+		fallthrough;
+	case TYPEC_STATE_USB:
+		tcphy->new_mode = MODE_DFP_USB;
+		phy_set_bus_width(tcphy->phys[TYPEC_PHY_DP], 0);
+		break;
+	case TYPEC_DP_STATE_C:
+	case TYPEC_DP_STATE_E:
+		if (state->alt->svid != USB_TYPEC_DP_SID)
+			break;
+		tcphy->new_mode = MODE_DFP_DP;
+		data = state->data;
+		hpd = !!(data->status & DP_STATUS_HPD_STATE);
+		phy_set_bus_width(tcphy->phys[TYPEC_PHY_DP], hpd ? 4 : 0);
+		break;
+	case TYPEC_DP_STATE_D:
+		if (state->alt->svid != USB_TYPEC_DP_SID)
+			break;
+		tcphy->new_mode = MODE_DFP_DP | MODE_DFP_USB;
+		data = state->data;
+		hpd = !!(data->status & DP_STATUS_HPD_STATE);
+		phy_set_bus_width(tcphy->phys[TYPEC_PHY_DP], hpd ? 2 : 0);
+		break;
+	default:
+		break;
+	}
+
+	mutex_unlock(&tcphy->lock);
+
+	return 0;
+}
+
+static void tcphy_typec_mux_unregister(void *data)
+{
+	struct rockchip_typec_phy *tcphy = data;
+
+	typec_mux_unregister(tcphy->mux);
+}
+
+static int tcphy_setup_typec_mux(struct rockchip_typec_phy *tcphy)
+{
+	struct typec_mux_desc mux_desc = {};
+	struct device_node *np;
+	int ret = 0;
+
+	np = of_get_child_by_name(tcphy->dev->of_node, "dp-port");
+	if (!np)
+		return 0;
+
+	if (!of_property_read_bool(np, "mode-switch"))
+		goto put_np;
+
+	mux_desc.drvdata = tcphy;
+	mux_desc.fwnode = device_get_named_child_node(tcphy->dev, "dp-port");
+	mux_desc.set = tcphy_typec_mux_set;
+
+	tcphy->mux = typec_mux_register(tcphy->dev, &mux_desc);
+	if (IS_ERR(tcphy->mux)) {
+		dev_err(tcphy->dev, "Error register typec mux: %ld\n",
+			PTR_ERR(tcphy->mux));
+		ret = PTR_ERR(tcphy->mux);
+		goto put_np;
+	}
+
+	ret = devm_add_action_or_reset(tcphy->dev, tcphy_typec_mux_unregister, tcphy);
+
+put_np:
+	of_node_put(np);
+	return ret;
+}
+#else
+static int tcphy_setup_typec_mux(struct rockchip_typec_phy *tcphy)
+{
+	return 0;
+}
+#endif
+
 static int tcphy_parse_dt(struct rockchip_typec_phy *tcphy,
 			  struct device *dev)
 {
@@ -1095,6 +1395,25 @@ static void typec_phy_pre_init(struct rockchip_typec_phy *tcphy)
 	tcphy->mode = MODE_DISCONNECT;
 }
 
+static int typec_dp_lane_get(struct rockchip_typec_phy *tcphy)
+{
+	int dp_lanes;
+
+	switch (tcphy->new_mode) {
+	case MODE_DFP_DP:
+		dp_lanes = 4;
+		break;
+	case MODE_DFP_DP | MODE_DFP_USB:
+		dp_lanes = 2;
+		break;
+	default:
+		dp_lanes = 0;
+		break;
+	}
+
+	return dp_lanes;
+}
+
 static int rockchip_typec_phy_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -1142,6 +1461,7 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev)
 		return ret;
 
 	tcphy->dev = dev;
+	tcphy->new_mode = MODE_DFP_USB;
 	platform_set_drvdata(pdev, tcphy);
 	mutex_init(&tcphy->lock);
 
@@ -1151,6 +1471,7 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev)
 	if (IS_ERR(tcphy->extcon)) {
 		if (PTR_ERR(tcphy->extcon) == -ENODEV) {
 			tcphy->extcon = NULL;
+			dev_info(dev, "extcon not exist, try to use typec mux\n");
 		} else {
 			if (PTR_ERR(tcphy->extcon) != -EPROBE_DEFER)
 				dev_err(dev, "Invalid or missing extcon\n");
@@ -1158,19 +1479,34 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev)
 		}
 	}
 
+	ret = tcphy_setup_orien_switch(tcphy);
+	if (ret)
+		return ret;
+
+	ret = tcphy_setup_typec_mux(tcphy);
+	if (ret)
+		return ret;
+
 	pm_runtime_enable(dev);
 
 	for_each_available_child_of_node(np, child_np) {
 		struct phy *phy;
 
-		if (of_node_name_eq(child_np, "dp-port"))
+		if (of_node_name_eq(child_np, "dp-port")) {
 			phy = devm_phy_create(dev, child_np,
 					      &rockchip_dp_phy_ops);
-		else if (of_node_name_eq(child_np, "usb3-port"))
+			if (!IS_ERR(phy)) {
+				tcphy->phys[TYPEC_PHY_DP] = phy;
+				phy_set_bus_width(phy, typec_dp_lane_get(tcphy));
+			}
+		} else if (of_node_name_eq(child_np, "usb3-port")) {
 			phy = devm_phy_create(dev, child_np,
 					      &rockchip_usb3_phy_ops);
-		else
+			if (!IS_ERR(phy))
+				tcphy->phys[TYPEC_PHY_USB] = phy;
+		} else {
 			continue;
+		}
 
 		if (IS_ERR(phy)) {
 			dev_err(dev, "failed to create phy: %pOFn\n",
-- 
2.51.1



From kernel at airkyi.com  Wed Nov 19 18:23:41 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Thu, 20 Nov 2025 10:23:41 +0800
Subject: [PATCH v10 09/11] drm/rockchip: cdn-dp: Add multiple bridges to support PHY port selection
In-Reply-To: <20251120022343.250-1-kernel@airkyi.com>
References: <20251120022343.250-1-kernel@airkyi.com>
Message-ID: <20251120022343.250-10-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

The RK3399 has two USB/DP combo PHY and one CDN-DP controller. And
the CDN-DP can be switched to output to one of the PHYs. If both ports
are plugged into DP, DP will select the first port for output.

This patch adds support for multiple bridges, enabling users to flexibly
select the output port. For each PHY port, a separate encoder and bridge
are registered.

The change is based on the DRM AUX HPD bridge, rather than the
extcon approach. This requires the DT to correctly describe the
connections between the first bridge in bridge chain and DP
controller. For example, the bridge chain may be like this:

PHY aux birdge -> fsa4480 analog audio switch bridge ->
onnn,nb7vpq904m USB reminder bridge -> USB-C controller AUX HPD bridge

In this case, the connection relationships among the PHY aux bridge
and the DP contorller need to be described in DT.

In addition, the cdn_dp_parse_next_bridge_dt() will parses it and
determines whether to register one or two bridges.

Since there is only one DP controller, only one of the PHY ports can
output at a time. The key is how to switch between different PHYs,
which is handled by cdn_dp_switch_port() and cdn_dp_enable().

There are two cases:

1. Neither bridge is enabled. In this case, both bridges can
independently read the EDID, and the PHY port may switch before
reading the EDID.

2. One bridge is already enabled. In this case, other bridges are not
allowed to read the EDID. So we will try to return the cached EDID.

Since the scenario of two ports plug in at the same time is rare,
I don't have a board which support two TypeC connector to test this.
Therefore, I tested forced switching on a single PHY port, as well as
output using a fake PHY port alongside a real PHY port.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---

Changes in v10:
- Fix refcount usage of drm_bridge.
- Remove unused cdn_dp_next_bridge type.

Changes in v9:
- Select DRM_AUX_HPD_BRIDGE when using DP driver.

(no changes since v7)

Changes in v6:
- Rename some variable names.
- Attach the DP bridge to the next bridge.

Changes in v5:
- By parsing the HPD bridge chain, set the connector's of_node to the
of_node corresponding to the USB-C connector.
- Return EDID cache when other port is already enabled.

 drivers/gpu/drm/rockchip/Kconfig       |   1 +
 drivers/gpu/drm/rockchip/cdn-dp-core.c | 325 ++++++++++++++++++++-----
 drivers/gpu/drm/rockchip/cdn-dp-core.h |  18 +-
 3 files changed, 287 insertions(+), 57 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index b7b025814e72..10d9f29a3d44 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -56,6 +56,7 @@ config ROCKCHIP_CDN_DP
 	select DRM_DISPLAY_HELPER
 	select DRM_BRIDGE_CONNECTOR
 	select DRM_DISPLAY_DP_HELPER
+	select DRM_AUX_HPD_BRIDGE
 	help
 	  This selects support for Rockchip SoC specific extensions
 	  for the cdn DP driver. If you want to enable Dp on
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 1e27301584a4..0bc3d248c266 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -27,16 +27,17 @@
 #include "cdn-dp-core.h"
 #include "cdn-dp-reg.h"
 
-static inline struct cdn_dp_device *bridge_to_dp(struct drm_bridge *bridge)
+static int cdn_dp_switch_port(struct cdn_dp_device *dp, struct cdn_dp_port *prev_port,
+			      struct cdn_dp_port *port);
+
+static inline struct cdn_dp_bridge *bridge_to_dp_bridge(struct drm_bridge *bridge)
 {
-	return container_of(bridge, struct cdn_dp_device, bridge);
+	return container_of(bridge, struct cdn_dp_bridge, bridge);
 }
 
-static inline struct cdn_dp_device *encoder_to_dp(struct drm_encoder *encoder)
+static inline struct cdn_dp_device *bridge_to_dp(struct drm_bridge *bridge)
 {
-	struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
-
-	return container_of(rkencoder, struct cdn_dp_device, encoder);
+	return bridge_to_dp_bridge(bridge)->parent;
 }
 
 #define GRF_SOC_CON9		0x6224
@@ -191,14 +192,27 @@ static int cdn_dp_get_sink_count(struct cdn_dp_device *dp, u8 *sink_count)
 static struct cdn_dp_port *cdn_dp_connected_port(struct cdn_dp_device *dp)
 {
 	struct cdn_dp_port *port;
-	int i, lanes;
+	int i, lanes[MAX_PHY];
 
 	for (i = 0; i < dp->ports; i++) {
 		port = dp->port[i];
-		lanes = cdn_dp_get_port_lanes(port);
-		if (lanes)
+		lanes[i] = cdn_dp_get_port_lanes(port);
+		if (!dp->next_bridge_valid)
 			return port;
 	}
+
+	if (dp->next_bridge_valid) {
+		/* If more than one port is available, pick the last active port */
+		if (dp->active_port > 0 && lanes[dp->active_port])
+			return dp->port[dp->active_port];
+
+		/* If the last active port is not available, pick an available port in order */
+		for (i = 0; i < dp->bridge_count; i++) {
+			if (lanes[i])
+				return dp->port[i];
+		}
+	}
+
 	return NULL;
 }
 
@@ -253,12 +267,45 @@ static const struct drm_edid *
 cdn_dp_bridge_edid_read(struct drm_bridge *bridge, struct drm_connector *connector)
 {
 	struct cdn_dp_device *dp = bridge_to_dp(bridge);
-	const struct drm_edid *drm_edid;
+	struct cdn_dp_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
+	struct cdn_dp_port *port = dp->port[dp_bridge->id];
+	struct cdn_dp_port *prev_port;
+	const struct drm_edid *drm_edid = NULL;
+	int i, ret;
 
 	mutex_lock(&dp->lock);
+
+	/* More than one port is available */
+	if (dp->bridge_count > 1 && !port->phy_enabled) {
+		for (i = 0; i < dp->bridge_count; i++) {
+			/* Another port already enable */
+			if (dp->bridge_list[i] != dp_bridge && dp->bridge_list[i]->enabled)
+				goto get_cache;
+			/* Find already enabled port */
+			if (dp->port[i]->phy_enabled)
+				prev_port = dp->port[i];
+		}
+
+		/* Switch to current port */
+		if (prev_port) {
+			ret = cdn_dp_switch_port(dp, prev_port, port);
+			if (ret)
+				goto get_cache;
+		}
+	}
+
 	drm_edid = drm_edid_read_custom(connector, cdn_dp_get_edid_block, dp);
+	/* replace edid cache */
+	if (dp->edid_cache[dp_bridge->id])
+		drm_edid_free(dp->edid_cache[dp_bridge->id]);
+	dp->edid_cache[dp_bridge->id] = drm_edid_dup(drm_edid);
+
 	mutex_unlock(&dp->lock);
+	return drm_edid;
 
+get_cache:
+	drm_edid = drm_edid_dup(dp->edid_cache[dp_bridge->id]);
+	mutex_unlock(&dp->lock);
 	return drm_edid;
 }
 
@@ -267,12 +314,13 @@ cdn_dp_bridge_mode_valid(struct drm_bridge *bridge,
 			 const struct drm_display_info *display_info,
 			 const struct drm_display_mode *mode)
 {
+	struct cdn_dp_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
 	struct cdn_dp_device *dp = bridge_to_dp(bridge);
 	u32 requested, actual, rate, sink_max, source_max = 0;
 	u8 lanes, bpc;
 
 	/* If DP is disconnected, every mode is invalid */
-	if (!dp->connected)
+	if (!dp_bridge->connected || !dp->connected)
 		return MODE_BAD;
 
 	switch (display_info->bpc) {
@@ -550,6 +598,54 @@ static bool cdn_dp_check_link_status(struct cdn_dp_device *dp)
 	return drm_dp_channel_eq_ok(link_status, min(port->lanes, sink_lanes));
 }
 
+static int cdn_dp_switch_port(struct cdn_dp_device *dp, struct cdn_dp_port *prev_port,
+			      struct cdn_dp_port *port)
+{
+	int ret;
+
+	if (dp->active)
+		return 0;
+
+	ret = cdn_dp_disable_phy(dp, prev_port);
+	if (ret)
+		goto out;
+	ret = cdn_dp_enable_phy(dp, port);
+	if (ret)
+		goto out;
+
+	ret = cdn_dp_get_sink_capability(dp);
+	if (ret) {
+		cdn_dp_disable_phy(dp, port);
+		goto out;
+	}
+
+	dp->active = true;
+	dp->lanes = port->lanes;
+
+	if (!cdn_dp_check_link_status(dp)) {
+		dev_info(dp->dev, "Connected with sink; re-train link\n");
+
+		ret = cdn_dp_train_link(dp);
+		if (ret) {
+			dev_err(dp->dev, "Training link failed: %d\n", ret);
+			goto out;
+		}
+
+		ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE);
+		if (ret) {
+			dev_err(dp->dev, "Failed to idle video %d\n", ret);
+			goto out;
+		}
+
+		ret = cdn_dp_config_video(dp);
+		if (ret)
+			dev_err(dp->dev, "Failed to configure video: %d\n", ret);
+	}
+
+out:
+	return ret;
+}
+
 static void cdn_dp_display_info_update(struct cdn_dp_device *dp,
 				       struct drm_display_info *display_info)
 {
@@ -571,6 +667,7 @@ static void cdn_dp_display_info_update(struct cdn_dp_device *dp,
 static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_atomic_state *state)
 {
 	struct cdn_dp_device *dp = bridge_to_dp(bridge);
+	struct cdn_dp_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
 	struct drm_connector *connector;
 	int ret, val;
 
@@ -580,7 +677,7 @@ static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_at
 
 	cdn_dp_display_info_update(dp, &connector->display_info);
 
-	ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, &dp->encoder.encoder);
+	ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, &dp_bridge->encoder.encoder);
 	if (ret < 0) {
 		DRM_DEV_ERROR(dp->dev, "Could not get vop id, %d", ret);
 		return;
@@ -599,6 +696,9 @@ static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_at
 
 	mutex_lock(&dp->lock);
 
+	if (dp->next_bridge_valid)
+		dp->active_port = dp_bridge->id;
+
 	ret = cdn_dp_enable(dp);
 	if (ret) {
 		DRM_DEV_ERROR(dp->dev, "Failed to enable bridge %d\n",
@@ -631,6 +731,7 @@ static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_at
 		goto out;
 	}
 
+	dp_bridge->enabled = true;
 out:
 	mutex_unlock(&dp->lock);
 }
@@ -638,9 +739,11 @@ static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_at
 static void cdn_dp_bridge_atomic_disable(struct drm_bridge *bridge, struct drm_atomic_state *state)
 {
 	struct cdn_dp_device *dp = bridge_to_dp(bridge);
+	struct cdn_dp_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
 	int ret;
 
 	mutex_lock(&dp->lock);
+	dp_bridge->enabled = false;
 
 	if (dp->active) {
 		ret = cdn_dp_disable(dp);
@@ -827,6 +930,16 @@ static int cdn_dp_audio_mute_stream(struct drm_bridge *bridge,
 	return ret;
 }
 
+static void cdn_dp_bridge_hpd_notify(struct drm_bridge *bridge,
+			   enum drm_connector_status status)
+{
+	struct cdn_dp_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
+	struct cdn_dp_device *dp = bridge_to_dp(bridge);
+
+	dp->bridge_list[dp_bridge->id]->connected = status == connector_status_connected;
+	schedule_work(&dp->event_work);
+}
+
 static const struct drm_bridge_funcs cdn_dp_bridge_funcs = {
 	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
 	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
@@ -837,6 +950,7 @@ static const struct drm_bridge_funcs cdn_dp_bridge_funcs = {
 	.atomic_disable = cdn_dp_bridge_atomic_disable,
 	.mode_valid = cdn_dp_bridge_mode_valid,
 	.mode_set = cdn_dp_bridge_mode_set,
+	.hpd_notify = cdn_dp_bridge_hpd_notify,
 
 	.dp_audio_prepare = cdn_dp_audio_prepare,
 	.dp_audio_mute_stream = cdn_dp_audio_mute_stream,
@@ -885,7 +999,8 @@ static void cdn_dp_pd_event_work(struct work_struct *work)
 {
 	struct cdn_dp_device *dp = container_of(work, struct cdn_dp_device,
 						event_work);
-	int ret;
+	bool connected;
+	int i, ret;
 
 	mutex_lock(&dp->lock);
 
@@ -944,9 +1059,12 @@ static void cdn_dp_pd_event_work(struct work_struct *work)
 
 out:
 	mutex_unlock(&dp->lock);
-	drm_bridge_hpd_notify(&dp->bridge,
-			      dp->connected ? connector_status_connected
-					    : connector_status_disconnected);
+	for (i = 0; i < dp->bridge_count; i++) {
+		connected = dp->connected && dp->bridge_list[i]->connected;
+		drm_bridge_hpd_notify(&dp->bridge_list[i]->bridge,
+				      connected ? connector_status_connected
+						: connector_status_disconnected);
+	}
 }
 
 static int cdn_dp_pd_event(struct notifier_block *nb,
@@ -966,28 +1084,16 @@ static int cdn_dp_pd_event(struct notifier_block *nb,
 	return NOTIFY_DONE;
 }
 
-static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
+static int cdn_bridge_add(struct device *dev,
+			  struct drm_bridge *bridge,
+			  struct drm_bridge *next_bridge,
+			  struct drm_encoder *encoder)
 {
 	struct cdn_dp_device *dp = dev_get_drvdata(dev);
-	struct drm_encoder *encoder;
+	struct drm_device *drm_dev = dp->drm_dev;
+	struct drm_bridge *last_bridge __free(drm_bridge_put) = NULL;
 	struct drm_connector *connector;
-	struct cdn_dp_port *port;
-	struct drm_device *drm_dev = data;
-	int ret, i;
-
-	ret = cdn_dp_parse_dt(dp);
-	if (ret < 0)
-		return ret;
-
-	dp->drm_dev = drm_dev;
-	dp->connected = false;
-	dp->active = false;
-	dp->active_port = -1;
-	dp->fw_loaded = false;
-
-	INIT_WORK(&dp->event_work, cdn_dp_pd_event_work);
-
-	encoder = &dp->encoder.encoder;
+	int ret;
 
 	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
 							     dev->of_node);
@@ -1002,26 +1108,35 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
 
 	drm_encoder_helper_add(encoder, &cdn_dp_encoder_helper_funcs);
 
-	dp->bridge.ops =
-			DRM_BRIDGE_OP_DETECT |
-			DRM_BRIDGE_OP_EDID |
-			DRM_BRIDGE_OP_HPD |
-			DRM_BRIDGE_OP_DP_AUDIO;
-	dp->bridge.of_node = dp->dev->of_node;
-	dp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
-	dp->bridge.hdmi_audio_dev = dp->dev;
-	dp->bridge.hdmi_audio_max_i2s_playback_channels = 8;
-	dp->bridge.hdmi_audio_spdif_playback = 1;
-	dp->bridge.hdmi_audio_dai_port = -1;
-
-	ret = devm_drm_bridge_add(dev, &dp->bridge);
+	bridge->ops =
+		DRM_BRIDGE_OP_DETECT |
+		DRM_BRIDGE_OP_EDID |
+		DRM_BRIDGE_OP_HPD |
+		DRM_BRIDGE_OP_DP_AUDIO;
+	bridge->of_node = dp->dev->of_node;
+	bridge->type = DRM_MODE_CONNECTOR_DisplayPort;
+	bridge->hdmi_audio_dev = dp->dev;
+	bridge->hdmi_audio_max_i2s_playback_channels = 8;
+	bridge->hdmi_audio_spdif_playback = 1;
+	bridge->hdmi_audio_dai_port = -1;
+
+	ret = devm_drm_bridge_add(dev, bridge);
 	if (ret)
 		return ret;
 
-	ret = drm_bridge_attach(encoder, &dp->bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+	ret = drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
 	if (ret)
 		return ret;
 
+	if (next_bridge) {
+		ret = drm_bridge_attach(encoder, next_bridge, bridge,
+					DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+		if (ret)
+			return ret;
+
+		last_bridge = drm_bridge_chain_get_last_bridge(bridge->encoder);
+	}
+
 	connector = drm_bridge_connector_init(drm_dev, encoder);
 	if (IS_ERR(connector)) {
 		ret = PTR_ERR(connector);
@@ -1029,8 +1144,100 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
 		return ret;
 	}
 
+	if (last_bridge)
+		connector->fwnode = fwnode_handle_get(of_fwnode_handle(last_bridge->of_node));
+
 	drm_connector_attach_encoder(connector, encoder);
 
+	return 0;
+}
+
+static int cdn_dp_parse_next_bridge_dt(struct cdn_dp_device *dp)
+{
+	struct device_node *np = dp->dev->of_node;
+	struct device_node *port __free(device_node) = of_graph_get_port_by_id(np, 1);
+	struct drm_bridge *bridge;
+	int count = 0;
+	int ret = 0;
+	int i;
+
+	/* If device use extcon, do not use hpd bridge */
+	for (i = 0; i < dp->ports; i++) {
+		if (dp->port[i]->extcon) {
+			dp->bridge_count = 1;
+			return 0;
+		}
+	}
+
+	/* One endpoint may correspond to one next bridge. */
+	for_each_of_graph_port_endpoint(port, dp_ep) {
+		struct device_node *next_bridge_node __free(device_node) =
+			of_graph_get_remote_port_parent(dp_ep);
+
+		bridge = of_drm_find_bridge(next_bridge_node);
+		if (!bridge) {
+			ret = -EPROBE_DEFER;
+			goto out;
+		}
+
+		drm_bridge_get(bridge);
+		dp->next_bridge_valid = true;
+		dp->next_bridge_list[count] = bridge;
+		count++;
+	}
+
+out:
+	dp->bridge_count = count ? count : 1;
+	return ret;
+}
+
+static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
+{
+	struct cdn_dp_device *dp = dev_get_drvdata(dev);
+	struct drm_bridge *bridge, *next_bridge;
+	struct drm_encoder *encoder;
+	struct cdn_dp_port *port;
+	struct drm_device *drm_dev = data;
+	struct cdn_dp_bridge *dp_bridge;
+	int ret, i;
+
+	ret = cdn_dp_parse_dt(dp);
+	if (ret < 0)
+		return ret;
+
+	ret = cdn_dp_parse_next_bridge_dt(dp);
+	if (ret)
+		return ret;
+
+	dp->drm_dev = drm_dev;
+	dp->connected = false;
+	dp->active = false;
+	dp->active_port = -1;
+	dp->fw_loaded = false;
+
+	for (i = 0; i < dp->bridge_count; i++) {
+		dp_bridge = devm_drm_bridge_alloc(dev, struct cdn_dp_bridge, bridge,
+						    &cdn_dp_bridge_funcs);
+		if (IS_ERR(dp_bridge))
+			return PTR_ERR(dp_bridge);
+		dp_bridge->id = i;
+		dp_bridge->parent = dp;
+		if (!dp->next_bridge_valid)
+			dp_bridge->connected = true;
+		dp->bridge_list[i] = dp_bridge;
+	}
+
+	for (i = 0; i < dp->bridge_count; i++) {
+		encoder = &dp->bridge_list[i]->encoder.encoder;
+		bridge = &dp->bridge_list[i]->bridge;
+		next_bridge = dp->next_bridge_list[i];
+		ret = cdn_bridge_add(dev, bridge, next_bridge, encoder);
+		if (ret)
+			return ret;
+	}
+
+	INIT_WORK(&dp->event_work, cdn_dp_pd_event_work);
+
 	for (i = 0; i < dp->ports; i++) {
 		port = dp->port[i];
 
@@ -1058,10 +1265,18 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
 static void cdn_dp_unbind(struct device *dev, struct device *master, void *data)
 {
 	struct cdn_dp_device *dp = dev_get_drvdata(dev);
-	struct drm_encoder *encoder = &dp->encoder.encoder;
+	struct drm_encoder *encoder;
+	int i;
 
 	cancel_work_sync(&dp->event_work);
-	encoder->funcs->destroy(encoder);
+	for (i = 0; i < dp->bridge_count; i++) {
+		encoder = &dp->bridge_list[i]->encoder.encoder;
+		encoder->funcs->destroy(encoder);
+		drm_bridge_put(dp->next_bridge_list[i]);
+	}
+
+	for (i = 0; i < MAX_PHY; i++)
+		drm_edid_free(dp->edid_cache[i]);
 
 	pm_runtime_disable(dev);
 	if (dp->fw_loaded)
@@ -1112,10 +1327,10 @@ static int cdn_dp_probe(struct platform_device *pdev)
 	int ret;
 	int i;
 
-	dp = devm_drm_bridge_alloc(dev, struct cdn_dp_device, bridge,
-				   &cdn_dp_bridge_funcs);
-	if (IS_ERR(dp))
-		return PTR_ERR(dp);
+	dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
+	if (!dp)
+		return -ENOMEM;
+
 	dp->dev = dev;
 
 	match = of_match_node(cdn_dp_dt_ids, pdev->dev.of_node);
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.h b/drivers/gpu/drm/rockchip/cdn-dp-core.h
index e9c30b9fd543..c10e423bbf06 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.h
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h
@@ -38,6 +38,8 @@ enum vic_pxl_encoding_format {
 	Y_ONLY = 0x10,
 };
 
+struct cdn_dp_device;
+
 struct video_info {
 	bool h_sync_polarity;
 	bool v_sync_polarity;
@@ -63,16 +65,28 @@ struct cdn_dp_port {
 	u8 id;
 };
 
+struct cdn_dp_bridge {
+	struct cdn_dp_device *parent;
+	struct drm_bridge bridge;
+	struct rockchip_encoder encoder;
+	bool connected;
+	bool enabled;
+	int id;
+};
+
 struct cdn_dp_device {
 	struct device *dev;
 	struct drm_device *drm_dev;
-	struct drm_bridge bridge;
-	struct rockchip_encoder encoder;
+	int bridge_count;
+	struct cdn_dp_bridge *bridge_list[MAX_PHY];
+	struct drm_bridge *next_bridge_list[MAX_PHY];
+	const struct drm_edid *edid_cache[MAX_PHY];
 	struct drm_display_mode mode;
 	struct platform_device *audio_pdev;
 	struct work_struct event_work;
 
 	struct mutex lock;
+	bool next_bridge_valid;
 	bool connected;
 	bool active;
 	bool suspended;
-- 
2.51.1



From kernel at airkyi.com  Wed Nov 19 18:23:36 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Thu, 20 Nov 2025 10:23:36 +0800
Subject: [PATCH v10 04/11] drm/bridge: aux: Add drm_aux_bridge_register_from_node()
In-Reply-To: <20251120022343.250-1-kernel@airkyi.com>
References: <20251120022343.250-1-kernel@airkyi.com>
Message-ID: <20251120022343.250-5-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

The drm_aux_bridge_register() uses the device->of_node as the
bridge->of_node.

This patch adds drm_aux_bridge_register_from_node() to allow
specifying the of_node corresponding to the bridge.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---
 drivers/gpu/drm/bridge/aux-bridge.c | 24 ++++++++++++++++++++++--
 include/drm/bridge/aux-bridge.h     |  6 ++++++
 2 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/aux-bridge.c b/drivers/gpu/drm/bridge/aux-bridge.c
index b3e4cdff61d6..52dff4601c2d 100644
--- a/drivers/gpu/drm/bridge/aux-bridge.c
+++ b/drivers/gpu/drm/bridge/aux-bridge.c
@@ -35,6 +35,7 @@ static void drm_aux_bridge_unregister_adev(void *_adev)
 /**
  * drm_aux_bridge_register - Create a simple bridge device to link the chain
  * @parent: device instance providing this bridge
+ * @np: device node pointer corresponding to this bridge instance
  *
  * Creates a simple DRM bridge that doesn't implement any drm_bridge
  * operations. Such bridges merely fill a place in the bridge chain linking
@@ -42,7 +43,7 @@ static void drm_aux_bridge_unregister_adev(void *_adev)
  *
  * Return: zero on success, negative error code on failure
  */
-int drm_aux_bridge_register(struct device *parent)
+int drm_aux_bridge_register_from_node(struct device *parent, struct device_node *np)
 {
 	struct auxiliary_device *adev;
 	int ret;
@@ -62,7 +63,10 @@ int drm_aux_bridge_register(struct device *parent)
 	adev->dev.parent = parent;
 	adev->dev.release = drm_aux_bridge_release;
 
-	device_set_of_node_from_dev(&adev->dev, parent);
+	if (np)
+		device_set_node(&adev->dev, of_fwnode_handle(np));
+	else
+		device_set_of_node_from_dev(&adev->dev, parent);
 
 	ret = auxiliary_device_init(adev);
 	if (ret) {
@@ -80,6 +84,22 @@ int drm_aux_bridge_register(struct device *parent)
 
 	return devm_add_action_or_reset(parent, drm_aux_bridge_unregister_adev, adev);
 }
+EXPORT_SYMBOL_GPL(drm_aux_bridge_register_from_node);
+
+/**
+ * drm_aux_bridge_register - Create a simple bridge device to link the chain
+ * @parent: device instance providing this bridge
+ *
+ * Creates a simple DRM bridge that doesn't implement any drm_bridge
+ * operations. Such bridges merely fill a place in the bridge chain linking
+ * surrounding DRM bridges.
+ *
+ * Return: zero on success, negative error code on failure
+ */
+int drm_aux_bridge_register(struct device *parent)
+{
+	return drm_aux_bridge_register_from_node(parent, NULL);
+}
 EXPORT_SYMBOL_GPL(drm_aux_bridge_register);
 
 struct drm_aux_bridge_data {
diff --git a/include/drm/bridge/aux-bridge.h b/include/drm/bridge/aux-bridge.h
index c2f5a855512f..7dd1f17a1354 100644
--- a/include/drm/bridge/aux-bridge.h
+++ b/include/drm/bridge/aux-bridge.h
@@ -13,11 +13,17 @@ struct auxiliary_device;
 
 #if IS_ENABLED(CONFIG_DRM_AUX_BRIDGE)
 int drm_aux_bridge_register(struct device *parent);
+int drm_aux_bridge_register_from_node(struct device *parent, struct device_node *np);
 #else
 static inline int drm_aux_bridge_register(struct device *parent)
 {
 	return 0;
 }
+
+static inline int drm_aux_bridge_register_from_node(struct device *parent, struct device_node *np)
+{
+	return 0;
+}
 #endif
 
 #if IS_ENABLED(CONFIG_DRM_AUX_HPD_BRIDGE)
-- 
2.51.1



From kernel at airkyi.com  Wed Nov 19 18:23:40 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Thu, 20 Nov 2025 10:23:40 +0800
Subject: [PATCH v10 08/11] drm/rockchip: cdn-dp: Support handle lane info without extcon
In-Reply-To: <20251120022343.250-1-kernel@airkyi.com>
References: <20251120022343.250-1-kernel@airkyi.com>
Message-ID: <20251120022343.250-9-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

This patch add support for get PHY lane info without help of extcon.

There is no extcon needed if the Type-C controller is present. In this
case, the lane info can be get from PHY instead of extcon.

The extcon device should still be supported if Type-C controller is
not present.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---

(no changes since v5)

Changes in v4:
- Remove cdn_dp_hpd_notify().

(no changes since v3)

Changes in v2:
- Ignore duplicate HPD events.

 drivers/gpu/drm/rockchip/cdn-dp-core.c | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index b7e3f5dcf8d5..1e27301584a4 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -156,6 +156,9 @@ static int cdn_dp_get_port_lanes(struct cdn_dp_port *port)
 	int dptx;
 	u8 lanes;
 
+	if (!edev)
+		return phy_get_bus_width(port->phy);
+
 	dptx = extcon_get_state(edev, EXTCON_DISP_DP);
 	if (dptx > 0) {
 		extcon_get_property(edev, EXTCON_DISP_DP,
@@ -219,7 +222,7 @@ static bool cdn_dp_check_sink_connection(struct cdn_dp_device *dp)
 	 * some docks need more time to power up.
 	 */
 	while (time_before(jiffies, timeout)) {
-		if (!extcon_get_state(port->extcon, EXTCON_DISP_DP))
+		if (port->extcon && !extcon_get_state(port->extcon, EXTCON_DISP_DP))
 			return false;
 
 		if (!cdn_dp_get_sink_count(dp, &sink_count))
@@ -385,11 +388,14 @@ static int cdn_dp_enable_phy(struct cdn_dp_device *dp, struct cdn_dp_port *port)
 		goto err_power_on;
 	}
 
-	ret = extcon_get_property(port->extcon, EXTCON_DISP_DP,
-				  EXTCON_PROP_USB_TYPEC_POLARITY, &property);
-	if (ret) {
-		DRM_DEV_ERROR(dp->dev, "get property failed\n");
-		goto err_power_on;
+	property.intval = 0;
+	if (port->extcon) {
+		ret = extcon_get_property(port->extcon, EXTCON_DISP_DP,
+					  EXTCON_PROP_USB_TYPEC_POLARITY, &property);
+		if (ret) {
+			DRM_DEV_ERROR(dp->dev, "get property failed\n");
+			goto err_power_on;
+		}
 	}
 
 	port->lanes = cdn_dp_get_port_lanes(port);
@@ -1028,6 +1034,9 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
 	for (i = 0; i < dp->ports; i++) {
 		port = dp->port[i];
 
+		if (!port->extcon)
+			continue;
+
 		port->event_nb.notifier_call = cdn_dp_pd_event;
 		ret = devm_extcon_register_notifier(dp->dev, port->extcon,
 						    EXTCON_DISP_DP,
@@ -1120,14 +1129,14 @@ static int cdn_dp_probe(struct platform_device *pdev)
 		    PTR_ERR(phy) == -EPROBE_DEFER)
 			return -EPROBE_DEFER;
 
-		if (IS_ERR(extcon) || IS_ERR(phy))
+		if (IS_ERR(phy) || PTR_ERR(extcon) != -ENODEV)
 			continue;
 
 		port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
 		if (!port)
 			return -ENOMEM;
 
-		port->extcon = extcon;
+		port->extcon = IS_ERR(extcon) ? NULL : extcon;
 		port->phy = phy;
 		port->dp = dp;
 		port->id = i;
-- 
2.51.1



From kernel at airkyi.com  Wed Nov 19 18:23:42 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Thu, 20 Nov 2025 10:23:42 +0800
Subject: [PATCH v10 10/11] arm64: dts: rockchip: Add missing dp_out port for RK3399 CDN-DP
In-Reply-To: <20251120022343.250-1-kernel@airkyi.com>
References: <20251120022343.250-1-kernel@airkyi.com>
Message-ID: <20251120022343.250-11-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

Let's make the ports nodes of cdn_dp in the same style as the other
display interface, and match the style of ports's yaml.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---

(no changes since v5)

Changes in v4:
- Remove unnecessary #address/#size-cells

(no changes since v1)

 arch/arm64/boot/dts/rockchip/rk3399-base.dtsi | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi
index 4dcceb9136b7..93b42820998f 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi
@@ -618,7 +618,11 @@ cdn_dp: dp at fec00000 {
 		status = "disabled";
 
 		ports {
-			dp_in: port {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			dp_in: port at 0 {
+				reg = <0>;
 				#address-cells = <1>;
 				#size-cells = <0>;
 
@@ -632,6 +636,10 @@ dp_in_vopl: endpoint at 1 {
 					remote-endpoint = <&vopl_out_dp>;
 				};
 			};
+
+			dp_out: port at 1 {
+				reg = <1>;
+			};
 		};
 	};
 
-- 
2.51.1



From kernel at airkyi.com  Wed Nov 19 18:23:43 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Thu, 20 Nov 2025 10:23:43 +0800
Subject: [PATCH v10 11/11] arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort
In-Reply-To: <20251120022343.250-1-kernel@airkyi.com>
References: <20251120022343.250-1-kernel@airkyi.com>
Message-ID: <20251120022343.250-12-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

The RK3399 EVB IND board has a Type-C interface DisplayPort.
It use fusb302 chip as Type-C controller.

fusb302 chip ---> USB/DP PHY0 <----> CDN-DP controller

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---

(no changes since v10)

Changes in v9:
- Add usb role switch for Type-C.
- Remove USB2 PHY in Type-C connection.

(no changes since v4)

Changes in v3:
- Fix wrong vdo value.
- Fix port node in usb-c-connector.

Changes in v2:
- Add endpoint to link DP PHY and DP controller.
- Fix devicetree coding style.

 .../boot/dts/rockchip/rk3399-evb-ind.dts      | 147 ++++++++++++++++++
 1 file changed, 147 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts
index 70aee1ab904c..be1e90f7a453 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts
@@ -4,6 +4,7 @@
  */
 
 /dts-v1/;
+#include <dt-bindings/usb/pd.h>
 #include "rk3399.dtsi"
 
 / {
@@ -19,6 +20,21 @@ chosen {
 		stdout-path = "serial2:1500000n8";
 	};
 
+	sound: sound {
+		compatible = "rockchip,rk3399-gru-sound";
+		rockchip,cpu = <&i2s0 &spdif>;
+	};
+
+	vbus_typec: regulator-vbus-typec {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc5v0_typec0_en>;
+		regulator-name = "vbus_typec";
+		vin-supply = <&vcc5v0_sys>;
+	};
+
 	vcc5v0_sys: regulator-vcc5v0-sys {
 		compatible = "regulator-fixed";
 		enable-active-high;
@@ -31,6 +47,11 @@ vcc5v0_sys: regulator-vcc5v0-sys {
 	};
 };
 
+&cdn_dp {
+	phys = <&tcphy0_dp>;
+	status = "okay";
+};
+
 &cpu_b0 {
 	cpu-supply = <&vdd_cpu_b>;
 };
@@ -55,6 +76,12 @@ &cpu_l3 {
 	cpu-supply = <&vdd_cpu_l>;
 };
 
+&dp_out {
+	dp_controller_output: endpoint {
+		remote-endpoint = <&dp_phy_in>;
+	};
+};
+
 &emmc_phy {
 	status = "okay";
 };
@@ -341,6 +368,71 @@ regulator-state-mem {
 	};
 };
 
+&i2c4 {
+	i2c-scl-rising-time-ns = <475>;
+	i2c-scl-falling-time-ns = <26>;
+	status = "okay";
+
+	usbc0: typec-portc at 22 {
+		compatible = "fcs,fusb302";
+		reg = <0x22>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <RK_PA2 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&usbc0_int>;
+		vbus-supply = <&vbus_typec>;
+
+		usb_con: connector {
+			compatible = "usb-c-connector";
+			label = "USB-C";
+			data-role = "dual";
+			power-role = "dual";
+			try-power-role = "sink";
+			op-sink-microwatt = <1000000>;
+			sink-pdos =
+				<PDO_FIXED(5000, 2500, PDO_FIXED_USB_COMM)>;
+			source-pdos =
+				<PDO_FIXED(5000, 1500, PDO_FIXED_USB_COMM)>;
+
+			altmodes {
+				displayport {
+					svid = /bits/ 16 <0xff01>;
+					vdo = <0x00001c46>;
+				};
+			};
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					reg = <0>;
+
+					usbc0_orien_sw: endpoint {
+						remote-endpoint = <&tcphy0_orientation_switch>;
+					};
+				};
+
+				port at 1 {
+					reg = <1>;
+
+					usbc0_role_sw: endpoint {
+						remote-endpoint = <&dwc3_0_role_switch>;
+					};
+				};
+
+				port at 2 {
+					reg = <2>;
+
+					dp_altmode_mux: endpoint {
+						remote-endpoint = <&tcphy0_typec_dp>;
+					};
+				};
+			};
+		};
+	};
+};
+
 &i2s2 {
 	status = "okay";
 };
@@ -354,6 +446,16 @@ &io_domains {
 };
 
 &pinctrl {
+	usb-typec {
+		usbc0_int: usbc0-int {
+			rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+
+		vcc5v0_typec0_en: vcc5v0-typec0-en {
+			rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
 	pmic {
 		pmic_int_l: pmic-int-l {
 			rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>;
@@ -400,10 +502,48 @@ &sdmmc {
 	status = "okay";
 };
 
+&sound {
+	rockchip,codec = <&cdn_dp>;
+	status = "okay";
+};
+
+&spdif {
+	status = "okay";
+};
+
 &tcphy0 {
 	status = "okay";
 };
 
+&tcphy0_dp {
+	mode-switch;
+
+	port {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		tcphy0_typec_dp: endpoint at 0 {
+			reg = <0>;
+			remote-endpoint = <&dp_altmode_mux>;
+		};
+
+		dp_phy_in: endpoint at 1 {
+			reg = <1>;
+			remote-endpoint = <&dp_controller_output>;
+		};
+	};
+};
+
+&tcphy0_usb3 {
+	orientation-switch;
+
+	port {
+		tcphy0_orientation_switch: endpoint {
+			remote-endpoint = <&usbc0_orien_sw>;
+		};
+	};
+};
+
 &tcphy1 {
 	status = "okay";
 };
@@ -461,7 +601,14 @@ &usb_host1_ohci {
 };
 
 &usbdrd_dwc3_0 {
+	usb-role-switch;
 	status = "okay";
+
+	port {
+		dwc3_0_role_switch: endpoint {
+			remote-endpoint = <&usbc0_role_sw>;
+		};
+	};
 };
 
 &usbdrd3_0 {
-- 
2.51.1



From martin.petersen at oracle.com  Wed Nov 19 19:35:51 2025
From: martin.petersen at oracle.com (Martin K. Petersen)
Date: Wed, 19 Nov 2025 22:35:51 -0500
Subject: [PATCH] scsi: ufs: rockchip: Reset controller on PRE_CHANGE of
 hce enable notify
In-Reply-To: <1763009575-237552-1-git-send-email-shawn.lin@rock-chips.com>
	(Shawn Lin's message of "Thu, 13 Nov 2025 12:52:55 +0800")
References: <1763009575-237552-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <yq18qg19y0f.fsf@ca-mkp.ca.oracle.com>


Shawn,

> This fixes the dme-reset failed when doing recoverying, because device
> reset is not enough, we could occasionally see the error below:

Applied to 6.19/scsi-staging, thanks!

-- 
Martin K. Petersen


From martin.petersen at oracle.com  Wed Nov 19 19:36:03 2025
From: martin.petersen at oracle.com (Martin K. Petersen)
Date: Wed, 19 Nov 2025 22:36:03 -0500
Subject: [PATCH] scsi: ufs: rockchip: Fix compile error without
 CONFIG_GPIOLIB
In-Reply-To: <1763011091-243727-1-git-send-email-shawn.lin@rock-chips.com>
	(Shawn Lin's message of "Thu, 13 Nov 2025 13:18:11 +0800")
References: <1763011091-243727-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <yq134699y03.fsf@ca-mkp.ca.oracle.com>


Shawn,

> drivers/ufs/host/ufs-rockchip.c:168:19: error: implicit declaration of function
> 'devm_gpiod_get'; did you mean 'em_pd_get'? [-Werror=implicit-function-declaration]

Applied to 6.19/scsi-staging, thanks!

-- 
Martin K. Petersen


From helgaas at kernel.org  Wed Nov 19 19:44:37 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Wed, 19 Nov 2025 21:44:37 -0600
Subject: [RFC v1 1/5] PCI: rockchip: Fix Link Control register offset and
 enable ASPM/CLKREQ
In-Reply-To: <CANAwSgRHuwoQjr95sXp-X97=L-X3vqUPxjR5=2jNtFZA+4gnwQ@mail.gmail.com>
Message-ID: <20251120034437.GA2625966@bhelgaas>

On Wed, Nov 19, 2025 at 07:49:06PM +0530, Anand Moon wrote:
> On Tue, 18 Nov 2025 at 23:20, Bjorn Helgaas <helgaas at kernel.org> wrote:
> > On Mon, Nov 17, 2025 at 11:40:09PM +0530, Anand Moon wrote:
> > > As per the RK3399 TRM (Part 2, 17.6.6.1.31), the Link Control register
> > > (RC_CONFIG_LC) resides at an offset of 0xd0 within the Root Complex (RC)
> > > configuration space, not at the offset of the PCI Express Capability List
> > > (0xc0). Following changes correct the register offset to use
> > > PCIE_RC_CONFIG_LC (0xd0) to configure link control.
> ...

> > Don't do two things at once in the same patch.  Fix the register
> > offset in one patch.  Actually, as I mentioned at [1], there's a lot
> > of fixing to do there, and I'm not even going to consider other
> > changes until the #define mess is cleaned up.

> > [1] https://lore.kernel.org/r/20251118005056.GA2541796 at bhelgaas
> 
> According to the RK3399 Technical Reference Manual (TRM), and pci_regs.h
> already includes the correct, pre-defined offsets for all PCI Express
> device types
> and their capabilities registers. To avoid overlapping register mappings,
> we should explicitly remove the addition of manual offsets within the code.

> Here is the example. Is this the correct approach?

> -       status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_CR +
> PCI_EXP_LNKCTL);
> +       status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LC);
>         status |= (PCI_EXP_LNKCTL_LBMIE | PCI_EXP_LNKCTL_LABIE);
> -       rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_CR +
> PCI_EXP_LNKCTL);
> +       rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LC);

No.  The call should include PCI_EXP_LNKCTL because that's what we
grep for when we want to see where Link Control is updated.

See my example from [1] above:

  rockchip_pcie_read(rockchip, ROCKCHIP_RP_PCIE_CAP + PCI_EXP_DEVCAP)
  rockchip_pcie_read(rockchip, ROCKCHIP_RP_PCIE_CAP + PCI_EXP_LNKCTL)

You should have a single #define for the offset of the PCIe
Capability, e.g., ROCKCHIP_RP_PCIE_CAP.  Every access to registers in
that capability would use ROCKCHIP_RP_PCIE_CAP and the relevant
PCI_EXP_* offset, e.g., PCI_EXP_DEVCAP, PCI_EXP_DEVCTL,
PCI_EXP_DEVSTA, PCI_EXP_LNKCAP, PCI_EXP_LNKCTL, PCI_EXP_LNKSTA, etc.

Bjorn


From mani at kernel.org  Wed Nov 19 23:40:56 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Thu, 20 Nov 2025 13:10:56 +0530
Subject: [PATCH v2 1/4] PCI: dwc: Advertise L1 PM Substates only if
 driver requests it
In-Reply-To: <20251118214312.2598220-2-helgaas@kernel.org>
References: <20251118214312.2598220-1-helgaas@kernel.org>
 <20251118214312.2598220-2-helgaas@kernel.org>
Message-ID: <wja7vxtg7bqq2udepl5r3mvgg5swvuqtuzk6cnimgcbw2aegqs@hru6yzg4xx3o>

On Tue, Nov 18, 2025 at 03:42:15PM -0600, Bjorn Helgaas wrote:
> From: Bjorn Helgaas <bhelgaas at google.com>
> 
> L1 PM Substates require the CLKREQ# signal and may also require
> device-specific support.  If CLKREQ# is not supported or driver support is
> lacking, enabling L1.1 or L1.2 may cause errors when accessing devices,
> e.g.,
> 
>   nvme nvme0: controller is down; will reset: CSTS=0xffffffff, PCI_STATUS=0x10
> 
> If the kernel is built with CONFIG_PCIEASPM_POWER_SUPERSAVE=y or users
> enable L1.x via sysfs, users may trip over these errors even if L1
> Substates haven't been enabled by firmware or the driver.
> 
> To prevent such errors, disable advertising the L1 PM Substates unless the
> driver sets "dw_pcie.l1ss_support" to indicate that it knows CLKREQ# is
> present and any device-specific configuration has been done.
> 

Going by this reasoning, why can't we enable L1 PM Substates for these platforms
by default?

- Mani

> Set "dw_pcie.l1ss_support" in tegra194 (if DT includes the
> "supports-clkreq' property) and qcom (for cfg_2_7_0, cfg_1_9_0, cfg_1_34_0,
> and cfg_sc8280xp controllers) so they can continue to use L1 Substates.
> 
> Based on Niklas's patch:
> https://patch.msgid.link/20251017163252.598812-2-cassel at kernel.org
> 
> Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
> ---
>  .../pci/controller/dwc/pcie-designware-ep.c   |  2 ++
>  .../pci/controller/dwc/pcie-designware-host.c |  2 ++
>  drivers/pci/controller/dwc/pcie-designware.c  | 24 +++++++++++++++++++
>  drivers/pci/controller/dwc/pcie-designware.h  |  2 ++
>  drivers/pci/controller/dwc/pcie-qcom.c        |  2 ++
>  drivers/pci/controller/dwc/pcie-tegra194.c    |  3 +++
>  6 files changed, 35 insertions(+)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
> index 7f2112c2fb21..ad6c0fd67a65 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> @@ -966,6 +966,8 @@ int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)
>  	if (ep->ops->init)
>  		ep->ops->init(ep);
>  
> +	dw_pcie_hide_unsupported_l1ss(pci);
> +
>  	ptm_cap_base = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_PTM);
>  
>  	/*
> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> index 20c9333bcb1c..7abeb771e32d 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -1060,6 +1060,8 @@ int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
>  		PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
>  	dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
>  
> +	dw_pcie_hide_unsupported_l1ss(pci);
> +
>  	dw_pcie_config_presets(pp);
>  	/*
>  	 * If the platform provides its own child bus config accesses, it means
> diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
> index c644216995f6..6e6a0dac5b53 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.c
> +++ b/drivers/pci/controller/dwc/pcie-designware.c
> @@ -1081,6 +1081,30 @@ void dw_pcie_edma_remove(struct dw_pcie *pci)
>  	dw_edma_remove(&pci->edma);
>  }
>  
> +void dw_pcie_hide_unsupported_l1ss(struct dw_pcie *pci)
> +{
> +	u16 l1ss;
> +	u32 l1ss_cap;
> +
> +	if (pci->l1ss_support)
> +		return;
> +
> +	l1ss = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_L1SS);
> +	if (!l1ss)
> +		return;
> +
> +	/*
> +	 * Unless the driver claims "l1ss_support", don't advertise L1 PM
> +	 * Substates because they require CLKREQ# and possibly other
> +	 * device-specific configuration.
> +	 */
> +	l1ss_cap = dw_pcie_readl_dbi(pci, l1ss + PCI_L1SS_CAP);
> +	l1ss_cap &= ~(PCI_L1SS_CAP_PCIPM_L1_1 | PCI_L1SS_CAP_ASPM_L1_1 |
> +		      PCI_L1SS_CAP_PCIPM_L1_2 | PCI_L1SS_CAP_ASPM_L1_2 |
> +		      PCI_L1SS_CAP_L1_PM_SS);
> +	dw_pcie_writel_dbi(pci, l1ss + PCI_L1SS_CAP, l1ss_cap);
> +}
> +
>  void dw_pcie_setup(struct dw_pcie *pci)
>  {
>  	u32 val;
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> index e995f692a1ec..a68eea47d451 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -516,6 +516,7 @@ struct dw_pcie {
>  	int			max_link_speed;
>  	u8			n_fts[2];
>  	struct dw_edma_chip	edma;
> +	bool			l1ss_support;	/* L1 PM Substates support */
>  	struct clk_bulk_data	app_clks[DW_PCIE_NUM_APP_CLKS];
>  	struct clk_bulk_data	core_clks[DW_PCIE_NUM_CORE_CLKS];
>  	struct reset_control_bulk_data	app_rsts[DW_PCIE_NUM_APP_RSTS];
> @@ -573,6 +574,7 @@ int dw_pcie_prog_ep_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
>  				int type, u64 parent_bus_addr,
>  				u8 bar, size_t size);
>  void dw_pcie_disable_atu(struct dw_pcie *pci, u32 dir, int index);
> +void dw_pcie_hide_unsupported_l1ss(struct dw_pcie *pci);
>  void dw_pcie_setup(struct dw_pcie *pci);
>  void dw_pcie_iatu_detect(struct dw_pcie *pci);
>  int dw_pcie_edma_detect(struct dw_pcie *pci);
> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
> index 805edbbfe7eb..61c2f4e2f74d 100644
> --- a/drivers/pci/controller/dwc/pcie-qcom.c
> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> @@ -1067,6 +1067,8 @@ static int qcom_pcie_init_2_7_0(struct qcom_pcie *pcie)
>  	val &= ~REQ_NOT_ENTR_L1;
>  	writel(val, pcie->parf + PARF_PM_CTRL);
>  
> +	pci->l1ss_support = true;
> +
>  	val = readl(pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
>  	val |= EN;
>  	writel(val, pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
> diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
> index 10e74458e667..3934757baa30 100644
> --- a/drivers/pci/controller/dwc/pcie-tegra194.c
> +++ b/drivers/pci/controller/dwc/pcie-tegra194.c
> @@ -703,6 +703,9 @@ static void init_host_aspm(struct tegra_pcie_dw *pcie)
>  	val |= (pcie->aspm_pwr_on_t << 19);
>  	dw_pcie_writel_dbi(pci, pcie->cfg_link_cap_l1sub, val);
>  
> +	if (pcie->supports_clkreq)
> +		pci->l1ss_support = true;
> +
>  	/* Program L0s and L1 entrance latencies */
>  	val = dw_pcie_readl_dbi(pci, PCIE_PORT_AFR);
>  	val &= ~PORT_AFR_L0S_ENTRANCE_LAT_MASK;
> -- 
> 2.43.0
> 

-- 
????????? ????????


From mani at kernel.org  Wed Nov 19 23:52:19 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Thu, 20 Nov 2025 13:22:19 +0530
Subject: [PATCH v2 1/4] PCI: dwc: Advertise L1 PM Substates only if
 driver requests it
In-Reply-To: <aRz0ak6onKzZs2lY@lizhi-Precision-Tower-5810>
References: <20251118214312.2598220-1-helgaas@kernel.org>
 <20251118214312.2598220-2-helgaas@kernel.org>
 <aRz0ak6onKzZs2lY@lizhi-Precision-Tower-5810>
Message-ID: <lhunx3lpx3fgzyszf3librekhlrqtewcu664i7anj2s54j7kcr@52tt66auzpnr>

On Tue, Nov 18, 2025 at 05:34:18PM -0500, Frank Li wrote:
> On Tue, Nov 18, 2025 at 03:42:15PM -0600, Bjorn Helgaas wrote:
> > From: Bjorn Helgaas <bhelgaas at google.com>
> >
> > L1 PM Substates require the CLKREQ# signal and may also require
> > device-specific support.  If CLKREQ# is not supported or driver support is
> > lacking, enabling L1.1 or L1.2 may cause errors when accessing devices,
> > e.g.,
> >
> >   nvme nvme0: controller is down; will reset: CSTS=0xffffffff, PCI_STATUS=0x10
> >
> > If the kernel is built with CONFIG_PCIEASPM_POWER_SUPERSAVE=y or users
> > enable L1.x via sysfs, users may trip over these errors even if L1
> > Substates haven't been enabled by firmware or the driver.
> >
> > To prevent such errors, disable advertising the L1 PM Substates unless the
> > driver sets "dw_pcie.l1ss_support" to indicate that it knows CLKREQ# is
> > present and any device-specific configuration has been done.
> >
> > Set "dw_pcie.l1ss_support" in tegra194 (if DT includes the
> > "supports-clkreq' property) and qcom (for cfg_2_7_0, cfg_1_9_0, cfg_1_34_0,
> > and cfg_sc8280xp controllers) so they can continue to use L1 Substates.
> >
> > Based on Niklas's patch:
> > https://patch.msgid.link/20251017163252.598812-2-cassel at kernel.org
> >
> > Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
> > ---
> >  .../pci/controller/dwc/pcie-designware-ep.c   |  2 ++
> >  .../pci/controller/dwc/pcie-designware-host.c |  2 ++
> >  drivers/pci/controller/dwc/pcie-designware.c  | 24 +++++++++++++++++++
> >  drivers/pci/controller/dwc/pcie-designware.h  |  2 ++
> >  drivers/pci/controller/dwc/pcie-qcom.c        |  2 ++
> >  drivers/pci/controller/dwc/pcie-tegra194.c    |  3 +++
> >  6 files changed, 35 insertions(+)
> >
> > diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
> > index 7f2112c2fb21..ad6c0fd67a65 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> > @@ -966,6 +966,8 @@ int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)
> >  	if (ep->ops->init)
> >  		ep->ops->init(ep);
> >
> > +	dw_pcie_hide_unsupported_l1ss(pci);
> > +
> 
> And, I don't think EP need clean L1SS CAP flags. If EP don't support L1SS,
> it should be force pull down #clkreq.
> 
> EP don't know if #clkreq connected in host boards, assume EP with same
> software, which can run at two difference host system, one host system
> connect #clkreq, the other system have not connect #clkreq.
> 
> otherwords, support-clkreq property should be only for RC side. not EP
> side. EP side l1ss support should depend on specific epf function and
> controller's capablity.
> 

'support-clkreq' DT property is only applicable to the RC as per dtschema. So
using it in the EP driver is wrong in the first place. We could add it to the EP
schema, but that should be done first before relying on it in the driver.

Also, I do think that the device capability should accurately reflect whether
L1ss is supported or not and not assume that the EP will pull the CLKREQ# low
when it is not supported. If the L1ss CAP is available on both RC and EP, host
software may enable L1ss and expect it to work.

But enabling/disabling the CAP for EP should be done later based on either the
DT property or controller specific flag.

- Mani

-- 
????????? ????????


From amadeus at jmu.edu.cn  Thu Nov 20 04:00:07 2025
From: amadeus at jmu.edu.cn (Chukun Pan)
Date: Thu, 20 Nov 2025 20:00:07 +0800
Subject: [PATCH v2 1/5] arm64: dts: rockchip: remove mmc max-frequency for 100ASK DshanPi A1
In-Reply-To: <20251120120011.279104-1-amadeus@jmu.edu.cn>
References: <20251120120011.279104-1-amadeus@jmu.edu.cn>
Message-ID: <20251120120011.279104-2-amadeus@jmu.edu.cn>

The max-frequency property is already defined in the mmc
node of rk3576.dtsi. Remove the redundant definition.

Signed-off-by: Chukun Pan <amadeus at jmu.edu.cn>
---
 arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts b/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
index cb04ab96d1e8..f9dc4fa39167 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
@@ -689,7 +689,6 @@ &sai6 {
 &sdhci {
 	bus-width = <8>;
 	full-pwr-cycle-in-suspend;
-	max-frequency = <200000000>;
 	mmc-hs400-1_8v;
 	mmc-hs400-enhanced-strobe;
 	no-sdio;
@@ -703,7 +702,6 @@ &sdmmc {
 	cap-mmc-highspeed;
 	cap-sd-highspeed;
 	disable-wp;
-	max-frequency = <200000000>;
 	sd-uhs-sdr104;
 	vmmc-supply = <&vcc_3v3_s0>;
 	vqmmc-supply = <&vccio_sd_s0>;
-- 
2.25.1



From amadeus at jmu.edu.cn  Thu Nov 20 04:00:06 2025
From: amadeus at jmu.edu.cn (Chukun Pan)
Date: Thu, 20 Nov 2025 20:00:06 +0800
Subject: [PATCH v2 0/5] arm64: dts: rockchip: update 100ASK DshanPi A1 support
Message-ID: <20251120120011.279104-1-amadeus@jmu.edu.cn>

Changed from v2:
  Remove merged patches
  Split patch for more details

Chukun Pan (5):
  arm64: dts: rockchip: remove mmc max-frequency for 100ASK DshanPi A1
  arm64: dts: rockchip: add mmc aliases for 100ASK DshanPi A1
  arm64: dts: rockchip: enable button for 100ASK DshanPi A1
  arm64: dts: rockchip: enable USB for 100ASK DshanPi A1
  arm64: dts: rockchip: enable RTC for 100ASK DshanPi A1

 .../dts/rockchip/rk3576-100ask-dshanpi-a1.dts | 93 ++++++++++++++++++-
 1 file changed, 91 insertions(+), 2 deletions(-)

-- 
2.25.1



From amadeus at jmu.edu.cn  Thu Nov 20 04:00:08 2025
From: amadeus at jmu.edu.cn (Chukun Pan)
Date: Thu, 20 Nov 2025 20:00:08 +0800
Subject: [PATCH v2 2/5] arm64: dts: rockchip: add mmc aliases for 100ASK DshanPi A1
In-Reply-To: <20251120120011.279104-1-amadeus@jmu.edu.cn>
References: <20251120120011.279104-1-amadeus@jmu.edu.cn>
Message-ID: <20251120120011.279104-3-amadeus@jmu.edu.cn>

Add missing MMC aliases for 100ASK DshanPi A1 board.

Signed-off-by: Chukun Pan <amadeus at jmu.edu.cn>
---
 arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts b/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
index f9dc4fa39167..815f75e7cd70 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
@@ -19,6 +19,8 @@ / {
 	aliases {
 		ethernet0 = &gmac0;
 		ethernet1 = &gmac1;
+		mmc0 = &sdhci;
+		mmc1 = &sdmmc;
 	};
 
 	chosen {
-- 
2.25.1



From amadeus at jmu.edu.cn  Thu Nov 20 04:00:09 2025
From: amadeus at jmu.edu.cn (Chukun Pan)
Date: Thu, 20 Nov 2025 20:00:09 +0800
Subject: [PATCH v2 3/5] arm64: dts: rockchip: enable button for 100ASK DshanPi A1
In-Reply-To: <20251120120011.279104-1-amadeus@jmu.edu.cn>
References: <20251120120011.279104-1-amadeus@jmu.edu.cn>
Message-ID: <20251120120011.279104-4-amadeus@jmu.edu.cn>

The 100ASK DshanPi A1 board has three ADC buttons and one
GPIO button. Enable them.

Signed-off-by: Chukun Pan <amadeus at jmu.edu.cn>
---
 .../dts/rockchip/rk3576-100ask-dshanpi-a1.dts | 67 +++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts b/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
index 815f75e7cd70..9ef41f0c6920 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
@@ -7,6 +7,7 @@
 /dts-v1/;
 
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
 #include <dt-bindings/leds/common.h>
 #include <dt-bindings/pinctrl/rockchip.h>
 #include <dt-bindings/soc/rockchip,vop2.h>
@@ -66,6 +67,61 @@ hdmi_con_in: endpoint {
 		};
 	};
 
+	keys-0 {
+		compatible = "adc-keys";
+		io-channels = <&saradc 0>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <1800000>;
+		poll-interval = <100>;
+
+		button-maskrom {
+			label = "MASKROM";
+			linux,code = <KEY_SETUP>;
+			press-threshold-microvolt = <0>;
+		};
+	};
+
+	keys-1 {
+		compatible = "adc-keys";
+		io-channels = <&saradc 1>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <1800000>;
+		poll-interval = <100>;
+
+		button-recovery {
+			label = "RECOVERY";
+			linux,code = <KEY_VENDOR>;
+			press-threshold-microvolt = <0>;
+		};
+	};
+
+	keys-2 {
+		compatible = "adc-keys";
+		io-channels = <&saradc 4>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <1800000>;
+		poll-interval = <100>;
+
+		button-user2 {
+			label = "USER2";
+			linux,code = <BTN_2>;
+			press-threshold-microvolt = <0>;
+		};
+	};
+
+	keys-3 {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&gpio0_a0_d>;
+
+		button-user1 {
+			gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_LOW>;
+			label = "USER1";
+			linux,code = <BTN_1>;
+			wakeup-source;
+		};
+	};
+
 	vcc_in: regulator-vcc-12v0-dcin {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc_in";
@@ -661,6 +717,12 @@ gmac1_rst: gmac1-rst {
 		};
 	};
 
+	gpio-keys {
+		gpio0_a0_d: gpio0-a0-d {
+			rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
 	headphone {
 		hp_det: hp-det {
 			rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
@@ -688,6 +750,11 @@ &sai6 {
 	status = "okay";
 };
 
+&saradc {
+	vref-supply = <&vcca1v8_pldo2_s0>;
+	status = "okay";
+};
+
 &sdhci {
 	bus-width = <8>;
 	full-pwr-cycle-in-suspend;
-- 
2.25.1



From amadeus at jmu.edu.cn  Thu Nov 20 04:00:10 2025
From: amadeus at jmu.edu.cn (Chukun Pan)
Date: Thu, 20 Nov 2025 20:00:10 +0800
Subject: [PATCH v2 4/5] arm64: dts: rockchip: enable USB for 100ASK DshanPi A1
In-Reply-To: <20251120120011.279104-1-amadeus@jmu.edu.cn>
References: <20251120120011.279104-1-amadeus@jmu.edu.cn>
Message-ID: <20251120120011.279104-5-amadeus@jmu.edu.cn>

Enable USB support for the 100ASK DshanPi A1 board.
Note that the HUSB311 Type-C chip is not supported.

Signed-off-by: Chukun Pan <amadeus at jmu.edu.cn>
---
 .../boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts  | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts b/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
index 9ef41f0c6920..d23c87fe6a9d 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
@@ -800,6 +800,19 @@ &uart0 {
 	status = "okay";
 };
 
+&usbdp_phy {
+	status = "okay";
+};
+
+&usb_drd0_dwc3 {
+	status = "okay";
+};
+
+&usb_drd1_dwc3 {
+	dr_mode = "host";
+	status = "okay";
+};
+
 &vop {
 	status = "okay";
 };
-- 
2.25.1



From amadeus at jmu.edu.cn  Thu Nov 20 04:00:11 2025
From: amadeus at jmu.edu.cn (Chukun Pan)
Date: Thu, 20 Nov 2025 20:00:11 +0800
Subject: [PATCH v2 5/5] arm64: dts: rockchip: enable RTC for 100ASK DshanPi A1
In-Reply-To: <20251120120011.279104-1-amadeus@jmu.edu.cn>
References: <20251120120011.279104-1-amadeus@jmu.edu.cn>
Message-ID: <20251120120011.279104-6-amadeus@jmu.edu.cn>

Enable RTC support for the 100ASK DshanPi A1 board.

Signed-off-by: Chukun Pan <amadeus at jmu.edu.cn>
---
 .../arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts b/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
index d23c87fe6a9d..b19f9b6be6bf 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
@@ -655,6 +655,15 @@ regulator-state-mem {
 	};
 };
 
+&i2c2 {
+	status = "okay";
+
+	rtc at 68 {
+		compatible = "dallas,ds1338";
+		reg = <0x68>;
+	};
+};
+
 &i2c4 {
 	status = "okay";
 
-- 
2.25.1



From shawn.lin at rock-chips.com  Thu Nov 20 04:59:16 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Thu, 20 Nov 2025 20:59:16 +0800
Subject: [PATCH v2 1/5] arm64: dts: rockchip: remove mmc max-frequency for
 100ASK DshanPi A1
In-Reply-To: <20251120120011.279104-2-amadeus@jmu.edu.cn>
References: <20251120120011.279104-1-amadeus@jmu.edu.cn>
 <20251120120011.279104-2-amadeus@jmu.edu.cn>
Message-ID: <a73ea843-6896-4153-9a2b-668a91adba5d@rock-chips.com>

? 2025/11/20 ??? 20:00, Chukun Pan ??:
> The max-frequency property is already defined in the mmc
> node of rk3576.dtsi. Remove the redundant definition.
> 

Reviewed-by: Shawn Lin <shawn.lin at rock-chips.com>

> Signed-off-by: Chukun Pan <amadeus at jmu.edu.cn>
> ---
>   arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts | 2 --
>   1 file changed, 2 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts b/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
> index cb04ab96d1e8..f9dc4fa39167 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
> @@ -689,7 +689,6 @@ &sai6 {
>   &sdhci {
>   	bus-width = <8>;
>   	full-pwr-cycle-in-suspend;
> -	max-frequency = <200000000>;
>   	mmc-hs400-1_8v;
>   	mmc-hs400-enhanced-strobe;
>   	no-sdio;
> @@ -703,7 +702,6 @@ &sdmmc {
>   	cap-mmc-highspeed;
>   	cap-sd-highspeed;
>   	disable-wp;
> -	max-frequency = <200000000>;
>   	sd-uhs-sdr104;
>   	vmmc-supply = <&vcc_3v3_s0>;
>   	vqmmc-supply = <&vccio_sd_s0>;



From linux.amoon at gmail.com  Thu Nov 20 05:58:14 2025
From: linux.amoon at gmail.com (Anand Moon)
Date: Thu, 20 Nov 2025 19:28:14 +0530
Subject: [RFC v1 1/5] PCI: rockchip: Fix Link Control register offset and
 enable ASPM/CLKREQ
In-Reply-To: <20251120034437.GA2625966@bhelgaas>
References: <CANAwSgRHuwoQjr95sXp-X97=L-X3vqUPxjR5=2jNtFZA+4gnwQ@mail.gmail.com>
 <20251120034437.GA2625966@bhelgaas>
Message-ID: <CANAwSgStRZW322X3H_B4wK5CthFube_4MBUBw=U1BRjyRGeu9g@mail.gmail.com>

Hi Bjorn,

Thanks for your input.

On Thu, 20 Nov 2025 at 09:14, Bjorn Helgaas <helgaas at kernel.org> wrote:
>
> On Wed, Nov 19, 2025 at 07:49:06PM +0530, Anand Moon wrote:
> > On Tue, 18 Nov 2025 at 23:20, Bjorn Helgaas <helgaas at kernel.org> wrote:
> > > On Mon, Nov 17, 2025 at 11:40:09PM +0530, Anand Moon wrote:
> > > > As per the RK3399 TRM (Part 2, 17.6.6.1.31), the Link Control register
> > > > (RC_CONFIG_LC) resides at an offset of 0xd0 within the Root Complex (RC)
> > > > configuration space, not at the offset of the PCI Express Capability List
> > > > (0xc0). Following changes correct the register offset to use
> > > > PCIE_RC_CONFIG_LC (0xd0) to configure link control.
> > ...
>
> > > Don't do two things at once in the same patch.  Fix the register
> > > offset in one patch.  Actually, as I mentioned at [1], there's a lot
> > > of fixing to do there, and I'm not even going to consider other
> > > changes until the #define mess is cleaned up.
>
> > > [1] https://lore.kernel.org/r/20251118005056.GA2541796 at bhelgaas
> >
> > According to the RK3399 Technical Reference Manual (TRM), and pci_regs.h
> > already includes the correct, pre-defined offsets for all PCI Express
> > device types
> > and their capabilities registers. To avoid overlapping register mappings,
> > we should explicitly remove the addition of manual offsets within the code.
>
> > Here is the example. Is this the correct approach?
>
> > -       status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_CR +
> > PCI_EXP_LNKCTL);
> > +       status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LC);
> >         status |= (PCI_EXP_LNKCTL_LBMIE | PCI_EXP_LNKCTL_LABIE);
> > -       rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_CR +
> > PCI_EXP_LNKCTL);
> > +       rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LC);
>
> No.  The call should include PCI_EXP_LNKCTL because that's what we
> grep for when we want to see where Link Control is updated.
>
> See my example from [1] above:
>
>   rockchip_pcie_read(rockchip, ROCKCHIP_RP_PCIE_CAP + PCI_EXP_DEVCAP)
>   rockchip_pcie_read(rockchip, ROCKCHIP_RP_PCIE_CAP + PCI_EXP_LNKCTL)
>
> You should have a single #define for the offset of the PCIe
> Capability, e.g., ROCKCHIP_RP_PCIE_CAP.  Every access to registers in
> that capability would use ROCKCHIP_RP_PCIE_CAP and the relevant
> PCI_EXP_* offset, e.g., PCI_EXP_DEVCAP, PCI_EXP_DEVCTL,
> PCI_EXP_DEVSTA, PCI_EXP_LNKCAP, PCI_EXP_LNKCTL, PCI_EXP_LNKSTA, etc.
>
I apologize for not fully understanding the issue earlier. I did not
carefully review your email,
 which caused me to overlook the required changes.

So, as per the TRM

17.6.4.5.1 PCI Express Capability List Register
Propname?PCI Express Capability List Register
Address?@0xc0

#define PCIE_EP_CONFIG_DID_VID          (PCIE_EP_CONFIG_BASE + 0x00)
#define PCIE_EP_CONFIG_LCS              (PCIE_EP_CONFIG_BASE + 0xd0)
#define PCIE_RC_CONFIG_RID_CCR          (PCIE_RC_CONFIG_BASE + 0x08)
#define PCIE_RC_CONFIG_CR               (PCIE_RC_CONFIG_BASE + 0xc0)
#define ROCKCHIP_RP_PCIE_CAP            (PCIE_RC_CONFIG_BASE + 0xc0)
/* Link Control and Status Register */
#define PCIE_RC_CONFIG_LC               (ROCKCHIP_RP_PCIE_CAP + 0xd0)
/* Device Control */
#define PCIE_RC_CONFIG_DC               (ROCKCHIP_RP_PCIE_CAP + 0xc8)
/* Slot Capability Register */
#define PCIE_RC_CONFIG_SC               (ROCKCHIP_RP_PCIE_CAP + 0xd4)
/* Link Control 2 Register */
#define PCIE_RC_CONFIG_LC2              (ROCKCHIP_RP_PCIE_CAP + 0xf0)
/* Linkwidth Control Register */
#define PCIE_RC_CONFIG_LWC              (ROCKCHIP_RP_PCIE_CAP + 0x50)

And then use these like this.

status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LC + PCI_EXP_LNKCTL);
status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_DC + PCI_EXP_DEVCTL);
status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_SC + PCI_EXP_DEVCAP);
status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LC2 + PCI_EXP_LNKCTL2);
status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LWC + PCI_EXP_LNKCTL);

If you agree that this approach correctly resolves the issue,
I would prefer to confirm now to prevent further iterative changes
that might confuse.

> Bjorn

Thanks
-Anand


From mripard at kernel.org  Thu Nov 20 07:54:25 2025
From: mripard at kernel.org (Maxime Ripard)
Date: Thu, 20 Nov 2025 16:54:25 +0100
Subject: [PATCH v4 07/10] drm/display: hdmi-state-helper: Act on color
 format DRM property
In-Reply-To: <7179523.lOV4Wx5bFT@workhorse>
References: <20251117-color-format-v4-0-0ded72bd1b00@collabora.com>
 <20251117-color-format-v4-7-0ded72bd1b00@collabora.com>
 <4wt5dbvseauo2bvi66ohtk445zsfjtpjwgvochwwlyk4uugcmy@5ubwtkxyy2ax>
 <7179523.lOV4Wx5bFT@workhorse>
Message-ID: <nbrdnftrsybpowsu2f6me3jumdeodg45x4quouzlzd5jo7xrux@4pny3aiverzn>

On Wed, Nov 19, 2025 at 01:41:18PM +0100, Nicolas Frattaroli wrote:
> On Wednesday, 19 November 2025 10:09:12 Central European Standard Time Maxime Ripard wrote:
> > Hi,
> > 
> > On Mon, Nov 17, 2025 at 08:11:51PM +0100, Nicolas Frattaroli wrote:
> > > With the introduction of the "color format" DRM property, which allows
> > > userspace to request a specific color format, the HDMI state helper
> > > should implement this.
> > > 
> > > Implement it by checking whether the property is set and set to
> > > something other than auto. If so, pass the requested color format, and
> > > otherwise set RGB.
> > > 
> > > Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
> > > ---
> > >  drivers/gpu/drm/display/drm_hdmi_state_helper.c | 8 +++++++-
> > >  1 file changed, 7 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> > > index a561f124be99..add0d51fce33 100644
> > > --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> > > +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
> > > @@ -650,9 +650,15 @@ hdmi_compute_config(const struct drm_connector *connector,
> > >  				       conn_state->max_bpc,
> > >  				       8, connector->max_bpc);
> > >  	int ret;
> > > +	enum hdmi_colorspace hdmi_colorspace;
> > > +
> > > +	if (conn_state->color_format && conn_state->color_format != DRM_COLOR_FORMAT_AUTO)
> > > +		hdmi_colorspace = color_format_to_hdmi_colorspace(conn_state->color_format);
> > > +	else
> > > +		hdmi_colorspace = HDMI_COLORSPACE_RGB;
> > >  
> > >  	ret = hdmi_compute_format_bpc(connector, conn_state, mode, max_bpc,
> > > -				      HDMI_COLORSPACE_RGB);
> > > +				      hdmi_colorspace);
> > 
> > I don't think we want the fallback to yuv420 for anything but auto, so
> 
> Okay. Changing all the non-hdmi-state-helper drivers (amdgpu, i915)
> to do this as well would require some more work however, especially
> in the case of amdgpu where the code flow is not always obvious.

Yeah, I think we want to be consistent here, the whole point of the HDMI
state helpers was to be consistently consistent with Intel's behaviour
anyway :)

> > I'd rather have something like
> > 
> > if (conn_state->color_format != DRM_COLOR_FORMAT_AUTO)
> >    return hdmi_compute_format_bpc(connector, conn_state, mode, max_bpc,
> >                                   color_format_to_hdmi_colorspace(conn_state->color_format))
> > 
> > We'll also need unit tests.
> 
> Sure, am I guessing correctly that they'd go in
> drm_hdmi_state_helper_test.c?

Yes

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 273 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251120/6825317f/attachment.sig>

From vkoul at kernel.org  Thu Nov 20 09:11:15 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Thu, 20 Nov 2025 22:41:15 +0530
Subject: (subset) [PATCH 0/9] drm/rockchip: Introduce Rockchip RK3506
 VOP
In-Reply-To: <20251106020632.92-1-kernel@airkyi.com>
References: <20251106020632.92-1-kernel@airkyi.com>
Message-ID: <176365867573.207696.11271190998956084830.b4-ty@kernel.org>


On Thu, 06 Nov 2025 10:06:23 +0800, Chaoyi Chen wrote:
> The VOP on rk3506:
> - Support 2 lane MIPI DSI interface, 1.5Gbps/lane.
> - Support RGB interface.
> - Max output resolution is 1280x1280 at 60fps.
> - WIN1 layer support RGB888/ARGB8888/RGB565.
> - Support Gamma LUT.
> 
> [...]

Applied, thanks!

[2/9] dt-bindings: phy: rockchip-inno-dsidphy: Add compatible for rk3506
      commit: 323c5c05a0a07b931ede1fa0a3396a1a165ed798
[6/9] phy: rockchip: inno-dsidphy: Add support for rk3506
      commit: 785a9d5bb145109558063080ebc9a3e8be86471d

Best regards,
-- 
~Vinod




From vkoul at kernel.org  Thu Nov 20 09:11:57 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Thu, 20 Nov 2025 22:41:57 +0530
Subject: [PATCH RESEND 0/3] Fixes for phy-rockchip-samsung-hdptx
In-Reply-To: <20251028-phy-hdptx-fixes-v1-0-ecc642a59d94@collabora.com>
References: <20251028-phy-hdptx-fixes-v1-0-ecc642a59d94@collabora.com>
Message-ID: <176365871731.207696.6981124772253997386.b4-ty@kernel.org>


On Tue, 28 Oct 2025 10:00:53 +0200, Cristian Ciocaltea wrote:
> These patches were initially part of the HDMI 2.1 FRL support series [1]
> aiming to provide a few fixes for the Samsung HDMI/eDP Transmitter Combo
> PHY.
> 
> I'm sending this as a distinct series right now, since the FRL part
> might require additional time for review.
> 
> [...]

Applied, thanks!

[1/3] phy: rockchip: samsung-hdptx: Fix reported clock rate in high bpc mode
      commit: 72126e9623e1696ea83c77ef6d0306a6263bdd6b
[2/3] phy: rockchip: samsung-hdptx: Reduce ROPLL loop bandwidth
      commit: 8daaced9f5eeb4a2c8ca08b0a8286b6a498a8387
[3/3] phy: rockchip: samsung-hdptx: Prevent Inter-Pair Skew from exceeding the limits
      commit: 51023cf6cc5db3423dea6620746d9087e336e024

Best regards,
-- 
~Vinod




From vkoul at kernel.org  Thu Nov 20 09:12:00 2025
From: vkoul at kernel.org (Vinod Koul)
Date: Thu, 20 Nov 2025 22:42:00 +0530
Subject: [PATCH v2 1/2] phy: rockchip: naneng-combphy: Fix PCIe L1ss
 support RK3528
In-Reply-To: <1763459526-35004-1-git-send-email-shawn.lin@rock-chips.com>
References: <1763459526-35004-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <176365872091.207696.17487424973195215305.b4-ty@kernel.org>


On Tue, 18 Nov 2025 17:52:05 +0800, Shawn Lin wrote:
> When PCIe link enters L1 PM substates, the PHY will turn off its
> PLL for power-saving. However, it turns off the PLL too fast which
> leads the PHY to be broken. According to the PHY document, we need
> to delay PLL turnoff time.
> 
> 

Applied, thanks!

[1/2] phy: rockchip: naneng-combphy: Fix PCIe L1ss support RK3528
      commit: a2a18e5da64f8da306fa97c397b4c739ea776f37
[2/2] phy: rockchip: naneng-combphy: Fix PCIe L1ss support RK3562
      commit: be866e68966d20bcc4a73708093d577176f99c0c

Best regards,
-- 
~Vinod




From michael.opdenacker at rootcommit.com  Thu Nov 20 11:00:34 2025
From: michael.opdenacker at rootcommit.com (Michael Opdenacker)
Date: Thu, 20 Nov 2025 19:00:34 +0000 (UTC)
Subject: [PATCH] arm64: dts: rockchip: Enable i2c2 on Orange Pi 3B
Message-ID: <20251120-orangepi3-enable-i2c2-v1-1-2e023a74012a@rootcommit.com>

Enable the "i2c2" bus on header pins 3 (I2C_SDA_M1)
and 5 (I2C2_SCL_M1) of the Orange Pi 3B board.

As documented on http://www.orangepi.org/img/pi3b/0719-pi3b-19.png,
such pins are the only ones offering I2C functionality
without conflicting with other SoC blocks.

Signed-off-by: Michael Opdenacker <michael.opdenacker at rootcommit.com>
---
 arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b.dtsi
index d539570f531e..e2f0ccc6dbe7 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b.dtsi
@@ -435,6 +435,11 @@ regulator-state-mem {
 	};
 };
 
+&i2c2 {
+	pinctrl-0 = <&i2c2m1_xfer>;
+	status = "okay";
+};
+
 &i2s0_8ch {
 	status = "okay";
 };

---
base-commit: 8e621c9a337555c914cf1664605edfaa6f839774
change-id: 20251120-orangepi3-enable-i2c2-fe6d25ec681a

Best regards,
-- 
Michael Opdenacker <michael.opdenacker at rootcommit.com>



From jgg at nvidia.com  Thu Nov 20 11:26:12 2025
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Thu, 20 Nov 2025 15:26:12 -0400
Subject: [PATCH 2/3] iommu/amd: Don't call report_iommu_fault()
In-Reply-To: <20251023142657.GH262900@nvidia.com>
References: <2-v1-391058a85f30+14b-iommu_set_fault_jgg@nvidia.com>
 <579bdc4e-ab71-4120-8991-34400d4bbf8d@arm.com>
 <20251023142657.GH262900@nvidia.com>
Message-ID: <20251120192612.GA258497@nvidia.com>

On Thu, Oct 23, 2025 at 11:26:57AM -0300, Jason Gunthorpe wrote:
> > >   	if (dev_data) {
> > > -		/*
> > > -		 * If this is a DMA fault (for which the I(nterrupt)
> > > -		 * bit will be unset), allow report_iommu_fault() to
> > > -		 * prevent logging it.
> > > -		 */
> > > -		if (IS_IOMMU_MEM_TRANSACTION(flags)) {
> > > -			/* Device not attached to domain properly */
> > > -			if (dev_data->domain == NULL) {
> > > -				pr_err_ratelimited("Event logged [Device not attached to domain properly]\n");
> > > -				pr_err_ratelimited("  device=%04x:%02x:%02x.%x domain=0x%04x\n",
> > > -						   iommu->pci_seg->id, PCI_BUS_NUM(devid), PCI_SLOT(devid),
> > > -						   PCI_FUNC(devid), domain_id);
> > > -				goto out;
> > > -			}
> > This part is unrelated to the report_iommu_fault() call - in fact it was
> > specifically added even more recently.
> 
> Yeah, I'll fix it

Coming back to this, it was right in the v1, it should be deleted.

The (dev_data->domain == NULL) test was added because calling
report_iommu_fault() will crash if the domain is NULL. This removed
that call it so we can't crash anymore.

Instead we fall through to this:

		if (__ratelimit(&dev_data->rs)) {
			pci_err(pdev, "Event logged [IO_PAGE_FAULT domain=0x%04x address=0x%llx flags=0x%04x]\n",
				domain_id, address, flags);
		}

Which prints the same information, the "domain is null" is not
especially useful. Further this only happens when dev_data is set it
so is very unlikely to be NULL anyhow, there is only a short period
after probe before the default domain is attached.

I will add some remarks to the commit message since I forgot why I did
it when you asked :\

Jason


From jgg at nvidia.com  Thu Nov 20 11:35:06 2025
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Thu, 20 Nov 2025 15:35:06 -0400
Subject: [PATCH v2 2/3] iommu/amd: Don't call report_iommu_fault()
In-Reply-To: <BN9PR11MB5276858062B57F944A7EBE778CD6A@BN9PR11MB5276.namprd11.prod.outlook.com>
References: <0-v2-25fc75484cab+ab-iommu_set_fault_jgg@nvidia.com>
 <2-v2-25fc75484cab+ab-iommu_set_fault_jgg@nvidia.com>
 <BN9PR11MB5276EFE7D236FF918A79263C8CC9A@BN9PR11MB5276.namprd11.prod.outlook.com>
 <20251118185831.GQ10864@nvidia.com>
 <BN9PR11MB5276858062B57F944A7EBE778CD6A@BN9PR11MB5276.namprd11.prod.outlook.com>
Message-ID: <20251120193506.GE153257@nvidia.com>

On Tue, Nov 18, 2025 at 11:58:39PM +0000, Tian, Kevin wrote:
> > > > -
> > > > -			if (!report_iommu_fault(&dev_data->domain-
> > > > >domain,
> > > > -						&pdev->dev, address,
> > > > -						IS_WRITE_REQUEST(flags) ?
> > > > -
> > > > 	IOMMU_FAULT_WRITE :
> > > > -
> > > > 	IOMMU_FAULT_READ))
> > > > -				goto out;
> > > >  		}
> > > >
> > > >  		if (__ratelimit(&dev_data->rs)) {
> > >
> > > Remove amd_iommu_report_page_fault() too?
> > 
> > I don't understand this remark?
> > 
> > amd_iommu_report_page_fault() generates the dmesg logging on iommu
> > faults?
> 
> sorry I meant generating the dmesg logging same as other error
> types in iommu_print_event(). No need for a separate function.

Okay, that does make sense, but this driver is kinda broken because it
is using 

	pdev = pci_get_domain_bus_and_slot(iommu->pci_seg->id, PCI_BUS_NUM(devid),
					   devid & 0xff);
	if (pdev)
		dev_data = dev_iommu_priv_get(&pdev->dev);

Which is UAF racy on dev_data.

Fixing that is troublesome..

Really all the fault handling here needs some attention, all the
events that have BDFs should all print the same, using a pci print or
using raw BDFs. Translation fault shouldn't be special..

Too big for this series, so I'll leave it..

Thanks,
Jason




From jgg at nvidia.com  Thu Nov 20 11:46:21 2025
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Thu, 20 Nov 2025 15:46:21 -0400
Subject: [PATCH v3 0/3] Cleanup around iommu_set_fault_handler()
Message-ID: <0-v3-e5d08e2d551e+109-iommu_set_fault_jgg@nvidia.com>

report_iommu_fault() is an older API that has been superseded by
iommu_report_device_fault() which is capable to support PRI.

Only four external drivers consume this via iommu_set_fault_handler()
  drivers/remoteproc/omap_remoteproc.c
  drivers/remoteproc/qcom_q6v5_adsp.c
  drivers/gpu/drm/msm
  drivers/infiniband/hw/usnic

Remove the use in usnic as the iommu driver logging is good enough these
days.

Remove generation support from the AMD iommu driver since msm and two
remoteproc drivers are not used on AMD x86 CPUs.

Fail iommu_set_fault_handler() if the underlying iommu driver does not
support it.

v3:
 - Go back to the v1 version of the AMD, removing the print was the right
   thing, explain in the commit message.
v2: https://patch.msgid.link/r/0-v2-25fc75484cab+ab-iommu_set_fault_jgg at nvidia.com
 - Revise commit messages
 - Move report_iommu_fault_supported into the struct iommu_ops
 - Put back the pr_err in the AMD driver
v1: https://patch.msgid.link/r/0-v1-391058a85f30+14b-iommu_set_fault_jgg at nvidia.com

Jason Gunthorpe (3):
  RDMA/usnic: Remove iommu_set_fault_handler()
  iommu/amd: Don't call report_iommu_fault()
  iommu: Allow drivers to say if they use report_iommu_fault()

 drivers/infiniband/hw/usnic/usnic_uiom.c | 13 -------------
 drivers/iommu/amd/iommu.c                | 24 ------------------------
 drivers/iommu/arm/arm-smmu/arm-smmu.c    |  1 +
 drivers/iommu/arm/arm-smmu/qcom_iommu.c  |  1 +
 drivers/iommu/iommu.c                    |  6 +++++-
 drivers/iommu/ipmmu-vmsa.c               |  1 +
 drivers/iommu/mtk_iommu.c                |  1 +
 drivers/iommu/mtk_iommu_v1.c             |  1 +
 drivers/iommu/omap-iommu.c               |  1 +
 drivers/iommu/rockchip-iommu.c           |  1 +
 drivers/iommu/sun50i-iommu.c             |  1 +
 include/linux/iommu.h                    |  3 +++
 12 files changed, 16 insertions(+), 38 deletions(-)


base-commit: 211ddde0823f1442e4ad052a2f30f050145ccada
-- 
2.43.0



From jgg at nvidia.com  Thu Nov 20 11:46:23 2025
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Thu, 20 Nov 2025 15:46:23 -0400
Subject: [PATCH v3 2/3] iommu/amd: Don't call report_iommu_fault()
In-Reply-To: <0-v3-e5d08e2d551e+109-iommu_set_fault_jgg@nvidia.com>
Message-ID: <2-v3-e5d08e2d551e+109-iommu_set_fault_jgg@nvidia.com>

This old style API is only used by drivers/gpu/drm/msm,
drivers/remoteproc/omap_remoteproc.c, and
drivers/remoteproc/qcom_q6v5_adsp.c none are used on x86 HW.

Remove the dead code to discourage new users.

Also remove the domain == NULL print because it was intended to protect
against a NULL deref inside report_iommu_fault() which is no longer
possible.

Just always print the fault in the same format if it could get a dev_data.
There is no value to be gained by also printing if the domain is NULL. In
today's kernel when the dev_data is populated the domain will be made
!NULL very quickly during iommu device probing.

Reviewed-by: Vasant Hegde <vasant.hegde at amd.com>
Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 drivers/iommu/amd/iommu.c | 24 ------------------------
 1 file changed, 24 deletions(-)

diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 2e1865daa1cee8..072c80bb2c2b3a 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -840,29 +840,6 @@ static void amd_iommu_report_page_fault(struct amd_iommu *iommu,
 		dev_data = dev_iommu_priv_get(&pdev->dev);
 
 	if (dev_data) {
-		/*
-		 * If this is a DMA fault (for which the I(nterrupt)
-		 * bit will be unset), allow report_iommu_fault() to
-		 * prevent logging it.
-		 */
-		if (IS_IOMMU_MEM_TRANSACTION(flags)) {
-			/* Device not attached to domain properly */
-			if (dev_data->domain == NULL) {
-				pr_err_ratelimited("Event logged [Device not attached to domain properly]\n");
-				pr_err_ratelimited("  device=%04x:%02x:%02x.%x domain=0x%04x\n",
-						   iommu->pci_seg->id, PCI_BUS_NUM(devid), PCI_SLOT(devid),
-						   PCI_FUNC(devid), domain_id);
-				goto out;
-			}
-
-			if (!report_iommu_fault(&dev_data->domain->domain,
-						&pdev->dev, address,
-						IS_WRITE_REQUEST(flags) ?
-							IOMMU_FAULT_WRITE :
-							IOMMU_FAULT_READ))
-				goto out;
-		}
-
 		if (__ratelimit(&dev_data->rs)) {
 			pci_err(pdev, "Event logged [IO_PAGE_FAULT domain=0x%04x address=0x%llx flags=0x%04x]\n",
 				domain_id, address, flags);
@@ -873,7 +850,6 @@ static void amd_iommu_report_page_fault(struct amd_iommu *iommu,
 			domain_id, address, flags);
 	}
 
-out:
 	if (pdev)
 		pci_dev_put(pdev);
 }
-- 
2.43.0



From jgg at nvidia.com  Thu Nov 20 11:46:22 2025
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Thu, 20 Nov 2025 15:46:22 -0400
Subject: [PATCH v3 1/3] RDMA/usnic: Remove iommu_set_fault_handler()
In-Reply-To: <0-v3-e5d08e2d551e+109-iommu_set_fault_jgg@nvidia.com>
Message-ID: <1-v3-e5d08e2d551e+109-iommu_set_fault_jgg@nvidia.com>

The handler in usnic just prints a fault report message, the iommu drivers
all do a better job of that these days. Just remove the use of this old
API.

Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
Reviewed-by: Kevin Tian <kevin.tian at intel.com>
Acked-by: Jason Gunthorpe <jgg at nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 drivers/infiniband/hw/usnic/usnic_uiom.c | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/drivers/infiniband/hw/usnic/usnic_uiom.c b/drivers/infiniband/hw/usnic/usnic_uiom.c
index 3fbf99757b1148..f7fb6246c83aba 100644
--- a/drivers/infiniband/hw/usnic/usnic_uiom.c
+++ b/drivers/infiniband/hw/usnic/usnic_uiom.c
@@ -51,17 +51,6 @@
 	((void *) &((struct usnic_uiom_chunk *) 0)->page_list[1] -	\
 	(void *) &((struct usnic_uiom_chunk *) 0)->page_list[0]))
 
-static int usnic_uiom_dma_fault(struct iommu_domain *domain,
-				struct device *dev,
-				unsigned long iova, int flags,
-				void *token)
-{
-	usnic_err("Device %s iommu fault domain 0x%p va 0x%lx flags 0x%x\n",
-		dev_name(dev),
-		domain, iova, flags);
-	return -ENOSYS;
-}
-
 static void usnic_uiom_put_pages(struct list_head *chunk_list, int dirty)
 {
 	struct usnic_uiom_chunk *chunk, *tmp;
@@ -450,8 +439,6 @@ struct usnic_uiom_pd *usnic_uiom_alloc_pd(struct device *dev)
 		return ERR_CAST(domain);
 	}
 
-	iommu_set_fault_handler(pd->domain, usnic_uiom_dma_fault, NULL);
-
 	spin_lock_init(&pd->lock);
 	INIT_LIST_HEAD(&pd->devs);
 
-- 
2.43.0



From jgg at nvidia.com  Thu Nov 20 11:46:24 2025
From: jgg at nvidia.com (Jason Gunthorpe)
Date: Thu, 20 Nov 2025 15:46:24 -0400
Subject: [PATCH v3 3/3] iommu: Allow drivers to say if they use report_iommu_fault()
In-Reply-To: <0-v3-e5d08e2d551e+109-iommu_set_fault_jgg@nvidia.com>
Message-ID: <3-v3-e5d08e2d551e+109-iommu_set_fault_jgg@nvidia.com>

report_iommu_fault() is an older API that has been superseded by
iommu_report_device_fault() which is capable to support PRI.

Only two external drivers consume this, drivers/remoteproc and
drivers/gpu/drm/msm. Ideally they would move over to the new APIs, but for
now protect against accidentally mix and matching the wrong components.

The iommu drivers support either the old iommu_set_fault_handler() via the
driver calling report_iommu_fault(), or they are newer server focused
drivers that call iommu_report_device_fault().

Include a flag in the iommu_ops if the driver calls report_iommu_fault()
and block iommu_set_fault_handler() for domain's of iommu drivers that
can't support it.

Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
Reviewed-by: Kevin Tian <kevin.tian at intel.com>
Reviewed-by: Vasant Hegde <vasant.hegde at amd.com>
Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
---
 drivers/iommu/arm/arm-smmu/arm-smmu.c   | 1 +
 drivers/iommu/arm/arm-smmu/qcom_iommu.c | 1 +
 drivers/iommu/iommu.c                   | 6 +++++-
 drivers/iommu/ipmmu-vmsa.c              | 1 +
 drivers/iommu/mtk_iommu.c               | 1 +
 drivers/iommu/mtk_iommu_v1.c            | 1 +
 drivers/iommu/omap-iommu.c              | 1 +
 drivers/iommu/rockchip-iommu.c          | 1 +
 drivers/iommu/sun50i-iommu.c            | 1 +
 include/linux/iommu.h                   | 3 +++
 10 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 4ced4b5bee4df3..f68a0576b9a3a6 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1643,6 +1643,7 @@ static const struct iommu_ops arm_smmu_ops = {
 	.get_resv_regions	= arm_smmu_get_resv_regions,
 	.def_domain_type	= arm_smmu_def_domain_type,
 	.owner			= THIS_MODULE,
+	.report_iommu_fault_supported = true,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
 		.attach_dev		= arm_smmu_attach_dev,
 		.map_pages		= arm_smmu_map_pages,
diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index c5be95e560317e..173d5957796790 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -597,6 +597,7 @@ static const struct iommu_ops qcom_iommu_ops = {
 	.probe_device	= qcom_iommu_probe_device,
 	.device_group	= generic_device_group,
 	.of_xlate	= qcom_iommu_of_xlate,
+	.report_iommu_fault_supported = true,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
 		.attach_dev	= qcom_iommu_attach_dev,
 		.map_pages	= qcom_iommu_map,
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 59244c744eabd2..8d9086a37671e1 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2005,6 +2005,9 @@ EXPORT_SYMBOL_GPL(iommu_group_has_isolated_msi);
  * This function should be used by IOMMU users which want to be notified
  * whenever an IOMMU fault happens.
  *
+ * This is a legacy API not supported by all drivers. New users should look
+ * to using domain->iopf_handler for the modern API.
+ *
  * The fault handler itself should return 0 on success, and an appropriate
  * error code otherwise.
  */
@@ -2012,7 +2015,8 @@ void iommu_set_fault_handler(struct iommu_domain *domain,
 					iommu_fault_handler_t handler,
 					void *token)
 {
-	if (WARN_ON(!domain || domain->cookie_type != IOMMU_COOKIE_NONE))
+	if (WARN_ON(!domain || domain->cookie_type != IOMMU_COOKIE_NONE ||
+		    !domain->owner->report_iommu_fault_supported))
 		return;
 
 	domain->cookie_type = IOMMU_COOKIE_FAULT_HANDLER;
diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
index ffa892f6571406..04a5836bf36000 100644
--- a/drivers/iommu/ipmmu-vmsa.c
+++ b/drivers/iommu/ipmmu-vmsa.c
@@ -884,6 +884,7 @@ static const struct iommu_ops ipmmu_ops = {
 	.device_group = IS_ENABLED(CONFIG_ARM) && !IS_ENABLED(CONFIG_IOMMU_DMA)
 			? generic_device_group : generic_single_device_group,
 	.of_xlate = ipmmu_of_xlate,
+	.report_iommu_fault_supported = true,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
 		.attach_dev	= ipmmu_attach_device,
 		.map_pages	= ipmmu_map,
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 0e0285348d2b8e..ccf6fdeb64a261 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -1018,6 +1018,7 @@ static const struct iommu_ops mtk_iommu_ops = {
 	.of_xlate	= mtk_iommu_of_xlate,
 	.get_resv_regions = mtk_iommu_get_resv_regions,
 	.owner		= THIS_MODULE,
+	.report_iommu_fault_supported = true,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
 		.attach_dev	= mtk_iommu_attach_device,
 		.map_pages	= mtk_iommu_map,
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index 10cc0b1197e801..3dd6222d210921 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -581,6 +581,7 @@ static const struct iommu_ops mtk_iommu_v1_ops = {
 	.release_device	= mtk_iommu_v1_release_device,
 	.device_group	= generic_device_group,
 	.owner          = THIS_MODULE,
+	.report_iommu_fault_supported = true,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
 		.attach_dev	= mtk_iommu_v1_attach_device,
 		.map_pages	= mtk_iommu_v1_map,
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index 5c6f5943f44b1f..7ba67600f32915 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -1723,6 +1723,7 @@ static const struct iommu_ops omap_iommu_ops = {
 	.release_device	= omap_iommu_release_device,
 	.device_group	= generic_single_device_group,
 	.of_xlate	= omap_iommu_of_xlate,
+	.report_iommu_fault_supported = true,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
 		.attach_dev	= omap_iommu_attach_dev,
 		.map_pages	= omap_iommu_map,
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 0861dd469bd866..932b5a62bac572 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -1173,6 +1173,7 @@ static const struct iommu_ops rk_iommu_ops = {
 	.release_device = rk_iommu_release_device,
 	.device_group = generic_single_device_group,
 	.of_xlate = rk_iommu_of_xlate,
+	.report_iommu_fault_supported = true,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
 		.attach_dev	= rk_iommu_attach_device,
 		.map_pages	= rk_iommu_map,
diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c
index de10b569d9a940..13c37b1be481d7 100644
--- a/drivers/iommu/sun50i-iommu.c
+++ b/drivers/iommu/sun50i-iommu.c
@@ -848,6 +848,7 @@ static const struct iommu_ops sun50i_iommu_ops = {
 	.domain_alloc_paging = sun50i_iommu_domain_alloc_paging,
 	.of_xlate	= sun50i_iommu_of_xlate,
 	.probe_device	= sun50i_iommu_probe_device,
+	.report_iommu_fault_supported = true,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
 		.attach_dev	= sun50i_iommu_attach_device,
 		.flush_iotlb_all = sun50i_iommu_flush_iotlb_all,
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index c30d12e16473df..941e4971b05fd3 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -659,6 +659,8 @@ __iommu_copy_struct_to_user(const struct iommu_user_data *dst_data,
  *                    no user domain for each PASID and the I/O page faults are
  *                    forwarded through the user domain attached to the device
  *                    RID.
+ * @report_iommu_fault_supported: True if the domain supports
+ *                                iommu_set_fault_handler()
  */
 struct iommu_ops {
 	bool (*capable)(struct device *dev, enum iommu_cap);
@@ -710,6 +712,7 @@ struct iommu_ops {
 	struct iommu_domain *release_domain;
 	struct iommu_domain *default_domain;
 	u8 user_pasid_table:1;
+	u8 report_iommu_fault_supported:1;
 };
 
 /**
-- 
2.43.0



From heiko at sntech.de  Thu Nov 20 14:23:01 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Thu, 20 Nov 2025 23:23:01 +0100
Subject: [PATCH V2 0/4] Indiedroid Nova Devicetree Updates
In-Reply-To: <20251118223048.4531-1-macroalpha82@gmail.com>
References: <20251118223048.4531-1-macroalpha82@gmail.com>
Message-ID: <176367711166.9778.8294237491641265903.b4-ty@sntech.de>


On Tue, 18 Nov 2025 16:30:44 -0600, Chris Morgan wrote:
> This series fixes up a few remaining issues with the devicetree for the
> Indiedroid Nova. Namely it adds or updates a few pinctrl definitions,
> it removes a few workarounds that no longer appear to be necessary for
> eMMC and bluetooth, it adds support for the NPU, and it sets the device
> type as embedded.
> 
> Changes since V1:
>  - The device type addition, NPU enablement, HS400 enablement, and DMA
>    fixes for bluetooth were accepted as a subset and have been removed
>    from this series.
>  - The individual changes from the pinctrl fixes have been broken out
>    into a series of separate patches.
> 
> [...]

Applied, thanks!

[1/4] arm64: dts: rockchip: Add clk32k_in for Indiedroid Nova
      commit: e28f44013dc4ec820bdb7182d5a2188550bc07fd
[2/4] arm64: dts: rockchip: Define regulator for pcie2x1l2
      commit: 835c909e8576919437227f6ac1d4e4769016137f
[3/4] arm64: dts: rockchip: Correct pinctrl for pcie for Indiedroid Nova
      commit: 6f563ebf0b21e661f6a663ea55ae00544192a213
[4/4] arm64: dts: rockchip: Add host wake pin for wifi on Indiedroid Nova
      commit: 932feac9d8c591a6c5d3824765f71e2cd87f33e8

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Thu Nov 20 14:22:58 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Thu, 20 Nov 2025 23:22:58 +0100
Subject: [PATCH] arm64: dts: rockchip: fix PCIe 3.3V regulator voltage on 9Tripod X3568 v4
In-Reply-To: <20251114092114.62664-2-coiaprant@gmail.com>
References: <20251114092114.62664-2-coiaprant@gmail.com>
Message-ID: <176367711173.9778.13722457091909539079.b4-ty@sntech.de>


On Fri, 14 Nov 2025 17:21:15 +0800, Coia Prant wrote:
> The regulator type is "regulator-fixed" since its voltage always be
> 3.3v, min and max should be 3300000 make the regulator has a voltage
> 
> The regulator is supplied by dc_12v, so add the vin-supply.
> 
> 

Applied, thanks!

[1/1] arm64: dts: rockchip: fix PCIe 3.3V regulator voltage on 9Tripod X3568 v4
      commit: c8ecda015eb4070ced887eba34cdb60737a9893b

Changes "gpio" to the correct "gpios" property.
"gpio" only works because the kernel handles this common mistake :-) .

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Thu Nov 20 14:23:03 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Thu, 20 Nov 2025 23:23:03 +0100
Subject: [PATCH v3 0/2] arm64: dts: rockchip: add Tinker Board 3 and 3S device tree
In-Reply-To: <20251118-tinker3-v3-0-2903693f2ebb@rootcommit.com>
References: <20251118-tinker3-v3-0-2903693f2ebb@rootcommit.com>
Message-ID: <176367711163.9778.16671960189532919719.b4-ty@sntech.de>


On Tue, 18 Nov 2025 15:56:41 +0000, Michael Opdenacker wrote:
> Add initial device tree support for Asus Tinker Board 3 [1] and 3S [2],
> which are SBCs based on the Rockchip 3566 SoC.
> 
> The "3S" version ("S" for "storage") is just a regular Tinker Board 3
> fitted with a 16 GB eMMC and a "mask ROM" DIP switch
> (to mask the eMMC and enter "Mask ROM" mode for recovery).
> 
> [...]

Applied, thanks!

[1/2] dt-bindings: arm: rockchip: Add Asus Tinker Board 3/3S
      commit: f4e81d0b95f3257a2fcfdbfaa2d8ed41015c621b
[2/2] arm64: dts: rockchip: Add Asus Tinker Board 3 and 3S device tree
      commit: 9f80b3952318d7ef18573a5010f06118602f992e

Changed the property sorting of the RTC and also migrated all the
pinctrl names to match the schematics.

When creating pinctrl entries, please always _try_ to use the names
found in the device schematics. This makes it way easier in the future
to find one from the other :-)


Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Thu Nov 20 14:23:05 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Thu, 20 Nov 2025 23:23:05 +0100
Subject: (subset) [PATCH v7 0/5] clk: rockchip: Add clock controller for the
In-Reply-To: <20251111025738.869847-1-zhangqing@rock-chips.com>
References: <20251111025738.869847-1-zhangqing@rock-chips.com>
Message-ID: <176367711155.9778.8068115837215397006.b4-ty@sntech.de>


On Tue, 11 Nov 2025 10:57:33 +0800, Elaine Zhang wrote:
> Add yaml and dt-bindings for the RV1126B and RK3506.
> RK3506 depend on patches 1/5, so it is merged and submitted.
> 
> Change in V7:
> [PATCH v7 1/5]: No change
> [PATCH v7 2/5]: Redefine clk id(start at 0), drop RESETN for reset id.
> [PATCH v7 3/5]: Drop RESETN for reset id.
> [PATCH v7 4/5]: Fix "description: |", drop RESETN for reset id.
> [PATCH v7 5/5]: Drop RESETN for reset id.
> 
> [...]

Applied, thanks!

[1/5] clk: rockchip: Implement rockchip_clk_register_armclk_multi_pll()
      commit: 826eaa8f5bac6e919cf7c0b4161b2d783fdc45b3
[2/5] dt-bindings: clock, reset: Add support for rv1126b
      commit: d0d9a9629f505ac70e1ffd172e092ff71f5d989a
[3/5] clk: rockchip: Add clock controller for the RV1126B
      commit: 652c108cc44cd961b58b2998ff429f11ee60c9fd

Please address the review comments received from the DT maintainers for
the RK3506 binding - adding the xin24m supply clock, that is also
present on that RK3506, as with all previous socs :-)


Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Thu Nov 20 14:23:02 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Thu, 20 Nov 2025 23:23:02 +0100
Subject: [PATCH] dt-bindings: arm: rockchip: merge Asus Tinker and Tinker S
In-Reply-To: <20251119-merge-tinker-bindings-v1-1-4072b55750c1@rootcommit.com>
References: <20251119-merge-tinker-bindings-v1-1-4072b55750c1@rootcommit.com>
Message-ID: <176367711159.9778.13398191776805888348.b4-ty@sntech.de>


On Wed, 19 Nov 2025 09:22:38 +0000, Michael Opdenacker wrote:
> Merge sections for Asus Tinker Board and Asus Tinker Board S.
> 
> Asus Tinker Board S (Storage) is just a variant of Tinker Board
> with an added eMMC chip.
> 
> 

Applied, thanks!

[1/1] dt-bindings: arm: rockchip: merge Asus Tinker and Tinker S
      commit: 605945281a65ca68af00f3d7592a191b20b21ad4

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Thu Nov 20 14:22:59 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Thu, 20 Nov 2025 23:22:59 +0100
Subject: [PATCH v2 0/5] Some cleanups and addition of another Qnap TSx33 device
In-Reply-To: <20251112214206.423244-1-heiko@sntech.de>
References: <20251112214206.423244-1-heiko@sntech.de>
Message-ID: <176367711145.9778.8075871539964271822.b4-ty@sntech.de>


On Wed, 12 Nov 2025 22:42:01 +0100, Heiko Stuebner wrote:
> This fixes the 2nd network adapter on the TS433 and adds the TS233
> a 2-bay device being otherwise similar to the TS433.
> 
> changes in v2:
> - add Conor's Ack on the TS233 binding
> - drop TS433 ethernet-delay patch, as that was unneeded and resulted
>   from me doing wonky stuff during testing and are completely useless
> - drop tx/rx-delays from new TS233 dts as well
> 
> [...]

Applied, thanks!

[1/5] arm64: dts: rockchip: move cpu_thermal node to the correct position
      commit: 15efa2414602ad4c411ea8d4113b87656ebe0737
[2/5] arm64: dts: rockchip: describe mcu eeprom cells on rk3568-ts433
      commit: 81f116991433d2547d7f350873cb4511ebcd4fec
[3/5] arm64: dts: rockchip: move common qnap tsx33 parts to dtsi
      commit: 35202606ea08b9ec2b1386ac937a729e25d5beb0
[4/5] dt-bindings: arm: rockchip: add TS233 to RK3568-based QNAP NAS devices
      commit: a576b51e13870ba957e13e6cc265431260a32a77
[5/5] arm64: dts: rockchip: add QNAP TS233 devicetree
      commit: ce0b84e766ad7b2ec5d2ac7840675f223640f3e3

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Thu Nov 20 14:23:00 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Thu, 20 Nov 2025 23:23:00 +0100
Subject: (subset) [PATCH v2 0/9] General RK3368 HDMI support and 2 outputs for RK3368-Lion
In-Reply-To: <20251021074254.87065-1-heiko@sntech.de>
References: <20251021074254.87065-1-heiko@sntech.de>
Message-ID: <176367711171.9778.9000322898026906278.b4-ty@sntech.de>


On Tue, 21 Oct 2025 09:42:45 +0200, Heiko Stuebner wrote:
> This series adds the necessary bits for HDMI output on RK3368 and enables
> this on RK3368-Lion. At the same time, use the recently added DSI support
> to enable the generic Video-Demo-adapter as an overlay on Lion as well.
> 
> 
> The reason I'm shaving this Yak is that the recently added DSI support
> created DTC warnings about a single endpoint with an address.
> 
> [...]

Applied, thanks!

[4/9] arm64: dts: rockchip: Add power-domain to RK3368 DSI controller
      commit: 8319be65e860a2881e5213ed95e03992037bf5c1
[5/9] arm64: dts: rockchip: Add power-domain to RK3368 VOP controller
      commit: f54b09d46f72e4548e14476ba771231b0ec2b0af

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Thu Nov 20 14:23:04 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Thu, 20 Nov 2025 23:23:04 +0100
Subject: (subset) [PATCH v3 0/3] Consolidate and clarify LED device tree descriptions on Radxa boards
In-Reply-To: <20251113124222.4691-1-naoki@radxa.com>
References: <20251113124222.4691-1-naoki@radxa.com>
Message-ID: <176367711181.9778.6379873847365673369.b4-ty@sntech.de>


On Thu, 13 Nov 2025 12:42:19 +0000, FUKAUMI Naoki wrote:
> Currently, on Radxa boards, the power LED is turned on immediately
> after power-up, independent of software control. The heartbeat LED and
> other available LEDs are subsequently turned on by the initial
> software, such as U-Boot, to indicate software is running.
> 
> However, the device tree description for this behavior is inconsistent
> and fragmented, with definitions split between the main Linux DTS
> files and separate U-Boot files (u-boot/arch/arm/dts/*-u-boot.dtsi).
> 
> [...]

Applied, thanks!

[1/3] arm64: dts: rockchip: Use default-state for power LED for Radxa boards
      commit: 6ed597fdbcfa5ffc1a01c8740320c5a20093b863

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From patchwork-bot+netdevbpf at kernel.org  Thu Nov 20 18:00:15 2025
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Fri, 21 Nov 2025 02:00:15 +0000
Subject: [PATCH net-next 0/3] net: stmmac: pass struct device to init/exit
In-Reply-To: <aR2V0Kib7j0L4FNN@shell.armlinux.org.uk>
References: <aR2V0Kib7j0L4FNN@shell.armlinux.org.uk>
Message-ID: <176369041551.1856901.1355582687378802410.git-patchwork-notify@kernel.org>

Hello:

This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba at kernel.org>:

On Wed, 19 Nov 2025 10:02:56 +0000 you wrote:
> Rather than passing the platform device to the ->init() and ->exit()
> methods, make these methods useful for other devices by passing the
> struct device instead. Update the implementations appropriately for
> this change.
> 
> Move the calls for these methods into the core driver's probe and
> remove methods from the stmmac_platform layer.
> 
> [...]

Here is the summary with links:
  - [net-next,1/3] net: stmmac: pass struct device to init()/exit() methods
    https://git.kernel.org/netdev/net-next/c/85081acc6b11
  - [net-next,2/3] net: stmmac: move probe/remove calling of init/exit
    https://git.kernel.org/netdev/net-next/c/32da89a840e8
  - [net-next,3/3] net: stmmac: rk: convert to init()/exit() methods
    https://git.kernel.org/netdev/net-next/c/1a62894e040d

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From patchwork-bot+netdevbpf at kernel.org  Thu Nov 20 18:00:18 2025
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Fri, 21 Nov 2025 02:00:18 +0000
Subject: [PATCH net-next] net: stmmac: rk: use phylink's interface mode
 for
 set_clk_tx_rate()
In-Reply-To: <E1vLgNA-0000000FMjN-0DSS@rmk-PC.armlinux.org.uk>
References: <E1vLgNA-0000000FMjN-0DSS@rmk-PC.armlinux.org.uk>
Message-ID: <176369041825.1856901.6474170870442345383.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba at kernel.org>:

On Wed, 19 Nov 2025 11:29:16 +0000 you wrote:
> rk_set_clk_tx_rate() is passed the interface mode from phylink which
> will be the same as bsp_priv->phy_iface. Use the passed-in interface
> mode rather than bsp_priv->phy_iface.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> ---
>  drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)

Here is the summary with links:
  - [net-next] net: stmmac: rk: use phylink's interface mode for set_clk_tx_rate()
    https://git.kernel.org/netdev/net-next/c/f15bcd071913

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From zhangqing at rock-chips.com  Thu Nov 20 18:46:43 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Fri, 21 Nov 2025 10:46:43 +0800
Subject: [PATCH v8 0/2] clk: rockchip: Add clock controller for the RK3506
Message-ID: <20251121024645.360615-1-zhangqing@rock-chips.com>

[PATCH 1/5] ~ [PATCH 3/5] has applied.

Change in V8:
[PATCH v8 1/2]: Add explanations for "clocks"
[PATCH v8 2/2]: No change

Change in V7:
[PATCH v7 1/5]: No change
[PATCH v7 2/5]: Redefine clk id(start at 0), drop RESETN for reset id.
[PATCH v7 3/5]: Drop RESETN for reset id.
[PATCH v7 4/5]: Fix "description: |", drop RESETN for reset id.
[PATCH v7 5/5]: Drop RESETN for reset id.

Change in V6:
Drop pvtpll, others no change.
There are many questions about pvtpll and have some dependency issues.
They will be submitted separately later.

Change in V5:
[PATCH v5 1/7]: No change
[PATCH v5 2/7]: No change
[PATCH v5 3/7]: Drop RV1126B_GRF_SOC_STATUS0
[PATCH v5 4/7]: Drop syscon
[PATCH v5 5/7]: No change
[PATCH v5 6/7]: Add clocks and clock-names, fix id define
[PATCH v5 7/7]: Drop RK3506_GRF_SOC_STATUS

Change in V4:
[PATCH v4 1/7]: No change
[PATCH v4 2/7]: remove label
[PATCH v4 3/7]: No change
[PATCH v4 4/7]: remove label,fix order
[PATCH v4 5/7]: No change
[PATCH v4 6/7]: Add yaml and dt-bindings for the RK3506
[PATCH v4 7/7]: Add clock controller for the RK3506

Change in V3:
[PATCH v3 1/5]: No change
[PATCH v3 2/5]: Fix define error
[PATCH v3 3/5]: update driver,fix errir
[PATCH v3 4/5]: fix error
[PATCH v3 5/5]: No change

Change in V2:
[PATCH v2 1/5]: update commit message, rename v2 to multi_pll
[PATCH v2 2/5]: Modify DT binding headers license
[PATCH v2 3/5]: update driver
[PATCH v2 4/5]: fix error
[PATCH v2 5/5]: update commit message

Elaine Zhang (1):
  clk: rockchip: Add clock and reset driver for RK3506

Finley Xiao (1):
  dt-bindings: clock: rockchip: Add RK3506 clock and reset unit

 .../bindings/clock/rockchip,rk3506-cru.yaml   |  54 ++
 drivers/clk/rockchip/Kconfig                  |   7 +
 drivers/clk/rockchip/Makefile                 |   1 +
 drivers/clk/rockchip/clk-rk3506.c             | 869 ++++++++++++++++++
 drivers/clk/rockchip/clk.h                    |  13 +
 drivers/clk/rockchip/rst-rk3506.c             | 226 +++++
 .../dt-bindings/clock/rockchip,rk3506-cru.h   | 285 ++++++
 .../dt-bindings/reset/rockchip,rk3506-cru.h   | 211 +++++
 8 files changed, 1666 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
 create mode 100644 drivers/clk/rockchip/clk-rk3506.c
 create mode 100644 drivers/clk/rockchip/rst-rk3506.c
 create mode 100644 include/dt-bindings/clock/rockchip,rk3506-cru.h
 create mode 100644 include/dt-bindings/reset/rockchip,rk3506-cru.h


base-commit: 4f0744c46de2c40e7a8f35d730e322bf33f2bb63
-- 
2.34.1



From zhangqing at rock-chips.com  Thu Nov 20 18:46:44 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Fri, 21 Nov 2025 10:46:44 +0800
Subject: [PATCH v8 1/2] dt-bindings: clock: rockchip: Add RK3506 clock and reset unit
In-Reply-To: <20251121024645.360615-1-zhangqing@rock-chips.com>
References: <20251121024645.360615-1-zhangqing@rock-chips.com>
Message-ID: <20251121024645.360615-2-zhangqing@rock-chips.com>

From: Finley Xiao <finley.xiao at rock-chips.com>

Add device tree bindings for clock and reset unit on RK3506 SoC.
Add clock and reset IDs for RK3506 SoC.

Signed-off-by: Finley Xiao <finley.xiao at rock-chips.com>
Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
---
 .../bindings/clock/rockchip,rk3506-cru.yaml   |  54 ++++
 .../dt-bindings/clock/rockchip,rk3506-cru.h   | 285 ++++++++++++++++++
 .../dt-bindings/reset/rockchip,rk3506-cru.h   | 211 +++++++++++++
 3 files changed, 550 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
 create mode 100644 include/dt-bindings/clock/rockchip,rk3506-cru.h
 create mode 100644 include/dt-bindings/reset/rockchip,rk3506-cru.h

diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml b/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
new file mode 100644
index 000000000000..fee49700113e
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/rockchip,rk3506-cru.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip RK3506 Clock and Reset Unit (CRU)
+
+maintainers:
+  - Finley Xiao <finley.xiao at rock-chips.com>
+  - Heiko Stuebner <heiko at sntech.de>
+
+description:
+  The RK3506 CRU generates the clock and also implements reset for SoC
+  peripherals.
+
+properties:
+  compatible:
+    const: rockchip,rk3506-cru
+
+  reg:
+    maxItems: 1
+
+  "#clock-cells":
+    const: 1
+
+  "#reset-cells":
+    const: 1
+
+  clocks:
+    maxItems: 1
+    description:
+      Reference clock input. This is optional when the clock source
+      has already been configured and enabled by the bootloader/firmware.
+
+  clock-names:
+    const: xin24m
+
+required:
+  - compatible
+  - reg
+  - "#clock-cells"
+  - "#reset-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller at ff9a0000 {
+      compatible = "rockchip,rk3506-cru";
+      reg = <0xff9a0000 0x20000>;
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+    };
diff --git a/include/dt-bindings/clock/rockchip,rk3506-cru.h b/include/dt-bindings/clock/rockchip,rk3506-cru.h
new file mode 100644
index 000000000000..71d7dda23cc9
--- /dev/null
+++ b/include/dt-bindings/clock/rockchip,rk3506-cru.h
@@ -0,0 +1,285 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2023-2025 Rockchip Electronics Co., Ltd.
+ * Author: Finley Xiao <finley.xiao at rock-chips.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3506_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_RK3506_H
+
+/* cru plls */
+#define PLL_GPLL			0
+#define PLL_V0PLL			1
+#define PLL_V1PLL			2
+
+/* cru-clocks indices */
+#define ARMCLK				3
+#define CLK_DDR				4
+#define XIN24M_GATE			5
+#define CLK_GPLL_GATE			6
+#define CLK_V0PLL_GATE			7
+#define CLK_V1PLL_GATE			8
+#define CLK_GPLL_DIV			9
+#define CLK_GPLL_DIV_100M		10
+#define CLK_V0PLL_DIV			11
+#define CLK_V1PLL_DIV			12
+#define CLK_INT_VOICE_MATRIX0		13
+#define CLK_INT_VOICE_MATRIX1		14
+#define CLK_INT_VOICE_MATRIX2		15
+#define CLK_FRAC_UART_MATRIX0_MUX	16
+#define CLK_FRAC_UART_MATRIX1_MUX	17
+#define CLK_FRAC_VOICE_MATRIX0_MUX	18
+#define CLK_FRAC_VOICE_MATRIX1_MUX	19
+#define CLK_FRAC_COMMON_MATRIX0_MUX	20
+#define CLK_FRAC_COMMON_MATRIX1_MUX	21
+#define CLK_FRAC_COMMON_MATRIX2_MUX	22
+#define CLK_FRAC_UART_MATRIX0		23
+#define CLK_FRAC_UART_MATRIX1		24
+#define CLK_FRAC_VOICE_MATRIX0		25
+#define CLK_FRAC_VOICE_MATRIX1		26
+#define CLK_FRAC_COMMON_MATRIX0		27
+#define CLK_FRAC_COMMON_MATRIX1		28
+#define CLK_FRAC_COMMON_MATRIX2		29
+#define CLK_REF_USBPHY_TOP		30
+#define CLK_REF_DPHY_TOP		31
+#define ACLK_CORE_ROOT			32
+#define PCLK_CORE_ROOT			33
+#define PCLK_DBG			34
+#define PCLK_CORE_GRF			35
+#define PCLK_CORE_CRU			36
+#define CLK_CORE_EMA_DETECT		37
+#define CLK_REF_PVTPLL_CORE		38
+#define PCLK_GPIO1			39
+#define DBCLK_GPIO1			40
+#define ACLK_CORE_PERI_ROOT		41
+#define HCLK_CORE_PERI_ROOT		42
+#define PCLK_CORE_PERI_ROOT		43
+#define CLK_DSMC			44
+#define ACLK_DSMC			45
+#define PCLK_DSMC			46
+#define CLK_FLEXBUS_TX			47
+#define CLK_FLEXBUS_RX			48
+#define ACLK_FLEXBUS			49
+#define HCLK_FLEXBUS			50
+#define ACLK_DSMC_SLV			51
+#define HCLK_DSMC_SLV			52
+#define ACLK_BUS_ROOT			53
+#define HCLK_BUS_ROOT			54
+#define PCLK_BUS_ROOT			55
+#define ACLK_SYSRAM			56
+#define HCLK_SYSRAM			57
+#define ACLK_DMAC0			58
+#define ACLK_DMAC1			59
+#define HCLK_M0				60
+#define PCLK_BUS_GRF			61
+#define PCLK_TIMER			62
+#define CLK_TIMER0_CH0			63
+#define CLK_TIMER0_CH1			64
+#define CLK_TIMER0_CH2			65
+#define CLK_TIMER0_CH3			66
+#define CLK_TIMER0_CH4			67
+#define CLK_TIMER0_CH5			68
+#define PCLK_WDT0			69
+#define TCLK_WDT0			70
+#define PCLK_WDT1			71
+#define TCLK_WDT1			72
+#define PCLK_MAILBOX			73
+#define PCLK_INTMUX			74
+#define PCLK_SPINLOCK			75
+#define PCLK_DDRC			76
+#define HCLK_DDRPHY			77
+#define PCLK_DDRMON			78
+#define CLK_DDRMON_OSC			79
+#define PCLK_STDBY			80
+#define HCLK_USBOTG0			81
+#define HCLK_USBOTG0_PMU		82
+#define CLK_USBOTG0_ADP			83
+#define HCLK_USBOTG1			84
+#define HCLK_USBOTG1_PMU		85
+#define CLK_USBOTG1_ADP			86
+#define PCLK_USBPHY			87
+#define ACLK_DMA2DDR			88
+#define PCLK_DMA2DDR			89
+#define STCLK_M0			90
+#define CLK_DDRPHY			91
+#define CLK_DDRC_SRC			92
+#define ACLK_DDRC_0			93
+#define ACLK_DDRC_1			94
+#define CLK_DDRC			95
+#define CLK_DDRMON			96
+#define HCLK_LSPERI_ROOT		97
+#define PCLK_LSPERI_ROOT		98
+#define PCLK_UART0			99
+#define PCLK_UART1			100
+#define PCLK_UART2			101
+#define PCLK_UART3			102
+#define PCLK_UART4			103
+#define SCLK_UART0			104
+#define SCLK_UART1			105
+#define SCLK_UART2			106
+#define SCLK_UART3			107
+#define SCLK_UART4			108
+#define PCLK_I2C0			109
+#define CLK_I2C0			110
+#define PCLK_I2C1			111
+#define CLK_I2C1			112
+#define PCLK_I2C2			113
+#define CLK_I2C2			114
+#define PCLK_PWM1			115
+#define CLK_PWM1			116
+#define CLK_OSC_PWM1			117
+#define CLK_RC_PWM1			118
+#define CLK_FREQ_PWM1			119
+#define CLK_COUNTER_PWM1		120
+#define PCLK_SPI0			121
+#define CLK_SPI0			122
+#define PCLK_SPI1			123
+#define CLK_SPI1			124
+#define PCLK_GPIO2			125
+#define DBCLK_GPIO2			126
+#define PCLK_GPIO3			127
+#define DBCLK_GPIO3			128
+#define PCLK_GPIO4			129
+#define DBCLK_GPIO4			130
+#define HCLK_CAN0			131
+#define CLK_CAN0			132
+#define HCLK_CAN1			133
+#define CLK_CAN1			134
+#define HCLK_PDM			135
+#define MCLK_PDM			136
+#define CLKOUT_PDM			137
+#define MCLK_SPDIFTX			138
+#define HCLK_SPDIFTX			139
+#define HCLK_SPDIFRX			140
+#define MCLK_SPDIFRX			141
+#define MCLK_SAI0			142
+#define HCLK_SAI0			143
+#define MCLK_OUT_SAI0			144
+#define MCLK_SAI1			145
+#define HCLK_SAI1			146
+#define MCLK_OUT_SAI1			147
+#define HCLK_ASRC0			148
+#define CLK_ASRC0			149
+#define HCLK_ASRC1			150
+#define CLK_ASRC1			151
+#define PCLK_CRU			152
+#define PCLK_PMU_ROOT			153
+#define MCLK_ASRC0			154
+#define MCLK_ASRC1			155
+#define MCLK_ASRC2			156
+#define MCLK_ASRC3			157
+#define LRCK_ASRC0_SRC			158
+#define LRCK_ASRC0_DST			159
+#define LRCK_ASRC1_SRC			160
+#define LRCK_ASRC1_DST			161
+#define ACLK_HSPERI_ROOT		162
+#define HCLK_HSPERI_ROOT		163
+#define PCLK_HSPERI_ROOT		164
+#define CCLK_SRC_SDMMC			165
+#define HCLK_SDMMC			166
+#define HCLK_FSPI			167
+#define SCLK_FSPI			168
+#define PCLK_SPI2			169
+#define ACLK_MAC0			170
+#define ACLK_MAC1			171
+#define PCLK_MAC0			172
+#define PCLK_MAC1			173
+#define CLK_MAC_ROOT			174
+#define CLK_MAC0			175
+#define CLK_MAC1			176
+#define MCLK_SAI2			177
+#define HCLK_SAI2			178
+#define MCLK_OUT_SAI2			179
+#define MCLK_SAI3_SRC			180
+#define HCLK_SAI3			181
+#define MCLK_SAI3			182
+#define MCLK_OUT_SAI3			183
+#define MCLK_SAI4_SRC			184
+#define HCLK_SAI4			185
+#define MCLK_SAI4			186
+#define HCLK_DSM			187
+#define MCLK_DSM			188
+#define PCLK_AUDIO_ADC			189
+#define MCLK_AUDIO_ADC			190
+#define MCLK_AUDIO_ADC_DIV4		191
+#define PCLK_SARADC			192
+#define CLK_SARADC			193
+#define PCLK_OTPC_NS			194
+#define CLK_SBPI_OTPC_NS		195
+#define CLK_USER_OTPC_NS		196
+#define PCLK_UART5			197
+#define SCLK_UART5			198
+#define PCLK_GPIO234_IOC		199
+#define CLK_MAC_PTP_ROOT		200
+#define CLK_MAC0_PTP			201
+#define CLK_MAC1_PTP			202
+#define CLK_SPI2			203
+#define ACLK_VIO_ROOT			204
+#define HCLK_VIO_ROOT			205
+#define PCLK_VIO_ROOT			206
+#define HCLK_RGA			207
+#define ACLK_RGA			208
+#define CLK_CORE_RGA			209
+#define ACLK_VOP			210
+#define HCLK_VOP			211
+#define DCLK_VOP			212
+#define PCLK_DPHY			213
+#define PCLK_DSI_HOST			214
+#define PCLK_TSADC			215
+#define CLK_TSADC			216
+#define CLK_TSADC_TSEN			217
+#define PCLK_GPIO1_IOC			218
+#define PCLK_OTPC_S			219
+#define CLK_SBPI_OTPC_S			220
+#define CLK_USER_OTPC_S			221
+#define PCLK_OTP_MASK			222
+#define PCLK_KEYREADER			223
+#define HCLK_BOOTROM			224
+#define PCLK_DDR_SERVICE		225
+#define HCLK_CRYPTO_S			226
+#define HCLK_KEYLAD			227
+#define CLK_CORE_CRYPTO			228
+#define CLK_PKA_CRYPTO			229
+#define CLK_CORE_CRYPTO_S		230
+#define CLK_PKA_CRYPTO_S		231
+#define ACLK_CRYPTO_S			232
+#define HCLK_RNG_S			233
+#define CLK_CORE_CRYPTO_NS		234
+#define CLK_PKA_CRYPTO_NS		235
+#define ACLK_CRYPTO_NS			236
+#define HCLK_CRYPTO_NS			237
+#define HCLK_RNG			238
+#define CLK_PMU				239
+#define PCLK_PMU			240
+#define CLK_PMU_32K			241
+#define PCLK_PMU_CRU			242
+#define PCLK_PMU_GRF			243
+#define PCLK_GPIO0_IOC			244
+#define PCLK_GPIO0			245
+#define DBCLK_GPIO0			246
+#define PCLK_GPIO1_SHADOW		247
+#define DBCLK_GPIO1_SHADOW		248
+#define PCLK_PMU_HP_TIMER		249
+#define CLK_PMU_HP_TIMER		250
+#define CLK_PMU_HP_TIMER_32K		251
+#define PCLK_PWM0			252
+#define CLK_PWM0			253
+#define CLK_OSC_PWM0			254
+#define CLK_RC_PWM0			255
+#define CLK_MAC_OUT			256
+#define CLK_REF_OUT0			257
+#define CLK_REF_OUT1			258
+#define CLK_32K_FRAC			259
+#define CLK_32K_RC			260
+#define CLK_32K				261
+#define CLK_32K_PMU			262
+#define PCLK_TOUCH_KEY			263
+#define CLK_TOUCH_KEY			264
+#define CLK_REF_PHY_PLL			265
+#define CLK_REF_PHY_PMU_MUX		266
+#define CLK_WIFI_OUT			267
+#define CLK_V0PLL_REF			268
+#define CLK_V1PLL_REF			269
+#define CLK_32K_FRAC_MUX		270
+
+#endif
diff --git a/include/dt-bindings/reset/rockchip,rk3506-cru.h b/include/dt-bindings/reset/rockchip,rk3506-cru.h
new file mode 100644
index 000000000000..31c0d4aa410f
--- /dev/null
+++ b/include/dt-bindings/reset/rockchip,rk3506-cru.h
@@ -0,0 +1,211 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2023-2025 Rockchip Electronics Co., Ltd.
+ * Author: Finley Xiao <finley.xiao at rock-chips.com>
+ */
+
+#ifndef _DT_BINDINGS_REST_ROCKCHIP_RK3506_H
+#define _DT_BINDINGS_REST_ROCKCHIP_RK3506_H
+
+/* CRU-->SOFTRST_CON00 */
+#define SRST_NCOREPORESET0_AC	0
+#define SRST_NCOREPORESET1_AC	1
+#define SRST_NCOREPORESET2_AC	2
+#define SRST_NCORESET0_AC	3
+#define SRST_NCORESET1_AC	4
+#define SRST_NCORESET2_AC	5
+#define SRST_NL2RESET_AC	6
+#define SRST_A_CORE_BIU_AC	7
+#define SRST_H_M0_AC		8
+
+/* CRU-->SOFTRST_CON02 */
+#define SRST_NDBGRESET		9
+#define SRST_P_CORE_BIU		10
+#define SRST_PMU		11
+
+/* CRU-->SOFTRST_CON03 */
+#define SRST_P_DBG		12
+#define SRST_POT_DBG		13
+#define SRST_P_CORE_GRF		14
+#define SRST_CORE_EMA_DETECT	15
+#define SRST_REF_PVTPLL_CORE	16
+#define SRST_P_GPIO1		17
+#define SRST_DB_GPIO1		18
+
+/* CRU-->SOFTRST_CON04 */
+#define SRST_A_CORE_PERI_BIU	19
+#define SRST_A_DSMC		20
+#define SRST_P_DSMC		21
+#define SRST_FLEXBUS		22
+#define SRST_A_FLEXBUS		23
+#define SRST_H_FLEXBUS		24
+#define SRST_A_DSMC_SLV		25
+#define SRST_H_DSMC_SLV		26
+#define SRST_DSMC_SLV		27
+
+/* CRU-->SOFTRST_CON05 */
+#define SRST_A_BUS_BIU		28
+#define SRST_H_BUS_BIU		29
+#define SRST_P_BUS_BIU		30
+#define SRST_A_SYSRAM		31
+#define SRST_H_SYSRAM		32
+#define SRST_A_DMAC0		33
+#define SRST_A_DMAC1		34
+#define SRST_H_M0		35
+#define SRST_M0_JTAG		36
+#define SRST_H_CRYPTO		37
+
+/* CRU-->SOFTRST_CON06 */
+#define SRST_H_RNG		38
+#define SRST_P_BUS_GRF		39
+#define SRST_P_TIMER0		40
+#define SRST_TIMER0_CH0		41
+#define SRST_TIMER0_CH1		42
+#define SRST_TIMER0_CH2		43
+#define SRST_TIMER0_CH3		44
+#define SRST_TIMER0_CH4		45
+#define SRST_TIMER0_CH5		46
+#define SRST_P_WDT0		47
+#define SRST_T_WDT0		48
+#define SRST_P_WDT1		49
+#define SRST_T_WDT1		50
+#define SRST_P_MAILBOX		51
+#define SRST_P_INTMUX		52
+#define SRST_P_SPINLOCK		53
+
+/* CRU-->SOFTRST_CON07 */
+#define SRST_P_DDRC		54
+#define SRST_H_DDRPHY		55
+#define SRST_P_DDRMON		56
+#define SRST_DDRMON_OSC		57
+#define SRST_P_DDR_LPC		58
+#define SRST_H_USBOTG0		59
+#define SRST_USBOTG0_ADP	60
+#define SRST_H_USBOTG1		61
+#define SRST_USBOTG1_ADP	62
+#define SRST_P_USBPHY		63
+#define SRST_USBPHY_POR		64
+#define SRST_USBPHY_OTG0	65
+#define SRST_USBPHY_OTG1	66
+
+/* CRU-->SOFTRST_CON08 */
+#define SRST_A_DMA2DDR		67
+#define SRST_P_DMA2DDR		68
+
+/* CRU-->SOFTRST_CON09 */
+#define SRST_USBOTG0_UTMI	69
+#define SRST_USBOTG1_UTMI	70
+
+/* CRU-->SOFTRST_CON10 */
+#define SRST_A_DDRC_0		71
+#define SRST_A_DDRC_1		72
+#define SRST_A_DDR_BIU		73
+#define SRST_DDRC		74
+#define SRST_DDRMON		75
+
+/* CRU-->SOFTRST_CON11 */
+#define SRST_H_LSPERI_BIU	76
+#define SRST_P_UART0		77
+#define SRST_P_UART1		78
+#define SRST_P_UART2		79
+#define SRST_P_UART3		80
+#define SRST_P_UART4		81
+#define SRST_UART0		82
+#define SRST_UART1		83
+#define SRST_UART2		84
+#define SRST_UART3		85
+#define SRST_UART4		86
+#define SRST_P_I2C0		87
+#define SRST_I2C0		88
+
+/* CRU-->SOFTRST_CON12 */
+#define SRST_P_I2C1		89
+#define SRST_I2C1		90
+#define SRST_P_I2C2		91
+#define SRST_I2C2		92
+#define SRST_P_PWM1		93
+#define SRST_PWM1		94
+#define SRST_P_SPI0		95
+#define SRST_SPI0		96
+#define SRST_P_SPI1		97
+#define SRST_SPI1		98
+#define SRST_P_GPIO2		99
+#define SRST_DB_GPIO2		100
+
+/* CRU-->SOFTRST_CON13 */
+#define SRST_P_GPIO3		101
+#define SRST_DB_GPIO3		102
+#define SRST_P_GPIO4		103
+#define SRST_DB_GPIO4		104
+#define SRST_H_CAN0		105
+#define SRST_CAN0		106
+#define SRST_H_CAN1		107
+#define SRST_CAN1		108
+#define SRST_H_PDM		109
+#define SRST_M_PDM		110
+#define SRST_PDM		111
+#define SRST_SPDIFTX		112
+#define SRST_H_SPDIFTX		113
+#define SRST_H_SPDIFRX		114
+#define SRST_SPDIFRX		115
+#define SRST_M_SAI0		116
+
+/* CRU-->SOFTRST_CON14 */
+#define SRST_H_SAI0		117
+#define SRST_M_SAI1		118
+#define SRST_H_SAI1		119
+#define SRST_H_ASRC0		120
+#define SRST_ASRC0		121
+#define SRST_H_ASRC1		122
+#define SRST_ASRC1		123
+
+/* CRU-->SOFTRST_CON17 */
+#define SRST_H_HSPERI_BIU	124
+#define SRST_H_SDMMC		125
+#define SRST_H_FSPI		126
+#define SRST_S_FSPI		127
+#define SRST_P_SPI2		128
+#define SRST_A_MAC0		129
+#define SRST_A_MAC1		130
+
+/* CRU-->SOFTRST_CON18 */
+#define SRST_M_SAI2		131
+#define SRST_H_SAI2		132
+#define SRST_H_SAI3		133
+#define SRST_M_SAI3		134
+#define SRST_H_SAI4		135
+#define SRST_M_SAI4		136
+#define SRST_H_DSM		137
+#define SRST_M_DSM		138
+#define SRST_P_AUDIO_ADC	139
+#define SRST_M_AUDIO_ADC	140
+
+/* CRU-->SOFTRST_CON19 */
+#define SRST_P_SARADC		141
+#define SRST_SARADC		142
+#define SRST_SARADC_PHY		143
+#define SRST_P_OTPC_NS		144
+#define SRST_SBPI_OTPC_NS	145
+#define SRST_USER_OTPC_NS	146
+#define SRST_P_UART5		147
+#define SRST_UART5		148
+#define SRST_P_GPIO234_IOC	149
+
+/* CRU-->SOFTRST_CON21 */
+#define SRST_A_VIO_BIU		150
+#define SRST_H_VIO_BIU		151
+#define SRST_H_RGA		152
+#define SRST_A_RGA		153
+#define SRST_CORE_RGA		154
+#define SRST_A_VOP		155
+#define SRST_H_VOP		156
+#define SRST_VOP		157
+#define SRST_P_DPHY		158
+#define SRST_P_DSI_HOST		159
+#define SRST_P_TSADC		160
+#define SRST_TSADC		161
+
+/* CRU-->SOFTRST_CON22 */
+#define SRST_P_GPIO1_IOC	162
+
+#endif
-- 
2.34.1



From zhangqing at rock-chips.com  Thu Nov 20 18:46:45 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Fri, 21 Nov 2025 10:46:45 +0800
Subject: [PATCH v8 2/2] clk: rockchip: Add clock and reset driver for RK3506
In-Reply-To: <20251121024645.360615-1-zhangqing@rock-chips.com>
References: <20251121024645.360615-1-zhangqing@rock-chips.com>
Message-ID: <20251121024645.360615-3-zhangqing@rock-chips.com>

Add the clock and reset tree definitions for the new
RK3506 SoC.

Signed-off-by: Finley Xiao <finley.xiao at rock-chips.com>
Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
---
 drivers/clk/rockchip/Kconfig      |   7 +
 drivers/clk/rockchip/Makefile     |   1 +
 drivers/clk/rockchip/clk-rk3506.c | 869 ++++++++++++++++++++++++++++++
 drivers/clk/rockchip/clk.h        |  13 +
 drivers/clk/rockchip/rst-rk3506.c | 226 ++++++++
 5 files changed, 1116 insertions(+)
 create mode 100644 drivers/clk/rockchip/clk-rk3506.c
 create mode 100644 drivers/clk/rockchip/rst-rk3506.c

diff --git a/drivers/clk/rockchip/Kconfig b/drivers/clk/rockchip/Kconfig
index e1ea0a098ca9..5cf1e0fd6fb3 100644
--- a/drivers/clk/rockchip/Kconfig
+++ b/drivers/clk/rockchip/Kconfig
@@ -100,6 +100,13 @@ config CLK_RK3399
 	help
 	  Build the driver for RK3399 Clock Driver.
 
+config CLK_RK3506
+	bool "Rockchip RK3506 clock controller support"
+	depends on ARM || COMPILE_TEST
+	default y
+	help
+	  Build the driver for RK3506 Clock Driver.
+
 config CLK_RK3528
 	bool "Rockchip RK3528 clock controller support"
 	depends on ARM64 || COMPILE_TEST
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index 82b4b29ad036..4d8cbb2044c7 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_CLK_RK3308)        += clk-rk3308.o
 obj-$(CONFIG_CLK_RK3328)        += clk-rk3328.o
 obj-$(CONFIG_CLK_RK3368)        += clk-rk3368.o
 obj-$(CONFIG_CLK_RK3399)        += clk-rk3399.o
+obj-$(CONFIG_CLK_RK3506)	+= clk-rk3506.o rst-rk3506.o
 obj-$(CONFIG_CLK_RK3528)	+= clk-rk3528.o rst-rk3528.o
 obj-$(CONFIG_CLK_RK3562)	+= clk-rk3562.o rst-rk3562.o
 obj-$(CONFIG_CLK_RK3568)	+= clk-rk3568.o
diff --git a/drivers/clk/rockchip/clk-rk3506.c b/drivers/clk/rockchip/clk-rk3506.c
new file mode 100644
index 000000000000..dd59bd60382e
--- /dev/null
+++ b/drivers/clk/rockchip/clk-rk3506.c
@@ -0,0 +1,869 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023-2025 Rockchip Electronics Co., Ltd.
+ * Author: Finley Xiao <finley.xiao at rock-chips.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/syscore_ops.h>
+#include <dt-bindings/clock/rockchip,rk3506-cru.h>
+#include "clk.h"
+
+#define PVTPLL_SRC_SEL_PVTPLL		(BIT(7) | BIT(23))
+
+enum rk3506_plls {
+	gpll, v0pll, v1pll,
+};
+
+/*
+ * [FRAC PLL]: GPLL, V0PLL, V1PLL
+ *   - VCO Frequency: 950MHz to 3800MHZ
+ *   - Output Frequency: 19MHz to 3800MHZ
+ *   - refdiv: 1 to 63 (Int Mode), 1 to 2 (Frac Mode)
+ *   - fbdiv: 16 to 3800 (Int Mode), 20 to 380 (Frac Mode)
+ *   - post1div: 1 to 7
+ *   - post2div: 1 to 7
+ */
+static struct rockchip_pll_rate_table rk3506_pll_rates[] = {
+	/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
+	RK3036_PLL_RATE(1896000000, 1, 79, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1800000000, 1, 75, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1704000000, 1, 71, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1512000000, 1, 63, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1350000000, 4, 225, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1179648000, 1, 49, 1, 1, 0, 2550137),
+	RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1000000000, 3, 125, 1, 1, 1, 0),
+	RK3036_PLL_RATE(993484800, 1, 41, 1, 1, 0, 6630355),
+	RK3036_PLL_RATE(983040000, 1, 40, 1, 1, 0, 16106127),
+	RK3036_PLL_RATE(960000000, 1, 80, 2, 1, 1, 0),
+	RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0),
+	RK3036_PLL_RATE(903168000, 1, 75, 2, 1, 0, 4429185),
+	RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
+	RK3036_PLL_RATE(800000000, 3, 200, 2, 1, 1, 0),
+	RK3036_PLL_RATE(600000000, 1, 50, 2, 1, 1, 0),
+	RK3036_PLL_RATE(594000000, 2, 99, 2, 1, 1, 0),
+	RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0),
+	RK3036_PLL_RATE(312000000, 1, 78, 6, 1, 1, 0),
+	RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0),
+	RK3036_PLL_RATE(96000000, 1, 48, 6, 2, 1, 0),
+	{ /* sentinel */ },
+};
+
+#define RK3506_DIV_ACLK_CORE_MASK	0xf
+#define RK3506_DIV_ACLK_CORE_SHIFT	9
+#define RK3506_DIV_PCLK_CORE_MASK	0xf
+#define RK3506_DIV_PCLK_CORE_SHIFT	0
+
+#define RK3506_CLKSEL15(_aclk_core_div)					\
+{									\
+	.reg = RK3506_CLKSEL_CON(15),					\
+	.val = HIWORD_UPDATE(_aclk_core_div, RK3506_DIV_ACLK_CORE_MASK,	\
+			     RK3506_DIV_ACLK_CORE_SHIFT),		\
+}
+
+#define RK3506_CLKSEL16(_pclk_core_div)					\
+{									\
+	.reg = RK3506_CLKSEL_CON(16),					\
+	.val = HIWORD_UPDATE(_pclk_core_div, RK3506_DIV_PCLK_CORE_MASK,	\
+			     RK3506_DIV_PCLK_CORE_SHIFT),		\
+}
+
+/* SIGN-OFF: aclk_core: 500M, pclk_core: 125M, */
+#define RK3506_CPUCLK_RATE(_prate, _aclk_core_div, _pclk_core_div)	\
+{									\
+	.prate = _prate,						\
+	.divs = {							\
+		RK3506_CLKSEL15(_aclk_core_div),			\
+		RK3506_CLKSEL16(_pclk_core_div),			\
+	},								\
+}
+
+static struct rockchip_cpuclk_rate_table rk3506_cpuclk_rates[] __initdata = {
+	RK3506_CPUCLK_RATE(1608000000, 3, 12),
+	RK3506_CPUCLK_RATE(1512000000, 3, 12),
+	RK3506_CPUCLK_RATE(1416000000, 2, 11),
+	RK3506_CPUCLK_RATE(1296000000, 2, 10),
+	RK3506_CPUCLK_RATE(1200000000, 2, 9),
+	RK3506_CPUCLK_RATE(1179648000, 2, 9),
+	RK3506_CPUCLK_RATE(1008000000, 1, 7),
+	RK3506_CPUCLK_RATE(903168000, 1, 7),
+	RK3506_CPUCLK_RATE(800000000, 1, 6),
+	RK3506_CPUCLK_RATE(750000000, 1, 5),
+	RK3506_CPUCLK_RATE(589824000, 1, 4),
+	RK3506_CPUCLK_RATE(400000000, 1, 3),
+	RK3506_CPUCLK_RATE(200000000, 1, 1),
+};
+
+PNAME(mux_pll_p)				= { "xin24m" };
+PNAME(gpll_v0pll_v1pll_parents_p)		= { "gpll", "v0pll", "v1pll" };
+PNAME(gpll_v0pll_v1pll_g_parents_p)		= { "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate" };
+PNAME(gpll_v0pll_v1pll_div_parents_p)		= { "clk_gpll_div", "clk_v0pll_div", "clk_v1pll_div" };
+PNAME(xin24m_gpll_v0pll_v1pll_g_parents_p)	= { "xin24m", "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate" };
+PNAME(xin24m_g_gpll_v0pll_v1pll_g_parents_p)	= { "xin24m_gate", "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate" };
+PNAME(xin24m_g_gpll_v0pll_v1pll_div_parents_p)	= { "xin24m_gate", "clk_gpll_div", "clk_v0pll_div", "clk_v1pll_div" };
+PNAME(xin24m_400k_32k_parents_p)		= { "xin24m", "clk_rc", "clk_32k" };
+PNAME(clk_frac_uart_matrix0_mux_parents_p)	= { "xin24m", "gpll", "clk_v0pll_gate", "clk_v1pll_gate" };
+PNAME(clk_timer0_parents_p)			= { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai0_mclk_in", "sai0_sclk_in" };
+PNAME(clk_timer1_parents_p)			= { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai1_mclk_in", "sai1_sclk_in" };
+PNAME(clk_timer2_parents_p)			= { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai2_mclk_in", "sai2_sclk_in" };
+PNAME(clk_timer3_parents_p)			= { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai3_mclk_in", "sai3_sclk_in" };
+PNAME(clk_timer4_parents_p)			= { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "mclk_asrc0" };
+PNAME(clk_timer5_parents_p)			= { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "mclk_asrc1" };
+PNAME(sclk_uart_parents_p)			= { "xin24m", "clk_gpll_gate", "clk_v0pll_gate", "clk_frac_uart_matrix0", "clk_frac_uart_matrix1",
+						    "clk_frac_common_matrix0", "clk_frac_common_matrix1", "clk_frac_common_matrix2" };
+PNAME(clk_mac_ptp_root_parents_p)		= { "gpll", "v0pll", "v1pll" };
+PNAME(clk_pwm_parents_p)			= { "clk_rc", "sai0_mclk_in", "sai1_mclk_in", "sai2_mclk_in", "sai3_mclk_in", "sai0_sclk_in", "sai1_sclk_in",
+						    "sai2_sclk_in", "sai3_sclk_in", "mclk_asrc0", "mclk_asrc1" };
+PNAME(clk_can_parents_p)			= { "xin24m", "gpll", "clk_v0pll_gate", "clk_v1pll_gate", "clk_frac_voice_matrix1",
+						    "clk_frac_common_matrix0", "clk_frac_common_matrix1", "clk_frac_common_matrix2" };
+PNAME(clk_pdm_parents_p)			= { "xin24m_gate", "clk_int_voice_matrix0", "clk_int_voice_matrix1", "clk_int_voice_matrix2",
+						    "clk_frac_voice_matrix0", "clk_frac_voice_matrix1", "clk_frac_common_matrix0", "clk_frac_common_matrix1",
+						    "clk_frac_common_matrix2", "sai0_mclk_in", "sai1_mclk_in", "sai2_mclk_in", "sai3_mclk_in", "clk_gpll_div" };
+PNAME(mclk_sai_asrc_parents_p)			= { "xin24m_gate", "clk_int_voice_matrix0", "clk_int_voice_matrix1", "clk_int_voice_matrix2",
+						    "clk_frac_voice_matrix0", "clk_frac_voice_matrix1", "clk_frac_common_matrix0", "clk_frac_common_matrix1",
+						    "clk_frac_common_matrix2", "sai0_mclk_in", "sai1_mclk_in", "sai2_mclk_in", "sai3_mclk_in" };
+PNAME(lrck_asrc_parents_p)			= { "mclk_asrc0", "mclk_asrc1", "mclk_asrc2", "mclk_asrc3", "mclk_spdiftx", "clk_spdifrx_to_asrc", "clkout_pdm",
+						    "sai0_fs", "sai1_fs", "sai2_fs", "sai3_fs", "sai4_fs" };
+PNAME(cclk_src_sdmmc_parents_p)			= { "xin24m_gate", "gpll", "clk_v0pll_gate", "clk_v1pll_gate" };
+PNAME(dclk_vop_parents_p)			= { "xin24m_gate", "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate", "dummy_vop_dclk",
+						    "dummy_vop_dclk", "dummy_vop_dclk", "dummy_vop_dclk" };
+PNAME(dbclk_gpio0_parents_p)			= { "xin24m", "clk_rc", "clk_32k_pmu" };
+PNAME(clk_pmu_hp_timer_parents_p)		= { "xin24m", "gpll_div_100m", "clk_core_pvtpll" };
+PNAME(clk_ref_out_parents_p)			= { "xin24m", "gpll", "v0pll", "v1pll" };
+PNAME(clk_32k_frac_parents_p)			= { "xin24m", "v0pll", "v1pll", "clk_rc" };
+PNAME(clk_32k_parents_p)			= { "xin32k", "clk_32k_rc", "clk_32k_frac" };
+PNAME(clk_ref_phy_pmu_mux_parents_p)		= { "xin24m", "clk_ref_phy_pll" };
+PNAME(clk_vpll_ref_parents_p)			= { "xin24m", "clk_pll_ref_io" };
+PNAME(mux_armclk_p)				= { "armclk_pll", "clk_core_pvtpll" };
+
+#define MFLAGS CLK_MUX_HIWORD_MASK
+#define DFLAGS CLK_DIVIDER_HIWORD_MASK
+#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
+
+static struct rockchip_pll_clock rk3506_pll_clks[] __initdata = {
+	[gpll] = PLL(pll_rk3328, PLL_GPLL, "gpll", mux_pll_p,
+		     CLK_IS_CRITICAL, RK3506_PLL_CON(0),
+		     RK3506_MODE_CON, 0, 2, 0, rk3506_pll_rates),
+	[v0pll] = PLL(pll_rk3328, PLL_V0PLL, "v0pll", mux_pll_p,
+		     CLK_IS_CRITICAL, RK3506_PLL_CON(8),
+		     RK3506_MODE_CON, 2, 0, 0, rk3506_pll_rates),
+	[v1pll] = PLL(pll_rk3328, PLL_V1PLL, "v1pll", mux_pll_p,
+		     CLK_IS_CRITICAL, RK3506_PLL_CON(16),
+		     RK3506_MODE_CON, 4, 1, 0, rk3506_pll_rates),
+};
+
+static struct rockchip_clk_branch rk3506_armclk __initdata =
+	MUX(ARMCLK, "armclk", mux_armclk_p, CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
+			RK3506_CLKSEL_CON(15), 8, 1, MFLAGS);
+
+static struct rockchip_clk_branch rk3506_clk_branches[] __initdata = {
+	/*
+	 * CRU Clock-Architecture
+	 */
+	/* top */
+	GATE(XIN24M_GATE, "xin24m_gate", "xin24m", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(0), 1, GFLAGS),
+	GATE(CLK_GPLL_GATE, "clk_gpll_gate", "gpll", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(0), 2, GFLAGS),
+	GATE(CLK_V0PLL_GATE, "clk_v0pll_gate", "v0pll", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(0), 3, GFLAGS),
+	GATE(CLK_V1PLL_GATE, "clk_v1pll_gate", "v1pll", 0,
+			RK3506_CLKGATE_CON(0), 4, GFLAGS),
+	COMPOSITE_NOMUX(CLK_GPLL_DIV, "clk_gpll_div", "clk_gpll_gate", CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(0), 6, 4, DFLAGS,
+			RK3506_CLKGATE_CON(0), 5, GFLAGS),
+	COMPOSITE_NOMUX(CLK_GPLL_DIV_100M, "clk_gpll_div_100m", "clk_gpll_div", 0,
+			RK3506_CLKSEL_CON(0), 10, 4, DFLAGS,
+			RK3506_CLKGATE_CON(0), 6, GFLAGS),
+	COMPOSITE_NOMUX(CLK_V0PLL_DIV, "clk_v0pll_div", "clk_v0pll_gate", CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(1), 0, 4, DFLAGS,
+			RK3506_CLKGATE_CON(0), 7, GFLAGS),
+	COMPOSITE_NOMUX(CLK_V1PLL_DIV, "clk_v1pll_div", "clk_v1pll_gate", 0,
+			RK3506_CLKSEL_CON(1), 4, 4, DFLAGS,
+			RK3506_CLKGATE_CON(0), 8, GFLAGS),
+	COMPOSITE_NOMUX(CLK_INT_VOICE_MATRIX0, "clk_int_voice_matrix0", "clk_v0pll_gate", 0,
+			RK3506_CLKSEL_CON(1), 8, 5, DFLAGS,
+			RK3506_CLKGATE_CON(0), 9, GFLAGS),
+	COMPOSITE_NOMUX(CLK_INT_VOICE_MATRIX1, "clk_int_voice_matrix1", "clk_v1pll_gate", 0,
+			RK3506_CLKSEL_CON(2), 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(0), 10, GFLAGS),
+	COMPOSITE_NOMUX(CLK_INT_VOICE_MATRIX2, "clk_int_voice_matrix2", "clk_v0pll_gate", 0,
+			RK3506_CLKSEL_CON(2), 5, 5, DFLAGS,
+			RK3506_CLKGATE_CON(0), 11, GFLAGS),
+	MUX(CLK_FRAC_UART_MATRIX0_MUX, "clk_frac_uart_matrix0_mux", clk_frac_uart_matrix0_mux_parents_p, 0,
+			RK3506_CLKSEL_CON(3), 9, 2, MFLAGS),
+	MUX(CLK_FRAC_UART_MATRIX1_MUX, "clk_frac_uart_matrix1_mux", xin24m_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(3), 11, 2, MFLAGS),
+	MUX(CLK_FRAC_VOICE_MATRIX0_MUX, "clk_frac_voice_matrix0_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(3), 13, 2, MFLAGS),
+	MUX(CLK_FRAC_VOICE_MATRIX1_MUX, "clk_frac_voice_matrix1_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(4), 0, 2, MFLAGS),
+	MUX(CLK_FRAC_COMMON_MATRIX0_MUX, "clk_frac_common_matrix0_mux", xin24m_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(4), 2, 2, MFLAGS),
+	MUX(CLK_FRAC_COMMON_MATRIX1_MUX, "clk_frac_common_matrix1_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(4), 4, 2, MFLAGS),
+	MUX(CLK_FRAC_COMMON_MATRIX2_MUX, "clk_frac_common_matrix2_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(4), 6, 2, MFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_UART_MATRIX0, "clk_frac_uart_matrix0", "clk_frac_uart_matrix0_mux", 0,
+			RK3506_CLKSEL_CON(5), 0,
+			RK3506_CLKGATE_CON(0), 13, GFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_UART_MATRIX1, "clk_frac_uart_matrix1", "clk_frac_uart_matrix1_mux", 0,
+			RK3506_CLKSEL_CON(6), 0,
+			RK3506_CLKGATE_CON(0), 14, GFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_VOICE_MATRIX0, "clk_frac_voice_matrix0", "clk_frac_voice_matrix0_mux", 0,
+			RK3506_CLKSEL_CON(7), 0,
+			RK3506_CLKGATE_CON(0), 15, GFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_VOICE_MATRIX1, "clk_frac_voice_matrix1", "clk_frac_voice_matrix1_mux", 0,
+			RK3506_CLKSEL_CON(9), 0,
+			RK3506_CLKGATE_CON(1), 0, GFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_COMMON_MATRIX0, "clk_frac_common_matrix0", "clk_frac_common_matrix0_mux", 0,
+			RK3506_CLKSEL_CON(11), 0,
+			RK3506_CLKGATE_CON(1), 1, GFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_COMMON_MATRIX1, "clk_frac_common_matrix1", "clk_frac_common_matrix1_mux", 0,
+			RK3506_CLKSEL_CON(12), 0,
+			RK3506_CLKGATE_CON(1), 2, GFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_COMMON_MATRIX2, "clk_frac_common_matrix2", "clk_frac_common_matrix2_mux", 0,
+			RK3506_CLKSEL_CON(13), 0,
+			RK3506_CLKGATE_CON(1), 3, GFLAGS),
+	GATE(CLK_REF_USBPHY_TOP, "clk_ref_usbphy_top", "xin24m", 0,
+			RK3506_CLKGATE_CON(1), 4, GFLAGS),
+	GATE(CLK_REF_DPHY_TOP, "clk_ref_dphy_top", "xin24m", 0,
+			RK3506_CLKGATE_CON(1), 5, GFLAGS),
+
+	/* core */
+	COMPOSITE_NOGATE(0, "armclk_pll", gpll_v0pll_v1pll_parents_p, CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(15), 5, 2, MFLAGS, 0, 5, DFLAGS),
+	COMPOSITE_NOMUX(ACLK_CORE_ROOT, "aclk_core_root", "armclk", CLK_IGNORE_UNUSED,
+			RK3506_CLKSEL_CON(15), 9, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
+			RK3506_CLKGATE_CON(2), 11, GFLAGS),
+	COMPOSITE_NOMUX(PCLK_CORE_ROOT, "pclk_core_root", "armclk", CLK_IGNORE_UNUSED,
+			RK3506_CLKSEL_CON(16), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
+			RK3506_CLKGATE_CON(2), 12, GFLAGS),
+	GATE(PCLK_DBG, "pclk_dbg", "pclk_core_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(3), 1, GFLAGS),
+	GATE(PCLK_CORE_GRF, "pclk_core_grf", "pclk_core_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(3), 4, GFLAGS),
+	GATE(PCLK_CORE_CRU, "pclk_core_cru", "pclk_core_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(3), 5, GFLAGS),
+	GATE(CLK_CORE_EMA_DETECT, "clk_core_ema_detect", "xin24m_gate", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(3), 6, GFLAGS),
+	GATE(PCLK_GPIO1, "pclk_gpio1", "aclk_core_root", 0,
+			RK3506_CLKGATE_CON(3), 8, GFLAGS),
+	GATE(DBCLK_GPIO1, "dbclk_gpio1", "xin24m_gate", 0,
+			RK3506_CLKGATE_CON(3), 9, GFLAGS),
+
+	/* core peri */
+	COMPOSITE(ACLK_CORE_PERI_ROOT, "aclk_core_peri_root", gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(18), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(4), 0, GFLAGS),
+	GATE(HCLK_CORE_PERI_ROOT, "hclk_core_peri_root", "aclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 1, GFLAGS),
+	GATE(PCLK_CORE_PERI_ROOT, "pclk_core_peri_root", "aclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 2, GFLAGS),
+	COMPOSITE(CLK_DSMC, "clk_dsmc", xin24m_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(18), 12, 2, MFLAGS, 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(4), 4, GFLAGS),
+	GATE(ACLK_DSMC, "aclk_dsmc", "aclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 5, GFLAGS),
+	GATE(PCLK_DSMC, "pclk_dsmc", "pclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 6, GFLAGS),
+	COMPOSITE(CLK_FLEXBUS_TX, "clk_flexbus_tx", xin24m_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(19), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(4), 7, GFLAGS),
+	COMPOSITE(CLK_FLEXBUS_RX, "clk_flexbus_rx", xin24m_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(19), 12, 2, MFLAGS, 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(4), 8, GFLAGS),
+	GATE(ACLK_FLEXBUS, "aclk_flexbus", "aclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 9, GFLAGS),
+	GATE(HCLK_FLEXBUS, "hclk_flexbus", "hclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 10, GFLAGS),
+	GATE(ACLK_DSMC_SLV, "aclk_dsmc_slv", "aclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 11, GFLAGS),
+	GATE(HCLK_DSMC_SLV, "hclk_dsmc_slv", "hclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 12, GFLAGS),
+
+	/* bus */
+	COMPOSITE(ACLK_BUS_ROOT, "aclk_bus_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(21), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(5), 0, GFLAGS),
+	COMPOSITE(HCLK_BUS_ROOT, "hclk_bus_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(21), 12, 2, MFLAGS, 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(5), 1, GFLAGS),
+	COMPOSITE(PCLK_BUS_ROOT, "pclk_bus_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(22), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(5), 2, GFLAGS),
+	GATE(ACLK_SYSRAM, "aclk_sysram", "aclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(5), 6, GFLAGS),
+	GATE(HCLK_SYSRAM, "hclk_sysram", "aclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(5), 7, GFLAGS),
+	GATE(ACLK_DMAC0, "aclk_dmac0", "aclk_bus_root", 0,
+			RK3506_CLKGATE_CON(5), 8, GFLAGS),
+	GATE(ACLK_DMAC1, "aclk_dmac1", "aclk_bus_root", 0,
+			RK3506_CLKGATE_CON(5), 9, GFLAGS),
+	GATE(HCLK_M0, "hclk_m0", "aclk_bus_root", 0,
+			RK3506_CLKGATE_CON(5), 10, GFLAGS),
+	GATE(ACLK_CRYPTO_NS, "aclk_crypto_ns", "aclk_bus_root", 0,
+			RK3506_CLKGATE_CON(5), 14, GFLAGS),
+	GATE(HCLK_CRYPTO_NS, "hclk_crypto_ns", "hclk_bus_root", 0,
+			RK3506_CLKGATE_CON(5), 15, GFLAGS),
+	GATE(HCLK_RNG, "hclk_rng", "hclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 0, GFLAGS),
+	GATE(PCLK_BUS_GRF, "pclk_bus_grf", "pclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(6), 1, GFLAGS),
+	GATE(PCLK_TIMER, "pclk_timer", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 2, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0_CH0, "clk_timer0_ch0", clk_timer0_parents_p, 0,
+			RK3506_CLKSEL_CON(22), 7, 3, MFLAGS,
+			RK3506_CLKGATE_CON(6), 3, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0_CH1, "clk_timer0_ch1", clk_timer1_parents_p, 0,
+			RK3506_CLKSEL_CON(22), 10, 3, MFLAGS,
+			RK3506_CLKGATE_CON(6), 4, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0_CH2, "clk_timer0_ch2", clk_timer2_parents_p, 0,
+			RK3506_CLKSEL_CON(22), 13, 3, MFLAGS,
+			RK3506_CLKGATE_CON(6), 5, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0_CH3, "clk_timer0_ch3", clk_timer3_parents_p, 0,
+			RK3506_CLKSEL_CON(23), 0, 3, MFLAGS,
+			RK3506_CLKGATE_CON(6), 6, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0_CH4, "clk_timer0_ch4", clk_timer4_parents_p, 0,
+			RK3506_CLKSEL_CON(23), 3, 3, MFLAGS,
+			RK3506_CLKGATE_CON(6), 7, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0_CH5, "clk_timer0_ch5", clk_timer5_parents_p, 0,
+			RK3506_CLKSEL_CON(23), 6, 3, MFLAGS,
+			RK3506_CLKGATE_CON(6), 8, GFLAGS),
+	GATE(PCLK_WDT0, "pclk_wdt0", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 9, GFLAGS),
+	GATE(TCLK_WDT0, "tclk_wdt0", "xin24m_gate", 0,
+			RK3506_CLKGATE_CON(6), 10, GFLAGS),
+	GATE(PCLK_WDT1, "pclk_wdt1", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 11, GFLAGS),
+	GATE(TCLK_WDT1, "tclk_wdt1", "xin24m_gate", 0,
+			RK3506_CLKGATE_CON(6), 12, GFLAGS),
+	GATE(PCLK_MAILBOX, "pclk_mailbox", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 13, GFLAGS),
+	GATE(PCLK_INTMUX, "pclk_intmux", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 14, GFLAGS),
+	GATE(PCLK_SPINLOCK, "pclk_spinlock", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 15, GFLAGS),
+	GATE(PCLK_DDRC, "pclk_ddrc", "pclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(7), 0, GFLAGS),
+	GATE(HCLK_DDRPHY, "hclk_ddrphy", "hclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(7), 1, GFLAGS),
+	GATE(PCLK_DDRMON, "pclk_ddrmon", "pclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(7), 2, GFLAGS),
+	GATE(CLK_DDRMON_OSC, "clk_ddrmon_osc", "xin24m_gate", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(7), 3, GFLAGS),
+	GATE(PCLK_STDBY, "pclk_stdby", "pclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(7), 4, GFLAGS),
+	GATE(HCLK_USBOTG0, "hclk_usbotg0", "hclk_bus_root", 0,
+			RK3506_CLKGATE_CON(7), 5, GFLAGS),
+	GATE(HCLK_USBOTG0_PMU, "hclk_usbotg0_pmu", "hclk_bus_root", 0,
+			RK3506_CLKGATE_CON(7), 6, GFLAGS),
+	GATE(CLK_USBOTG0_ADP, "clk_usbotg0_adp", "clk_32k", 0,
+			RK3506_CLKGATE_CON(7), 7, GFLAGS),
+	GATE(HCLK_USBOTG1, "hclk_usbotg1", "hclk_bus_root", 0,
+			RK3506_CLKGATE_CON(7), 8, GFLAGS),
+	GATE(HCLK_USBOTG1_PMU, "hclk_usbotg1_pmu", "hclk_bus_root", 0,
+			RK3506_CLKGATE_CON(7), 9, GFLAGS),
+	GATE(CLK_USBOTG1_ADP, "clk_usbotg1_adp", "clk_32k", 0,
+			RK3506_CLKGATE_CON(7), 10, GFLAGS),
+	GATE(PCLK_USBPHY, "pclk_usbphy", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(7), 11, GFLAGS),
+	GATE(ACLK_DMA2DDR, "aclk_dma2ddr", "aclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(8), 0, GFLAGS),
+	GATE(PCLK_DMA2DDR, "pclk_dma2ddr", "pclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(8), 1, GFLAGS),
+	COMPOSITE_NOMUX(STCLK_M0, "stclk_m0", "xin24m_gate", 0,
+			RK3506_CLKSEL_CON(23), 9, 6, DFLAGS,
+			RK3506_CLKGATE_CON(8), 2, GFLAGS),
+	COMPOSITE(CLK_DDRPHY, "clk_ddrphy", gpll_v0pll_v1pll_parents_p, CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKSEL_CON(4), 4, 2, MFLAGS, 0, 4, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 10, GFLAGS),
+	FACTOR(CLK_DDRC_SRC, "clk_ddrc_src", "clk_ddrphy", 0, 1, 4),
+	GATE(ACLK_DDRC_0, "aclk_ddrc_0", "clk_ddrc_src", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(10), 0, GFLAGS),
+	GATE(ACLK_DDRC_1, "aclk_ddrc_1", "clk_ddrc_src", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(10), 1, GFLAGS),
+	GATE(CLK_DDRC, "clk_ddrc", "clk_ddrc_src", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(10), 3, GFLAGS),
+	GATE(CLK_DDRMON, "clk_ddrmon", "clk_ddrc_src", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(10), 4, GFLAGS),
+
+	/* ls peri */
+	COMPOSITE(HCLK_LSPERI_ROOT, "hclk_lsperi_root", gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(29), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(11), 0, GFLAGS),
+	GATE(PCLK_LSPERI_ROOT, "pclk_lsperi_root", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 1, GFLAGS),
+	GATE(PCLK_UART0, "pclk_uart0", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 4, GFLAGS),
+	GATE(PCLK_UART1, "pclk_uart1", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 5, GFLAGS),
+	GATE(PCLK_UART2, "pclk_uart2", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 6, GFLAGS),
+	GATE(PCLK_UART3, "pclk_uart3", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 7, GFLAGS),
+	GATE(PCLK_UART4, "pclk_uart4", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 8, GFLAGS),
+	COMPOSITE(SCLK_UART0, "sclk_uart0", sclk_uart_parents_p, 0,
+			RK3506_CLKSEL_CON(29), 12, 3, MFLAGS, 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(11), 9, GFLAGS),
+	COMPOSITE(SCLK_UART1, "sclk_uart1", sclk_uart_parents_p, 0,
+			RK3506_CLKSEL_CON(30), 5, 3, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(11), 10, GFLAGS),
+	COMPOSITE(SCLK_UART2, "sclk_uart2", sclk_uart_parents_p, 0,
+			RK3506_CLKSEL_CON(30), 13, 3, MFLAGS, 8, 5, DFLAGS,
+			RK3506_CLKGATE_CON(11), 11, GFLAGS),
+	COMPOSITE(SCLK_UART3, "sclk_uart3", sclk_uart_parents_p, 0,
+			RK3506_CLKSEL_CON(31), 5, 3, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(11), 12, GFLAGS),
+	COMPOSITE(SCLK_UART4, "sclk_uart4", sclk_uart_parents_p, 0,
+			RK3506_CLKSEL_CON(31), 13, 3, MFLAGS, 8, 5, DFLAGS,
+			RK3506_CLKGATE_CON(11), 13, GFLAGS),
+	GATE(PCLK_I2C0, "pclk_i2c0", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 14, GFLAGS),
+	COMPOSITE(CLK_I2C0, "clk_i2c0", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(32), 4, 2, MFLAGS, 0, 4, DFLAGS,
+			RK3506_CLKGATE_CON(11), 15, GFLAGS),
+	GATE(PCLK_I2C1, "pclk_i2c1", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(12), 0, GFLAGS),
+	COMPOSITE(CLK_I2C1, "clk_i2c1", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(32), 10, 2, MFLAGS, 6, 4, DFLAGS,
+			RK3506_CLKGATE_CON(12), 1, GFLAGS),
+	GATE(PCLK_I2C2, "pclk_i2c2", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(12), 2, GFLAGS),
+	COMPOSITE(CLK_I2C2, "clk_i2c2", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(33), 4, 2, MFLAGS, 0, 4, DFLAGS,
+			RK3506_CLKGATE_CON(12), 3, GFLAGS),
+	GATE(PCLK_PWM1, "pclk_pwm1", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(12), 4, GFLAGS),
+	COMPOSITE(CLK_PWM1, "clk_pwm1", gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(33), 10, 2, MFLAGS, 6, 4, DFLAGS,
+			RK3506_CLKGATE_CON(12), 5, GFLAGS),
+	GATE(CLK_OSC_PWM1, "clk_osc_pwm1", "xin24m", 0,
+			RK3506_CLKGATE_CON(12), 6, GFLAGS),
+	GATE(CLK_RC_PWM1, "clk_rc_pwm1", "clk_rc", 0,
+			RK3506_CLKGATE_CON(12), 7, GFLAGS),
+	COMPOSITE_NODIV(CLK_FREQ_PWM1, "clk_freq_pwm1", clk_pwm_parents_p, 0,
+			RK3506_CLKSEL_CON(33), 12, 4, MFLAGS,
+			RK3506_CLKGATE_CON(12), 8, GFLAGS),
+	COMPOSITE_NODIV(CLK_COUNTER_PWM1, "clk_counter_pwm1", clk_pwm_parents_p, 0,
+			RK3506_CLKSEL_CON(34), 0, 4, MFLAGS,
+			RK3506_CLKGATE_CON(12), 9, GFLAGS),
+	GATE(PCLK_SPI0, "pclk_spi0", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(12), 10, GFLAGS),
+	COMPOSITE(CLK_SPI0, "clk_spi0", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(34), 8, 2, MFLAGS, 4, 4, DFLAGS,
+			RK3506_CLKGATE_CON(12), 11, GFLAGS),
+	GATE(PCLK_SPI1, "pclk_spi1", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(12), 12, GFLAGS),
+	COMPOSITE(CLK_SPI1, "clk_spi1", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(34), 14, 2, MFLAGS, 10, 4, DFLAGS,
+			RK3506_CLKGATE_CON(12), 13, GFLAGS),
+	GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(12), 14, GFLAGS),
+	COMPOSITE_NODIV(DBCLK_GPIO2, "dbclk_gpio2", xin24m_400k_32k_parents_p, 0,
+			RK3506_CLKSEL_CON(35), 0, 2, MFLAGS,
+			RK3506_CLKGATE_CON(12), 15, GFLAGS),
+	GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 0, GFLAGS),
+	COMPOSITE_NODIV(DBCLK_GPIO3, "dbclk_gpio3", xin24m_400k_32k_parents_p, 0,
+			RK3506_CLKSEL_CON(35), 2, 2, MFLAGS,
+			RK3506_CLKGATE_CON(13), 1, GFLAGS),
+	GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 2, GFLAGS),
+	COMPOSITE_NODIV(DBCLK_GPIO4, "dbclk_gpio4", xin24m_400k_32k_parents_p, 0,
+			RK3506_CLKSEL_CON(35), 4, 2, MFLAGS,
+			RK3506_CLKGATE_CON(13), 3, GFLAGS),
+	GATE(HCLK_CAN0, "hclk_can0", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 4, GFLAGS),
+	COMPOSITE(CLK_CAN0, "clk_can0", clk_can_parents_p, 0,
+			RK3506_CLKSEL_CON(35), 11, 3, MFLAGS, 6, 5, DFLAGS,
+			RK3506_CLKGATE_CON(13), 5, GFLAGS),
+	GATE(HCLK_CAN1, "hclk_can1", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 6, GFLAGS),
+	COMPOSITE(CLK_CAN1, "clk_can1", clk_can_parents_p, 0,
+			RK3506_CLKSEL_CON(36), 5, 3, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(13), 7, GFLAGS),
+	GATE(HCLK_PDM, "hclk_pdm", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 8, GFLAGS),
+	COMPOSITE(MCLK_PDM, "mclk_pdm", clk_pdm_parents_p, 0,
+			RK3506_CLKSEL_CON(37), 5, 4, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(13), 9, GFLAGS),
+	COMPOSITE(CLKOUT_PDM, "clkout_pdm", clk_pdm_parents_p, 0,
+			RK3506_CLKSEL_CON(38), 10, 4, MFLAGS, 0, 10, DFLAGS,
+			RK3506_CLKGATE_CON(13), 10, GFLAGS),
+	COMPOSITE(MCLK_SPDIFTX, "mclk_spdiftx", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(39), 5, 4, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(13), 11, GFLAGS),
+	GATE(HCLK_SPDIFTX, "hclk_spdiftx", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 12, GFLAGS),
+	GATE(HCLK_SPDIFRX, "hclk_spdifrx", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 13, GFLAGS),
+	COMPOSITE(MCLK_SPDIFRX, "mclk_spdifrx", gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(39), 14, 2, MFLAGS, 9, 5, DFLAGS,
+			RK3506_CLKGATE_CON(13), 14, GFLAGS),
+	COMPOSITE(MCLK_SAI0, "mclk_sai0", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(40), 8, 4, MFLAGS, 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(13), 15, GFLAGS),
+	GATE(HCLK_SAI0, "hclk_sai0", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(14), 0, GFLAGS),
+	GATE(MCLK_OUT_SAI0, "mclk_out_sai0", "mclk_sai0", 0,
+			RK3506_CLKGATE_CON(14), 1, GFLAGS),
+	COMPOSITE(MCLK_SAI1, "mclk_sai1", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(41), 8, 4, MFLAGS, 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(14), 2, GFLAGS),
+	GATE(HCLK_SAI1, "hclk_sai1", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(14), 3, GFLAGS),
+	GATE(MCLK_OUT_SAI1, "mclk_out_sai1", "mclk_sai1", 0,
+			RK3506_CLKGATE_CON(14), 4, GFLAGS),
+	GATE(HCLK_ASRC0, "hclk_asrc0", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(14), 5, GFLAGS),
+	COMPOSITE(CLK_ASRC0, "clk_asrc0", gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(42), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(14), 6, GFLAGS),
+	GATE(HCLK_ASRC1, "hclk_asrc1", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(14), 7, GFLAGS),
+	COMPOSITE(CLK_ASRC1, "clk_asrc1", gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(42), 12, 2, MFLAGS, 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(14), 8, GFLAGS),
+	GATE(PCLK_CRU, "pclk_cru", "pclk_lsperi_root", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(14), 9, GFLAGS),
+	GATE(PCLK_PMU_ROOT, "pclk_pmu_root", "pclk_lsperi_root", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(14), 10, GFLAGS),
+	COMPOSITE_NODIV(MCLK_ASRC0, "mclk_asrc0", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(46), 0, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 0, GFLAGS),
+	COMPOSITE_NODIV(MCLK_ASRC1, "mclk_asrc1", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(46), 4, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 1, GFLAGS),
+	COMPOSITE_NODIV(MCLK_ASRC2, "mclk_asrc2", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(46), 8, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 2, GFLAGS),
+	COMPOSITE_NODIV(MCLK_ASRC3, "mclk_asrc3", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(46), 12, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 3, GFLAGS),
+	COMPOSITE_NODIV(LRCK_ASRC0_SRC, "lrck_asrc0_src", lrck_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(47), 0, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 4, GFLAGS),
+	COMPOSITE_NODIV(LRCK_ASRC0_DST, "lrck_asrc0_dst", lrck_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(47), 4, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 5, GFLAGS),
+	COMPOSITE_NODIV(LRCK_ASRC1_SRC, "lrck_asrc1_src", lrck_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(47), 8, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 6, GFLAGS),
+	COMPOSITE_NODIV(LRCK_ASRC1_DST, "lrck_asrc1_dst", lrck_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(47), 12, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 7, GFLAGS),
+
+	/* hs peri */
+	COMPOSITE(ACLK_HSPERI_ROOT, "aclk_hsperi_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(49), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(17), 0, GFLAGS),
+	GATE(HCLK_HSPERI_ROOT, "hclk_hsperi_root", "aclk_hsperi_root", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(17), 1, GFLAGS),
+	GATE(PCLK_HSPERI_ROOT, "pclk_hsperi_root", "hclk_hsperi_root", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(17), 2, GFLAGS),
+	COMPOSITE(CCLK_SRC_SDMMC, "cclk_src_sdmmc", cclk_src_sdmmc_parents_p, 0,
+			RK3506_CLKSEL_CON(49), 13, 2, MFLAGS, 7, 6, DFLAGS,
+			RK3506_CLKGATE_CON(17), 6, GFLAGS),
+	GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 7, GFLAGS),
+	GATE(HCLK_FSPI, "hclk_fspi", "hclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 8, GFLAGS),
+	COMPOSITE(SCLK_FSPI, "sclk_fspi", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(50), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(17), 9, GFLAGS),
+	GATE(PCLK_SPI2, "pclk_spi2", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 10, GFLAGS),
+	GATE(ACLK_MAC0, "aclk_mac0", "aclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 11, GFLAGS),
+	GATE(ACLK_MAC1, "aclk_mac1", "aclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 12, GFLAGS),
+	GATE(PCLK_MAC0, "pclk_mac0", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 13, GFLAGS),
+	GATE(PCLK_MAC1, "pclk_mac1", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 14, GFLAGS),
+	COMPOSITE_NOMUX(CLK_MAC_ROOT, "clk_mac_root", "gpll", 0,
+			RK3506_CLKSEL_CON(50), 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(17), 15, GFLAGS),
+	GATE(CLK_MAC0, "clk_mac0", "clk_mac_root", 0,
+			RK3506_CLKGATE_CON(18), 0, GFLAGS),
+	GATE(CLK_MAC1, "clk_mac1", "clk_mac_root", 0,
+			RK3506_CLKGATE_CON(18), 1, GFLAGS),
+	COMPOSITE(MCLK_SAI2, "mclk_sai2", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(51), 8, 4, MFLAGS, 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(18), 2, GFLAGS),
+	GATE(HCLK_SAI2, "hclk_sai2", "hclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(18), 3, GFLAGS),
+	GATE(MCLK_OUT_SAI2, "mclk_out_sai2", "mclk_sai2", 0,
+			RK3506_CLKGATE_CON(18), 4, GFLAGS),
+	COMPOSITE(MCLK_SAI3_SRC, "mclk_sai3_src", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(52), 8, 4, MFLAGS, 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(18), 5, GFLAGS),
+	GATE(HCLK_SAI3, "hclk_sai3", "hclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(18), 6, GFLAGS),
+	GATE(MCLK_SAI3, "mclk_sai3", "mclk_sai3_src", 0,
+			RK3506_CLKGATE_CON(18), 7, GFLAGS),
+	GATE(MCLK_OUT_SAI3, "mclk_out_sai3", "mclk_sai3_src", 0,
+			RK3506_CLKGATE_CON(18), 8, GFLAGS),
+	COMPOSITE(MCLK_SAI4_SRC, "mclk_sai4_src", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(53), 8, 4, MFLAGS, 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(18), 9, GFLAGS),
+	GATE(HCLK_SAI4, "hclk_sai4", "hclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(18), 10, GFLAGS),
+	GATE(MCLK_SAI4, "mclk_sai4", "mclk_sai4_src", 0,
+			RK3506_CLKGATE_CON(18), 11, GFLAGS),
+	GATE(HCLK_DSM, "hclk_dsm", "hclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(18), 12, GFLAGS),
+	GATE(MCLK_DSM, "mclk_dsm", "mclk_sai3_src", 0,
+			RK3506_CLKGATE_CON(18), 13, GFLAGS),
+	GATE(PCLK_AUDIO_ADC, "pclk_audio_adc", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(18), 14, GFLAGS),
+	GATE(MCLK_AUDIO_ADC, "mclk_audio_adc", "mclk_sai4_src", 0,
+			RK3506_CLKGATE_CON(18), 15, GFLAGS),
+	FACTOR(MCLK_AUDIO_ADC_DIV4, "mclk_audio_adc_div4", "mclk_audio_adc", 0, 1, 4),
+	GATE(PCLK_SARADC, "pclk_saradc", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(19), 0, GFLAGS),
+	COMPOSITE(CLK_SARADC, "clk_saradc", xin24m_400k_32k_parents_p, 0,
+			RK3506_CLKSEL_CON(54), 4, 2, MFLAGS, 0, 4, DFLAGS,
+			RK3506_CLKGATE_CON(19), 1, GFLAGS),
+	GATE(PCLK_OTPC_NS, "pclk_otpc_ns", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(19), 3, GFLAGS),
+	GATE(CLK_SBPI_OTPC_NS, "clk_sbpi_otpc_ns", "xin24m_gate", 0,
+			RK3506_CLKGATE_CON(19), 4, GFLAGS),
+	FACTOR(CLK_USER_OTPC_NS, "clk_user_otpc_ns", "clk_sbpi_otpc_ns", 0, 1, 2),
+	GATE(PCLK_UART5, "pclk_uart5", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(19), 6, GFLAGS),
+	COMPOSITE(SCLK_UART5, "sclk_uart5", sclk_uart_parents_p, 0,
+			RK3506_CLKSEL_CON(54), 11, 3, MFLAGS, 6, 5, DFLAGS,
+			RK3506_CLKGATE_CON(19), 7, GFLAGS),
+	GATE(PCLK_GPIO234_IOC, "pclk_gpio234_ioc", "pclk_hsperi_root", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(19), 8, GFLAGS),
+	COMPOSITE(CLK_MAC_PTP_ROOT, "clk_mac_ptp_root", clk_mac_ptp_root_parents_p, 0,
+			RK3506_CLKSEL_CON(55), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(19), 9, GFLAGS),
+	GATE(CLK_MAC0_PTP, "clk_mac0_ptp", "clk_mac_ptp_root", 0,
+			RK3506_CLKGATE_CON(19), 10, GFLAGS),
+	GATE(CLK_MAC1_PTP, "clk_mac1_ptp", "clk_mac_ptp_root", 0,
+			RK3506_CLKGATE_CON(19), 11, GFLAGS),
+	COMPOSITE(ACLK_VIO_ROOT, "aclk_vio_root", gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(58), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(21), 0, GFLAGS),
+	COMPOSITE(HCLK_VIO_ROOT, "hclk_vio_root", gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(58), 12, 2, MFLAGS, 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(21), 1, GFLAGS),
+	GATE(PCLK_VIO_ROOT, "pclk_vio_root", "hclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 2, GFLAGS),
+	GATE(HCLK_RGA, "hclk_rga", "hclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 6, GFLAGS),
+	GATE(ACLK_RGA, "aclk_rga", "aclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 7, GFLAGS),
+	COMPOSITE(CLK_CORE_RGA, "clk_core_rga", gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(59), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(21), 8, GFLAGS),
+	GATE(ACLK_VOP, "aclk_vop", "aclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 9, GFLAGS),
+	GATE(HCLK_VOP, "hclk_vop", "hclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 10, GFLAGS),
+	COMPOSITE(DCLK_VOP, "dclk_vop", dclk_vop_parents_p, 0,
+			RK3506_CLKSEL_CON(60), 8, 3, MFLAGS, 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(21), 11, GFLAGS),
+	GATE(PCLK_DPHY, "pclk_dphy", "pclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 12, GFLAGS),
+	GATE(PCLK_DSI_HOST, "pclk_dsi_host", "pclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 13, GFLAGS),
+	GATE(PCLK_TSADC, "pclk_tsadc", "pclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 14, GFLAGS),
+	COMPOSITE_NOMUX(CLK_TSADC, "clk_tsadc", "xin24m_gate", 0,
+			RK3506_CLKSEL_CON(61), 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(21), 15, GFLAGS),
+	COMPOSITE_NOMUX(CLK_TSADC_TSEN, "clk_tsadc_tsen", "xin24m_gate", 0,
+			RK3506_CLKSEL_CON(61), 8, 3, DFLAGS,
+			RK3506_CLKGATE_CON(22), 0, GFLAGS),
+	GATE(PCLK_GPIO1_IOC, "pclk_gpio1_ioc", "pclk_vio_root", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(22), 1, GFLAGS),
+
+	/* pmu */
+	GATE(CLK_PMU, "clk_pmu", "xin24m", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 1, GFLAGS),
+	GATE(PCLK_PMU, "pclk_pmu", "pclk_pmu_root", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 2, GFLAGS),
+	GATE(PCLK_PMU_CRU, "pclk_pmu_cru", "pclk_pmu_root", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 4, GFLAGS),
+	GATE(PCLK_PMU_GRF, "pclk_pmu_grf", "pclk_pmu_root", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 5, GFLAGS),
+	GATE(PCLK_GPIO0_IOC, "pclk_gpio0_ioc", "pclk_pmu_root", CLK_IS_CRITICAL,
+			RK3506_PMU_CLKGATE_CON(0), 7, GFLAGS),
+	GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pmu_root", 0,
+			RK3506_PMU_CLKGATE_CON(0), 8, GFLAGS),
+	COMPOSITE_NODIV(DBCLK_GPIO0, "dbclk_gpio0", dbclk_gpio0_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(0), 0, 2, MFLAGS,
+			RK3506_PMU_CLKGATE_CON(0), 9, GFLAGS),
+	GATE(PCLK_GPIO1_SHADOW, "pclk_gpio1_shadow", "pclk_pmu_root", 0,
+			RK3506_PMU_CLKGATE_CON(0), 10, GFLAGS),
+	COMPOSITE_NODIV(DBCLK_GPIO1_SHADOW, "dbclk_gpio1_shadow", dbclk_gpio0_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(0), 2, 2, MFLAGS,
+			RK3506_PMU_CLKGATE_CON(0), 11, GFLAGS),
+	GATE(PCLK_PMU_HP_TIMER, "pclk_pmu_hp_timer", "pclk_pmu_root", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 12, GFLAGS),
+	MUX(CLK_PMU_HP_TIMER, "clk_pmu_hp_timer", clk_pmu_hp_timer_parents_p, CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKSEL_CON(0), 4, 2, MFLAGS),
+	GATE(PCLK_PWM0, "pclk_pwm0", "pclk_pmu_root", 0,
+			RK3506_PMU_CLKGATE_CON(0), 15, GFLAGS),
+	COMPOSITE_NOMUX(CLK_PWM0, "clk_pwm0", "clk_gpll_div_100m", 0,
+			RK3506_PMU_CLKSEL_CON(0), 6, 4, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 0, GFLAGS),
+	GATE(CLK_OSC_PWM0, "clk_osc_pwm0", "xin24m", 0,
+			RK3506_PMU_CLKGATE_CON(1), 1, GFLAGS),
+	GATE(CLK_RC_PWM0, "clk_rc_pwm0", "clk_rc", 0,
+			RK3506_PMU_CLKGATE_CON(1), 2, GFLAGS),
+	COMPOSITE_NOMUX(CLK_MAC_OUT, "clk_mac_out", "gpll", 0,
+			RK3506_PMU_CLKSEL_CON(0), 10, 6, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 3, GFLAGS),
+	COMPOSITE(CLK_REF_OUT0, "clk_ref_out0", clk_ref_out_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(1), 6, 2, MFLAGS, 0, 6, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 4, GFLAGS),
+	COMPOSITE(CLK_REF_OUT1, "clk_ref_out1", clk_ref_out_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(1), 14, 2, MFLAGS, 8, 6, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 5, GFLAGS),
+	MUX(CLK_32K_FRAC_MUX, "clk_32k_frac_mux", clk_32k_frac_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(3), 0, 2, MFLAGS),
+	COMPOSITE_FRAC(CLK_32K_FRAC, "clk_32k_frac", "clk_32k_frac_mux", 0,
+			RK3506_PMU_CLKSEL_CON(2), 0,
+			RK3506_PMU_CLKGATE_CON(1), 6, GFLAGS),
+	COMPOSITE_NOMUX(CLK_32K_RC, "clk_32k_rc", "clk_rc", CLK_IS_CRITICAL,
+			RK3506_PMU_CLKSEL_CON(3), 2, 5, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 7, GFLAGS),
+	COMPOSITE_NODIV(CLK_32K, "clk_32k", clk_32k_parents_p, CLK_IS_CRITICAL,
+			RK3506_PMU_CLKSEL_CON(3), 7, 2, MFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 8, GFLAGS),
+	COMPOSITE_NODIV(CLK_32K_PMU, "clk_32k_pmu", clk_32k_parents_p, CLK_IS_CRITICAL,
+			RK3506_PMU_CLKSEL_CON(3), 9, 2, MFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 9, GFLAGS),
+	GATE(CLK_PMU_32K, "clk_pmu_32k", "clk_32k_pmu", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 3, GFLAGS),
+	GATE(CLK_PMU_HP_TIMER_32K, "clk_pmu_hp_timer_32k", "clk_32k_pmu", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 14, GFLAGS),
+	GATE(PCLK_TOUCH_KEY, "pclk_touch_key", "pclk_pmu_root", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(1), 12, GFLAGS),
+	GATE(CLK_TOUCH_KEY, "clk_touch_key", "xin24m", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(1), 13, GFLAGS),
+	COMPOSITE(CLK_REF_PHY_PLL, "clk_ref_phy_pll", gpll_v0pll_v1pll_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(4), 13, 2, MFLAGS, 6, 7, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 14, GFLAGS),
+	MUX(CLK_REF_PHY_PMU_MUX, "clk_ref_phy_pmu_mux", clk_ref_phy_pmu_mux_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(4), 15, 1, MFLAGS),
+	GATE(CLK_WIFI_OUT, "clk_wifi_out", "xin24m", 0,
+			RK3506_PMU_CLKGATE_CON(2), 0, GFLAGS),
+	MUX(CLK_V0PLL_REF, "clk_v0pll_ref", clk_vpll_ref_parents_p, CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKSEL_CON(6), 0, 1, MFLAGS),
+	MUX(CLK_V1PLL_REF, "clk_v1pll_ref", clk_vpll_ref_parents_p, CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKSEL_CON(6), 1, 1, MFLAGS),
+
+	/* secure ns */
+	GATE(CLK_CORE_CRYPTO_NS, "clk_core_crypto_ns", "clk_core_crypto", 0,
+			RK3506_CLKGATE_CON(5), 12, GFLAGS),
+	GATE(CLK_PKA_CRYPTO_NS, "clk_pka_crypto_ns", "clk_pka_crypto", 0,
+			RK3506_CLKGATE_CON(5), 13, GFLAGS),
+
+	/* io */
+	GATE(CLK_SPI2, "clk_spi2", "clk_spi2_io", 0,
+			RK3506_CLKGATE_CON(20), 0, GFLAGS),
+};
+
+static void __init rk3506_clk_init(struct device_node *np)
+{
+	struct rockchip_clk_provider *ctx;
+	unsigned long clk_nr_clks;
+	void __iomem *reg_base;
+
+	clk_nr_clks = rockchip_clk_find_max_clk_id(rk3506_clk_branches,
+						   ARRAY_SIZE(rk3506_clk_branches)) + 1;
+
+	reg_base = of_iomap(np, 0);
+	if (!reg_base) {
+		pr_err("%s: could not map cru region\n", __func__);
+		return;
+	}
+
+	ctx = rockchip_clk_init(np, reg_base, clk_nr_clks);
+	if (IS_ERR(ctx)) {
+		pr_err("%s: rockchip clk init failed\n", __func__);
+		iounmap(reg_base);
+		return;
+	}
+
+	rockchip_clk_register_plls(ctx, rk3506_pll_clks,
+				   ARRAY_SIZE(rk3506_pll_clks),
+				   0);
+
+	rockchip_clk_register_armclk_multi_pll(ctx, &rk3506_armclk,
+					       rk3506_cpuclk_rates,
+					       ARRAY_SIZE(rk3506_cpuclk_rates));
+
+	rockchip_clk_register_branches(ctx, rk3506_clk_branches,
+				       ARRAY_SIZE(rk3506_clk_branches));
+
+	rk3506_rst_init(np, reg_base);
+
+	rockchip_register_restart_notifier(ctx, RK3506_GLB_SRST_FST, NULL);
+
+	rockchip_clk_of_add_provider(np, ctx);
+
+	/* pvtpll src init */
+	writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RK3506_CLKSEL_CON(15));
+}
+
+CLK_OF_DECLARE(rk3506_cru, "rockchip,rk3506-cru", rk3506_clk_init);
+
+struct clk_rk3506_inits {
+	void (*inits)(struct device_node *np);
+};
+
+static const struct clk_rk3506_inits clk_rk3506_cru_init = {
+	.inits = rk3506_clk_init,
+};
+
+static const struct of_device_id clk_rk3506_match_table[] = {
+	{
+		.compatible = "rockchip,rk3506-cru",
+		.data = &clk_rk3506_cru_init,
+	},
+	{ }
+};
+
+static int clk_rk3506_probe(struct platform_device *pdev)
+{
+	const struct clk_rk3506_inits *init_data;
+	struct device *dev = &pdev->dev;
+
+	init_data = device_get_match_data(dev);
+	if (!init_data)
+		return -EINVAL;
+
+	if (init_data->inits)
+		init_data->inits(dev->of_node);
+
+	return 0;
+}
+
+static struct platform_driver clk_rk3506_driver = {
+	.probe		= clk_rk3506_probe,
+	.driver		= {
+		.name	= "clk-rk3506",
+		.of_match_table = clk_rk3506_match_table,
+		.suppress_bind_attrs = true,
+	},
+};
+builtin_platform_driver_probe(clk_rk3506_driver, clk_rk3506_probe);
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index 87f09320b942..b2fff1d13a4a 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -275,6 +275,18 @@ struct clk;
 #define RK3399_PMU_CLKGATE_CON(x)	((x) * 0x4 + 0x100)
 #define RK3399_PMU_SOFTRST_CON(x)	((x) * 0x4 + 0x110)
 
+#define RK3506_PMU_CRU_BASE		0x10000
+#define RK3506_PLL_CON(x)		((x) * 0x4 + RK3506_PMU_CRU_BASE)
+#define RK3506_CLKSEL_CON(x)		((x) * 0x4 + 0x300)
+#define RK3506_CLKGATE_CON(x)		((x) * 0x4 + 0x800)
+#define RK3506_SOFTRST_CON(x)		((x) * 0x4 + 0xa00)
+#define RK3506_PMU_CLKSEL_CON(x)	((x) * 0x4 + 0x300 + RK3506_PMU_CRU_BASE)
+#define RK3506_PMU_CLKGATE_CON(x)	((x) * 0x4 + 0x800 + RK3506_PMU_CRU_BASE)
+#define RK3506_MODE_CON			0x280
+#define RK3506_GLB_CNT_TH		0xc00
+#define RK3506_GLB_SRST_FST		0xc08
+#define RK3506_GLB_SRST_SND		0xc0c
+
 #define RK3528_PMU_CRU_BASE		0x10000
 #define RK3528_PCIE_CRU_BASE		0x20000
 #define RK3528_DDRPHY_CRU_BASE		0x28000
@@ -1329,6 +1341,7 @@ static inline void rockchip_register_softrst(struct device_node *np,
 }
 
 void rv1126b_rst_init(struct device_node *np, void __iomem *reg_base);
+void rk3506_rst_init(struct device_node *np, void __iomem *reg_base);
 void rk3528_rst_init(struct device_node *np, void __iomem *reg_base);
 void rk3562_rst_init(struct device_node *np, void __iomem *reg_base);
 void rk3576_rst_init(struct device_node *np, void __iomem *reg_base);
diff --git a/drivers/clk/rockchip/rst-rk3506.c b/drivers/clk/rockchip/rst-rk3506.c
new file mode 100644
index 000000000000..c3abde60f3c6
--- /dev/null
+++ b/drivers/clk/rockchip/rst-rk3506.c
@@ -0,0 +1,226 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2025 Rockchip Electronics Co., Ltd.
+ * Author: Finley Xiao <finley.xiao at rock-chips.com>
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <dt-bindings/reset/rockchip,rk3506-cru.h>
+#include "clk.h"
+
+/* 0xFF9A0000 + 0x0A00 */
+#define RK3506_CRU_RESET_OFFSET(id, reg, bit) [id] = (0 + reg * 16 + bit)
+
+/* mapping table for reset ID to register offset */
+static const int rk3506_register_offset[] = {
+	/* CRU-->SOFTRST_CON00 */
+	RK3506_CRU_RESET_OFFSET(SRST_NCOREPORESET0_AC, 0, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_NCOREPORESET1_AC, 0, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_NCOREPORESET2_AC, 0, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_NCORESET0_AC, 0, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_NCORESET1_AC, 0, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_NCORESET2_AC, 0, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_NL2RESET_AC, 0, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_A_CORE_BIU_AC, 0, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_H_M0_AC, 0, 10),
+
+	/* CRU-->SOFTRST_CON02 */
+	RK3506_CRU_RESET_OFFSET(SRST_NDBGRESET, 2, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_P_CORE_BIU, 2, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_PMU, 2, 15),
+
+	/* CRU-->SOFTRST_CON03 */
+	RK3506_CRU_RESET_OFFSET(SRST_P_DBG, 3, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_POT_DBG, 3, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_P_CORE_GRF, 3, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_CORE_EMA_DETECT, 3, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_REF_PVTPLL_CORE, 3, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_P_GPIO1, 3, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_DB_GPIO1, 3, 9),
+
+	/* CRU-->SOFTRST_CON04 */
+	RK3506_CRU_RESET_OFFSET(SRST_A_CORE_PERI_BIU, 4, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_A_DSMC, 4, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_P_DSMC, 4, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_FLEXBUS, 4, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_A_FLEXBUS, 4, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_H_FLEXBUS, 4, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_A_DSMC_SLV, 4, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_H_DSMC_SLV, 4, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_DSMC_SLV, 4, 13),
+
+	/* CRU-->SOFTRST_CON05 */
+	RK3506_CRU_RESET_OFFSET(SRST_A_BUS_BIU, 5, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_H_BUS_BIU, 5, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_P_BUS_BIU, 5, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_A_SYSRAM, 5, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_H_SYSRAM, 5, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_A_DMAC0, 5, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_A_DMAC1, 5, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_H_M0, 5, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_M0_JTAG, 5, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_H_CRYPTO, 5, 15),
+
+	/* CRU-->SOFTRST_CON06 */
+	RK3506_CRU_RESET_OFFSET(SRST_H_RNG, 6, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_P_BUS_GRF, 6, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_P_TIMER0, 6, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH0, 6, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH1, 6, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH2, 6, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH3, 6, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH4, 6, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH5, 6, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_P_WDT0, 6, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_T_WDT0, 6, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_P_WDT1, 6, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_T_WDT1, 6, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_P_MAILBOX, 6, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_P_INTMUX, 6, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_P_SPINLOCK, 6, 15),
+
+	/* CRU-->SOFTRST_CON07 */
+	RK3506_CRU_RESET_OFFSET(SRST_P_DDRC, 7, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_H_DDRPHY, 7, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_P_DDRMON, 7, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_DDRMON_OSC, 7, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_P_DDR_LPC, 7, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_H_USBOTG0, 7, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_USBOTG0_ADP, 7, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_H_USBOTG1, 7, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_USBOTG1_ADP, 7, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_P_USBPHY, 7, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_USBPHY_POR, 7, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_USBPHY_OTG0, 7, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_USBPHY_OTG1, 7, 14),
+
+	/* CRU-->SOFTRST_CON08 */
+	RK3506_CRU_RESET_OFFSET(SRST_A_DMA2DDR, 8, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_P_DMA2DDR, 8, 1),
+
+	/* CRU-->SOFTRST_CON09 */
+	RK3506_CRU_RESET_OFFSET(SRST_USBOTG0_UTMI, 9, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_USBOTG1_UTMI, 9, 1),
+
+	/* CRU-->SOFTRST_CON10 */
+	RK3506_CRU_RESET_OFFSET(SRST_A_DDRC_0, 10, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_A_DDRC_1, 10, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_A_DDR_BIU, 10, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_DDRC, 10, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_DDRMON, 10, 4),
+
+	/* CRU-->SOFTRST_CON11 */
+	RK3506_CRU_RESET_OFFSET(SRST_H_LSPERI_BIU, 11, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_P_UART0, 11, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_P_UART1, 11, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_P_UART2, 11, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_P_UART3, 11, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_P_UART4, 11, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_UART0, 11, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_UART1, 11, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_UART2, 11, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_UART3, 11, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_UART4, 11, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_P_I2C0, 11, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_I2C0, 11, 15),
+
+	/* CRU-->SOFTRST_CON12 */
+	RK3506_CRU_RESET_OFFSET(SRST_P_I2C1, 12, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_I2C1, 12, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_P_I2C2, 12, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_I2C2, 12, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_P_PWM1, 12, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_PWM1, 12, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_P_SPI0, 12, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_SPI0, 12, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_P_SPI1, 12, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_SPI1, 12, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_P_GPIO2, 12, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_DB_GPIO2, 12, 15),
+
+	/* CRU-->SOFTRST_CON13 */
+	RK3506_CRU_RESET_OFFSET(SRST_P_GPIO3, 13, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_DB_GPIO3, 13, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_P_GPIO4, 13, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_DB_GPIO4, 13, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_H_CAN0, 13, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_CAN0, 13, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_H_CAN1, 13, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_CAN1, 13, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_H_PDM, 13, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_M_PDM, 13, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_PDM, 13, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_SPDIFTX, 13, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_H_SPDIFTX, 13, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_H_SPDIFRX, 13, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_SPDIFRX, 13, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_M_SAI0, 13, 15),
+
+	/* CRU-->SOFTRST_CON14 */
+	RK3506_CRU_RESET_OFFSET(SRST_H_SAI0, 14, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_M_SAI1, 14, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_H_SAI1, 14, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_H_ASRC0, 14, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_ASRC0, 14, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_H_ASRC1, 14, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_ASRC1, 14, 8),
+
+	/* CRU-->SOFTRST_CON17 */
+	RK3506_CRU_RESET_OFFSET(SRST_H_HSPERI_BIU, 17, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_H_SDMMC, 17, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_H_FSPI, 17, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_S_FSPI, 17, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_P_SPI2, 17, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_A_MAC0, 17, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_A_MAC1, 17, 12),
+
+	/* CRU-->SOFTRST_CON18 */
+	RK3506_CRU_RESET_OFFSET(SRST_M_SAI2, 18, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_H_SAI2, 18, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_H_SAI3, 18, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_M_SAI3, 18, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_H_SAI4, 18, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_M_SAI4, 18, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_H_DSM, 18, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_M_DSM, 18, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_P_AUDIO_ADC, 18, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_M_AUDIO_ADC, 18, 15),
+
+	/* CRU-->SOFTRST_CON19 */
+	RK3506_CRU_RESET_OFFSET(SRST_P_SARADC, 19, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_SARADC, 19, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_SARADC_PHY, 19, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_P_OTPC_NS, 19, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_SBPI_OTPC_NS, 19, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_USER_OTPC_NS, 19, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_P_UART5, 19, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_UART5, 19, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_P_GPIO234_IOC, 19, 8),
+
+	/* CRU-->SOFTRST_CON21 */
+	RK3506_CRU_RESET_OFFSET(SRST_A_VIO_BIU, 21, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_H_VIO_BIU, 21, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_H_RGA, 21, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_A_RGA, 21, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_CORE_RGA, 21, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_A_VOP, 21, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_H_VOP, 21, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_VOP, 21, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_P_DPHY, 21, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_P_DSI_HOST, 21, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_P_TSADC, 21, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_TSADC, 21, 15),
+
+	/* CRU-->SOFTRST_CON22 */
+	RK3506_CRU_RESET_OFFSET(SRST_P_GPIO1_IOC, 22, 1),
+};
+
+void rk3506_rst_init(struct device_node *np, void __iomem *reg_base)
+{
+	rockchip_register_softrst_lut(np,
+				      rk3506_register_offset,
+				      ARRAY_SIZE(rk3506_register_offset),
+				      reg_base + RK3506_SOFTRST_CON(0),
+				      ROCKCHIP_SOFTRST_HIWORD_MASK);
+}
-- 
2.34.1



From kevin.tian at intel.com  Thu Nov 20 23:24:15 2025
From: kevin.tian at intel.com (Tian, Kevin)
Date: Fri, 21 Nov 2025 07:24:15 +0000
Subject: [PATCH v3 2/3] iommu/amd: Don't call report_iommu_fault()
In-Reply-To: <2-v3-e5d08e2d551e+109-iommu_set_fault_jgg@nvidia.com>
References: <0-v3-e5d08e2d551e+109-iommu_set_fault_jgg@nvidia.com>
 <2-v3-e5d08e2d551e+109-iommu_set_fault_jgg@nvidia.com>
Message-ID: <BN9PR11MB5276F59FE864DB7E6AE685C38CD5A@BN9PR11MB5276.namprd11.prod.outlook.com>

> From: Jason Gunthorpe <jgg at nvidia.com>
> Sent: Friday, November 21, 2025 3:46 AM
> 
> This old style API is only used by drivers/gpu/drm/msm,
> drivers/remoteproc/omap_remoteproc.c, and
> drivers/remoteproc/qcom_q6v5_adsp.c none are used on x86 HW.
> 
> Remove the dead code to discourage new users.
> 
> Also remove the domain == NULL print because it was intended to protect
> against a NULL deref inside report_iommu_fault() which is no longer
> possible.
> 
> Just always print the fault in the same format if it could get a dev_data.
> There is no value to be gained by also printing if the domain is NULL. In
> today's kernel when the dev_data is populated the domain will be made
> !NULL very quickly during iommu device probing.
> 
> Reviewed-by: Vasant Hegde <vasant.hegde at amd.com>
> Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>

Reviewed-by: Kevin Tian <kevin.tian at intel.com>


From krzk at kernel.org  Thu Nov 20 23:26:07 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Fri, 21 Nov 2025 08:26:07 +0100
Subject: [PATCH v8 1/2] dt-bindings: clock: rockchip: Add RK3506 clock
 and reset unit
In-Reply-To: <20251121024645.360615-2-zhangqing@rock-chips.com>
References: <20251121024645.360615-1-zhangqing@rock-chips.com>
 <20251121024645.360615-2-zhangqing@rock-chips.com>
Message-ID: <20251121-tunneling-quaint-copperhead-18328e@kuoka>

On Fri, Nov 21, 2025 at 10:46:44AM +0800, Elaine Zhang wrote:
> From: Finley Xiao <finley.xiao at rock-chips.com>
> 
> Add device tree bindings for clock and reset unit on RK3506 SoC.
> Add clock and reset IDs for RK3506 SoC.
> 
> Signed-off-by: Finley Xiao <finley.xiao at rock-chips.com>
> Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
> ---
>  .../bindings/clock/rockchip,rk3506-cru.yaml   |  54 ++++
>  .../dt-bindings/clock/rockchip,rk3506-cru.h   | 285 ++++++++++++++++++
>  .../dt-bindings/reset/rockchip,rk3506-cru.h   | 211 +++++++++++++
>  3 files changed, 550 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
>  create mode 100644 include/dt-bindings/clock/rockchip,rk3506-cru.h
>  create mode 100644 include/dt-bindings/reset/rockchip,rk3506-cru.h
> 
> diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml b/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
> new file mode 100644
> index 000000000000..fee49700113e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
> @@ -0,0 +1,54 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/rockchip,rk3506-cru.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Rockchip RK3506 Clock and Reset Unit (CRU)
> +
> +maintainers:
> +  - Finley Xiao <finley.xiao at rock-chips.com>
> +  - Heiko Stuebner <heiko at sntech.de>
> +
> +description:
> +  The RK3506 CRU generates the clock and also implements reset for SoC
> +  peripherals.
> +
> +properties:
> +  compatible:
> +    const: rockchip,rk3506-cru
> +
> +  reg:
> +    maxItems: 1
> +
> +  "#clock-cells":
> +    const: 1
> +
> +  "#reset-cells":
> +    const: 1
> +
> +  clocks:
> +    maxItems: 1
> +    description:
> +      Reference clock input. This is optional when the clock source
> +      has already been configured and enabled by the bootloader/firmware.

So your description confirms - this is not an optional clock. It must be
enabled/configure and it is always in the hardware. You could have
avoided one more version of patchset if you only bothered to respond to
review.

Drop description and make it required.

> +
> +  clock-names:
> +    const: xin24m

Nothing improved. Conor made comments some revisions ago and reminded
you about them. And you just ignored them?

That's just xin pin, isn't it?

> +
> +required:
> +  - compatible
> +  - reg
> +  - "#clock-cells"
> +  - "#reset-cells"

clocks and clock-names.

Best regards,
Krzysztof



From zhangqing at rock-chips.com  Thu Nov 20 23:53:48 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Fri, 21 Nov 2025 15:53:48 +0800
Subject: [PATCH v9 0/2] clk: rockchip: Add clock controller for the RK3506
Message-ID: <20251121075350.2564860-1-zhangqing@rock-chips.com>

[PATCH 1/5] ~ [PATCH 3/5] has applied.

Change in V9:
[PATCH v9 1/2]: Fix "clocks"
[PATCH v9 2/2]: No change

Change in V8:
[PATCH v8 1/2]: Add explanations for "clocks"
[PATCH v8 2/2]: No change

Change in V7:
[PATCH v7 1/5]: No change
[PATCH v7 2/5]: Redefine clk id(start at 0), drop RESETN for reset id.
[PATCH v7 3/5]: Drop RESETN for reset id.
[PATCH v7 4/5]: Fix "description: |", drop RESETN for reset id.
[PATCH v7 5/5]: Drop RESETN for reset id.

Change in V6:
Drop pvtpll, others no change.
There are many questions about pvtpll and have some dependency issues.
They will be submitted separately later.

Change in V5:
[PATCH v5 1/7]: No change
[PATCH v5 2/7]: No change
[PATCH v5 3/7]: Drop RV1126B_GRF_SOC_STATUS0
[PATCH v5 4/7]: Drop syscon
[PATCH v5 5/7]: No change
[PATCH v5 6/7]: Add clocks and clock-names, fix id define
[PATCH v5 7/7]: Drop RK3506_GRF_SOC_STATUS

Change in V4:
[PATCH v4 1/7]: No change
[PATCH v4 2/7]: remove label
[PATCH v4 3/7]: No change
[PATCH v4 4/7]: remove label,fix order
[PATCH v4 5/7]: No change
[PATCH v4 6/7]: Add yaml and dt-bindings for the RK3506
[PATCH v4 7/7]: Add clock controller for the RK3506

Change in V3:
[PATCH v3 1/5]: No change
[PATCH v3 2/5]: Fix define error
[PATCH v3 3/5]: update driver,fix errir
[PATCH v3 4/5]: fix error
[PATCH v3 5/5]: No change

Change in V2:
[PATCH v2 1/5]: update commit message, rename v2 to multi_pll
[PATCH v2 2/5]: Modify DT binding headers license
[PATCH v2 3/5]: update driver
[PATCH v2 4/5]: fix error
[PATCH v2 5/5]: update commit message

Elaine Zhang (1):
  clk: rockchip: Add clock and reset driver for RK3506

Finley Xiao (1):
  dt-bindings: clock: rockchip: Add RK3506 clock and reset unit

 .../bindings/clock/rockchip,rk3506-cru.yaml   |  55 ++
 drivers/clk/rockchip/Kconfig                  |   7 +
 drivers/clk/rockchip/Makefile                 |   1 +
 drivers/clk/rockchip/clk-rk3506.c             | 869 ++++++++++++++++++
 drivers/clk/rockchip/clk.h                    |  13 +
 drivers/clk/rockchip/rst-rk3506.c             | 226 +++++
 .../dt-bindings/clock/rockchip,rk3506-cru.h   | 285 ++++++
 .../dt-bindings/reset/rockchip,rk3506-cru.h   | 211 +++++
 8 files changed, 1667 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
 create mode 100644 drivers/clk/rockchip/clk-rk3506.c
 create mode 100644 drivers/clk/rockchip/rst-rk3506.c
 create mode 100644 include/dt-bindings/clock/rockchip,rk3506-cru.h
 create mode 100644 include/dt-bindings/reset/rockchip,rk3506-cru.h


base-commit: 4f0744c46de2c40e7a8f35d730e322bf33f2bb63
-- 
2.34.1



From zhangqing at rock-chips.com  Thu Nov 20 23:53:49 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Fri, 21 Nov 2025 15:53:49 +0800
Subject: [PATCH v9 1/2] dt-bindings: clock: rockchip: Add RK3506 clock and reset unit
In-Reply-To: <20251121075350.2564860-1-zhangqing@rock-chips.com>
References: <20251121075350.2564860-1-zhangqing@rock-chips.com>
Message-ID: <20251121075350.2564860-2-zhangqing@rock-chips.com>

From: Finley Xiao <finley.xiao at rock-chips.com>

Add device tree bindings for clock and reset unit on RK3506 SoC.
Add clock and reset IDs for RK3506 SoC.

Signed-off-by: Finley Xiao <finley.xiao at rock-chips.com>
Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
---
 .../bindings/clock/rockchip,rk3506-cru.yaml   |  55 ++++
 .../dt-bindings/clock/rockchip,rk3506-cru.h   | 285 ++++++++++++++++++
 .../dt-bindings/reset/rockchip,rk3506-cru.h   | 211 +++++++++++++
 3 files changed, 551 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
 create mode 100644 include/dt-bindings/clock/rockchip,rk3506-cru.h
 create mode 100644 include/dt-bindings/reset/rockchip,rk3506-cru.h

diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml b/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
new file mode 100644
index 000000000000..ca940475336c
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
@@ -0,0 +1,55 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/rockchip,rk3506-cru.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip RK3506 Clock and Reset Unit (CRU)
+
+maintainers:
+  - Finley Xiao <finley.xiao at rock-chips.com>
+  - Heiko Stuebner <heiko at sntech.de>
+
+description:
+  The RK3506 CRU generates the clock and also implements reset for SoC
+  peripherals.
+
+properties:
+  compatible:
+    const: rockchip,rk3506-cru
+
+  reg:
+    maxItems: 1
+
+  "#clock-cells":
+    const: 1
+
+  "#reset-cells":
+    const: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    const: xin
+
+required:
+  - compatible
+  - reg
+  - "#clock-cells"
+  - "#reset-cells"
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller at ff9a0000 {
+      compatible = "rockchip,rk3506-cru";
+      reg = <0xff9a0000 0x20000>;
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      clocks = <&xin24m>;
+      clock-names = "xin";
+    };
diff --git a/include/dt-bindings/clock/rockchip,rk3506-cru.h b/include/dt-bindings/clock/rockchip,rk3506-cru.h
new file mode 100644
index 000000000000..71d7dda23cc9
--- /dev/null
+++ b/include/dt-bindings/clock/rockchip,rk3506-cru.h
@@ -0,0 +1,285 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2023-2025 Rockchip Electronics Co., Ltd.
+ * Author: Finley Xiao <finley.xiao at rock-chips.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3506_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_RK3506_H
+
+/* cru plls */
+#define PLL_GPLL			0
+#define PLL_V0PLL			1
+#define PLL_V1PLL			2
+
+/* cru-clocks indices */
+#define ARMCLK				3
+#define CLK_DDR				4
+#define XIN24M_GATE			5
+#define CLK_GPLL_GATE			6
+#define CLK_V0PLL_GATE			7
+#define CLK_V1PLL_GATE			8
+#define CLK_GPLL_DIV			9
+#define CLK_GPLL_DIV_100M		10
+#define CLK_V0PLL_DIV			11
+#define CLK_V1PLL_DIV			12
+#define CLK_INT_VOICE_MATRIX0		13
+#define CLK_INT_VOICE_MATRIX1		14
+#define CLK_INT_VOICE_MATRIX2		15
+#define CLK_FRAC_UART_MATRIX0_MUX	16
+#define CLK_FRAC_UART_MATRIX1_MUX	17
+#define CLK_FRAC_VOICE_MATRIX0_MUX	18
+#define CLK_FRAC_VOICE_MATRIX1_MUX	19
+#define CLK_FRAC_COMMON_MATRIX0_MUX	20
+#define CLK_FRAC_COMMON_MATRIX1_MUX	21
+#define CLK_FRAC_COMMON_MATRIX2_MUX	22
+#define CLK_FRAC_UART_MATRIX0		23
+#define CLK_FRAC_UART_MATRIX1		24
+#define CLK_FRAC_VOICE_MATRIX0		25
+#define CLK_FRAC_VOICE_MATRIX1		26
+#define CLK_FRAC_COMMON_MATRIX0		27
+#define CLK_FRAC_COMMON_MATRIX1		28
+#define CLK_FRAC_COMMON_MATRIX2		29
+#define CLK_REF_USBPHY_TOP		30
+#define CLK_REF_DPHY_TOP		31
+#define ACLK_CORE_ROOT			32
+#define PCLK_CORE_ROOT			33
+#define PCLK_DBG			34
+#define PCLK_CORE_GRF			35
+#define PCLK_CORE_CRU			36
+#define CLK_CORE_EMA_DETECT		37
+#define CLK_REF_PVTPLL_CORE		38
+#define PCLK_GPIO1			39
+#define DBCLK_GPIO1			40
+#define ACLK_CORE_PERI_ROOT		41
+#define HCLK_CORE_PERI_ROOT		42
+#define PCLK_CORE_PERI_ROOT		43
+#define CLK_DSMC			44
+#define ACLK_DSMC			45
+#define PCLK_DSMC			46
+#define CLK_FLEXBUS_TX			47
+#define CLK_FLEXBUS_RX			48
+#define ACLK_FLEXBUS			49
+#define HCLK_FLEXBUS			50
+#define ACLK_DSMC_SLV			51
+#define HCLK_DSMC_SLV			52
+#define ACLK_BUS_ROOT			53
+#define HCLK_BUS_ROOT			54
+#define PCLK_BUS_ROOT			55
+#define ACLK_SYSRAM			56
+#define HCLK_SYSRAM			57
+#define ACLK_DMAC0			58
+#define ACLK_DMAC1			59
+#define HCLK_M0				60
+#define PCLK_BUS_GRF			61
+#define PCLK_TIMER			62
+#define CLK_TIMER0_CH0			63
+#define CLK_TIMER0_CH1			64
+#define CLK_TIMER0_CH2			65
+#define CLK_TIMER0_CH3			66
+#define CLK_TIMER0_CH4			67
+#define CLK_TIMER0_CH5			68
+#define PCLK_WDT0			69
+#define TCLK_WDT0			70
+#define PCLK_WDT1			71
+#define TCLK_WDT1			72
+#define PCLK_MAILBOX			73
+#define PCLK_INTMUX			74
+#define PCLK_SPINLOCK			75
+#define PCLK_DDRC			76
+#define HCLK_DDRPHY			77
+#define PCLK_DDRMON			78
+#define CLK_DDRMON_OSC			79
+#define PCLK_STDBY			80
+#define HCLK_USBOTG0			81
+#define HCLK_USBOTG0_PMU		82
+#define CLK_USBOTG0_ADP			83
+#define HCLK_USBOTG1			84
+#define HCLK_USBOTG1_PMU		85
+#define CLK_USBOTG1_ADP			86
+#define PCLK_USBPHY			87
+#define ACLK_DMA2DDR			88
+#define PCLK_DMA2DDR			89
+#define STCLK_M0			90
+#define CLK_DDRPHY			91
+#define CLK_DDRC_SRC			92
+#define ACLK_DDRC_0			93
+#define ACLK_DDRC_1			94
+#define CLK_DDRC			95
+#define CLK_DDRMON			96
+#define HCLK_LSPERI_ROOT		97
+#define PCLK_LSPERI_ROOT		98
+#define PCLK_UART0			99
+#define PCLK_UART1			100
+#define PCLK_UART2			101
+#define PCLK_UART3			102
+#define PCLK_UART4			103
+#define SCLK_UART0			104
+#define SCLK_UART1			105
+#define SCLK_UART2			106
+#define SCLK_UART3			107
+#define SCLK_UART4			108
+#define PCLK_I2C0			109
+#define CLK_I2C0			110
+#define PCLK_I2C1			111
+#define CLK_I2C1			112
+#define PCLK_I2C2			113
+#define CLK_I2C2			114
+#define PCLK_PWM1			115
+#define CLK_PWM1			116
+#define CLK_OSC_PWM1			117
+#define CLK_RC_PWM1			118
+#define CLK_FREQ_PWM1			119
+#define CLK_COUNTER_PWM1		120
+#define PCLK_SPI0			121
+#define CLK_SPI0			122
+#define PCLK_SPI1			123
+#define CLK_SPI1			124
+#define PCLK_GPIO2			125
+#define DBCLK_GPIO2			126
+#define PCLK_GPIO3			127
+#define DBCLK_GPIO3			128
+#define PCLK_GPIO4			129
+#define DBCLK_GPIO4			130
+#define HCLK_CAN0			131
+#define CLK_CAN0			132
+#define HCLK_CAN1			133
+#define CLK_CAN1			134
+#define HCLK_PDM			135
+#define MCLK_PDM			136
+#define CLKOUT_PDM			137
+#define MCLK_SPDIFTX			138
+#define HCLK_SPDIFTX			139
+#define HCLK_SPDIFRX			140
+#define MCLK_SPDIFRX			141
+#define MCLK_SAI0			142
+#define HCLK_SAI0			143
+#define MCLK_OUT_SAI0			144
+#define MCLK_SAI1			145
+#define HCLK_SAI1			146
+#define MCLK_OUT_SAI1			147
+#define HCLK_ASRC0			148
+#define CLK_ASRC0			149
+#define HCLK_ASRC1			150
+#define CLK_ASRC1			151
+#define PCLK_CRU			152
+#define PCLK_PMU_ROOT			153
+#define MCLK_ASRC0			154
+#define MCLK_ASRC1			155
+#define MCLK_ASRC2			156
+#define MCLK_ASRC3			157
+#define LRCK_ASRC0_SRC			158
+#define LRCK_ASRC0_DST			159
+#define LRCK_ASRC1_SRC			160
+#define LRCK_ASRC1_DST			161
+#define ACLK_HSPERI_ROOT		162
+#define HCLK_HSPERI_ROOT		163
+#define PCLK_HSPERI_ROOT		164
+#define CCLK_SRC_SDMMC			165
+#define HCLK_SDMMC			166
+#define HCLK_FSPI			167
+#define SCLK_FSPI			168
+#define PCLK_SPI2			169
+#define ACLK_MAC0			170
+#define ACLK_MAC1			171
+#define PCLK_MAC0			172
+#define PCLK_MAC1			173
+#define CLK_MAC_ROOT			174
+#define CLK_MAC0			175
+#define CLK_MAC1			176
+#define MCLK_SAI2			177
+#define HCLK_SAI2			178
+#define MCLK_OUT_SAI2			179
+#define MCLK_SAI3_SRC			180
+#define HCLK_SAI3			181
+#define MCLK_SAI3			182
+#define MCLK_OUT_SAI3			183
+#define MCLK_SAI4_SRC			184
+#define HCLK_SAI4			185
+#define MCLK_SAI4			186
+#define HCLK_DSM			187
+#define MCLK_DSM			188
+#define PCLK_AUDIO_ADC			189
+#define MCLK_AUDIO_ADC			190
+#define MCLK_AUDIO_ADC_DIV4		191
+#define PCLK_SARADC			192
+#define CLK_SARADC			193
+#define PCLK_OTPC_NS			194
+#define CLK_SBPI_OTPC_NS		195
+#define CLK_USER_OTPC_NS		196
+#define PCLK_UART5			197
+#define SCLK_UART5			198
+#define PCLK_GPIO234_IOC		199
+#define CLK_MAC_PTP_ROOT		200
+#define CLK_MAC0_PTP			201
+#define CLK_MAC1_PTP			202
+#define CLK_SPI2			203
+#define ACLK_VIO_ROOT			204
+#define HCLK_VIO_ROOT			205
+#define PCLK_VIO_ROOT			206
+#define HCLK_RGA			207
+#define ACLK_RGA			208
+#define CLK_CORE_RGA			209
+#define ACLK_VOP			210
+#define HCLK_VOP			211
+#define DCLK_VOP			212
+#define PCLK_DPHY			213
+#define PCLK_DSI_HOST			214
+#define PCLK_TSADC			215
+#define CLK_TSADC			216
+#define CLK_TSADC_TSEN			217
+#define PCLK_GPIO1_IOC			218
+#define PCLK_OTPC_S			219
+#define CLK_SBPI_OTPC_S			220
+#define CLK_USER_OTPC_S			221
+#define PCLK_OTP_MASK			222
+#define PCLK_KEYREADER			223
+#define HCLK_BOOTROM			224
+#define PCLK_DDR_SERVICE		225
+#define HCLK_CRYPTO_S			226
+#define HCLK_KEYLAD			227
+#define CLK_CORE_CRYPTO			228
+#define CLK_PKA_CRYPTO			229
+#define CLK_CORE_CRYPTO_S		230
+#define CLK_PKA_CRYPTO_S		231
+#define ACLK_CRYPTO_S			232
+#define HCLK_RNG_S			233
+#define CLK_CORE_CRYPTO_NS		234
+#define CLK_PKA_CRYPTO_NS		235
+#define ACLK_CRYPTO_NS			236
+#define HCLK_CRYPTO_NS			237
+#define HCLK_RNG			238
+#define CLK_PMU				239
+#define PCLK_PMU			240
+#define CLK_PMU_32K			241
+#define PCLK_PMU_CRU			242
+#define PCLK_PMU_GRF			243
+#define PCLK_GPIO0_IOC			244
+#define PCLK_GPIO0			245
+#define DBCLK_GPIO0			246
+#define PCLK_GPIO1_SHADOW		247
+#define DBCLK_GPIO1_SHADOW		248
+#define PCLK_PMU_HP_TIMER		249
+#define CLK_PMU_HP_TIMER		250
+#define CLK_PMU_HP_TIMER_32K		251
+#define PCLK_PWM0			252
+#define CLK_PWM0			253
+#define CLK_OSC_PWM0			254
+#define CLK_RC_PWM0			255
+#define CLK_MAC_OUT			256
+#define CLK_REF_OUT0			257
+#define CLK_REF_OUT1			258
+#define CLK_32K_FRAC			259
+#define CLK_32K_RC			260
+#define CLK_32K				261
+#define CLK_32K_PMU			262
+#define PCLK_TOUCH_KEY			263
+#define CLK_TOUCH_KEY			264
+#define CLK_REF_PHY_PLL			265
+#define CLK_REF_PHY_PMU_MUX		266
+#define CLK_WIFI_OUT			267
+#define CLK_V0PLL_REF			268
+#define CLK_V1PLL_REF			269
+#define CLK_32K_FRAC_MUX		270
+
+#endif
diff --git a/include/dt-bindings/reset/rockchip,rk3506-cru.h b/include/dt-bindings/reset/rockchip,rk3506-cru.h
new file mode 100644
index 000000000000..31c0d4aa410f
--- /dev/null
+++ b/include/dt-bindings/reset/rockchip,rk3506-cru.h
@@ -0,0 +1,211 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2023-2025 Rockchip Electronics Co., Ltd.
+ * Author: Finley Xiao <finley.xiao at rock-chips.com>
+ */
+
+#ifndef _DT_BINDINGS_REST_ROCKCHIP_RK3506_H
+#define _DT_BINDINGS_REST_ROCKCHIP_RK3506_H
+
+/* CRU-->SOFTRST_CON00 */
+#define SRST_NCOREPORESET0_AC	0
+#define SRST_NCOREPORESET1_AC	1
+#define SRST_NCOREPORESET2_AC	2
+#define SRST_NCORESET0_AC	3
+#define SRST_NCORESET1_AC	4
+#define SRST_NCORESET2_AC	5
+#define SRST_NL2RESET_AC	6
+#define SRST_A_CORE_BIU_AC	7
+#define SRST_H_M0_AC		8
+
+/* CRU-->SOFTRST_CON02 */
+#define SRST_NDBGRESET		9
+#define SRST_P_CORE_BIU		10
+#define SRST_PMU		11
+
+/* CRU-->SOFTRST_CON03 */
+#define SRST_P_DBG		12
+#define SRST_POT_DBG		13
+#define SRST_P_CORE_GRF		14
+#define SRST_CORE_EMA_DETECT	15
+#define SRST_REF_PVTPLL_CORE	16
+#define SRST_P_GPIO1		17
+#define SRST_DB_GPIO1		18
+
+/* CRU-->SOFTRST_CON04 */
+#define SRST_A_CORE_PERI_BIU	19
+#define SRST_A_DSMC		20
+#define SRST_P_DSMC		21
+#define SRST_FLEXBUS		22
+#define SRST_A_FLEXBUS		23
+#define SRST_H_FLEXBUS		24
+#define SRST_A_DSMC_SLV		25
+#define SRST_H_DSMC_SLV		26
+#define SRST_DSMC_SLV		27
+
+/* CRU-->SOFTRST_CON05 */
+#define SRST_A_BUS_BIU		28
+#define SRST_H_BUS_BIU		29
+#define SRST_P_BUS_BIU		30
+#define SRST_A_SYSRAM		31
+#define SRST_H_SYSRAM		32
+#define SRST_A_DMAC0		33
+#define SRST_A_DMAC1		34
+#define SRST_H_M0		35
+#define SRST_M0_JTAG		36
+#define SRST_H_CRYPTO		37
+
+/* CRU-->SOFTRST_CON06 */
+#define SRST_H_RNG		38
+#define SRST_P_BUS_GRF		39
+#define SRST_P_TIMER0		40
+#define SRST_TIMER0_CH0		41
+#define SRST_TIMER0_CH1		42
+#define SRST_TIMER0_CH2		43
+#define SRST_TIMER0_CH3		44
+#define SRST_TIMER0_CH4		45
+#define SRST_TIMER0_CH5		46
+#define SRST_P_WDT0		47
+#define SRST_T_WDT0		48
+#define SRST_P_WDT1		49
+#define SRST_T_WDT1		50
+#define SRST_P_MAILBOX		51
+#define SRST_P_INTMUX		52
+#define SRST_P_SPINLOCK		53
+
+/* CRU-->SOFTRST_CON07 */
+#define SRST_P_DDRC		54
+#define SRST_H_DDRPHY		55
+#define SRST_P_DDRMON		56
+#define SRST_DDRMON_OSC		57
+#define SRST_P_DDR_LPC		58
+#define SRST_H_USBOTG0		59
+#define SRST_USBOTG0_ADP	60
+#define SRST_H_USBOTG1		61
+#define SRST_USBOTG1_ADP	62
+#define SRST_P_USBPHY		63
+#define SRST_USBPHY_POR		64
+#define SRST_USBPHY_OTG0	65
+#define SRST_USBPHY_OTG1	66
+
+/* CRU-->SOFTRST_CON08 */
+#define SRST_A_DMA2DDR		67
+#define SRST_P_DMA2DDR		68
+
+/* CRU-->SOFTRST_CON09 */
+#define SRST_USBOTG0_UTMI	69
+#define SRST_USBOTG1_UTMI	70
+
+/* CRU-->SOFTRST_CON10 */
+#define SRST_A_DDRC_0		71
+#define SRST_A_DDRC_1		72
+#define SRST_A_DDR_BIU		73
+#define SRST_DDRC		74
+#define SRST_DDRMON		75
+
+/* CRU-->SOFTRST_CON11 */
+#define SRST_H_LSPERI_BIU	76
+#define SRST_P_UART0		77
+#define SRST_P_UART1		78
+#define SRST_P_UART2		79
+#define SRST_P_UART3		80
+#define SRST_P_UART4		81
+#define SRST_UART0		82
+#define SRST_UART1		83
+#define SRST_UART2		84
+#define SRST_UART3		85
+#define SRST_UART4		86
+#define SRST_P_I2C0		87
+#define SRST_I2C0		88
+
+/* CRU-->SOFTRST_CON12 */
+#define SRST_P_I2C1		89
+#define SRST_I2C1		90
+#define SRST_P_I2C2		91
+#define SRST_I2C2		92
+#define SRST_P_PWM1		93
+#define SRST_PWM1		94
+#define SRST_P_SPI0		95
+#define SRST_SPI0		96
+#define SRST_P_SPI1		97
+#define SRST_SPI1		98
+#define SRST_P_GPIO2		99
+#define SRST_DB_GPIO2		100
+
+/* CRU-->SOFTRST_CON13 */
+#define SRST_P_GPIO3		101
+#define SRST_DB_GPIO3		102
+#define SRST_P_GPIO4		103
+#define SRST_DB_GPIO4		104
+#define SRST_H_CAN0		105
+#define SRST_CAN0		106
+#define SRST_H_CAN1		107
+#define SRST_CAN1		108
+#define SRST_H_PDM		109
+#define SRST_M_PDM		110
+#define SRST_PDM		111
+#define SRST_SPDIFTX		112
+#define SRST_H_SPDIFTX		113
+#define SRST_H_SPDIFRX		114
+#define SRST_SPDIFRX		115
+#define SRST_M_SAI0		116
+
+/* CRU-->SOFTRST_CON14 */
+#define SRST_H_SAI0		117
+#define SRST_M_SAI1		118
+#define SRST_H_SAI1		119
+#define SRST_H_ASRC0		120
+#define SRST_ASRC0		121
+#define SRST_H_ASRC1		122
+#define SRST_ASRC1		123
+
+/* CRU-->SOFTRST_CON17 */
+#define SRST_H_HSPERI_BIU	124
+#define SRST_H_SDMMC		125
+#define SRST_H_FSPI		126
+#define SRST_S_FSPI		127
+#define SRST_P_SPI2		128
+#define SRST_A_MAC0		129
+#define SRST_A_MAC1		130
+
+/* CRU-->SOFTRST_CON18 */
+#define SRST_M_SAI2		131
+#define SRST_H_SAI2		132
+#define SRST_H_SAI3		133
+#define SRST_M_SAI3		134
+#define SRST_H_SAI4		135
+#define SRST_M_SAI4		136
+#define SRST_H_DSM		137
+#define SRST_M_DSM		138
+#define SRST_P_AUDIO_ADC	139
+#define SRST_M_AUDIO_ADC	140
+
+/* CRU-->SOFTRST_CON19 */
+#define SRST_P_SARADC		141
+#define SRST_SARADC		142
+#define SRST_SARADC_PHY		143
+#define SRST_P_OTPC_NS		144
+#define SRST_SBPI_OTPC_NS	145
+#define SRST_USER_OTPC_NS	146
+#define SRST_P_UART5		147
+#define SRST_UART5		148
+#define SRST_P_GPIO234_IOC	149
+
+/* CRU-->SOFTRST_CON21 */
+#define SRST_A_VIO_BIU		150
+#define SRST_H_VIO_BIU		151
+#define SRST_H_RGA		152
+#define SRST_A_RGA		153
+#define SRST_CORE_RGA		154
+#define SRST_A_VOP		155
+#define SRST_H_VOP		156
+#define SRST_VOP		157
+#define SRST_P_DPHY		158
+#define SRST_P_DSI_HOST		159
+#define SRST_P_TSADC		160
+#define SRST_TSADC		161
+
+/* CRU-->SOFTRST_CON22 */
+#define SRST_P_GPIO1_IOC	162
+
+#endif
-- 
2.34.1



From zhangqing at rock-chips.com  Thu Nov 20 23:53:50 2025
From: zhangqing at rock-chips.com (Elaine Zhang)
Date: Fri, 21 Nov 2025 15:53:50 +0800
Subject: [PATCH v9 2/2] clk: rockchip: Add clock and reset driver for RK3506
In-Reply-To: <20251121075350.2564860-1-zhangqing@rock-chips.com>
References: <20251121075350.2564860-1-zhangqing@rock-chips.com>
Message-ID: <20251121075350.2564860-3-zhangqing@rock-chips.com>

Add the clock and reset tree definitions for the new
RK3506 SoC.

Signed-off-by: Finley Xiao <finley.xiao at rock-chips.com>
Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>
---
 drivers/clk/rockchip/Kconfig      |   7 +
 drivers/clk/rockchip/Makefile     |   1 +
 drivers/clk/rockchip/clk-rk3506.c | 869 ++++++++++++++++++++++++++++++
 drivers/clk/rockchip/clk.h        |  13 +
 drivers/clk/rockchip/rst-rk3506.c | 226 ++++++++
 5 files changed, 1116 insertions(+)
 create mode 100644 drivers/clk/rockchip/clk-rk3506.c
 create mode 100644 drivers/clk/rockchip/rst-rk3506.c

diff --git a/drivers/clk/rockchip/Kconfig b/drivers/clk/rockchip/Kconfig
index e1ea0a098ca9..5cf1e0fd6fb3 100644
--- a/drivers/clk/rockchip/Kconfig
+++ b/drivers/clk/rockchip/Kconfig
@@ -100,6 +100,13 @@ config CLK_RK3399
 	help
 	  Build the driver for RK3399 Clock Driver.
 
+config CLK_RK3506
+	bool "Rockchip RK3506 clock controller support"
+	depends on ARM || COMPILE_TEST
+	default y
+	help
+	  Build the driver for RK3506 Clock Driver.
+
 config CLK_RK3528
 	bool "Rockchip RK3528 clock controller support"
 	depends on ARM64 || COMPILE_TEST
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index 82b4b29ad036..4d8cbb2044c7 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_CLK_RK3308)        += clk-rk3308.o
 obj-$(CONFIG_CLK_RK3328)        += clk-rk3328.o
 obj-$(CONFIG_CLK_RK3368)        += clk-rk3368.o
 obj-$(CONFIG_CLK_RK3399)        += clk-rk3399.o
+obj-$(CONFIG_CLK_RK3506)	+= clk-rk3506.o rst-rk3506.o
 obj-$(CONFIG_CLK_RK3528)	+= clk-rk3528.o rst-rk3528.o
 obj-$(CONFIG_CLK_RK3562)	+= clk-rk3562.o rst-rk3562.o
 obj-$(CONFIG_CLK_RK3568)	+= clk-rk3568.o
diff --git a/drivers/clk/rockchip/clk-rk3506.c b/drivers/clk/rockchip/clk-rk3506.c
new file mode 100644
index 000000000000..dd59bd60382e
--- /dev/null
+++ b/drivers/clk/rockchip/clk-rk3506.c
@@ -0,0 +1,869 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023-2025 Rockchip Electronics Co., Ltd.
+ * Author: Finley Xiao <finley.xiao at rock-chips.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/syscore_ops.h>
+#include <dt-bindings/clock/rockchip,rk3506-cru.h>
+#include "clk.h"
+
+#define PVTPLL_SRC_SEL_PVTPLL		(BIT(7) | BIT(23))
+
+enum rk3506_plls {
+	gpll, v0pll, v1pll,
+};
+
+/*
+ * [FRAC PLL]: GPLL, V0PLL, V1PLL
+ *   - VCO Frequency: 950MHz to 3800MHZ
+ *   - Output Frequency: 19MHz to 3800MHZ
+ *   - refdiv: 1 to 63 (Int Mode), 1 to 2 (Frac Mode)
+ *   - fbdiv: 16 to 3800 (Int Mode), 20 to 380 (Frac Mode)
+ *   - post1div: 1 to 7
+ *   - post2div: 1 to 7
+ */
+static struct rockchip_pll_rate_table rk3506_pll_rates[] = {
+	/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
+	RK3036_PLL_RATE(1896000000, 1, 79, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1800000000, 1, 75, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1704000000, 1, 71, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1512000000, 1, 63, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1350000000, 4, 225, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1179648000, 1, 49, 1, 1, 0, 2550137),
+	RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1000000000, 3, 125, 1, 1, 1, 0),
+	RK3036_PLL_RATE(993484800, 1, 41, 1, 1, 0, 6630355),
+	RK3036_PLL_RATE(983040000, 1, 40, 1, 1, 0, 16106127),
+	RK3036_PLL_RATE(960000000, 1, 80, 2, 1, 1, 0),
+	RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0),
+	RK3036_PLL_RATE(903168000, 1, 75, 2, 1, 0, 4429185),
+	RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
+	RK3036_PLL_RATE(800000000, 3, 200, 2, 1, 1, 0),
+	RK3036_PLL_RATE(600000000, 1, 50, 2, 1, 1, 0),
+	RK3036_PLL_RATE(594000000, 2, 99, 2, 1, 1, 0),
+	RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0),
+	RK3036_PLL_RATE(312000000, 1, 78, 6, 1, 1, 0),
+	RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0),
+	RK3036_PLL_RATE(96000000, 1, 48, 6, 2, 1, 0),
+	{ /* sentinel */ },
+};
+
+#define RK3506_DIV_ACLK_CORE_MASK	0xf
+#define RK3506_DIV_ACLK_CORE_SHIFT	9
+#define RK3506_DIV_PCLK_CORE_MASK	0xf
+#define RK3506_DIV_PCLK_CORE_SHIFT	0
+
+#define RK3506_CLKSEL15(_aclk_core_div)					\
+{									\
+	.reg = RK3506_CLKSEL_CON(15),					\
+	.val = HIWORD_UPDATE(_aclk_core_div, RK3506_DIV_ACLK_CORE_MASK,	\
+			     RK3506_DIV_ACLK_CORE_SHIFT),		\
+}
+
+#define RK3506_CLKSEL16(_pclk_core_div)					\
+{									\
+	.reg = RK3506_CLKSEL_CON(16),					\
+	.val = HIWORD_UPDATE(_pclk_core_div, RK3506_DIV_PCLK_CORE_MASK,	\
+			     RK3506_DIV_PCLK_CORE_SHIFT),		\
+}
+
+/* SIGN-OFF: aclk_core: 500M, pclk_core: 125M, */
+#define RK3506_CPUCLK_RATE(_prate, _aclk_core_div, _pclk_core_div)	\
+{									\
+	.prate = _prate,						\
+	.divs = {							\
+		RK3506_CLKSEL15(_aclk_core_div),			\
+		RK3506_CLKSEL16(_pclk_core_div),			\
+	},								\
+}
+
+static struct rockchip_cpuclk_rate_table rk3506_cpuclk_rates[] __initdata = {
+	RK3506_CPUCLK_RATE(1608000000, 3, 12),
+	RK3506_CPUCLK_RATE(1512000000, 3, 12),
+	RK3506_CPUCLK_RATE(1416000000, 2, 11),
+	RK3506_CPUCLK_RATE(1296000000, 2, 10),
+	RK3506_CPUCLK_RATE(1200000000, 2, 9),
+	RK3506_CPUCLK_RATE(1179648000, 2, 9),
+	RK3506_CPUCLK_RATE(1008000000, 1, 7),
+	RK3506_CPUCLK_RATE(903168000, 1, 7),
+	RK3506_CPUCLK_RATE(800000000, 1, 6),
+	RK3506_CPUCLK_RATE(750000000, 1, 5),
+	RK3506_CPUCLK_RATE(589824000, 1, 4),
+	RK3506_CPUCLK_RATE(400000000, 1, 3),
+	RK3506_CPUCLK_RATE(200000000, 1, 1),
+};
+
+PNAME(mux_pll_p)				= { "xin24m" };
+PNAME(gpll_v0pll_v1pll_parents_p)		= { "gpll", "v0pll", "v1pll" };
+PNAME(gpll_v0pll_v1pll_g_parents_p)		= { "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate" };
+PNAME(gpll_v0pll_v1pll_div_parents_p)		= { "clk_gpll_div", "clk_v0pll_div", "clk_v1pll_div" };
+PNAME(xin24m_gpll_v0pll_v1pll_g_parents_p)	= { "xin24m", "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate" };
+PNAME(xin24m_g_gpll_v0pll_v1pll_g_parents_p)	= { "xin24m_gate", "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate" };
+PNAME(xin24m_g_gpll_v0pll_v1pll_div_parents_p)	= { "xin24m_gate", "clk_gpll_div", "clk_v0pll_div", "clk_v1pll_div" };
+PNAME(xin24m_400k_32k_parents_p)		= { "xin24m", "clk_rc", "clk_32k" };
+PNAME(clk_frac_uart_matrix0_mux_parents_p)	= { "xin24m", "gpll", "clk_v0pll_gate", "clk_v1pll_gate" };
+PNAME(clk_timer0_parents_p)			= { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai0_mclk_in", "sai0_sclk_in" };
+PNAME(clk_timer1_parents_p)			= { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai1_mclk_in", "sai1_sclk_in" };
+PNAME(clk_timer2_parents_p)			= { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai2_mclk_in", "sai2_sclk_in" };
+PNAME(clk_timer3_parents_p)			= { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai3_mclk_in", "sai3_sclk_in" };
+PNAME(clk_timer4_parents_p)			= { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "mclk_asrc0" };
+PNAME(clk_timer5_parents_p)			= { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "mclk_asrc1" };
+PNAME(sclk_uart_parents_p)			= { "xin24m", "clk_gpll_gate", "clk_v0pll_gate", "clk_frac_uart_matrix0", "clk_frac_uart_matrix1",
+						    "clk_frac_common_matrix0", "clk_frac_common_matrix1", "clk_frac_common_matrix2" };
+PNAME(clk_mac_ptp_root_parents_p)		= { "gpll", "v0pll", "v1pll" };
+PNAME(clk_pwm_parents_p)			= { "clk_rc", "sai0_mclk_in", "sai1_mclk_in", "sai2_mclk_in", "sai3_mclk_in", "sai0_sclk_in", "sai1_sclk_in",
+						    "sai2_sclk_in", "sai3_sclk_in", "mclk_asrc0", "mclk_asrc1" };
+PNAME(clk_can_parents_p)			= { "xin24m", "gpll", "clk_v0pll_gate", "clk_v1pll_gate", "clk_frac_voice_matrix1",
+						    "clk_frac_common_matrix0", "clk_frac_common_matrix1", "clk_frac_common_matrix2" };
+PNAME(clk_pdm_parents_p)			= { "xin24m_gate", "clk_int_voice_matrix0", "clk_int_voice_matrix1", "clk_int_voice_matrix2",
+						    "clk_frac_voice_matrix0", "clk_frac_voice_matrix1", "clk_frac_common_matrix0", "clk_frac_common_matrix1",
+						    "clk_frac_common_matrix2", "sai0_mclk_in", "sai1_mclk_in", "sai2_mclk_in", "sai3_mclk_in", "clk_gpll_div" };
+PNAME(mclk_sai_asrc_parents_p)			= { "xin24m_gate", "clk_int_voice_matrix0", "clk_int_voice_matrix1", "clk_int_voice_matrix2",
+						    "clk_frac_voice_matrix0", "clk_frac_voice_matrix1", "clk_frac_common_matrix0", "clk_frac_common_matrix1",
+						    "clk_frac_common_matrix2", "sai0_mclk_in", "sai1_mclk_in", "sai2_mclk_in", "sai3_mclk_in" };
+PNAME(lrck_asrc_parents_p)			= { "mclk_asrc0", "mclk_asrc1", "mclk_asrc2", "mclk_asrc3", "mclk_spdiftx", "clk_spdifrx_to_asrc", "clkout_pdm",
+						    "sai0_fs", "sai1_fs", "sai2_fs", "sai3_fs", "sai4_fs" };
+PNAME(cclk_src_sdmmc_parents_p)			= { "xin24m_gate", "gpll", "clk_v0pll_gate", "clk_v1pll_gate" };
+PNAME(dclk_vop_parents_p)			= { "xin24m_gate", "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate", "dummy_vop_dclk",
+						    "dummy_vop_dclk", "dummy_vop_dclk", "dummy_vop_dclk" };
+PNAME(dbclk_gpio0_parents_p)			= { "xin24m", "clk_rc", "clk_32k_pmu" };
+PNAME(clk_pmu_hp_timer_parents_p)		= { "xin24m", "gpll_div_100m", "clk_core_pvtpll" };
+PNAME(clk_ref_out_parents_p)			= { "xin24m", "gpll", "v0pll", "v1pll" };
+PNAME(clk_32k_frac_parents_p)			= { "xin24m", "v0pll", "v1pll", "clk_rc" };
+PNAME(clk_32k_parents_p)			= { "xin32k", "clk_32k_rc", "clk_32k_frac" };
+PNAME(clk_ref_phy_pmu_mux_parents_p)		= { "xin24m", "clk_ref_phy_pll" };
+PNAME(clk_vpll_ref_parents_p)			= { "xin24m", "clk_pll_ref_io" };
+PNAME(mux_armclk_p)				= { "armclk_pll", "clk_core_pvtpll" };
+
+#define MFLAGS CLK_MUX_HIWORD_MASK
+#define DFLAGS CLK_DIVIDER_HIWORD_MASK
+#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
+
+static struct rockchip_pll_clock rk3506_pll_clks[] __initdata = {
+	[gpll] = PLL(pll_rk3328, PLL_GPLL, "gpll", mux_pll_p,
+		     CLK_IS_CRITICAL, RK3506_PLL_CON(0),
+		     RK3506_MODE_CON, 0, 2, 0, rk3506_pll_rates),
+	[v0pll] = PLL(pll_rk3328, PLL_V0PLL, "v0pll", mux_pll_p,
+		     CLK_IS_CRITICAL, RK3506_PLL_CON(8),
+		     RK3506_MODE_CON, 2, 0, 0, rk3506_pll_rates),
+	[v1pll] = PLL(pll_rk3328, PLL_V1PLL, "v1pll", mux_pll_p,
+		     CLK_IS_CRITICAL, RK3506_PLL_CON(16),
+		     RK3506_MODE_CON, 4, 1, 0, rk3506_pll_rates),
+};
+
+static struct rockchip_clk_branch rk3506_armclk __initdata =
+	MUX(ARMCLK, "armclk", mux_armclk_p, CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
+			RK3506_CLKSEL_CON(15), 8, 1, MFLAGS);
+
+static struct rockchip_clk_branch rk3506_clk_branches[] __initdata = {
+	/*
+	 * CRU Clock-Architecture
+	 */
+	/* top */
+	GATE(XIN24M_GATE, "xin24m_gate", "xin24m", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(0), 1, GFLAGS),
+	GATE(CLK_GPLL_GATE, "clk_gpll_gate", "gpll", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(0), 2, GFLAGS),
+	GATE(CLK_V0PLL_GATE, "clk_v0pll_gate", "v0pll", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(0), 3, GFLAGS),
+	GATE(CLK_V1PLL_GATE, "clk_v1pll_gate", "v1pll", 0,
+			RK3506_CLKGATE_CON(0), 4, GFLAGS),
+	COMPOSITE_NOMUX(CLK_GPLL_DIV, "clk_gpll_div", "clk_gpll_gate", CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(0), 6, 4, DFLAGS,
+			RK3506_CLKGATE_CON(0), 5, GFLAGS),
+	COMPOSITE_NOMUX(CLK_GPLL_DIV_100M, "clk_gpll_div_100m", "clk_gpll_div", 0,
+			RK3506_CLKSEL_CON(0), 10, 4, DFLAGS,
+			RK3506_CLKGATE_CON(0), 6, GFLAGS),
+	COMPOSITE_NOMUX(CLK_V0PLL_DIV, "clk_v0pll_div", "clk_v0pll_gate", CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(1), 0, 4, DFLAGS,
+			RK3506_CLKGATE_CON(0), 7, GFLAGS),
+	COMPOSITE_NOMUX(CLK_V1PLL_DIV, "clk_v1pll_div", "clk_v1pll_gate", 0,
+			RK3506_CLKSEL_CON(1), 4, 4, DFLAGS,
+			RK3506_CLKGATE_CON(0), 8, GFLAGS),
+	COMPOSITE_NOMUX(CLK_INT_VOICE_MATRIX0, "clk_int_voice_matrix0", "clk_v0pll_gate", 0,
+			RK3506_CLKSEL_CON(1), 8, 5, DFLAGS,
+			RK3506_CLKGATE_CON(0), 9, GFLAGS),
+	COMPOSITE_NOMUX(CLK_INT_VOICE_MATRIX1, "clk_int_voice_matrix1", "clk_v1pll_gate", 0,
+			RK3506_CLKSEL_CON(2), 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(0), 10, GFLAGS),
+	COMPOSITE_NOMUX(CLK_INT_VOICE_MATRIX2, "clk_int_voice_matrix2", "clk_v0pll_gate", 0,
+			RK3506_CLKSEL_CON(2), 5, 5, DFLAGS,
+			RK3506_CLKGATE_CON(0), 11, GFLAGS),
+	MUX(CLK_FRAC_UART_MATRIX0_MUX, "clk_frac_uart_matrix0_mux", clk_frac_uart_matrix0_mux_parents_p, 0,
+			RK3506_CLKSEL_CON(3), 9, 2, MFLAGS),
+	MUX(CLK_FRAC_UART_MATRIX1_MUX, "clk_frac_uart_matrix1_mux", xin24m_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(3), 11, 2, MFLAGS),
+	MUX(CLK_FRAC_VOICE_MATRIX0_MUX, "clk_frac_voice_matrix0_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(3), 13, 2, MFLAGS),
+	MUX(CLK_FRAC_VOICE_MATRIX1_MUX, "clk_frac_voice_matrix1_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(4), 0, 2, MFLAGS),
+	MUX(CLK_FRAC_COMMON_MATRIX0_MUX, "clk_frac_common_matrix0_mux", xin24m_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(4), 2, 2, MFLAGS),
+	MUX(CLK_FRAC_COMMON_MATRIX1_MUX, "clk_frac_common_matrix1_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(4), 4, 2, MFLAGS),
+	MUX(CLK_FRAC_COMMON_MATRIX2_MUX, "clk_frac_common_matrix2_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(4), 6, 2, MFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_UART_MATRIX0, "clk_frac_uart_matrix0", "clk_frac_uart_matrix0_mux", 0,
+			RK3506_CLKSEL_CON(5), 0,
+			RK3506_CLKGATE_CON(0), 13, GFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_UART_MATRIX1, "clk_frac_uart_matrix1", "clk_frac_uart_matrix1_mux", 0,
+			RK3506_CLKSEL_CON(6), 0,
+			RK3506_CLKGATE_CON(0), 14, GFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_VOICE_MATRIX0, "clk_frac_voice_matrix0", "clk_frac_voice_matrix0_mux", 0,
+			RK3506_CLKSEL_CON(7), 0,
+			RK3506_CLKGATE_CON(0), 15, GFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_VOICE_MATRIX1, "clk_frac_voice_matrix1", "clk_frac_voice_matrix1_mux", 0,
+			RK3506_CLKSEL_CON(9), 0,
+			RK3506_CLKGATE_CON(1), 0, GFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_COMMON_MATRIX0, "clk_frac_common_matrix0", "clk_frac_common_matrix0_mux", 0,
+			RK3506_CLKSEL_CON(11), 0,
+			RK3506_CLKGATE_CON(1), 1, GFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_COMMON_MATRIX1, "clk_frac_common_matrix1", "clk_frac_common_matrix1_mux", 0,
+			RK3506_CLKSEL_CON(12), 0,
+			RK3506_CLKGATE_CON(1), 2, GFLAGS),
+	COMPOSITE_FRAC(CLK_FRAC_COMMON_MATRIX2, "clk_frac_common_matrix2", "clk_frac_common_matrix2_mux", 0,
+			RK3506_CLKSEL_CON(13), 0,
+			RK3506_CLKGATE_CON(1), 3, GFLAGS),
+	GATE(CLK_REF_USBPHY_TOP, "clk_ref_usbphy_top", "xin24m", 0,
+			RK3506_CLKGATE_CON(1), 4, GFLAGS),
+	GATE(CLK_REF_DPHY_TOP, "clk_ref_dphy_top", "xin24m", 0,
+			RK3506_CLKGATE_CON(1), 5, GFLAGS),
+
+	/* core */
+	COMPOSITE_NOGATE(0, "armclk_pll", gpll_v0pll_v1pll_parents_p, CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(15), 5, 2, MFLAGS, 0, 5, DFLAGS),
+	COMPOSITE_NOMUX(ACLK_CORE_ROOT, "aclk_core_root", "armclk", CLK_IGNORE_UNUSED,
+			RK3506_CLKSEL_CON(15), 9, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
+			RK3506_CLKGATE_CON(2), 11, GFLAGS),
+	COMPOSITE_NOMUX(PCLK_CORE_ROOT, "pclk_core_root", "armclk", CLK_IGNORE_UNUSED,
+			RK3506_CLKSEL_CON(16), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
+			RK3506_CLKGATE_CON(2), 12, GFLAGS),
+	GATE(PCLK_DBG, "pclk_dbg", "pclk_core_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(3), 1, GFLAGS),
+	GATE(PCLK_CORE_GRF, "pclk_core_grf", "pclk_core_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(3), 4, GFLAGS),
+	GATE(PCLK_CORE_CRU, "pclk_core_cru", "pclk_core_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(3), 5, GFLAGS),
+	GATE(CLK_CORE_EMA_DETECT, "clk_core_ema_detect", "xin24m_gate", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(3), 6, GFLAGS),
+	GATE(PCLK_GPIO1, "pclk_gpio1", "aclk_core_root", 0,
+			RK3506_CLKGATE_CON(3), 8, GFLAGS),
+	GATE(DBCLK_GPIO1, "dbclk_gpio1", "xin24m_gate", 0,
+			RK3506_CLKGATE_CON(3), 9, GFLAGS),
+
+	/* core peri */
+	COMPOSITE(ACLK_CORE_PERI_ROOT, "aclk_core_peri_root", gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(18), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(4), 0, GFLAGS),
+	GATE(HCLK_CORE_PERI_ROOT, "hclk_core_peri_root", "aclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 1, GFLAGS),
+	GATE(PCLK_CORE_PERI_ROOT, "pclk_core_peri_root", "aclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 2, GFLAGS),
+	COMPOSITE(CLK_DSMC, "clk_dsmc", xin24m_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(18), 12, 2, MFLAGS, 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(4), 4, GFLAGS),
+	GATE(ACLK_DSMC, "aclk_dsmc", "aclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 5, GFLAGS),
+	GATE(PCLK_DSMC, "pclk_dsmc", "pclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 6, GFLAGS),
+	COMPOSITE(CLK_FLEXBUS_TX, "clk_flexbus_tx", xin24m_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(19), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(4), 7, GFLAGS),
+	COMPOSITE(CLK_FLEXBUS_RX, "clk_flexbus_rx", xin24m_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(19), 12, 2, MFLAGS, 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(4), 8, GFLAGS),
+	GATE(ACLK_FLEXBUS, "aclk_flexbus", "aclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 9, GFLAGS),
+	GATE(HCLK_FLEXBUS, "hclk_flexbus", "hclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 10, GFLAGS),
+	GATE(ACLK_DSMC_SLV, "aclk_dsmc_slv", "aclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 11, GFLAGS),
+	GATE(HCLK_DSMC_SLV, "hclk_dsmc_slv", "hclk_core_peri_root", 0,
+			RK3506_CLKGATE_CON(4), 12, GFLAGS),
+
+	/* bus */
+	COMPOSITE(ACLK_BUS_ROOT, "aclk_bus_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(21), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(5), 0, GFLAGS),
+	COMPOSITE(HCLK_BUS_ROOT, "hclk_bus_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(21), 12, 2, MFLAGS, 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(5), 1, GFLAGS),
+	COMPOSITE(PCLK_BUS_ROOT, "pclk_bus_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(22), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(5), 2, GFLAGS),
+	GATE(ACLK_SYSRAM, "aclk_sysram", "aclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(5), 6, GFLAGS),
+	GATE(HCLK_SYSRAM, "hclk_sysram", "aclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(5), 7, GFLAGS),
+	GATE(ACLK_DMAC0, "aclk_dmac0", "aclk_bus_root", 0,
+			RK3506_CLKGATE_CON(5), 8, GFLAGS),
+	GATE(ACLK_DMAC1, "aclk_dmac1", "aclk_bus_root", 0,
+			RK3506_CLKGATE_CON(5), 9, GFLAGS),
+	GATE(HCLK_M0, "hclk_m0", "aclk_bus_root", 0,
+			RK3506_CLKGATE_CON(5), 10, GFLAGS),
+	GATE(ACLK_CRYPTO_NS, "aclk_crypto_ns", "aclk_bus_root", 0,
+			RK3506_CLKGATE_CON(5), 14, GFLAGS),
+	GATE(HCLK_CRYPTO_NS, "hclk_crypto_ns", "hclk_bus_root", 0,
+			RK3506_CLKGATE_CON(5), 15, GFLAGS),
+	GATE(HCLK_RNG, "hclk_rng", "hclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 0, GFLAGS),
+	GATE(PCLK_BUS_GRF, "pclk_bus_grf", "pclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(6), 1, GFLAGS),
+	GATE(PCLK_TIMER, "pclk_timer", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 2, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0_CH0, "clk_timer0_ch0", clk_timer0_parents_p, 0,
+			RK3506_CLKSEL_CON(22), 7, 3, MFLAGS,
+			RK3506_CLKGATE_CON(6), 3, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0_CH1, "clk_timer0_ch1", clk_timer1_parents_p, 0,
+			RK3506_CLKSEL_CON(22), 10, 3, MFLAGS,
+			RK3506_CLKGATE_CON(6), 4, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0_CH2, "clk_timer0_ch2", clk_timer2_parents_p, 0,
+			RK3506_CLKSEL_CON(22), 13, 3, MFLAGS,
+			RK3506_CLKGATE_CON(6), 5, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0_CH3, "clk_timer0_ch3", clk_timer3_parents_p, 0,
+			RK3506_CLKSEL_CON(23), 0, 3, MFLAGS,
+			RK3506_CLKGATE_CON(6), 6, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0_CH4, "clk_timer0_ch4", clk_timer4_parents_p, 0,
+			RK3506_CLKSEL_CON(23), 3, 3, MFLAGS,
+			RK3506_CLKGATE_CON(6), 7, GFLAGS),
+	COMPOSITE_NODIV(CLK_TIMER0_CH5, "clk_timer0_ch5", clk_timer5_parents_p, 0,
+			RK3506_CLKSEL_CON(23), 6, 3, MFLAGS,
+			RK3506_CLKGATE_CON(6), 8, GFLAGS),
+	GATE(PCLK_WDT0, "pclk_wdt0", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 9, GFLAGS),
+	GATE(TCLK_WDT0, "tclk_wdt0", "xin24m_gate", 0,
+			RK3506_CLKGATE_CON(6), 10, GFLAGS),
+	GATE(PCLK_WDT1, "pclk_wdt1", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 11, GFLAGS),
+	GATE(TCLK_WDT1, "tclk_wdt1", "xin24m_gate", 0,
+			RK3506_CLKGATE_CON(6), 12, GFLAGS),
+	GATE(PCLK_MAILBOX, "pclk_mailbox", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 13, GFLAGS),
+	GATE(PCLK_INTMUX, "pclk_intmux", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 14, GFLAGS),
+	GATE(PCLK_SPINLOCK, "pclk_spinlock", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(6), 15, GFLAGS),
+	GATE(PCLK_DDRC, "pclk_ddrc", "pclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(7), 0, GFLAGS),
+	GATE(HCLK_DDRPHY, "hclk_ddrphy", "hclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(7), 1, GFLAGS),
+	GATE(PCLK_DDRMON, "pclk_ddrmon", "pclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(7), 2, GFLAGS),
+	GATE(CLK_DDRMON_OSC, "clk_ddrmon_osc", "xin24m_gate", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(7), 3, GFLAGS),
+	GATE(PCLK_STDBY, "pclk_stdby", "pclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(7), 4, GFLAGS),
+	GATE(HCLK_USBOTG0, "hclk_usbotg0", "hclk_bus_root", 0,
+			RK3506_CLKGATE_CON(7), 5, GFLAGS),
+	GATE(HCLK_USBOTG0_PMU, "hclk_usbotg0_pmu", "hclk_bus_root", 0,
+			RK3506_CLKGATE_CON(7), 6, GFLAGS),
+	GATE(CLK_USBOTG0_ADP, "clk_usbotg0_adp", "clk_32k", 0,
+			RK3506_CLKGATE_CON(7), 7, GFLAGS),
+	GATE(HCLK_USBOTG1, "hclk_usbotg1", "hclk_bus_root", 0,
+			RK3506_CLKGATE_CON(7), 8, GFLAGS),
+	GATE(HCLK_USBOTG1_PMU, "hclk_usbotg1_pmu", "hclk_bus_root", 0,
+			RK3506_CLKGATE_CON(7), 9, GFLAGS),
+	GATE(CLK_USBOTG1_ADP, "clk_usbotg1_adp", "clk_32k", 0,
+			RK3506_CLKGATE_CON(7), 10, GFLAGS),
+	GATE(PCLK_USBPHY, "pclk_usbphy", "pclk_bus_root", 0,
+			RK3506_CLKGATE_CON(7), 11, GFLAGS),
+	GATE(ACLK_DMA2DDR, "aclk_dma2ddr", "aclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(8), 0, GFLAGS),
+	GATE(PCLK_DMA2DDR, "pclk_dma2ddr", "pclk_bus_root", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(8), 1, GFLAGS),
+	COMPOSITE_NOMUX(STCLK_M0, "stclk_m0", "xin24m_gate", 0,
+			RK3506_CLKSEL_CON(23), 9, 6, DFLAGS,
+			RK3506_CLKGATE_CON(8), 2, GFLAGS),
+	COMPOSITE(CLK_DDRPHY, "clk_ddrphy", gpll_v0pll_v1pll_parents_p, CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKSEL_CON(4), 4, 2, MFLAGS, 0, 4, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 10, GFLAGS),
+	FACTOR(CLK_DDRC_SRC, "clk_ddrc_src", "clk_ddrphy", 0, 1, 4),
+	GATE(ACLK_DDRC_0, "aclk_ddrc_0", "clk_ddrc_src", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(10), 0, GFLAGS),
+	GATE(ACLK_DDRC_1, "aclk_ddrc_1", "clk_ddrc_src", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(10), 1, GFLAGS),
+	GATE(CLK_DDRC, "clk_ddrc", "clk_ddrc_src", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(10), 3, GFLAGS),
+	GATE(CLK_DDRMON, "clk_ddrmon", "clk_ddrc_src", CLK_IGNORE_UNUSED,
+			RK3506_CLKGATE_CON(10), 4, GFLAGS),
+
+	/* ls peri */
+	COMPOSITE(HCLK_LSPERI_ROOT, "hclk_lsperi_root", gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(29), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(11), 0, GFLAGS),
+	GATE(PCLK_LSPERI_ROOT, "pclk_lsperi_root", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 1, GFLAGS),
+	GATE(PCLK_UART0, "pclk_uart0", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 4, GFLAGS),
+	GATE(PCLK_UART1, "pclk_uart1", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 5, GFLAGS),
+	GATE(PCLK_UART2, "pclk_uart2", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 6, GFLAGS),
+	GATE(PCLK_UART3, "pclk_uart3", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 7, GFLAGS),
+	GATE(PCLK_UART4, "pclk_uart4", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 8, GFLAGS),
+	COMPOSITE(SCLK_UART0, "sclk_uart0", sclk_uart_parents_p, 0,
+			RK3506_CLKSEL_CON(29), 12, 3, MFLAGS, 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(11), 9, GFLAGS),
+	COMPOSITE(SCLK_UART1, "sclk_uart1", sclk_uart_parents_p, 0,
+			RK3506_CLKSEL_CON(30), 5, 3, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(11), 10, GFLAGS),
+	COMPOSITE(SCLK_UART2, "sclk_uart2", sclk_uart_parents_p, 0,
+			RK3506_CLKSEL_CON(30), 13, 3, MFLAGS, 8, 5, DFLAGS,
+			RK3506_CLKGATE_CON(11), 11, GFLAGS),
+	COMPOSITE(SCLK_UART3, "sclk_uart3", sclk_uart_parents_p, 0,
+			RK3506_CLKSEL_CON(31), 5, 3, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(11), 12, GFLAGS),
+	COMPOSITE(SCLK_UART4, "sclk_uart4", sclk_uart_parents_p, 0,
+			RK3506_CLKSEL_CON(31), 13, 3, MFLAGS, 8, 5, DFLAGS,
+			RK3506_CLKGATE_CON(11), 13, GFLAGS),
+	GATE(PCLK_I2C0, "pclk_i2c0", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(11), 14, GFLAGS),
+	COMPOSITE(CLK_I2C0, "clk_i2c0", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(32), 4, 2, MFLAGS, 0, 4, DFLAGS,
+			RK3506_CLKGATE_CON(11), 15, GFLAGS),
+	GATE(PCLK_I2C1, "pclk_i2c1", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(12), 0, GFLAGS),
+	COMPOSITE(CLK_I2C1, "clk_i2c1", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(32), 10, 2, MFLAGS, 6, 4, DFLAGS,
+			RK3506_CLKGATE_CON(12), 1, GFLAGS),
+	GATE(PCLK_I2C2, "pclk_i2c2", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(12), 2, GFLAGS),
+	COMPOSITE(CLK_I2C2, "clk_i2c2", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(33), 4, 2, MFLAGS, 0, 4, DFLAGS,
+			RK3506_CLKGATE_CON(12), 3, GFLAGS),
+	GATE(PCLK_PWM1, "pclk_pwm1", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(12), 4, GFLAGS),
+	COMPOSITE(CLK_PWM1, "clk_pwm1", gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(33), 10, 2, MFLAGS, 6, 4, DFLAGS,
+			RK3506_CLKGATE_CON(12), 5, GFLAGS),
+	GATE(CLK_OSC_PWM1, "clk_osc_pwm1", "xin24m", 0,
+			RK3506_CLKGATE_CON(12), 6, GFLAGS),
+	GATE(CLK_RC_PWM1, "clk_rc_pwm1", "clk_rc", 0,
+			RK3506_CLKGATE_CON(12), 7, GFLAGS),
+	COMPOSITE_NODIV(CLK_FREQ_PWM1, "clk_freq_pwm1", clk_pwm_parents_p, 0,
+			RK3506_CLKSEL_CON(33), 12, 4, MFLAGS,
+			RK3506_CLKGATE_CON(12), 8, GFLAGS),
+	COMPOSITE_NODIV(CLK_COUNTER_PWM1, "clk_counter_pwm1", clk_pwm_parents_p, 0,
+			RK3506_CLKSEL_CON(34), 0, 4, MFLAGS,
+			RK3506_CLKGATE_CON(12), 9, GFLAGS),
+	GATE(PCLK_SPI0, "pclk_spi0", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(12), 10, GFLAGS),
+	COMPOSITE(CLK_SPI0, "clk_spi0", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(34), 8, 2, MFLAGS, 4, 4, DFLAGS,
+			RK3506_CLKGATE_CON(12), 11, GFLAGS),
+	GATE(PCLK_SPI1, "pclk_spi1", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(12), 12, GFLAGS),
+	COMPOSITE(CLK_SPI1, "clk_spi1", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(34), 14, 2, MFLAGS, 10, 4, DFLAGS,
+			RK3506_CLKGATE_CON(12), 13, GFLAGS),
+	GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(12), 14, GFLAGS),
+	COMPOSITE_NODIV(DBCLK_GPIO2, "dbclk_gpio2", xin24m_400k_32k_parents_p, 0,
+			RK3506_CLKSEL_CON(35), 0, 2, MFLAGS,
+			RK3506_CLKGATE_CON(12), 15, GFLAGS),
+	GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 0, GFLAGS),
+	COMPOSITE_NODIV(DBCLK_GPIO3, "dbclk_gpio3", xin24m_400k_32k_parents_p, 0,
+			RK3506_CLKSEL_CON(35), 2, 2, MFLAGS,
+			RK3506_CLKGATE_CON(13), 1, GFLAGS),
+	GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 2, GFLAGS),
+	COMPOSITE_NODIV(DBCLK_GPIO4, "dbclk_gpio4", xin24m_400k_32k_parents_p, 0,
+			RK3506_CLKSEL_CON(35), 4, 2, MFLAGS,
+			RK3506_CLKGATE_CON(13), 3, GFLAGS),
+	GATE(HCLK_CAN0, "hclk_can0", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 4, GFLAGS),
+	COMPOSITE(CLK_CAN0, "clk_can0", clk_can_parents_p, 0,
+			RK3506_CLKSEL_CON(35), 11, 3, MFLAGS, 6, 5, DFLAGS,
+			RK3506_CLKGATE_CON(13), 5, GFLAGS),
+	GATE(HCLK_CAN1, "hclk_can1", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 6, GFLAGS),
+	COMPOSITE(CLK_CAN1, "clk_can1", clk_can_parents_p, 0,
+			RK3506_CLKSEL_CON(36), 5, 3, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(13), 7, GFLAGS),
+	GATE(HCLK_PDM, "hclk_pdm", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 8, GFLAGS),
+	COMPOSITE(MCLK_PDM, "mclk_pdm", clk_pdm_parents_p, 0,
+			RK3506_CLKSEL_CON(37), 5, 4, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(13), 9, GFLAGS),
+	COMPOSITE(CLKOUT_PDM, "clkout_pdm", clk_pdm_parents_p, 0,
+			RK3506_CLKSEL_CON(38), 10, 4, MFLAGS, 0, 10, DFLAGS,
+			RK3506_CLKGATE_CON(13), 10, GFLAGS),
+	COMPOSITE(MCLK_SPDIFTX, "mclk_spdiftx", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(39), 5, 4, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(13), 11, GFLAGS),
+	GATE(HCLK_SPDIFTX, "hclk_spdiftx", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 12, GFLAGS),
+	GATE(HCLK_SPDIFRX, "hclk_spdifrx", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(13), 13, GFLAGS),
+	COMPOSITE(MCLK_SPDIFRX, "mclk_spdifrx", gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(39), 14, 2, MFLAGS, 9, 5, DFLAGS,
+			RK3506_CLKGATE_CON(13), 14, GFLAGS),
+	COMPOSITE(MCLK_SAI0, "mclk_sai0", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(40), 8, 4, MFLAGS, 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(13), 15, GFLAGS),
+	GATE(HCLK_SAI0, "hclk_sai0", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(14), 0, GFLAGS),
+	GATE(MCLK_OUT_SAI0, "mclk_out_sai0", "mclk_sai0", 0,
+			RK3506_CLKGATE_CON(14), 1, GFLAGS),
+	COMPOSITE(MCLK_SAI1, "mclk_sai1", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(41), 8, 4, MFLAGS, 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(14), 2, GFLAGS),
+	GATE(HCLK_SAI1, "hclk_sai1", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(14), 3, GFLAGS),
+	GATE(MCLK_OUT_SAI1, "mclk_out_sai1", "mclk_sai1", 0,
+			RK3506_CLKGATE_CON(14), 4, GFLAGS),
+	GATE(HCLK_ASRC0, "hclk_asrc0", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(14), 5, GFLAGS),
+	COMPOSITE(CLK_ASRC0, "clk_asrc0", gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(42), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(14), 6, GFLAGS),
+	GATE(HCLK_ASRC1, "hclk_asrc1", "hclk_lsperi_root", 0,
+			RK3506_CLKGATE_CON(14), 7, GFLAGS),
+	COMPOSITE(CLK_ASRC1, "clk_asrc1", gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(42), 12, 2, MFLAGS, 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(14), 8, GFLAGS),
+	GATE(PCLK_CRU, "pclk_cru", "pclk_lsperi_root", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(14), 9, GFLAGS),
+	GATE(PCLK_PMU_ROOT, "pclk_pmu_root", "pclk_lsperi_root", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(14), 10, GFLAGS),
+	COMPOSITE_NODIV(MCLK_ASRC0, "mclk_asrc0", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(46), 0, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 0, GFLAGS),
+	COMPOSITE_NODIV(MCLK_ASRC1, "mclk_asrc1", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(46), 4, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 1, GFLAGS),
+	COMPOSITE_NODIV(MCLK_ASRC2, "mclk_asrc2", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(46), 8, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 2, GFLAGS),
+	COMPOSITE_NODIV(MCLK_ASRC3, "mclk_asrc3", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(46), 12, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 3, GFLAGS),
+	COMPOSITE_NODIV(LRCK_ASRC0_SRC, "lrck_asrc0_src", lrck_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(47), 0, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 4, GFLAGS),
+	COMPOSITE_NODIV(LRCK_ASRC0_DST, "lrck_asrc0_dst", lrck_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(47), 4, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 5, GFLAGS),
+	COMPOSITE_NODIV(LRCK_ASRC1_SRC, "lrck_asrc1_src", lrck_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(47), 8, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 6, GFLAGS),
+	COMPOSITE_NODIV(LRCK_ASRC1_DST, "lrck_asrc1_dst", lrck_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(47), 12, 4, MFLAGS,
+			RK3506_CLKGATE_CON(16), 7, GFLAGS),
+
+	/* hs peri */
+	COMPOSITE(ACLK_HSPERI_ROOT, "aclk_hsperi_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL,
+			RK3506_CLKSEL_CON(49), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(17), 0, GFLAGS),
+	GATE(HCLK_HSPERI_ROOT, "hclk_hsperi_root", "aclk_hsperi_root", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(17), 1, GFLAGS),
+	GATE(PCLK_HSPERI_ROOT, "pclk_hsperi_root", "hclk_hsperi_root", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(17), 2, GFLAGS),
+	COMPOSITE(CCLK_SRC_SDMMC, "cclk_src_sdmmc", cclk_src_sdmmc_parents_p, 0,
+			RK3506_CLKSEL_CON(49), 13, 2, MFLAGS, 7, 6, DFLAGS,
+			RK3506_CLKGATE_CON(17), 6, GFLAGS),
+	GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 7, GFLAGS),
+	GATE(HCLK_FSPI, "hclk_fspi", "hclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 8, GFLAGS),
+	COMPOSITE(SCLK_FSPI, "sclk_fspi", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(50), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(17), 9, GFLAGS),
+	GATE(PCLK_SPI2, "pclk_spi2", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 10, GFLAGS),
+	GATE(ACLK_MAC0, "aclk_mac0", "aclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 11, GFLAGS),
+	GATE(ACLK_MAC1, "aclk_mac1", "aclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 12, GFLAGS),
+	GATE(PCLK_MAC0, "pclk_mac0", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 13, GFLAGS),
+	GATE(PCLK_MAC1, "pclk_mac1", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(17), 14, GFLAGS),
+	COMPOSITE_NOMUX(CLK_MAC_ROOT, "clk_mac_root", "gpll", 0,
+			RK3506_CLKSEL_CON(50), 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(17), 15, GFLAGS),
+	GATE(CLK_MAC0, "clk_mac0", "clk_mac_root", 0,
+			RK3506_CLKGATE_CON(18), 0, GFLAGS),
+	GATE(CLK_MAC1, "clk_mac1", "clk_mac_root", 0,
+			RK3506_CLKGATE_CON(18), 1, GFLAGS),
+	COMPOSITE(MCLK_SAI2, "mclk_sai2", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(51), 8, 4, MFLAGS, 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(18), 2, GFLAGS),
+	GATE(HCLK_SAI2, "hclk_sai2", "hclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(18), 3, GFLAGS),
+	GATE(MCLK_OUT_SAI2, "mclk_out_sai2", "mclk_sai2", 0,
+			RK3506_CLKGATE_CON(18), 4, GFLAGS),
+	COMPOSITE(MCLK_SAI3_SRC, "mclk_sai3_src", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(52), 8, 4, MFLAGS, 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(18), 5, GFLAGS),
+	GATE(HCLK_SAI3, "hclk_sai3", "hclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(18), 6, GFLAGS),
+	GATE(MCLK_SAI3, "mclk_sai3", "mclk_sai3_src", 0,
+			RK3506_CLKGATE_CON(18), 7, GFLAGS),
+	GATE(MCLK_OUT_SAI3, "mclk_out_sai3", "mclk_sai3_src", 0,
+			RK3506_CLKGATE_CON(18), 8, GFLAGS),
+	COMPOSITE(MCLK_SAI4_SRC, "mclk_sai4_src", mclk_sai_asrc_parents_p, 0,
+			RK3506_CLKSEL_CON(53), 8, 4, MFLAGS, 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(18), 9, GFLAGS),
+	GATE(HCLK_SAI4, "hclk_sai4", "hclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(18), 10, GFLAGS),
+	GATE(MCLK_SAI4, "mclk_sai4", "mclk_sai4_src", 0,
+			RK3506_CLKGATE_CON(18), 11, GFLAGS),
+	GATE(HCLK_DSM, "hclk_dsm", "hclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(18), 12, GFLAGS),
+	GATE(MCLK_DSM, "mclk_dsm", "mclk_sai3_src", 0,
+			RK3506_CLKGATE_CON(18), 13, GFLAGS),
+	GATE(PCLK_AUDIO_ADC, "pclk_audio_adc", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(18), 14, GFLAGS),
+	GATE(MCLK_AUDIO_ADC, "mclk_audio_adc", "mclk_sai4_src", 0,
+			RK3506_CLKGATE_CON(18), 15, GFLAGS),
+	FACTOR(MCLK_AUDIO_ADC_DIV4, "mclk_audio_adc_div4", "mclk_audio_adc", 0, 1, 4),
+	GATE(PCLK_SARADC, "pclk_saradc", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(19), 0, GFLAGS),
+	COMPOSITE(CLK_SARADC, "clk_saradc", xin24m_400k_32k_parents_p, 0,
+			RK3506_CLKSEL_CON(54), 4, 2, MFLAGS, 0, 4, DFLAGS,
+			RK3506_CLKGATE_CON(19), 1, GFLAGS),
+	GATE(PCLK_OTPC_NS, "pclk_otpc_ns", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(19), 3, GFLAGS),
+	GATE(CLK_SBPI_OTPC_NS, "clk_sbpi_otpc_ns", "xin24m_gate", 0,
+			RK3506_CLKGATE_CON(19), 4, GFLAGS),
+	FACTOR(CLK_USER_OTPC_NS, "clk_user_otpc_ns", "clk_sbpi_otpc_ns", 0, 1, 2),
+	GATE(PCLK_UART5, "pclk_uart5", "pclk_hsperi_root", 0,
+			RK3506_CLKGATE_CON(19), 6, GFLAGS),
+	COMPOSITE(SCLK_UART5, "sclk_uart5", sclk_uart_parents_p, 0,
+			RK3506_CLKSEL_CON(54), 11, 3, MFLAGS, 6, 5, DFLAGS,
+			RK3506_CLKGATE_CON(19), 7, GFLAGS),
+	GATE(PCLK_GPIO234_IOC, "pclk_gpio234_ioc", "pclk_hsperi_root", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(19), 8, GFLAGS),
+	COMPOSITE(CLK_MAC_PTP_ROOT, "clk_mac_ptp_root", clk_mac_ptp_root_parents_p, 0,
+			RK3506_CLKSEL_CON(55), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(19), 9, GFLAGS),
+	GATE(CLK_MAC0_PTP, "clk_mac0_ptp", "clk_mac_ptp_root", 0,
+			RK3506_CLKGATE_CON(19), 10, GFLAGS),
+	GATE(CLK_MAC1_PTP, "clk_mac1_ptp", "clk_mac_ptp_root", 0,
+			RK3506_CLKGATE_CON(19), 11, GFLAGS),
+	COMPOSITE(ACLK_VIO_ROOT, "aclk_vio_root", gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(58), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(21), 0, GFLAGS),
+	COMPOSITE(HCLK_VIO_ROOT, "hclk_vio_root", gpll_v0pll_v1pll_div_parents_p, 0,
+			RK3506_CLKSEL_CON(58), 12, 2, MFLAGS, 7, 5, DFLAGS,
+			RK3506_CLKGATE_CON(21), 1, GFLAGS),
+	GATE(PCLK_VIO_ROOT, "pclk_vio_root", "hclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 2, GFLAGS),
+	GATE(HCLK_RGA, "hclk_rga", "hclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 6, GFLAGS),
+	GATE(ACLK_RGA, "aclk_rga", "aclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 7, GFLAGS),
+	COMPOSITE(CLK_CORE_RGA, "clk_core_rga", gpll_v0pll_v1pll_g_parents_p, 0,
+			RK3506_CLKSEL_CON(59), 5, 2, MFLAGS, 0, 5, DFLAGS,
+			RK3506_CLKGATE_CON(21), 8, GFLAGS),
+	GATE(ACLK_VOP, "aclk_vop", "aclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 9, GFLAGS),
+	GATE(HCLK_VOP, "hclk_vop", "hclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 10, GFLAGS),
+	COMPOSITE(DCLK_VOP, "dclk_vop", dclk_vop_parents_p, 0,
+			RK3506_CLKSEL_CON(60), 8, 3, MFLAGS, 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(21), 11, GFLAGS),
+	GATE(PCLK_DPHY, "pclk_dphy", "pclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 12, GFLAGS),
+	GATE(PCLK_DSI_HOST, "pclk_dsi_host", "pclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 13, GFLAGS),
+	GATE(PCLK_TSADC, "pclk_tsadc", "pclk_vio_root", 0,
+			RK3506_CLKGATE_CON(21), 14, GFLAGS),
+	COMPOSITE_NOMUX(CLK_TSADC, "clk_tsadc", "xin24m_gate", 0,
+			RK3506_CLKSEL_CON(61), 0, 8, DFLAGS,
+			RK3506_CLKGATE_CON(21), 15, GFLAGS),
+	COMPOSITE_NOMUX(CLK_TSADC_TSEN, "clk_tsadc_tsen", "xin24m_gate", 0,
+			RK3506_CLKSEL_CON(61), 8, 3, DFLAGS,
+			RK3506_CLKGATE_CON(22), 0, GFLAGS),
+	GATE(PCLK_GPIO1_IOC, "pclk_gpio1_ioc", "pclk_vio_root", CLK_IS_CRITICAL,
+			RK3506_CLKGATE_CON(22), 1, GFLAGS),
+
+	/* pmu */
+	GATE(CLK_PMU, "clk_pmu", "xin24m", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 1, GFLAGS),
+	GATE(PCLK_PMU, "pclk_pmu", "pclk_pmu_root", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 2, GFLAGS),
+	GATE(PCLK_PMU_CRU, "pclk_pmu_cru", "pclk_pmu_root", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 4, GFLAGS),
+	GATE(PCLK_PMU_GRF, "pclk_pmu_grf", "pclk_pmu_root", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 5, GFLAGS),
+	GATE(PCLK_GPIO0_IOC, "pclk_gpio0_ioc", "pclk_pmu_root", CLK_IS_CRITICAL,
+			RK3506_PMU_CLKGATE_CON(0), 7, GFLAGS),
+	GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pmu_root", 0,
+			RK3506_PMU_CLKGATE_CON(0), 8, GFLAGS),
+	COMPOSITE_NODIV(DBCLK_GPIO0, "dbclk_gpio0", dbclk_gpio0_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(0), 0, 2, MFLAGS,
+			RK3506_PMU_CLKGATE_CON(0), 9, GFLAGS),
+	GATE(PCLK_GPIO1_SHADOW, "pclk_gpio1_shadow", "pclk_pmu_root", 0,
+			RK3506_PMU_CLKGATE_CON(0), 10, GFLAGS),
+	COMPOSITE_NODIV(DBCLK_GPIO1_SHADOW, "dbclk_gpio1_shadow", dbclk_gpio0_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(0), 2, 2, MFLAGS,
+			RK3506_PMU_CLKGATE_CON(0), 11, GFLAGS),
+	GATE(PCLK_PMU_HP_TIMER, "pclk_pmu_hp_timer", "pclk_pmu_root", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 12, GFLAGS),
+	MUX(CLK_PMU_HP_TIMER, "clk_pmu_hp_timer", clk_pmu_hp_timer_parents_p, CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKSEL_CON(0), 4, 2, MFLAGS),
+	GATE(PCLK_PWM0, "pclk_pwm0", "pclk_pmu_root", 0,
+			RK3506_PMU_CLKGATE_CON(0), 15, GFLAGS),
+	COMPOSITE_NOMUX(CLK_PWM0, "clk_pwm0", "clk_gpll_div_100m", 0,
+			RK3506_PMU_CLKSEL_CON(0), 6, 4, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 0, GFLAGS),
+	GATE(CLK_OSC_PWM0, "clk_osc_pwm0", "xin24m", 0,
+			RK3506_PMU_CLKGATE_CON(1), 1, GFLAGS),
+	GATE(CLK_RC_PWM0, "clk_rc_pwm0", "clk_rc", 0,
+			RK3506_PMU_CLKGATE_CON(1), 2, GFLAGS),
+	COMPOSITE_NOMUX(CLK_MAC_OUT, "clk_mac_out", "gpll", 0,
+			RK3506_PMU_CLKSEL_CON(0), 10, 6, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 3, GFLAGS),
+	COMPOSITE(CLK_REF_OUT0, "clk_ref_out0", clk_ref_out_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(1), 6, 2, MFLAGS, 0, 6, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 4, GFLAGS),
+	COMPOSITE(CLK_REF_OUT1, "clk_ref_out1", clk_ref_out_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(1), 14, 2, MFLAGS, 8, 6, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 5, GFLAGS),
+	MUX(CLK_32K_FRAC_MUX, "clk_32k_frac_mux", clk_32k_frac_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(3), 0, 2, MFLAGS),
+	COMPOSITE_FRAC(CLK_32K_FRAC, "clk_32k_frac", "clk_32k_frac_mux", 0,
+			RK3506_PMU_CLKSEL_CON(2), 0,
+			RK3506_PMU_CLKGATE_CON(1), 6, GFLAGS),
+	COMPOSITE_NOMUX(CLK_32K_RC, "clk_32k_rc", "clk_rc", CLK_IS_CRITICAL,
+			RK3506_PMU_CLKSEL_CON(3), 2, 5, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 7, GFLAGS),
+	COMPOSITE_NODIV(CLK_32K, "clk_32k", clk_32k_parents_p, CLK_IS_CRITICAL,
+			RK3506_PMU_CLKSEL_CON(3), 7, 2, MFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 8, GFLAGS),
+	COMPOSITE_NODIV(CLK_32K_PMU, "clk_32k_pmu", clk_32k_parents_p, CLK_IS_CRITICAL,
+			RK3506_PMU_CLKSEL_CON(3), 9, 2, MFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 9, GFLAGS),
+	GATE(CLK_PMU_32K, "clk_pmu_32k", "clk_32k_pmu", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 3, GFLAGS),
+	GATE(CLK_PMU_HP_TIMER_32K, "clk_pmu_hp_timer_32k", "clk_32k_pmu", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(0), 14, GFLAGS),
+	GATE(PCLK_TOUCH_KEY, "pclk_touch_key", "pclk_pmu_root", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(1), 12, GFLAGS),
+	GATE(CLK_TOUCH_KEY, "clk_touch_key", "xin24m", CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKGATE_CON(1), 13, GFLAGS),
+	COMPOSITE(CLK_REF_PHY_PLL, "clk_ref_phy_pll", gpll_v0pll_v1pll_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(4), 13, 2, MFLAGS, 6, 7, DFLAGS,
+			RK3506_PMU_CLKGATE_CON(1), 14, GFLAGS),
+	MUX(CLK_REF_PHY_PMU_MUX, "clk_ref_phy_pmu_mux", clk_ref_phy_pmu_mux_parents_p, 0,
+			RK3506_PMU_CLKSEL_CON(4), 15, 1, MFLAGS),
+	GATE(CLK_WIFI_OUT, "clk_wifi_out", "xin24m", 0,
+			RK3506_PMU_CLKGATE_CON(2), 0, GFLAGS),
+	MUX(CLK_V0PLL_REF, "clk_v0pll_ref", clk_vpll_ref_parents_p, CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKSEL_CON(6), 0, 1, MFLAGS),
+	MUX(CLK_V1PLL_REF, "clk_v1pll_ref", clk_vpll_ref_parents_p, CLK_IGNORE_UNUSED,
+			RK3506_PMU_CLKSEL_CON(6), 1, 1, MFLAGS),
+
+	/* secure ns */
+	GATE(CLK_CORE_CRYPTO_NS, "clk_core_crypto_ns", "clk_core_crypto", 0,
+			RK3506_CLKGATE_CON(5), 12, GFLAGS),
+	GATE(CLK_PKA_CRYPTO_NS, "clk_pka_crypto_ns", "clk_pka_crypto", 0,
+			RK3506_CLKGATE_CON(5), 13, GFLAGS),
+
+	/* io */
+	GATE(CLK_SPI2, "clk_spi2", "clk_spi2_io", 0,
+			RK3506_CLKGATE_CON(20), 0, GFLAGS),
+};
+
+static void __init rk3506_clk_init(struct device_node *np)
+{
+	struct rockchip_clk_provider *ctx;
+	unsigned long clk_nr_clks;
+	void __iomem *reg_base;
+
+	clk_nr_clks = rockchip_clk_find_max_clk_id(rk3506_clk_branches,
+						   ARRAY_SIZE(rk3506_clk_branches)) + 1;
+
+	reg_base = of_iomap(np, 0);
+	if (!reg_base) {
+		pr_err("%s: could not map cru region\n", __func__);
+		return;
+	}
+
+	ctx = rockchip_clk_init(np, reg_base, clk_nr_clks);
+	if (IS_ERR(ctx)) {
+		pr_err("%s: rockchip clk init failed\n", __func__);
+		iounmap(reg_base);
+		return;
+	}
+
+	rockchip_clk_register_plls(ctx, rk3506_pll_clks,
+				   ARRAY_SIZE(rk3506_pll_clks),
+				   0);
+
+	rockchip_clk_register_armclk_multi_pll(ctx, &rk3506_armclk,
+					       rk3506_cpuclk_rates,
+					       ARRAY_SIZE(rk3506_cpuclk_rates));
+
+	rockchip_clk_register_branches(ctx, rk3506_clk_branches,
+				       ARRAY_SIZE(rk3506_clk_branches));
+
+	rk3506_rst_init(np, reg_base);
+
+	rockchip_register_restart_notifier(ctx, RK3506_GLB_SRST_FST, NULL);
+
+	rockchip_clk_of_add_provider(np, ctx);
+
+	/* pvtpll src init */
+	writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RK3506_CLKSEL_CON(15));
+}
+
+CLK_OF_DECLARE(rk3506_cru, "rockchip,rk3506-cru", rk3506_clk_init);
+
+struct clk_rk3506_inits {
+	void (*inits)(struct device_node *np);
+};
+
+static const struct clk_rk3506_inits clk_rk3506_cru_init = {
+	.inits = rk3506_clk_init,
+};
+
+static const struct of_device_id clk_rk3506_match_table[] = {
+	{
+		.compatible = "rockchip,rk3506-cru",
+		.data = &clk_rk3506_cru_init,
+	},
+	{ }
+};
+
+static int clk_rk3506_probe(struct platform_device *pdev)
+{
+	const struct clk_rk3506_inits *init_data;
+	struct device *dev = &pdev->dev;
+
+	init_data = device_get_match_data(dev);
+	if (!init_data)
+		return -EINVAL;
+
+	if (init_data->inits)
+		init_data->inits(dev->of_node);
+
+	return 0;
+}
+
+static struct platform_driver clk_rk3506_driver = {
+	.probe		= clk_rk3506_probe,
+	.driver		= {
+		.name	= "clk-rk3506",
+		.of_match_table = clk_rk3506_match_table,
+		.suppress_bind_attrs = true,
+	},
+};
+builtin_platform_driver_probe(clk_rk3506_driver, clk_rk3506_probe);
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index 87f09320b942..b2fff1d13a4a 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -275,6 +275,18 @@ struct clk;
 #define RK3399_PMU_CLKGATE_CON(x)	((x) * 0x4 + 0x100)
 #define RK3399_PMU_SOFTRST_CON(x)	((x) * 0x4 + 0x110)
 
+#define RK3506_PMU_CRU_BASE		0x10000
+#define RK3506_PLL_CON(x)		((x) * 0x4 + RK3506_PMU_CRU_BASE)
+#define RK3506_CLKSEL_CON(x)		((x) * 0x4 + 0x300)
+#define RK3506_CLKGATE_CON(x)		((x) * 0x4 + 0x800)
+#define RK3506_SOFTRST_CON(x)		((x) * 0x4 + 0xa00)
+#define RK3506_PMU_CLKSEL_CON(x)	((x) * 0x4 + 0x300 + RK3506_PMU_CRU_BASE)
+#define RK3506_PMU_CLKGATE_CON(x)	((x) * 0x4 + 0x800 + RK3506_PMU_CRU_BASE)
+#define RK3506_MODE_CON			0x280
+#define RK3506_GLB_CNT_TH		0xc00
+#define RK3506_GLB_SRST_FST		0xc08
+#define RK3506_GLB_SRST_SND		0xc0c
+
 #define RK3528_PMU_CRU_BASE		0x10000
 #define RK3528_PCIE_CRU_BASE		0x20000
 #define RK3528_DDRPHY_CRU_BASE		0x28000
@@ -1329,6 +1341,7 @@ static inline void rockchip_register_softrst(struct device_node *np,
 }
 
 void rv1126b_rst_init(struct device_node *np, void __iomem *reg_base);
+void rk3506_rst_init(struct device_node *np, void __iomem *reg_base);
 void rk3528_rst_init(struct device_node *np, void __iomem *reg_base);
 void rk3562_rst_init(struct device_node *np, void __iomem *reg_base);
 void rk3576_rst_init(struct device_node *np, void __iomem *reg_base);
diff --git a/drivers/clk/rockchip/rst-rk3506.c b/drivers/clk/rockchip/rst-rk3506.c
new file mode 100644
index 000000000000..c3abde60f3c6
--- /dev/null
+++ b/drivers/clk/rockchip/rst-rk3506.c
@@ -0,0 +1,226 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2025 Rockchip Electronics Co., Ltd.
+ * Author: Finley Xiao <finley.xiao at rock-chips.com>
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <dt-bindings/reset/rockchip,rk3506-cru.h>
+#include "clk.h"
+
+/* 0xFF9A0000 + 0x0A00 */
+#define RK3506_CRU_RESET_OFFSET(id, reg, bit) [id] = (0 + reg * 16 + bit)
+
+/* mapping table for reset ID to register offset */
+static const int rk3506_register_offset[] = {
+	/* CRU-->SOFTRST_CON00 */
+	RK3506_CRU_RESET_OFFSET(SRST_NCOREPORESET0_AC, 0, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_NCOREPORESET1_AC, 0, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_NCOREPORESET2_AC, 0, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_NCORESET0_AC, 0, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_NCORESET1_AC, 0, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_NCORESET2_AC, 0, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_NL2RESET_AC, 0, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_A_CORE_BIU_AC, 0, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_H_M0_AC, 0, 10),
+
+	/* CRU-->SOFTRST_CON02 */
+	RK3506_CRU_RESET_OFFSET(SRST_NDBGRESET, 2, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_P_CORE_BIU, 2, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_PMU, 2, 15),
+
+	/* CRU-->SOFTRST_CON03 */
+	RK3506_CRU_RESET_OFFSET(SRST_P_DBG, 3, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_POT_DBG, 3, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_P_CORE_GRF, 3, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_CORE_EMA_DETECT, 3, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_REF_PVTPLL_CORE, 3, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_P_GPIO1, 3, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_DB_GPIO1, 3, 9),
+
+	/* CRU-->SOFTRST_CON04 */
+	RK3506_CRU_RESET_OFFSET(SRST_A_CORE_PERI_BIU, 4, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_A_DSMC, 4, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_P_DSMC, 4, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_FLEXBUS, 4, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_A_FLEXBUS, 4, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_H_FLEXBUS, 4, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_A_DSMC_SLV, 4, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_H_DSMC_SLV, 4, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_DSMC_SLV, 4, 13),
+
+	/* CRU-->SOFTRST_CON05 */
+	RK3506_CRU_RESET_OFFSET(SRST_A_BUS_BIU, 5, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_H_BUS_BIU, 5, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_P_BUS_BIU, 5, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_A_SYSRAM, 5, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_H_SYSRAM, 5, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_A_DMAC0, 5, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_A_DMAC1, 5, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_H_M0, 5, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_M0_JTAG, 5, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_H_CRYPTO, 5, 15),
+
+	/* CRU-->SOFTRST_CON06 */
+	RK3506_CRU_RESET_OFFSET(SRST_H_RNG, 6, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_P_BUS_GRF, 6, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_P_TIMER0, 6, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH0, 6, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH1, 6, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH2, 6, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH3, 6, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH4, 6, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH5, 6, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_P_WDT0, 6, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_T_WDT0, 6, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_P_WDT1, 6, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_T_WDT1, 6, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_P_MAILBOX, 6, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_P_INTMUX, 6, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_P_SPINLOCK, 6, 15),
+
+	/* CRU-->SOFTRST_CON07 */
+	RK3506_CRU_RESET_OFFSET(SRST_P_DDRC, 7, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_H_DDRPHY, 7, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_P_DDRMON, 7, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_DDRMON_OSC, 7, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_P_DDR_LPC, 7, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_H_USBOTG0, 7, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_USBOTG0_ADP, 7, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_H_USBOTG1, 7, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_USBOTG1_ADP, 7, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_P_USBPHY, 7, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_USBPHY_POR, 7, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_USBPHY_OTG0, 7, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_USBPHY_OTG1, 7, 14),
+
+	/* CRU-->SOFTRST_CON08 */
+	RK3506_CRU_RESET_OFFSET(SRST_A_DMA2DDR, 8, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_P_DMA2DDR, 8, 1),
+
+	/* CRU-->SOFTRST_CON09 */
+	RK3506_CRU_RESET_OFFSET(SRST_USBOTG0_UTMI, 9, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_USBOTG1_UTMI, 9, 1),
+
+	/* CRU-->SOFTRST_CON10 */
+	RK3506_CRU_RESET_OFFSET(SRST_A_DDRC_0, 10, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_A_DDRC_1, 10, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_A_DDR_BIU, 10, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_DDRC, 10, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_DDRMON, 10, 4),
+
+	/* CRU-->SOFTRST_CON11 */
+	RK3506_CRU_RESET_OFFSET(SRST_H_LSPERI_BIU, 11, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_P_UART0, 11, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_P_UART1, 11, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_P_UART2, 11, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_P_UART3, 11, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_P_UART4, 11, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_UART0, 11, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_UART1, 11, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_UART2, 11, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_UART3, 11, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_UART4, 11, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_P_I2C0, 11, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_I2C0, 11, 15),
+
+	/* CRU-->SOFTRST_CON12 */
+	RK3506_CRU_RESET_OFFSET(SRST_P_I2C1, 12, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_I2C1, 12, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_P_I2C2, 12, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_I2C2, 12, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_P_PWM1, 12, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_PWM1, 12, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_P_SPI0, 12, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_SPI0, 12, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_P_SPI1, 12, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_SPI1, 12, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_P_GPIO2, 12, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_DB_GPIO2, 12, 15),
+
+	/* CRU-->SOFTRST_CON13 */
+	RK3506_CRU_RESET_OFFSET(SRST_P_GPIO3, 13, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_DB_GPIO3, 13, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_P_GPIO4, 13, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_DB_GPIO4, 13, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_H_CAN0, 13, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_CAN0, 13, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_H_CAN1, 13, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_CAN1, 13, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_H_PDM, 13, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_M_PDM, 13, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_PDM, 13, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_SPDIFTX, 13, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_H_SPDIFTX, 13, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_H_SPDIFRX, 13, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_SPDIFRX, 13, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_M_SAI0, 13, 15),
+
+	/* CRU-->SOFTRST_CON14 */
+	RK3506_CRU_RESET_OFFSET(SRST_H_SAI0, 14, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_M_SAI1, 14, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_H_SAI1, 14, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_H_ASRC0, 14, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_ASRC0, 14, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_H_ASRC1, 14, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_ASRC1, 14, 8),
+
+	/* CRU-->SOFTRST_CON17 */
+	RK3506_CRU_RESET_OFFSET(SRST_H_HSPERI_BIU, 17, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_H_SDMMC, 17, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_H_FSPI, 17, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_S_FSPI, 17, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_P_SPI2, 17, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_A_MAC0, 17, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_A_MAC1, 17, 12),
+
+	/* CRU-->SOFTRST_CON18 */
+	RK3506_CRU_RESET_OFFSET(SRST_M_SAI2, 18, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_H_SAI2, 18, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_H_SAI3, 18, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_M_SAI3, 18, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_H_SAI4, 18, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_M_SAI4, 18, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_H_DSM, 18, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_M_DSM, 18, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_P_AUDIO_ADC, 18, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_M_AUDIO_ADC, 18, 15),
+
+	/* CRU-->SOFTRST_CON19 */
+	RK3506_CRU_RESET_OFFSET(SRST_P_SARADC, 19, 0),
+	RK3506_CRU_RESET_OFFSET(SRST_SARADC, 19, 1),
+	RK3506_CRU_RESET_OFFSET(SRST_SARADC_PHY, 19, 2),
+	RK3506_CRU_RESET_OFFSET(SRST_P_OTPC_NS, 19, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_SBPI_OTPC_NS, 19, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_USER_OTPC_NS, 19, 5),
+	RK3506_CRU_RESET_OFFSET(SRST_P_UART5, 19, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_UART5, 19, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_P_GPIO234_IOC, 19, 8),
+
+	/* CRU-->SOFTRST_CON21 */
+	RK3506_CRU_RESET_OFFSET(SRST_A_VIO_BIU, 21, 3),
+	RK3506_CRU_RESET_OFFSET(SRST_H_VIO_BIU, 21, 4),
+	RK3506_CRU_RESET_OFFSET(SRST_H_RGA, 21, 6),
+	RK3506_CRU_RESET_OFFSET(SRST_A_RGA, 21, 7),
+	RK3506_CRU_RESET_OFFSET(SRST_CORE_RGA, 21, 8),
+	RK3506_CRU_RESET_OFFSET(SRST_A_VOP, 21, 9),
+	RK3506_CRU_RESET_OFFSET(SRST_H_VOP, 21, 10),
+	RK3506_CRU_RESET_OFFSET(SRST_VOP, 21, 11),
+	RK3506_CRU_RESET_OFFSET(SRST_P_DPHY, 21, 12),
+	RK3506_CRU_RESET_OFFSET(SRST_P_DSI_HOST, 21, 13),
+	RK3506_CRU_RESET_OFFSET(SRST_P_TSADC, 21, 14),
+	RK3506_CRU_RESET_OFFSET(SRST_TSADC, 21, 15),
+
+	/* CRU-->SOFTRST_CON22 */
+	RK3506_CRU_RESET_OFFSET(SRST_P_GPIO1_IOC, 22, 1),
+};
+
+void rk3506_rst_init(struct device_node *np, void __iomem *reg_base)
+{
+	rockchip_register_softrst_lut(np,
+				      rk3506_register_offset,
+				      ARRAY_SIZE(rk3506_register_offset),
+				      reg_base + RK3506_SOFTRST_CON(0),
+				      ROCKCHIP_SOFTRST_HIWORD_MASK);
+}
-- 
2.34.1



From gregkh at linuxfoundation.org  Fri Nov 21 06:07:03 2025
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Fri, 21 Nov 2025 15:07:03 +0100
Subject: [PATCH v10 01/11] usb: typec: Add notifier functions
In-Reply-To: <20251120022343.250-2-kernel@airkyi.com>
References: <20251120022343.250-1-kernel@airkyi.com>
 <20251120022343.250-2-kernel@airkyi.com>
Message-ID: <2025112102-laurel-mulch-58e4@gregkh>

On Thu, Nov 20, 2025 at 10:23:33AM +0800, Chaoyi Chen wrote:
> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> 
> Some other part of kernel may want to know the event of typec bus.

Be specific, WHAT part of the kernel will need to know this?

And why a new notifier, why not just use the existing notifiers that you
already have?  And what is this going to be used for?

Notifiers are a pain, and should almost never be added.  Use real
function calls instead.

thanks,

greg k-h


From gregkh at linuxfoundation.org  Fri Nov 21 06:07:30 2025
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Fri, 21 Nov 2025 15:07:30 +0100
Subject: [PATCH v10 02/11] usb: typec: Export all typec device types
In-Reply-To: <20251120022343.250-3-kernel@airkyi.com>
References: <20251120022343.250-1-kernel@airkyi.com>
 <20251120022343.250-3-kernel@airkyi.com>
Message-ID: <2025112109-glacial-outmatch-add7@gregkh>

On Thu, Nov 20, 2025 at 10:23:34AM +0800, Chaoyi Chen wrote:
> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> 
> Export all typec device types for identification.

I do not understand what this means.  Who is going to use these symbols,
and for what exactly?

Be specific please.

thanks,

greg k-h


From neil.armstrong at linaro.org  Fri Nov 21 06:54:18 2025
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Fri, 21 Nov 2025 15:54:18 +0100
Subject: [PATCH v10 04/11] drm/bridge: aux: Add
 drm_aux_bridge_register_from_node()
In-Reply-To: <20251120022343.250-5-kernel@airkyi.com>
References: <20251120022343.250-1-kernel@airkyi.com>
 <20251120022343.250-5-kernel@airkyi.com>
Message-ID: <cd200f33-dd6f-4eb3-b2d9-8f41d0dde992@linaro.org>

On 11/20/25 03:23, Chaoyi Chen wrote:
> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> 
> The drm_aux_bridge_register() uses the device->of_node as the
> bridge->of_node.
> 
> This patch adds drm_aux_bridge_register_from_node() to allow
> specifying the of_node corresponding to the bridge.
> 
> Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> ---
>   drivers/gpu/drm/bridge/aux-bridge.c | 24 ++++++++++++++++++++++--
>   include/drm/bridge/aux-bridge.h     |  6 ++++++
>   2 files changed, 28 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/aux-bridge.c b/drivers/gpu/drm/bridge/aux-bridge.c
> index b3e4cdff61d6..52dff4601c2d 100644
> --- a/drivers/gpu/drm/bridge/aux-bridge.c
> +++ b/drivers/gpu/drm/bridge/aux-bridge.c
> @@ -35,6 +35,7 @@ static void drm_aux_bridge_unregister_adev(void *_adev)
>   /**
>    * drm_aux_bridge_register - Create a simple bridge device to link the chain
>    * @parent: device instance providing this bridge
> + * @np: device node pointer corresponding to this bridge instance
>    *
>    * Creates a simple DRM bridge that doesn't implement any drm_bridge
>    * operations. Such bridges merely fill a place in the bridge chain linking
> @@ -42,7 +43,7 @@ static void drm_aux_bridge_unregister_adev(void *_adev)
>    *
>    * Return: zero on success, negative error code on failure
>    */
> -int drm_aux_bridge_register(struct device *parent)
> +int drm_aux_bridge_register_from_node(struct device *parent, struct device_node *np)
>   {
>   	struct auxiliary_device *adev;
>   	int ret;
> @@ -62,7 +63,10 @@ int drm_aux_bridge_register(struct device *parent)
>   	adev->dev.parent = parent;
>   	adev->dev.release = drm_aux_bridge_release;
>   
> -	device_set_of_node_from_dev(&adev->dev, parent);
> +	if (np)
> +		device_set_node(&adev->dev, of_fwnode_handle(np));
> +	else
> +		device_set_of_node_from_dev(&adev->dev, parent);
>   
>   	ret = auxiliary_device_init(adev);
>   	if (ret) {
> @@ -80,6 +84,22 @@ int drm_aux_bridge_register(struct device *parent)
>   
>   	return devm_add_action_or_reset(parent, drm_aux_bridge_unregister_adev, adev);
>   }
> +EXPORT_SYMBOL_GPL(drm_aux_bridge_register_from_node);
> +
> +/**
> + * drm_aux_bridge_register - Create a simple bridge device to link the chain
> + * @parent: device instance providing this bridge
> + *
> + * Creates a simple DRM bridge that doesn't implement any drm_bridge
> + * operations. Such bridges merely fill a place in the bridge chain linking
> + * surrounding DRM bridges.
> + *
> + * Return: zero on success, negative error code on failure
> + */
> +int drm_aux_bridge_register(struct device *parent)
> +{
> +	return drm_aux_bridge_register_from_node(parent, NULL);
> +}
>   EXPORT_SYMBOL_GPL(drm_aux_bridge_register);
>   
>   struct drm_aux_bridge_data {
> diff --git a/include/drm/bridge/aux-bridge.h b/include/drm/bridge/aux-bridge.h
> index c2f5a855512f..7dd1f17a1354 100644
> --- a/include/drm/bridge/aux-bridge.h
> +++ b/include/drm/bridge/aux-bridge.h
> @@ -13,11 +13,17 @@ struct auxiliary_device;
>   
>   #if IS_ENABLED(CONFIG_DRM_AUX_BRIDGE)
>   int drm_aux_bridge_register(struct device *parent);
> +int drm_aux_bridge_register_from_node(struct device *parent, struct device_node *np);
>   #else
>   static inline int drm_aux_bridge_register(struct device *parent)
>   {
>   	return 0;
>   }
> +
> +static inline int drm_aux_bridge_register_from_node(struct device *parent, struct device_node *np)
> +{
> +	return 0;
> +}
>   #endif
>   
>   #if IS_ENABLED(CONFIG_DRM_AUX_HPD_BRIDGE)

Looks fine:
Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From neil.armstrong at linaro.org  Fri Nov 21 06:54:34 2025
From: neil.armstrong at linaro.org (Neil Armstrong)
Date: Fri, 21 Nov 2025 15:54:34 +0100
Subject: [PATCH v10 07/11] phy: rockchip: phy-rockchip-typec: Add DRM AUX
 bridge
In-Reply-To: <20251120022343.250-8-kernel@airkyi.com>
References: <20251120022343.250-1-kernel@airkyi.com>
 <20251120022343.250-8-kernel@airkyi.com>
Message-ID: <326cd208-fcce-49d1-94ee-4913f85bffbf@linaro.org>

On 11/20/25 03:23, Chaoyi Chen wrote:
> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> 
> Using the DRM_AUX_BRIDGE helper to create the transparent DRM bridge
> device.
> 
> Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> ---
> 
> Changes in v10:
> - Use drm_aux_bridge_register_from_node() instead.
> 
> (no changes since v7)
> 
> Changes in v6:
> - Fix depend in Kconfig.
> 
>   drivers/phy/rockchip/Kconfig              | 2 ++
>   drivers/phy/rockchip/phy-rockchip-typec.c | 5 +++++
>   2 files changed, 7 insertions(+)
> 
> diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
> index db4adc7c53da..bcb5476222fc 100644
> --- a/drivers/phy/rockchip/Kconfig
> +++ b/drivers/phy/rockchip/Kconfig
> @@ -120,6 +120,8 @@ config PHY_ROCKCHIP_TYPEC
>   	tristate "Rockchip TYPEC PHY Driver"
>   	depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST)
>   	depends on TYPEC || TYPEC=n
> +	depends on DRM || DRM=n
> +	select DRM_AUX_BRIDGE if DRM_BRIDGE
>   	select EXTCON
>   	select GENERIC_PHY
>   	select RESET_CONTROLLER
> diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c
> index 1f5b4142cbe4..e31b778c3537 100644
> --- a/drivers/phy/rockchip/phy-rockchip-typec.c
> +++ b/drivers/phy/rockchip/phy-rockchip-typec.c
> @@ -56,6 +56,7 @@
>   #include <linux/phy/phy.h>
>   #include <linux/usb/typec_dp.h>
>   #include <linux/usb/typec_mux.h>
> +#include <drm/bridge/aux-bridge.h>
>   
>   #define CMN_SSM_BANDGAP			(0x21 << 2)
>   #define CMN_SSM_BIAS			(0x22 << 2)
> @@ -1312,6 +1313,10 @@ static int tcphy_setup_typec_mux(struct rockchip_typec_phy *tcphy)
>   	if (!of_property_read_bool(np, "mode-switch"))
>   		goto put_np;
>   
> +	ret = drm_aux_bridge_register_from_node(tcphy->dev, np);
> +	if (ret)
> +		goto put_np;
> +
>   	mux_desc.drvdata = tcphy;
>   	mux_desc.fwnode = device_get_named_child_node(tcphy->dev, "dp-port");
>   	mux_desc.set = tcphy_typec_mux_set;

Much better now !
Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>


From mripard at kernel.org  Fri Nov 21 07:36:28 2025
From: mripard at kernel.org (Maxime Ripard)
Date: Fri, 21 Nov 2025 16:36:28 +0100
Subject: [PATCH v3 00/11] drm/connector: hdmi: limit infoframes per
 driver capabilities
In-Reply-To: <pibxhl5hlcpuk3zsgyienfdlda5cwuxrnofwlw356scuzzplqy@zw3ofelgvwik>
References: <20250910-didactic-honored-chachalaca-f233b2@houat>
 <x562ueky2z5deqqmhl222moyrbylfwi35u4hb34dpl3z52ra4c@dyw4iayrewnz>
 <20250925-fervent-merry-beagle-2baba3@penduick>
 <qx5ashx62pufott6hnsfna3qntnoyvxwxze4rihhuxcsdxi37s@bbdvc3sfsgne>
 <20250929-gregarious-worm-of-memory-c5354d@houat>
 <itgffxygopi7etkt7xhvmyuvyl5ad3k43nsxvjzw3ubtwiikn7@ocugfdaigtu7>
 <20251003-uptight-echidna-of-stamina-815305@houat>
 <zpygq4kapil3swsmhhqkdwny4ry2dznnzixsw5rkza5p2kqnvp@abvf2vxlbwif>
 <2a5fitdzr2bz235fj6rvqzxr6ckszkjbazjfszlvnizdh2cvbt@w3ypjo7vahhs>
 <pibxhl5hlcpuk3zsgyienfdlda5cwuxrnofwlw356scuzzplqy@zw3ofelgvwik>
Message-ID: <bsoqyzxi45i67jpzhwr2d4illufa5ghqf25z6flbp67lsbvh22@rrlcihp2oxea>

On Tue, Oct 14, 2025 at 06:48:19PM +0300, Dmitry Baryshkov wrote:
> On Tue, Oct 14, 2025 at 02:59:43PM +0200, Maxime Ripard wrote:
> > On Fri, Oct 03, 2025 at 06:54:47PM +0300, Dmitry Baryshkov wrote:
> > > On Fri, Oct 03, 2025 at 03:22:23PM +0200, Maxime Ripard wrote:
> > > > On Tue, Sep 30, 2025 at 10:02:28AM +0300, Dmitry Baryshkov wrote:
> > > > > On Mon, Sep 29, 2025 at 03:00:04PM +0200, Maxime Ripard wrote:
> > > > > > On Thu, Sep 25, 2025 at 05:16:07PM +0300, Dmitry Baryshkov wrote:
> > > > > > > On Thu, Sep 25, 2025 at 03:13:47PM +0200, Maxime Ripard wrote:
> > > > > > > > On Wed, Sep 10, 2025 at 06:26:56PM +0300, Dmitry Baryshkov wrote:
> > > > > > > > > On Wed, Sep 10, 2025 at 09:30:19AM +0200, Maxime Ripard wrote:
> > > > > > > > > > On Wed, Sep 03, 2025 at 03:03:43AM +0300, Dmitry Baryshkov wrote:
> > > > > > > > > > > On Tue, Sep 02, 2025 at 08:06:54PM +0200, Maxime Ripard wrote:
> > > > > > > > > > > > On Tue, Sep 02, 2025 at 06:45:44AM +0300, Dmitry Baryshkov wrote:
> > > > > > > > > > > > > On Mon, Sep 01, 2025 at 09:07:02AM +0200, Maxime Ripard wrote:
> > > > > > > > > > > > > > On Sun, Aug 31, 2025 at 01:29:13AM +0300, Dmitry Baryshkov wrote:
> > > > > > > > > > > > > > > On Sat, Aug 30, 2025 at 09:30:01AM +0200, Daniel Stone wrote:
> > > > > > > > > > > > > > > > Hi Dmitry,
> > > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > > On Sat, 30 Aug 2025 at 02:23, Dmitry Baryshkov
> > > > > > > > > > > > > > > > <dmitry.baryshkov at oss.qualcomm.com> wrote:
> > > > > > > > > > > > > > > > > It's not uncommon for the particular device to support only a subset of
> > > > > > > > > > > > > > > > > HDMI InfoFrames. It's not a big problem for the kernel, since we adopted
> > > > > > > > > > > > > > > > > a model of ignoring the unsupported Infoframes, but it's a bigger
> > > > > > > > > > > > > > > > > problem for the userspace: we end up having files in debugfs which do
> > > > > > > > > > > > > > > > > mot match what is being sent on the wire.
> > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > Sort that out, making sure that all interfaces are consistent.
> > > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > > Thanks for the series, it's a really good cleanup.
> > > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > > I know that dw-hdmi-qp can support _any_ infoframe, by manually
> > > > > > > > > > > > > > > > packing it into the two GHDMI banks. So the supported set there is
> > > > > > > > > > > > > > > > 'all of the currently well-known ones, plus any two others, but only
> > > > > > > > > > > > > > > > two and not more'. I wonder if that has any effect on the interface
> > > > > > > > > > > > > > > > you were thinking about for userspace?
> > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > I was mostly concerned with the existing debugfs interface (as it is
> > > > > > > > > > > > > > > also used e.g. for edid-decode, etc).
> > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > It seems "everything + 2 spare" is more or less common (ADV7511, MSM
> > > > > > > > > > > > > > > HDMI also have those. I don't have at hand the proper datasheet for
> > > > > > > > > > > > > > > LT9611 (non-UXC one), but I think its InfoFrames are also more or less
> > > > > > > > > > > > > > > generic).  Maybe we should change debugfs integration to register the
> > > > > > > > > > > > > > > file when the frame is being enabled and removing it when it gets unset.
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > > But, like, for what benefit?
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > > It's a debugfs interface for userspace to consume. The current setup
> > > > > > > > > > > > > > works fine with edid-decode already. Why should we complicate the design
> > > > > > > > > > > > > > that much and create fun races like "I'm running edid-decode in parallel
> > > > > > > > > > > > > > to a modeset that would remove the file I just opened, what is the file
> > > > > > > > > > > > > > now?".
> > > > > > > > > > > > > 
> > > > > > > > > > > > > Aren't we trading that with the 'I'm running edid-decode in paralle with
> > > > > > > > > > > > > to a modeset and the file suddenly becomes empty'?
> > > > > > > > > > > > 
> > > > > > > > > > > > In that case, you know what the file is going to be: empty. And you went
> > > > > > > > > > > > from a racy, straightforward, design to a racy, complicated, design.
> > > > > > > > > > > > 
> > > > > > > > > > > > It was my question before, but I still don't really see what benefits it
> > > > > > > > > > > > would have, and why we need to care about it in the core, when it could
> > > > > > > > > > > > be dealt with in the drivers just fine on a case by case basis.
> > > > > > > > > > > 
> > > > > > > > > > > Actually it can not: debugfs files are registered from the core, not
> > > > > > > > > > > from the drivers. That's why I needed all the supported_infoframes
> > > > > > > > > > > (which later became software_infoframes).
> > > > > > > > > > 
> > > > > > > > > > That's one thing we can change then.
> > > > > > > > > > 
> > > > > > > > > > > Anyway, I'm fine with having empty files there.
> > > > > > > > > > > 
> > > > > > > > > > > > > > > Then in the long run we can add 'slots' and allocate some of the frames
> > > > > > > > > > > > > > > to the slots. E.g. ADV7511 would get 'software AVI', 'software SPD',
> > > > > > > > > > > > > > > 'auto AUDIO' + 2 generic slots (and MPEG InfoFrame which can probably be
> > > > > > > > > > > > > > > salvaged as another generic one)). MSM HDMI would get 'software AVI',
> > > > > > > > > > > > > > > 'software AUDIO' + 2 generic slots (+MPEG + obsucre HDMI which I don't
> > > > > > > > > > > > > > > want to use). Then the framework might be able to prioritize whether to
> > > > > > > > > > > > > > > use generic slots for important data (as DRM HDR, HDMI) or less important
> > > > > > > > > > > > > > > (SPD).
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > > Why is it something for the framework to deal with? If you want to have
> > > > > > > > > > > > > > extra infoframes in there, just go ahead and create additional debugfs
> > > > > > > > > > > > > > files in your driver.
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > > If you want to have the slot mechanism, check in your atomic_check that
> > > > > > > > > > > > > > only $NUM_SLOT at most infoframes are set.
> > > > > > > > > > > > > 
> > > > > > > > > > > > > The driver can only decide that 'we have VSI, SPD and DRM InfoFrames
> > > > > > > > > > > > > which is -ETOOMUCH for 2 generic slots'. The framework should be able to
> > > > > > > > > > > > > decide 'the device has 2 generic slots, we have HDR data, use VSI and
> > > > > > > > > > > > > DRM InfoFrames and disable SPD for now'.
> > > > > > > > > > > > 
> > > > > > > > > > > > I mean... the spec does? The spec says when a particular feature
> > > > > > > > > > > > requires to send a particular infoframe. If your device cannot support
> > > > > > > > > > > > to have more than two "features" enabled at the same time, so be it. It
> > > > > > > > > > > > something that should be checked in that driver atomic_check.
> > > > > > > > > > > 
> > > > > > > > > > > Sounds good to me. Let's have those checks in the drivers until we
> > > > > > > > > > > actually have seveal drivers performing generic frame allocation.
> > > > > > > > > > > 
> > > > > > > > > > > > Or just don't register the SPD debugfs file, ignore it, put a comment
> > > > > > > > > > > > there, and we're done too.
> > > > > > > > > > > 
> > > > > > > > > > > It's generic code.
> > > > > > > > > > > 
> > > > > > > > > > > > > But... We are not there yet and I don't have clear usecase (we support
> > > > > > > > > > > > > HDR neither on ADV7511 nor on MSM HDMI, after carefully reading the
> > > > > > > > > > > > > guide I realised that ADV7511 has normal audio infoframes). Maybe I
> > > > > > > > > > > > > should drop all the 'auto' features, simplifying this series and land
> > > > > > > > > > > > > [1] for LT9611UXC as I wanted origianlly.
> > > > > > > > > > > > > 
> > > > > > > > > > > > > [1] https://lore.kernel.org/dri-devel/20250803-lt9611uxc-hdmi-v1-2-cb9ce1793acf at oss.qualcomm.com/
> > > > > > > > > > > > 
> > > > > > > > > > > > Looking back at that series, I think it still has value to rely on the
> > > > > > > > > > > > HDMI infrastructure at the very least for the atomic_check sanitization.
> > > > > > > > > > > > 
> > > > > > > > > > > > But since you wouldn't use the generated infoframes, just skip the
> > > > > > > > > > > > debugfs files registration. You're not lying to userspace anymore, and
> > > > > > > > > > > > you get the benefits of the HDMI framework.
> > > > > > > > > > > 
> > > > > > > > > > > We create all infoframe files for all HDMI connectors.
> > > > > > > > > > 
> > > > > > > > > > Then we can provide a debugfs_init helper to register all of them, or
> > > > > > > > > > only some of them, and let the drivers figure it out.
> > > > > > > > > > 
> > > > > > > > > > Worst case scenario, debugfs files will not get created, which is a much
> > > > > > > > > > better outcome than having to put boilerplate in every driver that will
> > > > > > > > > > get inconsistent over time.
> > > > > > > > > 
> > > > > > > > > debugfs_init() for each infoframe or taking some kind of bitmask?
> > > > > > > > 
> > > > > > > > I meant turning hdmi_debugfs_add and create_hdmi_*_infoframe_file into
> > > > > > > > public helpers. That way, drivers that don't care can use the (renamed)
> > > > > > > > hdmi_debugfs_add, and drivers with different constraints can register
> > > > > > > > the relevant infoframes directly.
> > > > > > > 
> > > > > > > Doesn't that mean more boilerplate?
> > > > > > 
> > > > > > I don't think it would? In the general case, it wouldn't change
> > > > > > anything, and in special cases, then it's probably going to be different
> > > > > > from one driver to the next so there's not much we can do.
> > > > > > 
> > > > > > > In the end, LT9611UXC is a special case, for which I'm totally fine
> > > > > > > not to use HDMI helpers at this point: we don't control infoframes
> > > > > > > (hopefully that can change), we don't care about the TMDS clock, no
> > > > > > > CEC, etc.
> > > > > > 
> > > > > > Not using the helpers sound pretty reasonable here too.
> > > > > > 
> > > > > > > For all other usecases I'm fine with having atomic_check() unset all
> > > > > > > unsupported infoframes and having empty files in debugfs. Then we can
> > > > > > > evolve over the time, once we see a pattern. We had several drivers
> > > > > > > which had very limited infoframes support, but I think this now gets
> > > > > > > sorted over the time.
> > > > > > 
> > > > > > I never talked about atomic_check()? You were initially concerned that
> > > > > > the framework would expose data in debugfs that it's not using. Not
> > > > > > registering anything in debugfs solves that, but I'm not sure we need to
> > > > > > special case atomic_check.
> > > > > 
> > > > > Well... I ended up with [1], handling infoframes in the atomic_check()
> > > > > rather than registering fewer infoframe debugfs files. This way device
> > > > > state is consistent, we don't have enabled instances, etc. However it
> > > > > results in repetetive code in atomic_check().
> > > > > 
> > > > > [1] https://lore.kernel.org/dri-devel/20250928-limit-infoframes-2-v2-0-6f8f5fd04214 at oss.qualcomm.com/
> > > > 
> > > > I guess we can continue the discussion there, but I'm not sure we want
> > > > to have more boilerplate in drivers, and especially in the atomic_check
> > > > part. If drivers are inconsistent or wrong in the debugfs path, there's
> > > > no major issue. If they are wrong in the atomic_check path, it will lead
> > > > to regressions, possibly in paths that are pretty hard to test.
> > > 
> > > You've responded there and I can drop the extra handling for HDR DRM and
> > > audio infoframes in the atomic_check(). What is your opinion about the
> > > atomic_check() unsetting the infoframe->set for SPD and HDMI infoframes?
> > 
> > HDMI infoframes are mandatory, so that's a big no-no.
> 
> Nevertheless... There are drivers (sun4i, inno_hdmi, rk3066, dw_hdmi_qp)
> which don't (yet) implement VSI support.

We should really differentiate drivers that didn't because they were
allowed to, and drivers that can't.

For the bridge you mentioned earlier in the discussion, it makes sense
not to expose the debugfs file because we simply don't have access to
the actual content. That's fine.

For the drivers you listed there, I'm pretty confident that it's because
nobody really tried. That's definitely not fine, and we should complain
as loudly as possible for that particular case, and not give them a free
pass. Checking sun4i, I'm pretty sure it can be implemented. Looking at
the incomplete RK3066 TRM, it can be implemented too. And inno_hdmi
looks really similar.

So it's not really impossible, you just need some hardware and a day's
worth of work.

There's no reason these should get a pass, it's breaking the spec for no
reason.

> > For SPD, It's really not clear to me why atomic_check should do that in
> > the first place. Your initial concern was about exposing infoframes in
> > debugfs that wouldn't be used by the driver.
> > 
> > If the driver doesn't register a debugfs file for SPD, and ignores
> > whatever is in the atomic state, what's should we force drivers to do
> > that?
> 
> I really don't think that drivers should mess up with debugfs on their
> own. Making atomic_check() disable the unsupported InfoFrames makes the
> picture perfect: the DRM no longer tries to program them to the
> hardware, DebugFS files stay empty, so the whole state becomes
> consistent.

In the "bridge has no access to infoframes" case, there's really no
infoframe. An empty file is "the infoframe can be there but isn't used",
not "we don't have access to it and can't report them". Only drivers
have those infos.

If we do split up write_infoframe into multiple functions though, I
guess we could create the debugfs file only if the function pointer is
set, which removes drivers' involvement if you don't like that.

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 273 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251121/3616f5aa/attachment.sig>

From mripard at kernel.org  Fri Nov 21 07:48:02 2025
From: mripard at kernel.org (Maxime Ripard)
Date: Fri, 21 Nov 2025 16:48:02 +0100
Subject: [PATCH v4 01/10] drm/connector: let drivers declare infoframes
 as unsupported
In-Reply-To: <ez6y7q4lgbwt7kpnlpausjpznckr3yyejrwtxm7o6qw6wlhqoj@6iypzdhfthzy>
References: <20250909-drm-limit-infoframes-v4-0-53fd0a65a4a2@oss.qualcomm.com>
 <20250909-drm-limit-infoframes-v4-1-53fd0a65a4a2@oss.qualcomm.com>
 <20250910-furry-singing-axolotl-9aceac@houat>
 <z333ysst5ifakomo35jtbpydj44epqwwn4da76rcnsq4are62m@32gsmgx2pcdi>
 <20250925-didactic-spiked-lobster-fefabe@penduick>
 <jfxtcvh4l5kzyv74llmzz3bbt6m4mhzhhwl6lh5kfeqgqhkrhi@jzfvtxpedmyf>
 <20251003-primitive-sepia-griffin-cfca55@houat>
 <54a06852-4897-4dae-ab9c-330d99f3bf42@oss.qualcomm.com>
 <5cc5l2dihgdbgnwyugelwrklpaiiy5yaczqllu4bi6asvlt354@kib3flskh34g>
 <ez6y7q4lgbwt7kpnlpausjpznckr3yyejrwtxm7o6qw6wlhqoj@6iypzdhfthzy>
Message-ID: <eiaxss57hauegv64ek4ddi3ib5x4t4g4xwiqvuaj43b52wpctb@p63ewh6tqblk>

On Tue, Oct 14, 2025 at 07:02:03PM +0300, Dmitry Baryshkov wrote:
> On Tue, Oct 14, 2025 at 02:43:58PM +0200, Maxime Ripard wrote:
> > On Fri, Oct 03, 2025 at 06:41:58PM +0300, Dmitry Baryshkov wrote:
> > > On 03/10/2025 17:23, Maxime Ripard wrote:
> > > > On Thu, Sep 25, 2025 at 05:55:06PM +0300, Dmitry Baryshkov wrote:
> > > > > > > As we will be getting more and more features, some of the InfoFrames
> > > > > > > or data packets will be 'good to have, but not required'.
> > > > > > 
> > > > > > And drivers would be free to ignore those.
> > > > > > 
> > > > > > > > So, no, sorry. That's still a no for me. Please stop sending that patch
> > > > > > > 
> > > > > > > Oops :-)
> > > > > > > 
> > > > > > > > unless we have a discussion about it and you convince me that it's
> > > > > > > > actually something that we'd need.
> > > > > > > 
> > > > > > > My main concern is that the drivers should not opt-out of the features.
> > > > > > > E.g. if we start supporting ISRC packets or MPEG or NTSC VBI InfoFrames
> > > > > > > (yes, stupid examples), it should not be required to go through all the
> > > > > > > drivers, making sure that they disable those. Instead the DRM framework
> > > > > > > should be able to make decisions like:
> > > > > > > 
> > > > > > > - The driver supports SPD and the VSDB defines SPD, enable this
> > > > > > >    InfoFrame (BTW, this needs to be done anyway, we should not be sending
> > > > > > >    SPD if it's not defined in VSDB, if I read it correctly).
> > > > > > > 
> > > > > > > - The driver hints that the pixel data has only 10 meaninful bits of
> > > > > > >    data per component (e.g. out of 12 for DeepColor 36), the Sink has
> > > > > > >    HF-VSDB, send HF-VSIF.
> > > > > > > 
> > > > > > > - The driver has enabled 3D stereo mode, but it doesn't declare support
> > > > > > >    for HF-VSIF. Send only H14b-VSIF.
> > > > > > > 
> > > > > > > Similarly (no, I don't have these on my TODO list, these are just
> > > > > > > examples):
> > > > > > > - The driver defines support for NTSC VBI, register a VBI device.
> > > > > > > 
> > > > > > > - The driver defines support for ISRC packets, register ISRC-related
> > > > > > >    properties.
> > > > > > > 
> > > > > > > - The driver defines support for MPEG Source InfoFrame, provide a way
> > > > > > >    for media players to report frame type and bit rate.
> > > > > > > 
> > > > > > > - The driver provides limited support for Extended HDR DM InfoFrames,
> > > > > > >    select the correct frame type according to driver capabilities.
> > > > > > > 
> > > > > > > Without the 'supported' information we should change atomic_check()
> > > > > > > functions to set infoframe->set to false for all unsupported InfoFrames
> > > > > > > _and_ go through all the drivers again each time we add support for a
> > > > > > > feature (e.g. after adding HF-VSIF support).
> > > > > > 
> > > > > >  From what you described here, I think we share a similar goal and have
> > > > > > somewhat similar concerns (thanks, btw, it wasn't obvious to me before),
> > > > > > we just disagree on the trade-offs and ideal solution :)
> > > > > > 
> > > > > > I agree that we need to sanity check the drivers, and I don't want to go
> > > > > > back to the situation we had before where drivers could just ignore
> > > > > > infoframes and take the easy way out.
> > > > > > 
> > > > > > It should be hard, and easy to catch during review.
> > > > > > 
> > > > > > I don't think bitflag are a solution because, to me, it kind of fails
> > > > > > both.
> > > > > > 
> > > > > > What if, just like the debugfs discussion, we split write_infoframe into
> > > > > > write_avi_infoframe (mandatory), write_spd_infoframe (optional),
> > > > > > write_audio_infoframe (checked by drm_connector_hdmi_audio_init?) and
> > > > > > write_hdr_infoframe (checked in drmm_connector_hdmi_init if max_bpc > 8)
> > > > > > 
> > > > > > How does that sound?
> > > > > 
> > > > > I'd say, I really like the single function to be called for writing the
> > > > > infoframes. It makes it much harder for drivers to misbehave or to skip
> > > > > something.
> > > > 
> > > >  From a driver PoV, I believe we should still have that single function
> > > > indeed. It would be drm_atomic_helper_connector_hdmi_update_infoframes's
> > > > job to fan out and call the multiple callbacks, not the drivers.
> > > 
> > > I like this idea, however it stops at the drm_bridge_connector abstraction.
> > > The only way to handle this I can foresee is to make individual bridges
> > > provide struct drm_connector_hdmi_funcs implementation (which I'm fine with)
> > > and store void *data or struct drm_bridge *hdmi_bridge somewhere inside
> > > struct drm_connector_hdmi in order to let bridge drivers find their data.
> > 
> > Does it change anything? The last HDMI bridge should implement all the
> > infoframes it supports. I don't think we should take care of one bridge
> > with one infoframe type and some other with another?
> 
> Note: I wrote about the _data_. So far the connector's write_infoframe /
> clear_infoframe callbacks get drm_connector as an arg. The fact that
> there is a drm_bridge which implements a callback is hidden well inside
> drm_bridge_connector (and only it knows the bridge_hdmi pointer).
> Otherwise, the bridge, trying to implement drm_connector_hdmi_funcs has
> no way to go from drm_connector to drm_bridge.
> 
> The only possible solution would be to introduce something like
> drm_connector_hdmi::data (either void* or drm_bridge*) and use it
> internally. But for me this looks like a bit loose abstraction. Though,
> if it looks good from your POV, I agree, it would solve enough of
> issues.

I'm not sure I understand, sorry.

What prevents us from adding ~4 functions to bridge->funcs that take the
bridge, and drm_bridge_connector would get the connector, retrieve the
bridge instance from it, and pass it to the bridge actually implementing
it? Like we do currently for write_infoframe and clear_infoframe
already?

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 273 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251121/562de55c/attachment-0001.sig>

From dmitry.baryshkov at oss.qualcomm.com  Fri Nov 21 08:08:03 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Fri, 21 Nov 2025 18:08:03 +0200
Subject: [PATCH v4 01/10] drm/connector: let drivers declare infoframes
 as unsupported
In-Reply-To: <eiaxss57hauegv64ek4ddi3ib5x4t4g4xwiqvuaj43b52wpctb@p63ewh6tqblk>
References: <20250909-drm-limit-infoframes-v4-1-53fd0a65a4a2@oss.qualcomm.com>
 <20250910-furry-singing-axolotl-9aceac@houat>
 <z333ysst5ifakomo35jtbpydj44epqwwn4da76rcnsq4are62m@32gsmgx2pcdi>
 <20250925-didactic-spiked-lobster-fefabe@penduick>
 <jfxtcvh4l5kzyv74llmzz3bbt6m4mhzhhwl6lh5kfeqgqhkrhi@jzfvtxpedmyf>
 <20251003-primitive-sepia-griffin-cfca55@houat>
 <54a06852-4897-4dae-ab9c-330d99f3bf42@oss.qualcomm.com>
 <5cc5l2dihgdbgnwyugelwrklpaiiy5yaczqllu4bi6asvlt354@kib3flskh34g>
 <ez6y7q4lgbwt7kpnlpausjpznckr3yyejrwtxm7o6qw6wlhqoj@6iypzdhfthzy>
 <eiaxss57hauegv64ek4ddi3ib5x4t4g4xwiqvuaj43b52wpctb@p63ewh6tqblk>
Message-ID: <5qncx5sww7feugjmtkskvoussd376rgxtcx3fqqgmgatjrdamx@iio4gxk2ildp>

On Fri, Nov 21, 2025 at 04:48:02PM +0100, Maxime Ripard wrote:
> On Tue, Oct 14, 2025 at 07:02:03PM +0300, Dmitry Baryshkov wrote:
> > On Tue, Oct 14, 2025 at 02:43:58PM +0200, Maxime Ripard wrote:
> > > On Fri, Oct 03, 2025 at 06:41:58PM +0300, Dmitry Baryshkov wrote:
> > > > On 03/10/2025 17:23, Maxime Ripard wrote:
> > > > > On Thu, Sep 25, 2025 at 05:55:06PM +0300, Dmitry Baryshkov wrote:
> > > > > > > > As we will be getting more and more features, some of the InfoFrames
> > > > > > > > or data packets will be 'good to have, but not required'.
> > > > > > > 
> > > > > > > And drivers would be free to ignore those.
> > > > > > > 
> > > > > > > > > So, no, sorry. That's still a no for me. Please stop sending that patch
> > > > > > > > 
> > > > > > > > Oops :-)
> > > > > > > > 
> > > > > > > > > unless we have a discussion about it and you convince me that it's
> > > > > > > > > actually something that we'd need.
> > > > > > > > 
> > > > > > > > My main concern is that the drivers should not opt-out of the features.
> > > > > > > > E.g. if we start supporting ISRC packets or MPEG or NTSC VBI InfoFrames
> > > > > > > > (yes, stupid examples), it should not be required to go through all the
> > > > > > > > drivers, making sure that they disable those. Instead the DRM framework
> > > > > > > > should be able to make decisions like:
> > > > > > > > 
> > > > > > > > - The driver supports SPD and the VSDB defines SPD, enable this
> > > > > > > >    InfoFrame (BTW, this needs to be done anyway, we should not be sending
> > > > > > > >    SPD if it's not defined in VSDB, if I read it correctly).
> > > > > > > > 
> > > > > > > > - The driver hints that the pixel data has only 10 meaninful bits of
> > > > > > > >    data per component (e.g. out of 12 for DeepColor 36), the Sink has
> > > > > > > >    HF-VSDB, send HF-VSIF.
> > > > > > > > 
> > > > > > > > - The driver has enabled 3D stereo mode, but it doesn't declare support
> > > > > > > >    for HF-VSIF. Send only H14b-VSIF.
> > > > > > > > 
> > > > > > > > Similarly (no, I don't have these on my TODO list, these are just
> > > > > > > > examples):
> > > > > > > > - The driver defines support for NTSC VBI, register a VBI device.
> > > > > > > > 
> > > > > > > > - The driver defines support for ISRC packets, register ISRC-related
> > > > > > > >    properties.
> > > > > > > > 
> > > > > > > > - The driver defines support for MPEG Source InfoFrame, provide a way
> > > > > > > >    for media players to report frame type and bit rate.
> > > > > > > > 
> > > > > > > > - The driver provides limited support for Extended HDR DM InfoFrames,
> > > > > > > >    select the correct frame type according to driver capabilities.
> > > > > > > > 
> > > > > > > > Without the 'supported' information we should change atomic_check()
> > > > > > > > functions to set infoframe->set to false for all unsupported InfoFrames
> > > > > > > > _and_ go through all the drivers again each time we add support for a
> > > > > > > > feature (e.g. after adding HF-VSIF support).
> > > > > > > 
> > > > > > >  From what you described here, I think we share a similar goal and have
> > > > > > > somewhat similar concerns (thanks, btw, it wasn't obvious to me before),
> > > > > > > we just disagree on the trade-offs and ideal solution :)
> > > > > > > 
> > > > > > > I agree that we need to sanity check the drivers, and I don't want to go
> > > > > > > back to the situation we had before where drivers could just ignore
> > > > > > > infoframes and take the easy way out.
> > > > > > > 
> > > > > > > It should be hard, and easy to catch during review.
> > > > > > > 
> > > > > > > I don't think bitflag are a solution because, to me, it kind of fails
> > > > > > > both.
> > > > > > > 
> > > > > > > What if, just like the debugfs discussion, we split write_infoframe into
> > > > > > > write_avi_infoframe (mandatory), write_spd_infoframe (optional),
> > > > > > > write_audio_infoframe (checked by drm_connector_hdmi_audio_init?) and
> > > > > > > write_hdr_infoframe (checked in drmm_connector_hdmi_init if max_bpc > 8)
> > > > > > > 
> > > > > > > How does that sound?
> > > > > > 
> > > > > > I'd say, I really like the single function to be called for writing the
> > > > > > infoframes. It makes it much harder for drivers to misbehave or to skip
> > > > > > something.
> > > > > 
> > > > >  From a driver PoV, I believe we should still have that single function
> > > > > indeed. It would be drm_atomic_helper_connector_hdmi_update_infoframes's
> > > > > job to fan out and call the multiple callbacks, not the drivers.
> > > > 
> > > > I like this idea, however it stops at the drm_bridge_connector abstraction.
> > > > The only way to handle this I can foresee is to make individual bridges
> > > > provide struct drm_connector_hdmi_funcs implementation (which I'm fine with)
> > > > and store void *data or struct drm_bridge *hdmi_bridge somewhere inside
> > > > struct drm_connector_hdmi in order to let bridge drivers find their data.
> > > 
> > > Does it change anything? The last HDMI bridge should implement all the
> > > infoframes it supports. I don't think we should take care of one bridge
> > > with one infoframe type and some other with another?
> > 
> > Note: I wrote about the _data_. So far the connector's write_infoframe /
> > clear_infoframe callbacks get drm_connector as an arg. The fact that
> > there is a drm_bridge which implements a callback is hidden well inside
> > drm_bridge_connector (and only it knows the bridge_hdmi pointer).
> > Otherwise, the bridge, trying to implement drm_connector_hdmi_funcs has
> > no way to go from drm_connector to drm_bridge.
> > 
> > The only possible solution would be to introduce something like
> > drm_connector_hdmi::data (either void* or drm_bridge*) and use it
> > internally. But for me this looks like a bit loose abstraction. Though,
> > if it looks good from your POV, I agree, it would solve enough of
> > issues.
> 
> I'm not sure I understand, sorry.
> 
> What prevents us from adding ~4 functions to bridge->funcs that take the
> bridge, and drm_bridge_connector would get the connector, retrieve the
> bridge instance from it, and pass it to the bridge actually implementing
> it? Like we do currently for write_infoframe and clear_infoframe
> already?

Well, we discussed that having the write_foo_infoframe in the
drm_connector_hdmi_funcs means that the connector supports that
infoframe (and it can be used to e.g. report errors). However with
drm_bridge_container, we need to set all callbacks in
drm_connector_hdmi_funcs, even if the underlying bridge reports them as
unsupported.

Am I missing something?

-- 
With best wishes
Dmitry


From sebastian.reichel at collabora.com  Fri Nov 21 08:26:59 2025
From: sebastian.reichel at collabora.com (Sebastian Reichel)
Date: Fri, 21 Nov 2025 17:26:59 +0100
Subject: [PATCH] mmc: sdhci-of-dwcmshc: Fix command queue support for
 RK3576
Message-ID: <20251121-rockchip-emmc-cqe-rk3576-fix-v1-1-a77805f40072@collabora.com>

When I added command queue engine (CQE) support for the Rockchip eMMC
controller, I missed that RK3576 has a separate platform data struct.
While things are working fine on RK3588 (I tested the ROCK 5B) and
the suspend issue is fixed on the RK3576 (I tested the Sige5), this
results in stability issues. By also adding the necessary hooks for
the RK3576 platform the following problems can be avoided:

[   15.606895] mmc0: running CQE recovery
[   15.616189] mmc0: running CQE recovery
[...]
[   25.911484] mmc0: running CQE recovery
[   25.926305] mmc0: running CQE recovery
[   25.927468] mmc0: running CQE recovery
[...]
[   26.255719] mmc0: running CQE recovery
[   26.257162] ------------[ cut here ]------------
[   26.257581] mmc0: cqhci: spurious TCN for tag 31
[   26.258034] WARNING: CPU: 0 PID: 0 at drivers/mmc/host/cqhci-core.c:796 cqhci_irq+0x440/0x68c
[   26.263786] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.18.0-rc6-gd984ebbf0d15 #1 PREEMPT
[   26.264561] Hardware name: ArmSoM Sige5 (DT)
[...]
[   26.272748] Call trace:
[   26.272964]  cqhci_irq+0x440/0x68c (P)
[   26.273296]  dwcmshc_cqe_irq_handler+0x54/0x88
[   26.273689]  sdhci_irq+0xbc/0x1200
[   26.273991]  __handle_irq_event_percpu+0x54/0x1d0
[...]

Note that the above problems do not necessarily happen with every boot.

Reported-by: Adrian Hunter <adrian.hunter at intel.com>
Closes: https://lore.kernel.org/linux-rockchip/01949bc9-4873-498b-ac7d-f008393ccc4c at intel.com/
Fixes: fda1e0af7c28f ("mmc: sdhci-of-dwcmshc: Add command queue support for rockchip SOCs")
Signed-off-by: Sebastian Reichel <sebastian.reichel at collabora.com>
---
Sorry for the delay in sending this :)
---
 drivers/mmc/host/sdhci-of-dwcmshc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c
index c66a8dfad47c..ee0008d91b98 100644
--- a/drivers/mmc/host/sdhci-of-dwcmshc.c
+++ b/drivers/mmc/host/sdhci-of-dwcmshc.c
@@ -1767,6 +1767,7 @@ static const struct dwcmshc_pltfm_data sdhci_dwcmshc_rk3576_pdata = {
 		.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
 			   SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN,
 	},
+	.cqhci_host_ops = &rk35xx_cqhci_ops,
 	.init = dwcmshc_rk35xx_init,
 	.postinit = dwcmshc_rk3576_postinit,
 };

---
base-commit: dcbce328d3a2d87770133834210cf328c083d480
change-id: 20251121-rockchip-emmc-cqe-rk3576-fix-ec8ac72e6e32

Best regards,
-- 
Sebastian Reichel <sebastian.reichel at collabora.com>



From dmitry.baryshkov at oss.qualcomm.com  Fri Nov 21 09:09:01 2025
From: dmitry.baryshkov at oss.qualcomm.com (Dmitry Baryshkov)
Date: Fri, 21 Nov 2025 19:09:01 +0200
Subject: [PATCH v3 00/11] drm/connector: hdmi: limit infoframes per
 driver capabilities
In-Reply-To: <bsoqyzxi45i67jpzhwr2d4illufa5ghqf25z6flbp67lsbvh22@rrlcihp2oxea>
References: <x562ueky2z5deqqmhl222moyrbylfwi35u4hb34dpl3z52ra4c@dyw4iayrewnz>
 <20250925-fervent-merry-beagle-2baba3@penduick>
 <qx5ashx62pufott6hnsfna3qntnoyvxwxze4rihhuxcsdxi37s@bbdvc3sfsgne>
 <20250929-gregarious-worm-of-memory-c5354d@houat>
 <itgffxygopi7etkt7xhvmyuvyl5ad3k43nsxvjzw3ubtwiikn7@ocugfdaigtu7>
 <20251003-uptight-echidna-of-stamina-815305@houat>
 <zpygq4kapil3swsmhhqkdwny4ry2dznnzixsw5rkza5p2kqnvp@abvf2vxlbwif>
 <2a5fitdzr2bz235fj6rvqzxr6ckszkjbazjfszlvnizdh2cvbt@w3ypjo7vahhs>
 <pibxhl5hlcpuk3zsgyienfdlda5cwuxrnofwlw356scuzzplqy@zw3ofelgvwik>
 <bsoqyzxi45i67jpzhwr2d4illufa5ghqf25z6flbp67lsbvh22@rrlcihp2oxea>
Message-ID: <cgzclxjubj5oca3rdnv44qwrkmpddxve4tlz76cc6p3b4hz3oc@3l7mt5ha7do6>

On Fri, Nov 21, 2025 at 04:36:28PM +0100, Maxime Ripard wrote:
> On Tue, Oct 14, 2025 at 06:48:19PM +0300, Dmitry Baryshkov wrote:
> > On Tue, Oct 14, 2025 at 02:59:43PM +0200, Maxime Ripard wrote:
> > > On Fri, Oct 03, 2025 at 06:54:47PM +0300, Dmitry Baryshkov wrote:
> > > > On Fri, Oct 03, 2025 at 03:22:23PM +0200, Maxime Ripard wrote:
> > > > > On Tue, Sep 30, 2025 at 10:02:28AM +0300, Dmitry Baryshkov wrote:
> > > > > > On Mon, Sep 29, 2025 at 03:00:04PM +0200, Maxime Ripard wrote:
> > > > > > > On Thu, Sep 25, 2025 at 05:16:07PM +0300, Dmitry Baryshkov wrote:
> > > > > > > > On Thu, Sep 25, 2025 at 03:13:47PM +0200, Maxime Ripard wrote:
> > > > > > > > > On Wed, Sep 10, 2025 at 06:26:56PM +0300, Dmitry Baryshkov wrote:
> > > > > > > > > > On Wed, Sep 10, 2025 at 09:30:19AM +0200, Maxime Ripard wrote:
> > > > > > > > > > > On Wed, Sep 03, 2025 at 03:03:43AM +0300, Dmitry Baryshkov wrote:
> > > > > > > > > > > > On Tue, Sep 02, 2025 at 08:06:54PM +0200, Maxime Ripard wrote:
> > > > > > > > > > > > > On Tue, Sep 02, 2025 at 06:45:44AM +0300, Dmitry Baryshkov wrote:
> > > > > > > > > > > > > > On Mon, Sep 01, 2025 at 09:07:02AM +0200, Maxime Ripard wrote:
> > > > > > > > > > > > > > > On Sun, Aug 31, 2025 at 01:29:13AM +0300, Dmitry Baryshkov wrote:
> > > > > > > > > > > > > > > > On Sat, Aug 30, 2025 at 09:30:01AM +0200, Daniel Stone wrote:
> > > > > > > > > > > > > > > > > Hi Dmitry,
> > > > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > > > On Sat, 30 Aug 2025 at 02:23, Dmitry Baryshkov
> > > > > > > > > > > > > > > > > <dmitry.baryshkov at oss.qualcomm.com> wrote:
> > > > > > > > > > > > > > > > > > It's not uncommon for the particular device to support only a subset of
> > > > > > > > > > > > > > > > > > HDMI InfoFrames. It's not a big problem for the kernel, since we adopted
> > > > > > > > > > > > > > > > > > a model of ignoring the unsupported Infoframes, but it's a bigger
> > > > > > > > > > > > > > > > > > problem for the userspace: we end up having files in debugfs which do
> > > > > > > > > > > > > > > > > > mot match what is being sent on the wire.
> > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > > Sort that out, making sure that all interfaces are consistent.
> > > > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > > > Thanks for the series, it's a really good cleanup.
> > > > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > > > I know that dw-hdmi-qp can support _any_ infoframe, by manually
> > > > > > > > > > > > > > > > > packing it into the two GHDMI banks. So the supported set there is
> > > > > > > > > > > > > > > > > 'all of the currently well-known ones, plus any two others, but only
> > > > > > > > > > > > > > > > > two and not more'. I wonder if that has any effect on the interface
> > > > > > > > > > > > > > > > > you were thinking about for userspace?
> > > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > > I was mostly concerned with the existing debugfs interface (as it is
> > > > > > > > > > > > > > > > also used e.g. for edid-decode, etc).
> > > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > > It seems "everything + 2 spare" is more or less common (ADV7511, MSM
> > > > > > > > > > > > > > > > HDMI also have those. I don't have at hand the proper datasheet for
> > > > > > > > > > > > > > > > LT9611 (non-UXC one), but I think its InfoFrames are also more or less
> > > > > > > > > > > > > > > > generic).  Maybe we should change debugfs integration to register the
> > > > > > > > > > > > > > > > file when the frame is being enabled and removing it when it gets unset.
> > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > But, like, for what benefit?
> > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > It's a debugfs interface for userspace to consume. The current setup
> > > > > > > > > > > > > > > works fine with edid-decode already. Why should we complicate the design
> > > > > > > > > > > > > > > that much and create fun races like "I'm running edid-decode in parallel
> > > > > > > > > > > > > > > to a modeset that would remove the file I just opened, what is the file
> > > > > > > > > > > > > > > now?".
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > > Aren't we trading that with the 'I'm running edid-decode in paralle with
> > > > > > > > > > > > > > to a modeset and the file suddenly becomes empty'?
> > > > > > > > > > > > > 
> > > > > > > > > > > > > In that case, you know what the file is going to be: empty. And you went
> > > > > > > > > > > > > from a racy, straightforward, design to a racy, complicated, design.
> > > > > > > > > > > > > 
> > > > > > > > > > > > > It was my question before, but I still don't really see what benefits it
> > > > > > > > > > > > > would have, and why we need to care about it in the core, when it could
> > > > > > > > > > > > > be dealt with in the drivers just fine on a case by case basis.
> > > > > > > > > > > > 
> > > > > > > > > > > > Actually it can not: debugfs files are registered from the core, not
> > > > > > > > > > > > from the drivers. That's why I needed all the supported_infoframes
> > > > > > > > > > > > (which later became software_infoframes).
> > > > > > > > > > > 
> > > > > > > > > > > That's one thing we can change then.
> > > > > > > > > > > 
> > > > > > > > > > > > Anyway, I'm fine with having empty files there.
> > > > > > > > > > > > 
> > > > > > > > > > > > > > > > Then in the long run we can add 'slots' and allocate some of the frames
> > > > > > > > > > > > > > > > to the slots. E.g. ADV7511 would get 'software AVI', 'software SPD',
> > > > > > > > > > > > > > > > 'auto AUDIO' + 2 generic slots (and MPEG InfoFrame which can probably be
> > > > > > > > > > > > > > > > salvaged as another generic one)). MSM HDMI would get 'software AVI',
> > > > > > > > > > > > > > > > 'software AUDIO' + 2 generic slots (+MPEG + obsucre HDMI which I don't
> > > > > > > > > > > > > > > > want to use). Then the framework might be able to prioritize whether to
> > > > > > > > > > > > > > > > use generic slots for important data (as DRM HDR, HDMI) or less important
> > > > > > > > > > > > > > > > (SPD).
> > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > Why is it something for the framework to deal with? If you want to have
> > > > > > > > > > > > > > > extra infoframes in there, just go ahead and create additional debugfs
> > > > > > > > > > > > > > > files in your driver.
> > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > If you want to have the slot mechanism, check in your atomic_check that
> > > > > > > > > > > > > > > only $NUM_SLOT at most infoframes are set.
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > > The driver can only decide that 'we have VSI, SPD and DRM InfoFrames
> > > > > > > > > > > > > > which is -ETOOMUCH for 2 generic slots'. The framework should be able to
> > > > > > > > > > > > > > decide 'the device has 2 generic slots, we have HDR data, use VSI and
> > > > > > > > > > > > > > DRM InfoFrames and disable SPD for now'.
> > > > > > > > > > > > > 
> > > > > > > > > > > > > I mean... the spec does? The spec says when a particular feature
> > > > > > > > > > > > > requires to send a particular infoframe. If your device cannot support
> > > > > > > > > > > > > to have more than two "features" enabled at the same time, so be it. It
> > > > > > > > > > > > > something that should be checked in that driver atomic_check.
> > > > > > > > > > > > 
> > > > > > > > > > > > Sounds good to me. Let's have those checks in the drivers until we
> > > > > > > > > > > > actually have seveal drivers performing generic frame allocation.
> > > > > > > > > > > > 
> > > > > > > > > > > > > Or just don't register the SPD debugfs file, ignore it, put a comment
> > > > > > > > > > > > > there, and we're done too.
> > > > > > > > > > > > 
> > > > > > > > > > > > It's generic code.
> > > > > > > > > > > > 
> > > > > > > > > > > > > > But... We are not there yet and I don't have clear usecase (we support
> > > > > > > > > > > > > > HDR neither on ADV7511 nor on MSM HDMI, after carefully reading the
> > > > > > > > > > > > > > guide I realised that ADV7511 has normal audio infoframes). Maybe I
> > > > > > > > > > > > > > should drop all the 'auto' features, simplifying this series and land
> > > > > > > > > > > > > > [1] for LT9611UXC as I wanted origianlly.
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > > [1] https://lore.kernel.org/dri-devel/20250803-lt9611uxc-hdmi-v1-2-cb9ce1793acf at oss.qualcomm.com/
> > > > > > > > > > > > > 
> > > > > > > > > > > > > Looking back at that series, I think it still has value to rely on the
> > > > > > > > > > > > > HDMI infrastructure at the very least for the atomic_check sanitization.
> > > > > > > > > > > > > 
> > > > > > > > > > > > > But since you wouldn't use the generated infoframes, just skip the
> > > > > > > > > > > > > debugfs files registration. You're not lying to userspace anymore, and
> > > > > > > > > > > > > you get the benefits of the HDMI framework.
> > > > > > > > > > > > 
> > > > > > > > > > > > We create all infoframe files for all HDMI connectors.
> > > > > > > > > > > 
> > > > > > > > > > > Then we can provide a debugfs_init helper to register all of them, or
> > > > > > > > > > > only some of them, and let the drivers figure it out.
> > > > > > > > > > > 
> > > > > > > > > > > Worst case scenario, debugfs files will not get created, which is a much
> > > > > > > > > > > better outcome than having to put boilerplate in every driver that will
> > > > > > > > > > > get inconsistent over time.
> > > > > > > > > > 
> > > > > > > > > > debugfs_init() for each infoframe or taking some kind of bitmask?
> > > > > > > > > 
> > > > > > > > > I meant turning hdmi_debugfs_add and create_hdmi_*_infoframe_file into
> > > > > > > > > public helpers. That way, drivers that don't care can use the (renamed)
> > > > > > > > > hdmi_debugfs_add, and drivers with different constraints can register
> > > > > > > > > the relevant infoframes directly.
> > > > > > > > 
> > > > > > > > Doesn't that mean more boilerplate?
> > > > > > > 
> > > > > > > I don't think it would? In the general case, it wouldn't change
> > > > > > > anything, and in special cases, then it's probably going to be different
> > > > > > > from one driver to the next so there's not much we can do.
> > > > > > > 
> > > > > > > > In the end, LT9611UXC is a special case, for which I'm totally fine
> > > > > > > > not to use HDMI helpers at this point: we don't control infoframes
> > > > > > > > (hopefully that can change), we don't care about the TMDS clock, no
> > > > > > > > CEC, etc.
> > > > > > > 
> > > > > > > Not using the helpers sound pretty reasonable here too.
> > > > > > > 
> > > > > > > > For all other usecases I'm fine with having atomic_check() unset all
> > > > > > > > unsupported infoframes and having empty files in debugfs. Then we can
> > > > > > > > evolve over the time, once we see a pattern. We had several drivers
> > > > > > > > which had very limited infoframes support, but I think this now gets
> > > > > > > > sorted over the time.
> > > > > > > 
> > > > > > > I never talked about atomic_check()? You were initially concerned that
> > > > > > > the framework would expose data in debugfs that it's not using. Not
> > > > > > > registering anything in debugfs solves that, but I'm not sure we need to
> > > > > > > special case atomic_check.
> > > > > > 
> > > > > > Well... I ended up with [1], handling infoframes in the atomic_check()
> > > > > > rather than registering fewer infoframe debugfs files. This way device
> > > > > > state is consistent, we don't have enabled instances, etc. However it
> > > > > > results in repetetive code in atomic_check().
> > > > > > 
> > > > > > [1] https://lore.kernel.org/dri-devel/20250928-limit-infoframes-2-v2-0-6f8f5fd04214 at oss.qualcomm.com/
> > > > > 
> > > > > I guess we can continue the discussion there, but I'm not sure we want
> > > > > to have more boilerplate in drivers, and especially in the atomic_check
> > > > > part. If drivers are inconsistent or wrong in the debugfs path, there's
> > > > > no major issue. If they are wrong in the atomic_check path, it will lead
> > > > > to regressions, possibly in paths that are pretty hard to test.
> > > > 
> > > > You've responded there and I can drop the extra handling for HDR DRM and
> > > > audio infoframes in the atomic_check(). What is your opinion about the
> > > > atomic_check() unsetting the infoframe->set for SPD and HDMI infoframes?
> > > 
> > > HDMI infoframes are mandatory, so that's a big no-no.
> > 
> > Nevertheless... There are drivers (sun4i, inno_hdmi, rk3066, dw_hdmi_qp)
> > which don't (yet) implement VSI support.
> 
> We should really differentiate drivers that didn't because they were
> allowed to, and drivers that can't.
> 
> For the bridge you mentioned earlier in the discussion, it makes sense
> not to expose the debugfs file because we simply don't have access to
> the actual content. That's fine.
> 
> For the drivers you listed there, I'm pretty confident that it's because
> nobody really tried. That's definitely not fine, and we should complain
> as loudly as possible for that particular case, and not give them a free
> pass. Checking sun4i, I'm pretty sure it can be implemented. Looking at
> the incomplete RK3066 TRM, it can be implemented too. And inno_hdmi
> looks really similar.

Interesting, according do a10s and a31 user manuals, there is no support
for vendor infoframes, but it has SPD infoframe, which seemingly can be
reused for HVIF.

> So it's not really impossible, you just need some hardware and a day's
> worth of work.
> 
> There's no reason these should get a pass, it's breaking the spec for no
> reason.
> 
> > > For SPD, It's really not clear to me why atomic_check should do that in
> > > the first place. Your initial concern was about exposing infoframes in
> > > debugfs that wouldn't be used by the driver.
> > > 
> > > If the driver doesn't register a debugfs file for SPD, and ignores
> > > whatever is in the atomic state, what's should we force drivers to do
> > > that?
> > 
> > I really don't think that drivers should mess up with debugfs on their
> > own. Making atomic_check() disable the unsupported InfoFrames makes the
> > picture perfect: the DRM no longer tries to program them to the
> > hardware, DebugFS files stay empty, so the whole state becomes
> > consistent.
> 
> In the "bridge has no access to infoframes" case, there's really no
> infoframe. An empty file is "the infoframe can be there but isn't used",
> not "we don't have access to it and can't report them". Only drivers
> have those infos.
> 
> If we do split up write_infoframe into multiple functions though, I
> guess we could create the debugfs file only if the function pointer is
> set, which removes drivers' involvement if you don't like that.

I'm fine with not using HDMI connector framework for lt9611uxc.
Likewise, I think, it's fine to have empty files for the infoframes
which are not being sent over the wire for any reason (hw not supporting
it is one of the reasons). I really don't see a good way to implement
multiple-callbacks-as-a-supporter-flag inside drm_bridge_connector.
So, I really think, disabling unsupported infoframes in atomic_check is
the beset course.

-- 
With best wishes
Dmitry


From conor at kernel.org  Fri Nov 21 10:32:08 2025
From: conor at kernel.org (Conor Dooley)
Date: Fri, 21 Nov 2025 18:32:08 +0000
Subject: [PATCH v9 1/2] dt-bindings: clock: rockchip: Add RK3506 clock
 and reset unit
In-Reply-To: <20251121075350.2564860-2-zhangqing@rock-chips.com>
References: <20251121075350.2564860-1-zhangqing@rock-chips.com>
 <20251121075350.2564860-2-zhangqing@rock-chips.com>
Message-ID: <20251121-pardon-employee-9dec9bc4f722@spud>

On Fri, Nov 21, 2025 at 03:53:49PM +0800, Elaine Zhang wrote:
> From: Finley Xiao <finley.xiao at rock-chips.com>
> 
> Add device tree bindings for clock and reset unit on RK3506 SoC.
> Add clock and reset IDs for RK3506 SoC.
> 
> Signed-off-by: Finley Xiao <finley.xiao at rock-chips.com>
> Signed-off-by: Elaine Zhang <zhangqing at rock-chips.com>

Reviewed-by: Conor Dooley <conor.dooley at microchip.com>
pw-bot: not-applicable
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-rockchip/attachments/20251121/84a62ce2/attachment.sig>

From heiko at sntech.de  Fri Nov 21 13:45:27 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 21 Nov 2025 22:45:27 +0100
Subject: [PATCH v2 0/5] arm64: dts: rockchip: update 100ASK DshanPi A1 support
In-Reply-To: <20251120120011.279104-1-amadeus@jmu.edu.cn>
References: <20251120120011.279104-1-amadeus@jmu.edu.cn>
Message-ID: <176376151911.52478.4773292492841717025.b4-ty@sntech.de>


On Thu, 20 Nov 2025 20:00:06 +0800, Chukun Pan wrote:
> Changed from v2:
>   Remove merged patches
>   Split patch for more details
> 
> Chukun Pan (5):
>   arm64: dts: rockchip: remove mmc max-frequency for 100ASK DshanPi A1
>   arm64: dts: rockchip: add mmc aliases for 100ASK DshanPi A1
>   arm64: dts: rockchip: enable button for 100ASK DshanPi A1
>   arm64: dts: rockchip: enable USB for 100ASK DshanPi A1
>   arm64: dts: rockchip: enable RTC for 100ASK DshanPi A1
> 
> [...]

Applied, thanks!

[1/5] arm64: dts: rockchip: remove mmc max-frequency for 100ASK DshanPi A1
      commit: b120a9df264eab51952d0cf44c16f13f2606281d
[2/5] arm64: dts: rockchip: add mmc aliases for 100ASK DshanPi A1
      commit: 98461b5e3cdffd126aec610691078408c296d79f
[3/5] arm64: dts: rockchip: enable button for 100ASK DshanPi A1
      commit: 80ec14d1d2173cc3f225102a7db09a457541fe04
[4/5] arm64: dts: rockchip: enable USB for 100ASK DshanPi A1
      commit: d43935da2bfada9e83f5f7e46f7d72e5d4665bd6
[5/5] arm64: dts: rockchip: enable RTC for 100ASK DshanPi A1
      commit: e34003dd2fb05da8f420bbd7b8ec62ab88242c45

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Fri Nov 21 13:45:28 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 21 Nov 2025 22:45:28 +0100
Subject: [PATCH] arm64: dts: rockchip: Enable i2c2 on Orange Pi 3B
In-Reply-To: <20251120-orangepi3-enable-i2c2-v1-1-2e023a74012a@rootcommit.com>
References: <20251120-orangepi3-enable-i2c2-v1-1-2e023a74012a@rootcommit.com>
Message-ID: <176376151909.52478.6656930123388084668.b4-ty@sntech.de>


On Thu, 20 Nov 2025 19:00:34 +0000, Michael Opdenacker wrote:
> Enable the "i2c2" bus on header pins 3 (I2C_SDA_M1)
> and 5 (I2C2_SCL_M1) of the Orange Pi 3B board.
> 
> As documented on http://www.orangepi.org/img/pi3b/0719-pi3b-19.png,
> such pins are the only ones offering I2C functionality
> without conflicting with other SoC blocks.
> 
> [...]

Applied, thanks!

[1/1] arm64: dts: rockchip: Enable i2c2 on Orange Pi 3B
      commit: b92c4eae75468d5b7ad49fc0d1de76a7f0fa0bdb

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From leon at kernel.org  Sun Nov 23 01:29:20 2025
From: leon at kernel.org (Leon Romanovsky)
Date: Sun, 23 Nov 2025 11:29:20 +0200
Subject: [PATCH v3 1/3] RDMA/usnic: Remove iommu_set_fault_handler()
In-Reply-To: <1-v3-e5d08e2d551e+109-iommu_set_fault_jgg@nvidia.com>
References: <0-v3-e5d08e2d551e+109-iommu_set_fault_jgg@nvidia.com>
 <1-v3-e5d08e2d551e+109-iommu_set_fault_jgg@nvidia.com>
Message-ID: <20251123092920.GB16619@unreal>

On Thu, Nov 20, 2025 at 03:46:22PM -0400, Jason Gunthorpe wrote:
> The handler in usnic just prints a fault report message, the iommu drivers
> all do a better job of that these days. Just remove the use of this old
> API.
> 
> Reviewed-by: Lu Baolu <baolu.lu at linux.intel.com>
> Reviewed-by: Kevin Tian <kevin.tian at intel.com>
> Acked-by: Jason Gunthorpe <jgg at nvidia.com>
> Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> ---
>  drivers/infiniband/hw/usnic/usnic_uiom.c | 13 -------------
>  1 file changed, 13 deletions(-)
>

I imagine that you want to merge this patch through iommu tree.

Thanks,
Reviewed-by: Leon Romanovsky <leonro at nvidia.com>


From heiko at sntech.de  Sun Nov 23 12:25:58 2025
From: heiko at sntech.de (Heiko =?UTF-8?B?U3TDvGJuZXI=?=)
Date: Sun, 23 Nov 2025 21:25:58 +0100
Subject: [PATCH] drm/bridge: dw-hdmi-qp: Fix spurious IRQ on resume
In-Reply-To: <20251014-rockchip-hdmi-suspend-fix-v1-1-983fcbf44839@collabora.com>
References: <20251014-rockchip-hdmi-suspend-fix-v1-1-983fcbf44839@collabora.com>
Message-ID: <5028381.GXAFRqVoOG@diego>

Am Dienstag, 14. Oktober 2025, 18:00:57 Mitteleurop?ische Normalzeit schrieb Sebastian Reichel:
> After resume from suspend to RAM, the following splash is generated if
> the HDMI driver is probed (independent of a connected cable):
> 
> [ 1194.484052] irq 80: nobody cared (try booting with the "irqpoll" option)
> [ 1194.484074] CPU: 0 UID: 0 PID: 627 Comm: rtcwake Not tainted 6.17.0-rc7-g96f1a11414b3 #1 PREEMPT
> [ 1194.484082] Hardware name: Rockchip RK3576 EVB V10 Board (DT)
> [ 1194.484085] Call trace:
> [ 1194.484087]  ... (stripped)
> [ 1194.484283] handlers:
> [ 1194.484285] [<00000000bc363dcb>] dw_hdmi_qp_main_hardirq [dw_hdmi_qp]
> [ 1194.484302] Disabling IRQ #80
> 
> Apparently the HDMI IP is losing part of its state while the system
> is suspended and generates spurious interrupts during resume. The
> bug has not yet been noticed, as system suspend does not yet work
> properly on upstream kernel with either the Rockchip RK3588 or RK3576
> platform.
> 
> Fixes: 128a9bf8ace2 ("drm/rockchip: Add basic RK3588 HDMI output support")
> Signed-off-by: Sebastian Reichel <sebastian.reichel at collabora.com>

so, just to say, to me this looks good and also I guess the changes to the
main bridge are not looking controversial and most likely the issue
should appear in all (future) dw-hdmi-qp variants.

So I'll give that a day or two more and then apply it.

Heiko

> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c   |  9 +++++++++
>  drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 12 +++++++++++-
>  include/drm/bridge/dw_hdmi_qp.h                |  1 +
>  3 files changed, 21 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
> index 39332c57f2c5..c85eb340e5a3 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
> @@ -143,6 +143,7 @@ struct dw_hdmi_qp {
>  	} phy;
>  
>  	struct regmap *regm;
> +	int main_irq;
>  
>  	unsigned long tmds_char_rate;
>  };
> @@ -1068,6 +1069,7 @@ struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev,
>  
>  	dw_hdmi_qp_init_hw(hdmi);
>  
> +	hdmi->main_irq = plat_data->main_irq;
>  	ret = devm_request_threaded_irq(dev, plat_data->main_irq,
>  					dw_hdmi_qp_main_hardirq, NULL,
>  					IRQF_SHARED, dev_name(dev), hdmi);
> @@ -1106,9 +1108,16 @@ struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev,
>  }
>  EXPORT_SYMBOL_GPL(dw_hdmi_qp_bind);
>  
> +void dw_hdmi_qp_suspend(struct device *dev, struct dw_hdmi_qp *hdmi)
> +{
> +	disable_irq(hdmi->main_irq);
> +}
> +EXPORT_SYMBOL_GPL(dw_hdmi_qp_suspend);
> +
>  void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi)
>  {
>  	dw_hdmi_qp_init_hw(hdmi);
> +	enable_irq(hdmi->main_irq);
>  }
>  EXPORT_SYMBOL_GPL(dw_hdmi_qp_resume);
>  
> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
> index ed6e8f036f4b..9ac45e7bc987 100644
> --- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
> @@ -597,6 +597,15 @@ static void dw_hdmi_qp_rockchip_remove(struct platform_device *pdev)
>  	component_del(&pdev->dev, &dw_hdmi_qp_rockchip_ops);
>  }
>  
> +static int __maybe_unused dw_hdmi_qp_rockchip_suspend(struct device *dev)
> +{
> +	struct rockchip_hdmi_qp *hdmi = dev_get_drvdata(dev);
> +
> +	dw_hdmi_qp_suspend(dev, hdmi->hdmi);
> +
> +	return 0;
> +}
> +
>  static int __maybe_unused dw_hdmi_qp_rockchip_resume(struct device *dev)
>  {
>  	struct rockchip_hdmi_qp *hdmi = dev_get_drvdata(dev);
> @@ -612,7 +621,8 @@ static int __maybe_unused dw_hdmi_qp_rockchip_resume(struct device *dev)
>  }
>  
>  static const struct dev_pm_ops dw_hdmi_qp_rockchip_pm = {
> -	SET_SYSTEM_SLEEP_PM_OPS(NULL, dw_hdmi_qp_rockchip_resume)
> +	SET_SYSTEM_SLEEP_PM_OPS(dw_hdmi_qp_rockchip_suspend,
> +				dw_hdmi_qp_rockchip_resume)
>  };
>  
>  struct platform_driver dw_hdmi_qp_rockchip_pltfm_driver = {
> diff --git a/include/drm/bridge/dw_hdmi_qp.h b/include/drm/bridge/dw_hdmi_qp.h
> index e9be6d507ad9..8955450663e5 100644
> --- a/include/drm/bridge/dw_hdmi_qp.h
> +++ b/include/drm/bridge/dw_hdmi_qp.h
> @@ -28,5 +28,6 @@ struct dw_hdmi_qp_plat_data {
>  struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev,
>  				   struct drm_encoder *encoder,
>  				   const struct dw_hdmi_qp_plat_data *plat_data);
> +void dw_hdmi_qp_suspend(struct device *dev, struct dw_hdmi_qp *hdmi);
>  void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi);
>  #endif /* __DW_HDMI_QP__ */
> 
> ---
> base-commit: 3a8660878839faadb4f1a6dd72c3179c1df56787
> change-id: 20251014-rockchip-hdmi-suspend-fix-e9bd48588453
> 
> Best regards,
> 






From heiko at sntech.de  Sun Nov 23 14:04:21 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Sun, 23 Nov 2025 23:04:21 +0100
Subject: [PATCH v9 0/2] clk: rockchip: Add clock controller for the RK3506
In-Reply-To: <20251121075350.2564860-1-zhangqing@rock-chips.com>
References: <20251121075350.2564860-1-zhangqing@rock-chips.com>
Message-ID: <176393545901.212596.10640796816193748171.b4-ty@sntech.de>


On Fri, 21 Nov 2025 15:53:48 +0800, Elaine Zhang wrote:
> [PATCH 1/5] ~ [PATCH 3/5] has applied.
> 
> Change in V9:
> [PATCH v9 1/2]: Fix "clocks"
> [PATCH v9 2/2]: No change
> 
> Change in V8:
> [PATCH v8 1/2]: Add explanations for "clocks"
> [PATCH v8 2/2]: No change
> 
> [...]

Applied, thanks!

[1/2] dt-bindings: clock: rockchip: Add RK3506 clock and reset unit
      commit: 84898f8e9cea06f8178fc5ca53f068180f7bfba0
[2/2] clk: rockchip: Add clock and reset driver for RK3506
      commit: 18191dd750e6c9e17fabefd09ff418dd587bcdb9

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From andyshrk at 163.com  Sun Nov 23 16:52:47 2025
From: andyshrk at 163.com (Andy Yan)
Date: Mon, 24 Nov 2025 08:52:47 +0800 (CST)
Subject: [PATCH v8 1/2] drm/rockchip: inno-hdmi: Convert to drm
 bridge
In-Reply-To: <8913609.MhkbZ0Pkbq@phil>
References: <20251016083843.76675-1-andyshrk@163.com>
 <20251016083843.76675-2-andyshrk@163.com> <8913609.MhkbZ0Pkbq@phil>
Message-ID: <7cc43fc7.843.19ab3595609.Coremail.andyshrk@163.com>



ping....

At 2025-10-20 20:45:34, "Heiko Stuebner" <heiko at sntech.de> wrote:
>Am Donnerstag, 16. Oktober 2025, 10:38:31 Mitteleurop?ische Sommerzeit schrieb Andy Yan:
>> From: Andy Yan <andy.yan at rock-chips.com>
>> 
>> Convert it to drm bridge driver, it will be convenient for us to
>> migrate the connector part to the display driver later.
>> 
>> Signed-off-by: Andy Yan <andy.yan at rock-chips.com>
>
>Reviewed-by: Heiko Stuebner <heiko at sntech.de>
>
>But of course I would be really happy if someone with more experience
>on general bridges could also take a look.
>
>
>Heiko
>
>
>
>_______________________________________________
>Linux-rockchip mailing list
>Linux-rockchip at lists.infradead.org
>http://lists.infradead.org/mailman/listinfo/linux-rockchip

From chaoyi.chen at rock-chips.com  Sun Nov 23 17:40:03 2025
From: chaoyi.chen at rock-chips.com (Chaoyi Chen)
Date: Mon, 24 Nov 2025 09:40:03 +0800
Subject: [PATCH v10 01/11] usb: typec: Add notifier functions
In-Reply-To: <2025112102-laurel-mulch-58e4@gregkh>
References: <20251120022343.250-1-kernel@airkyi.com>
 <20251120022343.250-2-kernel@airkyi.com>
 <2025112102-laurel-mulch-58e4@gregkh>
Message-ID: <462ad1bd-7eec-4f26-b383-96b049e14559@rock-chips.com>

Hi Greg,

On 11/21/2025 10:07 PM, Greg Kroah-Hartman wrote:
> On Thu, Nov 20, 2025 at 10:23:33AM +0800, Chaoyi Chen wrote:
>> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
>>
>> Some other part of kernel may want to know the event of typec bus.
> Be specific, WHAT part of the kernel will need to know this?

For now, it is DRM.


>
> And why a new notifier, why not just use the existing notifiers that you
> already have?  And what is this going to be used for?

We have discussed this before, but the current bus notifier cannot achieve the expected notification [0].

[0] https://lore.kernel.org/all/aPsuLREPS_FEV3DS at kuha.fi.intel.com/


>
> Notifiers are a pain, and should almost never be added.  Use real
> function calls instead.

In v6, I used direct function calls, but had to switch to notifiers because couldn't resolve the dependencies between DRM and Type-C [1]. Do you have any good ideas? Thank you.

[1] https://lore.kernel.org/all/aPYImGmesrZWwyqh at kuha.fi.intel.com/


>
> thanks,
>
> greg k-h
>
>
-- 
Best,
Chaoyi



From chaoyi.chen at rock-chips.com  Sun Nov 23 17:45:57 2025
From: chaoyi.chen at rock-chips.com (Chaoyi Chen)
Date: Mon, 24 Nov 2025 09:45:57 +0800
Subject: [PATCH v10 02/11] usb: typec: Export all typec device types
In-Reply-To: <2025112109-glacial-outmatch-add7@gregkh>
References: <20251120022343.250-1-kernel@airkyi.com>
 <20251120022343.250-3-kernel@airkyi.com>
 <2025112109-glacial-outmatch-add7@gregkh>
Message-ID: <c73306de-f3a0-42ac-bfed-ef6b52cf4759@rock-chips.com>

Hi Greg,

On 11/21/2025 10:07 PM, Greg Kroah-Hartman wrote:
> On Thu, Nov 20, 2025 at 10:23:34AM +0800, Chaoyi Chen wrote:
>> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
>>
>> Export all typec device types for identification.
> I do not understand what this means.  Who is going to use these symbols,
> and for what exactly?
>
> Be specific please.

In patch3, we need to distinguish whether the notifiers in patch1 are triggered by the typec port device or the typec partner device. Therefore, we export the various device types of typec here.

Sorry for the confusion. I will add more information later.

>
> thanks,
>
> greg k-h
>
>
-- 
Best,
Chaoyi



From gregkh at linuxfoundation.org  Sun Nov 23 23:10:33 2025
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 24 Nov 2025 08:10:33 +0100
Subject: [PATCH v10 01/11] usb: typec: Add notifier functions
In-Reply-To: <462ad1bd-7eec-4f26-b383-96b049e14559@rock-chips.com>
References: <20251120022343.250-1-kernel@airkyi.com>
 <20251120022343.250-2-kernel@airkyi.com>
 <2025112102-laurel-mulch-58e4@gregkh>
 <462ad1bd-7eec-4f26-b383-96b049e14559@rock-chips.com>
Message-ID: <2025112402-unopposed-polio-e6e9@gregkh>

On Mon, Nov 24, 2025 at 09:40:03AM +0800, Chaoyi Chen wrote:
> Hi Greg,
> 
> On 11/21/2025 10:07 PM, Greg Kroah-Hartman wrote:
> > On Thu, Nov 20, 2025 at 10:23:33AM +0800, Chaoyi Chen wrote:
> > > From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> > > 
> > > Some other part of kernel may want to know the event of typec bus.
> > Be specific, WHAT part of the kernel will need to know this?
> 
> For now, it is DRM.

Then say this.

> > And why a new notifier, why not just use the existing notifiers that you
> > already have?  And what is this going to be used for?
> 
> We have discussed this before, but the current bus notifier cannot achieve the expected notification [0].
> 
> [0] https://lore.kernel.org/all/aPsuLREPS_FEV3DS at kuha.fi.intel.com/

Then you need to document the heck out of this in the changelog text.
But I'm still not quite understanding why the bus notifier does not work
here, as you only want this information if the usb device is bound to
the bus there, you do not want to know this if it did not complete.

That thread says you want this not "too late", but why?  What is the
problem there, and how will you handle your code getting loaded after
the typec code is loaded?  Notifier callbacks don't work for that
situation, right?

> > Notifiers are a pain, and should almost never be added.  Use real
> > function calls instead.
> 
> In v6, I used direct function calls, but had to switch to notifiers because couldn't resolve the dependencies between DRM and Type-C [1]. Do you have any good ideas? Thank you.

Only allow this DRM code to be built if typec code is enabled, do NOT
use a select, use a depends in the drm code.

thanks,

greg k-h


From chaoyi.chen at rock-chips.com  Mon Nov 24 00:05:53 2025
From: chaoyi.chen at rock-chips.com (Chaoyi Chen)
Date: Mon, 24 Nov 2025 16:05:53 +0800
Subject: [PATCH v10 01/11] usb: typec: Add notifier functions
In-Reply-To: <2025112402-unopposed-polio-e6e9@gregkh>
References: <20251120022343.250-1-kernel@airkyi.com>
 <20251120022343.250-2-kernel@airkyi.com>
 <2025112102-laurel-mulch-58e4@gregkh>
 <462ad1bd-7eec-4f26-b383-96b049e14559@rock-chips.com>
 <2025112402-unopposed-polio-e6e9@gregkh>
Message-ID: <a80483de-518d-45d5-b46a-9b70cca5b236@rock-chips.com>

Hi Greg,

On 11/24/2025 3:10 PM, Greg Kroah-Hartman wrote:

> On Mon, Nov 24, 2025 at 09:40:03AM +0800, Chaoyi Chen wrote:
>> Hi Greg,
>>
>> On 11/21/2025 10:07 PM, Greg Kroah-Hartman wrote:
>>> On Thu, Nov 20, 2025 at 10:23:33AM +0800, Chaoyi Chen wrote:
>>>> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
>>>>
>>>> Some other part of kernel may want to know the event of typec bus.
>>> Be specific, WHAT part of the kernel will need to know this?
>> For now, it is DRM.
> Then say this.

Okay, please refer to the discussion below.

>
>>> And why a new notifier, why not just use the existing notifiers that you
>>> already have?  And what is this going to be used for?
>> We have discussed this before, but the current bus notifier cannot achieve the expected notification [0].
>>
>> [0] https://lore.kernel.org/all/aPsuLREPS_FEV3DS at kuha.fi.intel.com/
> Then you need to document the heck out of this in the changelog text.
> But I'm still not quite understanding why the bus notifier does not work
> here, as you only want this information if the usb device is bound to
> the bus there, you do not want to know this if it did not complete.
>
> That thread says you want this not "too late", but why?  What is the
> problem there, and how will you handle your code getting loaded after
> the typec code is loaded?  Notifier callbacks don't work for that
> situation, right?

In fact, the typec_register_altmode() function generates two registered events.?The first one is the registered event of the port device,

and the second one is the registered event of the partner device.?The second one event only occurs after a Type-C device is inserted.

The bus notifier event does not actually take effect for the port device, because it only sets the bus for the partner device:

 ? ? /* The partners are bind to drivers */
 ? ? if (is_typec_partner(parent))
 ? ? ? ? alt->adev.dev.bus = &typec_bus;


I hope it's not too late. In fact, the notifier here will notify DRM to establish a bridge chain.

The downstream DP controller driver hopes to obtain the fwnode of the last-level Type-C device

through this bridge chain to create a DRM connector. And when a device is inserted,

drivers/usb/typec/altmodes/displayport.c can notify the HPD (Hot Plug Detect) event.

If relying on the second event, the bridge chain may never be established, and the operations of the DP driver will be

always deferred. Furthermore, other parts of the display controller driver will also be deferred accordingly.

>
>>> Notifiers are a pain, and should almost never be added.  Use real
>>> function calls instead.
>> In v6, I used direct function calls, but had to switch to notifiers because couldn't resolve the dependencies between DRM and Type-C [1]. Do you have any good ideas? Thank you.
> Only allow this DRM code to be built if typec code is enabled, do NOT
> use a select, use a depends in the drm code.

Sorry, I didn't get your point. Does this mean that the current notifiers approach still needs to be changed to direct function calls?

If so, then based on the previous discussion, typec should not depend on any DRM components. Does this mean that we should add the if (IS_REACHABLE(CONFIG_DRM_AUX_BRIDGE)) before the direct function call?

Additionally, the current version of CONFIG_DRM_AUX_BRIDGE is selected by the DP driver in patch9.

-- 
Best,
Chaoyi



From cassel at kernel.org  Mon Nov 24 01:49:44 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Mon, 24 Nov 2025 10:49:44 +0100
Subject: [PATCH v6 0/2] PCI: Configure Root Port MPS during host probing
In-Reply-To: <20251104165125.174168-1-18255117159@163.com>
References: <20251104165125.174168-1-18255117159@163.com>
Message-ID: <aSQqOHH2VLNNpX3D@ryzen>

On Wed, Nov 05, 2025 at 12:51:23AM +0800, Hans Zhang wrote:
> Current PCIe initialization exhibits a key optimization gap: Root Ports
> may operate with non-optimal Maximum Payload Size (MPS) settings. While
> downstream device configuration is handled during bus enumeration, Root
> Port MPS values inherited from firmware or hardware defaults often fail
> to utilize the full capabilities supported by controller hardware. This
> results in suboptimal data transfer efficiency throughout the PCIe
> hierarchy.

Hello PCI maintainers,

Merge window is opening soon,
what is the status of this series?


Kind regards,
Niklas


From cassel at kernel.org  Mon Nov 24 01:50:29 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Mon, 24 Nov 2025 10:50:29 +0100
Subject: [PATCH 0/6] PCI: dwc: Revert Link Up IRQ support
In-Reply-To: <20251111105100.869997-8-cassel@kernel.org>
References: <20251111105100.869997-8-cassel@kernel.org>
Message-ID: <aSQqZcW39Ze1IE74@ryzen>

On Tue, Nov 11, 2025 at 11:51:00AM +0100, Niklas Cassel wrote:
> Revert all patches related to pcie-designware Root Complex Link Up IRQ
> support.
> 
> While this fake hotplugging was a nice idea, it has shown that this feature
> does not handle PCIe switches correctly:
> pci_bus 0004:43: busn_res: can not insert [bus 43-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:43: busn_res: [bus 43-41] end is updated to 43
> pci_bus 0004:43: busn_res: can not insert [bus 43] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:00.0: devices behind bridge are unusable because [bus 43] cannot be assigned for them
> pci_bus 0004:44: busn_res: can not insert [bus 44-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:44: busn_res: [bus 44-41] end is updated to 44
> pci_bus 0004:44: busn_res: can not insert [bus 44] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:02.0: devices behind bridge are unusable because [bus 44] cannot be assigned for them
> pci_bus 0004:45: busn_res: can not insert [bus 45-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:45: busn_res: [bus 45-41] end is updated to 45
> pci_bus 0004:45: busn_res: can not insert [bus 45] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:06.0: devices behind bridge are unusable because [bus 45] cannot be assigned for them
> pci_bus 0004:46: busn_res: can not insert [bus 46-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:46: busn_res: [bus 46-41] end is updated to 46
> pci_bus 0004:46: busn_res: can not insert [bus 46] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:0e.0: devices behind bridge are unusable because [bus 46] cannot be assigned for them
> pci_bus 0004:42: busn_res: [bus 42-41] end is updated to 46
> pci_bus 0004:42: busn_res: can not insert [bus 42-46] under [bus 41] (conflicts with (null) [bus 41])
> pci 0004:41:00.0: devices behind bridge are unusable because [bus 42-46] cannot be assigned for them
> pcieport 0004:40:00.0: bridge has subordinate 41 but max busn 46
> 
> During the initial scan, PCI core doesn't see the switch and since the Root
> Port is not hot plug capable, the secondary bus number gets assigned as the
> subordinate bus number. This means, the PCI core assumes that only one bus
> will appear behind the Root Port since the Root Port is not hot plug
> capable.
> 
> This works perfectly fine for PCIe endpoints connected to the Root Port,
> since they don't extend the bus. However, if a PCIe switch is connected,
> then there is a problem when the downstream busses starts showing up and
> the PCI core doesn't extend the subordinate bus number after initial scan
> during boot.
> 
> The long term plan is to migrate this driver to the pwrctrl framework,
> once it adds proper support for powering up and enumerating PCIe switches.


Hello PCI maintainers,

Merge window is opening soon,
what is the status of this series?


Kind regards,
Niklas


From mani at kernel.org  Mon Nov 24 04:37:44 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Mon, 24 Nov 2025 18:07:44 +0530
Subject: [PATCH 0/6] PCI: dwc: Revert Link Up IRQ support
In-Reply-To: <20251111105100.869997-8-cassel@kernel.org>
References: <20251111105100.869997-8-cassel@kernel.org>
Message-ID: <mt7miqkipr4dvxemftq6octxqzauueln252ncrcwy6i2t7wfhi@jtwokeilhwsi>

On Tue, Nov 11, 2025 at 11:51:00AM +0100, Niklas Cassel wrote:
> Revert all patches related to pcie-designware Root Complex Link Up IRQ
> support.
> 
> While this fake hotplugging was a nice idea, it has shown that this feature
> does not handle PCIe switches correctly:
> pci_bus 0004:43: busn_res: can not insert [bus 43-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:43: busn_res: [bus 43-41] end is updated to 43
> pci_bus 0004:43: busn_res: can not insert [bus 43] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:00.0: devices behind bridge are unusable because [bus 43] cannot be assigned for them
> pci_bus 0004:44: busn_res: can not insert [bus 44-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:44: busn_res: [bus 44-41] end is updated to 44
> pci_bus 0004:44: busn_res: can not insert [bus 44] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:02.0: devices behind bridge are unusable because [bus 44] cannot be assigned for them
> pci_bus 0004:45: busn_res: can not insert [bus 45-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:45: busn_res: [bus 45-41] end is updated to 45
> pci_bus 0004:45: busn_res: can not insert [bus 45] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:06.0: devices behind bridge are unusable because [bus 45] cannot be assigned for them
> pci_bus 0004:46: busn_res: can not insert [bus 46-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:46: busn_res: [bus 46-41] end is updated to 46
> pci_bus 0004:46: busn_res: can not insert [bus 46] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:0e.0: devices behind bridge are unusable because [bus 46] cannot be assigned for them
> pci_bus 0004:42: busn_res: [bus 42-41] end is updated to 46
> pci_bus 0004:42: busn_res: can not insert [bus 42-46] under [bus 41] (conflicts with (null) [bus 41])
> pci 0004:41:00.0: devices behind bridge are unusable because [bus 42-46] cannot be assigned for them
> pcieport 0004:40:00.0: bridge has subordinate 41 but max busn 46
> 
> During the initial scan, PCI core doesn't see the switch and since the Root
> Port is not hot plug capable, the secondary bus number gets assigned as the
> subordinate bus number. This means, the PCI core assumes that only one bus
> will appear behind the Root Port since the Root Port is not hot plug
> capable.
> 
> This works perfectly fine for PCIe endpoints connected to the Root Port,
> since they don't extend the bus. However, if a PCIe switch is connected,
> then there is a problem when the downstream busses starts showing up and
> the PCI core doesn't extend the subordinate bus number after initial scan
> during boot.
> 
> The long term plan is to migrate this driver to the pwrctrl framework,
> once it adds proper support for powering up and enumerating PCIe switches.
> 

While I suggested to revert the link up IRQ patch for rockchip earlier, I didn't
expect to drop the support for Qcom. The reason is, on Qcom SoCs, we have not
seen a case where people connect a random PCIe switch and saw failures. Most of
the Qcom usecases were around the M.2 and other proprietary connectors. There is
only one in-house PCIe switch that is being actively used in our products, but
so far, none of the bootloaders have turned them ON before kernel booting. So
kernel relies on the newly merged pwrctrl driver to do the job. Even though it
also suffers from the same resource allocation issue, this series won't help in
any way as pwrctrl core performs rescan after the switch power ON, and by that
time, it will be very late anyway.

So I'm happy to take the rockhip patches from this series as they fix the real
issue that people have reported. But once the pwrctrl rework series gets merged,
and the rockchip drivers support them, we can bring back the reverted changes.

- Mani

-- 
????????? ????????


From cassel at kernel.org  Mon Nov 24 06:02:51 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Mon, 24 Nov 2025 15:02:51 +0100
Subject: [PATCH 0/6] PCI: dwc: Revert Link Up IRQ support
In-Reply-To: <mt7miqkipr4dvxemftq6octxqzauueln252ncrcwy6i2t7wfhi@jtwokeilhwsi>
References: <20251111105100.869997-8-cassel@kernel.org>
 <mt7miqkipr4dvxemftq6octxqzauueln252ncrcwy6i2t7wfhi@jtwokeilhwsi>
Message-ID: <aSRli_Mb6qoQ9TZO@ryzen>

On Mon, Nov 24, 2025 at 06:07:44PM +0530, Manivannan Sadhasivam wrote:
> While I suggested to revert the link up IRQ patch for rockchip earlier, I didn't
> expect to drop the support for Qcom. The reason is, on Qcom SoCs, we have not
> seen a case where people connect a random PCIe switch and saw failures. Most of
> the Qcom usecases were around the M.2 and other proprietary connectors. There is
> only one in-house PCIe switch that is being actively used in our products, but
> so far, none of the bootloaders have turned them ON before kernel booting. So
> kernel relies on the newly merged pwrctrl driver to do the job. Even though it
> also suffers from the same resource allocation issue, this series won't help in
> any way as pwrctrl core performs rescan after the switch power ON, and by that
> time, it will be very late anyway.
> 
> So I'm happy to take the rockhip patches from this series as they fix the real
> issue that people have reported. But once the pwrctrl rework series gets merged,
> and the rockchip drivers support them, we can bring back the reverted changes.

FUKAUMI Naoki, just to confirm:

Neither my suggested approach:
https://lore.kernel.org/linux-pci/aRHdeVCY3rRmxe80 at ryzen/

nor Shawn's suggested approach:
https://lore.kernel.org/linux-pci/dc932773-af5b-4af7-a0d0-8cc72dfbd3c7 at rock-chips.com/

worked for you?


If so, I don't see many alternative but for Mani to apply patch 1 and
patch 2 from this series.


Kind regards,
Niklas


From gregkh at linuxfoundation.org  Mon Nov 24 08:33:27 2025
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 24 Nov 2025 17:33:27 +0100
Subject: [PATCH v10 01/11] usb: typec: Add notifier functions
In-Reply-To: <a80483de-518d-45d5-b46a-9b70cca5b236@rock-chips.com>
References: <20251120022343.250-1-kernel@airkyi.com>
 <20251120022343.250-2-kernel@airkyi.com>
 <2025112102-laurel-mulch-58e4@gregkh>
 <462ad1bd-7eec-4f26-b383-96b049e14559@rock-chips.com>
 <2025112402-unopposed-polio-e6e9@gregkh>
 <a80483de-518d-45d5-b46a-9b70cca5b236@rock-chips.com>
Message-ID: <2025112448-brush-porcupine-c851@gregkh>

On Mon, Nov 24, 2025 at 04:05:53PM +0800, Chaoyi Chen wrote:
> Hi Greg,
> 
> On 11/24/2025 3:10 PM, Greg Kroah-Hartman wrote:
> 
> > On Mon, Nov 24, 2025 at 09:40:03AM +0800, Chaoyi Chen wrote:
> > > Hi Greg,
> > > 
> > > On 11/21/2025 10:07 PM, Greg Kroah-Hartman wrote:
> > > > On Thu, Nov 20, 2025 at 10:23:33AM +0800, Chaoyi Chen wrote:
> > > > > From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> > > > > 
> > > > > Some other part of kernel may want to know the event of typec bus.
> > > > Be specific, WHAT part of the kernel will need to know this?
> > > For now, it is DRM.
> > Then say this.
> 
> Okay, please refer to the discussion below.
> 
> > 
> > > > And why a new notifier, why not just use the existing notifiers that you
> > > > already have?  And what is this going to be used for?
> > > We have discussed this before, but the current bus notifier cannot achieve the expected notification [0].
> > > 
> > > [0] https://lore.kernel.org/all/aPsuLREPS_FEV3DS at kuha.fi.intel.com/
> > Then you need to document the heck out of this in the changelog text.
> > But I'm still not quite understanding why the bus notifier does not work
> > here, as you only want this information if the usb device is bound to
> > the bus there, you do not want to know this if it did not complete.
> > 
> > That thread says you want this not "too late", but why?  What is the
> > problem there, and how will you handle your code getting loaded after
> > the typec code is loaded?  Notifier callbacks don't work for that
> > situation, right?
> 
> In fact, the typec_register_altmode() function generates two
> registered events.?The first one is the registered event of the port
> device, and the second one is the registered event of the partner
> device.?The second one event only occurs after a Type-C device is
> inserted.
> The bus notifier event does not actually take effect for the port
> device, because it only sets the bus for the partner device:
> 
> ? ? /* The partners are bind to drivers */
> ? ? if (is_typec_partner(parent))
> ? ? ? ? alt->adev.dev.bus = &typec_bus;

Setting the bus is correct, then it needs to be registered with the
driver core so the bus link shows up (and a driver is bound to it.)
That is when the bus notifier can happen, right?

> I hope it's not too late. In fact, the notifier here will notify DRM to establish a bridge chain.

What is a "bridge chain"?

> The downstream DP controller driver hopes to obtain the fwnode of the last-level Type-C device
> through this bridge chain to create a DRM connector. And when a device is inserted,
> drivers/usb/typec/altmodes/displayport.c can notify the HPD (Hot Plug Detect) event.

But aren't you just the driver for the "partner device"?

If not, why isn't a real device being created that you then bind to,
what "fake" type of thing are you attempting to do here that would
require you to do this out-of-band?

> If relying on the second event, the bridge chain may never be established, and the operations of the DP driver will be
> always deferred. Furthermore, other parts of the display controller driver will also be deferred accordingly.

What operations?  What exactly is delayed?  You should not be touching a
device before you have it on your bus, right?

> > > > Notifiers are a pain, and should almost never be added.  Use real
> > > > function calls instead.
> > > In v6, I used direct function calls, but had to switch to notifiers because couldn't resolve the dependencies between DRM and Type-C [1]. Do you have any good ideas? Thank you.
> > Only allow this DRM code to be built if typec code is enabled, do NOT
> > use a select, use a depends in the drm code.
> 
> Sorry, I didn't get your point. Does this mean that the current notifiers approach still needs to be changed to direct function calls?

If you somehow convince me that the existing bus notifiers will not
work, yes :)

> If so, then based on the previous discussion, typec should not depend
> on any DRM components. Does this mean that we should add the if
> (IS_REACHABLE(CONFIG_DRM_AUX_BRIDGE)) before the direct function call?

No, do it properly like any other function call to another subsystem.

> Additionally, the current version of CONFIG_DRM_AUX_BRIDGE is selected
> by the DP driver in patch9.

Don't do "select" if at all possible, always try to do "depends on".

thanks,

greg k-h


From duwe at lst.de  Mon Nov 24 10:30:56 2025
From: duwe at lst.de (Torsten Duwe)
Date: Mon, 24 Nov 2025 19:30:56 +0100 (CET)
Subject: [PATCH] arm64: dts: rockchip: enable SPDIF audio on Rock 5 ITX
Message-ID: <20251124183056.B853068C4E@verein.lst.de>

The Rock5 ITX has an S/PDIF (TOSLINK) socket in its I/O-shield, whose
TX signal is wired to GPIO4 C1. Activate SPDIF TX unit 1 and select
the proper pinmux (M2).

Signed-off-by: Torsten Duwe <duwe at lst.de>
---

For Linux, activating spdif_tx1 only creates a "component", see
/sys/kernel/debug/asoc/components. ALSA needs a "simple-audio-card"
pseudo device wrapper along with a "dummy transmitter" (?!) in order
to turn it into a functioning audio output. This is not really
intuitive and IMHO does not belong in a hardware description.
But well, so be it.

	Torsten

---
 rk3588-rock-5-itx.dts |   23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
index bc8140883de4..6780fbb26efb 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
@@ -147,6 +147,24 @@ sdio_pwrseq: sdio-pwrseq {
 		reset-gpios = <&gpio0 RK_PC4 GPIO_ACTIVE_LOW>;
 	};
 
+	spdif_dit: spdif-dit {
+		compatible = "linux,spdif-dit";
+		#sound-dai-cells = <0>;
+	};
+
+	spdif_sound: spdif-sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "SPDIF";
+
+		simple-audio-card,cpu {
+			sound-dai = <&spdif_tx1>;
+		};
+
+		simple-audio-card,codec {
+			sound-dai = <&spdif_dit>;
+		};
+	};
+
 	typec_vin: regulator-typec-vin {
 		compatible = "regulator-fixed";
 		enable-active-high;
@@ -839,6 +857,11 @@ spi_flash: flash at 0 {
 	};
 };
 
+&spdif_tx1 {
+	pinctrl-0 = <&spdif1m2_tx>;
+	status = "okay";
+};
+
 &spi2 {
 	status = "okay";
 	assigned-clocks = <&cru CLK_SPI2>;


From robh at kernel.org  Mon Nov 24 10:54:04 2025
From: robh at kernel.org (Rob Herring)
Date: Mon, 24 Nov 2025 12:54:04 -0600
Subject: [PATCH v2 03/12] dt-bindings: net: Convert Marvell 8897/8997
 bindings to DT schema
In-Reply-To: <fb20e4fe-df0a-4089-a7cf-e82bfe1f8e00@collabora.com>
References: <20250911151001.108744-1-ariel.dalessandro@collabora.com>
 <20250911151001.108744-4-ariel.dalessandro@collabora.com> <20250912140619.GA1293647-robh@kernel.org>
 <fb20e4fe-df0a-4089-a7cf-e82bfe1f8e00@collabora.com>
Message-ID: <CAL_Jsq+eeiw9oaqQPWt2=rZSX98Pak_oB=tfQFvEehwLZ=S52g@mail.gmail.com>

On Wed, Oct 1, 2025 at 12:28?PM Ariel D'Alessandro
<ariel.dalessandro at collabora.com> wrote:
>
> Rob,
>
> On 9/12/25 11:06 AM, Rob Herring wrote:
> > On Thu, Sep 11, 2025 at 12:09:52PM -0300, Ariel D'Alessandro wrote:
> >> Convert the existing text-based DT bindings for Marvell 8897/8997
> >> (sd8897/sd8997) bluetooth devices controller to a DT schema.
> >>
> >> While here:
> >>
> >> * bindings for "usb1286,204e" (USB interface) are dropped from the DT
> >>    schema definition as these are currently documented in file [0].
> >> * DT binding users are updated to use bluetooth generic name
> >>    recommendation.
> >>
> >> [0] Documentation/devicetree/bindings/net/btusb.txt
> >>
> >> Signed-off-by: Ariel D'Alessandro <ariel.dalessandro at collabora.com>
> >> ---
> >>   .../net/bluetooth/marvell,sd8897-bt.yaml      | 79 ++++++++++++++++++
> >>   .../devicetree/bindings/net/btusb.txt         |  2 +-
> >>   .../bindings/net/marvell-bt-8xxx.txt          | 83 -------------------
> >
> >>   .../dts/rockchip/rk3288-veyron-fievel.dts     |  2 +-
> >>   .../boot/dts/rockchip/rk3288-veyron-jaq.dts   |  2 +-
> >>   arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi  |  2 +-
> >
> > .dts files should be separate patches. Please send the bindings patches
> > separately per subsystem so subsystem maintainers can apply them. All
> > the Mediatek dts changes can be 1 series.
>
> Ack, will fix in v3.

Are you going to send v3 still?

Rob


From helgaas at kernel.org  Mon Nov 24 13:17:33 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Mon, 24 Nov 2025 15:17:33 -0600
Subject: [PATCH 1/4] PCI: dwc: Advertise L1 PM Substates only if driver
 requests it
In-Reply-To: <20251118202210.GA2586610@bhelgaas>
Message-ID: <20251124211733.GA2712491@bhelgaas>

On Tue, Nov 18, 2025 at 02:22:13PM -0600, Bjorn Helgaas wrote:
> On Wed, Nov 12, 2025 at 11:21:07PM +0530, Manivannan Sadhasivam wrote:
> > On Wed, Nov 12, 2025 at 09:22:36AM +0100, Niklas Cassel wrote:
> > > On Tue, Nov 11, 2025 at 04:16:08PM -0600, Bjorn Helgaas wrote:
> > > > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > > > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > > > @@ -1060,6 +1060,8 @@ int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
> > > >  		PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
> > > >  	dw_pcie_writel_dbi(pci, PCI_COMMAND, val);
> > > >  
> > > > +	dw_pcie_config_l1ss(pci);
> 
> > > > --- a/drivers/pci/controller/dwc/pcie-qcom.c
> > > > +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> > > > @@ -1067,6 +1067,8 @@ static int qcom_pcie_init_2_7_0(struct qcom_pcie *pcie)
> > > >  	val &= ~REQ_NOT_ENTR_L1;
> > > >  	writel(val, pcie->parf + PARF_PM_CTRL);
> > > >  
> > > > +	pci->l1ss_support = true;
> > > > +
> > > >  	val = readl(pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
> > > >  	val |= EN;
> > > >  	writel(val, pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
> > > 
> > > While it seems like ops_2_7_0 is the only type that explicitly does a
> > > register write to enable L1ss, other versions might have the register
> > > as enabled by default, so it would be nice if Mani could confirm exactly
> > > which versions that should set l1ss_support = true.
> > > 
> > 
> > Yes, on the rest of the platforms, this bit is supposed to be enabled by
> > default. AFAIK, all Qcom platforms should support L1SS, atleast the
> > non-IPQ/APQ ones.
> > 
> > We should set it for below cfgs:
> > 
> > cfg_fw_managed
> > cfg_sc8280xp
> > cfg_1_34_0
> > cfg_1_9_0
> > cfg_2_7_0
> 
> Except for cfg_fw_managed, the above are all covered by
> qcom_pcie_init_2_7_0(), either via ops_2_7_0, ops_1_9_0, or
> ops_1_21_0.
> 
> cfg_fw_managed is harder because we don't use dw_pcie_host_init() or
> dw_pcie_setup_rc().
> 
> We do allocate a struct dw_pcie (where l1ss_support is) in
> qcom_pcie_ecam_host_init(), but only so we can call
> dw_pcie_msi_host_init() and dw_pcie_msi_init().

I'm just back from vacation so might be forgetting something, but I
think cfg_fw_managed is OK here because in that case we never call
dw_pcie_host_init(), so we never call dw_pcie_setup_rc() where
dw_pcie_hide_unsupported_l1ss().

So the L1SS cap should remain untouched and presumably advertises the
L1SS support we want for cfg_fw_managed.

Bjorn


From helgaas at kernel.org  Mon Nov 24 13:19:03 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Mon, 24 Nov 2025 15:19:03 -0600
Subject: [PATCH v2 1/4] PCI: dwc: Advertise L1 PM Substates only if
 driver requests it
In-Reply-To: <wja7vxtg7bqq2udepl5r3mvgg5swvuqtuzk6cnimgcbw2aegqs@hru6yzg4xx3o>
Message-ID: <20251124211903.GA2712341@bhelgaas>

On Thu, Nov 20, 2025 at 01:10:56PM +0530, Manivannan Sadhasivam wrote:
> On Tue, Nov 18, 2025 at 03:42:15PM -0600, Bjorn Helgaas wrote:
> > From: Bjorn Helgaas <bhelgaas at google.com>
> > 
> > L1 PM Substates require the CLKREQ# signal and may also require
> > device-specific support.  If CLKREQ# is not supported or driver support is
> > lacking, enabling L1.1 or L1.2 may cause errors when accessing devices,
> > e.g.,
> > 
> >   nvme nvme0: controller is down; will reset: CSTS=0xffffffff, PCI_STATUS=0x10
> > 
> > If the kernel is built with CONFIG_PCIEASPM_POWER_SUPERSAVE=y or users
> > enable L1.x via sysfs, users may trip over these errors even if L1
> > Substates haven't been enabled by firmware or the driver.
> > 
> > To prevent such errors, disable advertising the L1 PM Substates unless the
> > driver sets "dw_pcie.l1ss_support" to indicate that it knows CLKREQ# is
> > present and any device-specific configuration has been done.
> 
> Going by this reasoning, why can't we enable L1 PM Substates for
> these platforms by default?

I think we can, in a separate series.  I don't have time to deal with
this before the v6.19 merge window, but you can certainly do that.

Bjorn


From helgaas at kernel.org  Mon Nov 24 13:22:27 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Mon, 24 Nov 2025 15:22:27 -0600
Subject: [PATCH v2 1/4] PCI: dwc: Advertise L1 PM Substates only if
 driver requests it
In-Reply-To: <aR2lOZDBEdGVd9On@ryzen>
Message-ID: <20251124212227.GA2713330@bhelgaas>

On Wed, Nov 19, 2025 at 12:08:41PM +0100, Niklas Cassel wrote:
> On Tue, Nov 18, 2025 at 05:34:18PM -0500, Frank Li wrote:
> > On Tue, Nov 18, 2025 at 03:42:15PM -0600, Bjorn Helgaas wrote:
> > > From: Bjorn Helgaas <bhelgaas at google.com>
> > >
> > > L1 PM Substates require the CLKREQ# signal and may also require
> > > device-specific support.  If CLKREQ# is not supported or driver support is
> > > lacking, enabling L1.1 or L1.2 may cause errors when accessing devices,
> > > e.g.,
> > >
> > >   nvme nvme0: controller is down; will reset: CSTS=0xffffffff, PCI_STATUS=0x10
> > >
> > > If the kernel is built with CONFIG_PCIEASPM_POWER_SUPERSAVE=y or users
> > > enable L1.x via sysfs, users may trip over these errors even if L1
> > > Substates haven't been enabled by firmware or the driver.
> > >
> > > To prevent such errors, disable advertising the L1 PM Substates unless the
> > > driver sets "dw_pcie.l1ss_support" to indicate that it knows CLKREQ# is
> > > present and any device-specific configuration has been done.
> > >
> > > Set "dw_pcie.l1ss_support" in tegra194 (if DT includes the
> > > "supports-clkreq' property) and qcom (for cfg_2_7_0, cfg_1_9_0, cfg_1_34_0,
> > > and cfg_sc8280xp controllers) so they can continue to use L1 Substates.
> > >
> > > Based on Niklas's patch:
> > > https://patch.msgid.link/20251017163252.598812-2-cassel at kernel.org
> > >
> > > Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
> > > ---
> > >  .../pci/controller/dwc/pcie-designware-ep.c   |  2 ++
> > >  .../pci/controller/dwc/pcie-designware-host.c |  2 ++
> > >  drivers/pci/controller/dwc/pcie-designware.c  | 24 +++++++++++++++++++
> > >  drivers/pci/controller/dwc/pcie-designware.h  |  2 ++
> > >  drivers/pci/controller/dwc/pcie-qcom.c        |  2 ++
> > >  drivers/pci/controller/dwc/pcie-tegra194.c    |  3 +++
> > >  6 files changed, 35 insertions(+)
> > >
> > > diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
> > > index 7f2112c2fb21..ad6c0fd67a65 100644
> > > --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> > > +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> > > @@ -966,6 +966,8 @@ int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)
> > >  	if (ep->ops->init)
> > >  		ep->ops->init(ep);
> > >
> > > +	dw_pcie_hide_unsupported_l1ss(pci);
> > > +
> > 
> > And, I don't think EP need clean L1SS CAP flags. If EP don't support L1SS,
> > it should be force pull down #clkreq.
> 
> I think the problem is that we cannot force pull down CLKREQ# in a generic
> DWC function. That would have to be done in glue driver specific callbacks.
> 
> Bjorn, perhaps we should simply drop the dw_pcie_hide_unsupported_l1ss()
> call from dw_pcie_ep_init_registers(), and consider hiding L1ss for EPs to
> be out of scope for this series.
> 
> That way, we could still queue this series up for 6.19.
> 
> Thoughts from everyone?

Good idea, done locally, thanks!

Bjorn


From heiko at sntech.de  Mon Nov 24 13:56:06 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 24 Nov 2025 22:56:06 +0100
Subject: [GIT PULL] Rockchip dts64 changes for 6.19 #2
Message-ID: <2244391.irdbgypaU6@diego>

Hi soc maintainers,

please find below some more Rockchip arm64 dts changes for for 6.19 
on top of the previous changes.

Please pull.
Thanks
Heiko


The following changes since commit 78f316e90906d54c8aa6029e5c19ae83e420e56a:

  arm64: dts: rockchip: add vicap node to rk356x (2025-11-16 00:39:47 +0100)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git tags/v6.19-rockchip-dts64-2

for you to fetch changes up to e34003dd2fb05da8f420bbd7b8ec62ab88242c45:

  arm64: dts: rockchip: enable RTC for 100ASK DshanPi A1 (2025-11-21 22:39:06 +0100)

----------------------------------------------------------------
New boards: QNAP TS233 (2-bay variant of the RK3568 NAS series) and
Asus Tinkerboard 3 + 3S.
Additional peripherals enabled on 100ASK DshanPi A1, Orange Pi 3B,
Indiedroid Nova, QNAP-TSx33 series + LED states on Radxa boards,
power-domains for the previously added RK3368 display components.

----------------------------------------------------------------
Chris Morgan (4):
      arm64: dts: rockchip: Add clk32k_in for Indiedroid Nova
      arm64: dts: rockchip: Define regulator for pcie2x1l2 on Indiedroid Nova
      arm64: dts: rockchip: Correct pinctrl for pcie for Indiedroid Nova
      arm64: dts: rockchip: Add host wake pin for wifi on Indiedroid Nova

Chukun Pan (5):
      arm64: dts: rockchip: remove mmc max-frequency for 100ASK DshanPi A1
      arm64: dts: rockchip: add mmc aliases for 100ASK DshanPi A1
      arm64: dts: rockchip: enable button for 100ASK DshanPi A1
      arm64: dts: rockchip: enable USB for 100ASK DshanPi A1
      arm64: dts: rockchip: enable RTC for 100ASK DshanPi A1

Coia Prant (1):
      arm64: dts: rockchip: fix PCIe 3.3V regulator voltage on 9Tripod X3568 v4

FUKAUMI Naoki (1):
      arm64: dts: rockchip: Use default-state for power LED for Radxa boards

Heiko Stuebner (7):
      arm64: dts: rockchip: move cpu_thermal node to the correct position
      arm64: dts: rockchip: describe mcu eeprom cells on rk3568-ts433
      arm64: dts: rockchip: move common qnap tsx33 parts to dtsi
      dt-bindings: arm: rockchip: add TS233 to RK3568-based QNAP NAS devices
      arm64: dts: rockchip: add QNAP TS233 devicetree
      arm64: dts: rockchip: Add power-domain to RK3368 DSI controller
      arm64: dts: rockchip: Add power-domain to RK3368 VOP controller

Michael Opdenacker (4):
      dt-bindings: arm: rockchip: merge Asus Tinker and Tinker S
      dt-bindings: arm: rockchip: Add Asus Tinker Board 3/3S
      arm64: dts: rockchip: Add Asus Tinker Board 3 and 3S device tree
      arm64: dts: rockchip: Enable i2c2 on Orange Pi 3B

 .../devicetree/bindings/arm/rockchip.yaml          |  18 +-
 arch/arm64/boot/dts/rockchip/Makefile              |   3 +
 arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts  |   1 -
 arch/arm64/boot/dts/rockchip/rk3368.dtsi           |   2 +
 .../boot/dts/rockchip/rk3399-rock-4c-plus.dts      |   2 +-
 arch/arm64/boot/dts/rockchip/rk3528-rock-2a.dts    |   1 -
 .../boot/dts/rockchip/rk3566-orangepi-3b.dtsi      |   5 +
 .../boot/dts/rockchip/rk3566-tinker-board-3.dts    |  13 +
 .../boot/dts/rockchip/rk3566-tinker-board-3.dtsi   | 278 ++++++++++
 .../boot/dts/rockchip/rk3566-tinker-board-3s.dts   |  30 +
 .../boot/dts/rockchip/rk3568-9tripod-x3568-v4.dts  |  14 +-
 arch/arm64/boot/dts/rockchip/rk3568-qnap-ts233.dts | 131 +++++
 arch/arm64/boot/dts/rockchip/rk3568-qnap-ts433.dts | 604 ++------------------
 .../arm64/boot/dts/rockchip/rk3568-qnap-tsx33.dtsi | 608 +++++++++++++++++++++
 .../boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts |  93 +++-
 arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts    |   2 +-
 arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts |   2 +-
 .../boot/dts/rockchip/rk3588s-indiedroid-nova.dts  |  43 +-
 arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts   |   2 +-
 19 files changed, 1249 insertions(+), 603 deletions(-)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3.dts
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3.dtsi
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-tinker-board-3s.dts
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-qnap-ts233.dts
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-qnap-tsx33.dtsi





From heiko at sntech.de  Mon Nov 24 13:57:09 2025
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 24 Nov 2025 22:57:09 +0100
Subject: [GIT PULL] Rockchip clock changes for 6.19 #1
Message-ID: <3018362.e9J7NaK4W3@diego>

Hi Mike, Stephen,

please find below a pull-request with Rockchip clock change for 6.19

Please pull.

Thanks
Heiko


The following changes since commit 3a8660878839faadb4f1a6dd72c3179c1df56787:

  Linux 6.18-rc1 (2025-10-12 13:42:36 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git tags/v6.19-rockchip-clk1

for you to fetch changes up to 18191dd750e6c9e17fabefd09ff418dd587bcdb9:

  clk: rockchip: Add clock and reset driver for RK3506 (2025-11-23 22:56:49 +0100)

----------------------------------------------------------------
SCMI clock-ids and max-clk-number removal from dt-binding on RK3568 as
well as clock drivers for the new SoCs RV1126B and RK3506.

----------------------------------------------------------------
Elaine Zhang (4):
      clk: rockchip: Implement rockchip_clk_register_armclk_multi_pll()
      dt-bindings: clock, reset: Add support for rv1126b
      clk: rockchip: Add clock controller for the RV1126B
      clk: rockchip: Add clock and reset driver for RK3506

Finley Xiao (1):
      dt-bindings: clock: rockchip: Add RK3506 clock and reset unit

Heiko Stuebner (3):
      dt-bindings: clock: rk3568: Add SCMI clock ids
      clk: rockchip: rk3568: Drop CLK_NR_CLKS usage
      dt-bindings: clock: rk3568: Drop CLK_NR_CLKS define

 .../bindings/clock/rockchip,rk3506-cru.yaml        |   55 +
 .../bindings/clock/rockchip,rv1126b-cru.yaml       |   52 +
 drivers/clk/rockchip/Kconfig                       |   14 +
 drivers/clk/rockchip/Makefile                      |    2 +
 drivers/clk/rockchip/clk-cpu.c                     |  165 +++
 drivers/clk/rockchip/clk-rk3506.c                  |  869 +++++++++++++++
 drivers/clk/rockchip/clk-rk3568.c                  |    5 +-
 drivers/clk/rockchip/clk-rv1126b.c                 | 1117 ++++++++++++++++++++
 drivers/clk/rockchip/clk.c                         |   24 +
 drivers/clk/rockchip/clk.h                         |   96 ++
 drivers/clk/rockchip/rst-rk3506.c                  |  226 ++++
 drivers/clk/rockchip/rst-rv1126b.c                 |  443 ++++++++
 include/dt-bindings/clock/rk3568-cru.h             |    6 +-
 include/dt-bindings/clock/rockchip,rk3506-cru.h    |  285 +++++
 include/dt-bindings/clock/rockchip,rv1126b-cru.h   |  392 +++++++
 include/dt-bindings/reset/rockchip,rk3506-cru.h    |  211 ++++
 include/dt-bindings/reset/rockchip,rv1126b-cru.h   |  405 +++++++
 17 files changed, 4365 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3506-cru.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rv1126b-cru.yaml
 create mode 100644 drivers/clk/rockchip/clk-rk3506.c
 create mode 100644 drivers/clk/rockchip/clk-rv1126b.c
 create mode 100644 drivers/clk/rockchip/rst-rk3506.c
 create mode 100644 drivers/clk/rockchip/rst-rv1126b.c
 create mode 100644 include/dt-bindings/clock/rockchip,rk3506-cru.h
 create mode 100644 include/dt-bindings/clock/rockchip,rv1126b-cru.h
 create mode 100644 include/dt-bindings/reset/rockchip,rk3506-cru.h
 create mode 100644 include/dt-bindings/reset/rockchip,rv1126b-cru.h





From helgaas at kernel.org  Mon Nov 24 14:50:30 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Mon, 24 Nov 2025 16:50:30 -0600
Subject: [PATCH v2 0/4] PCI: dwc: Advertise L1 PM Substates only if
 driver requests it
In-Reply-To: <20251118214312.2598220-1-helgaas@kernel.org>
Message-ID: <20251124225030.GA2721839@bhelgaas>

On Tue, Nov 18, 2025 at 03:42:14PM -0600, Bjorn Helgaas wrote:
> From: Bjorn Helgaas <bhelgaas at google.com>
> 
> This is a follow-up to Niklas's patch at
> https://lore.kernel.org/r/20251017163252.598812-2-cassel at kernel.org.  That
> patch clears the L1 PM Substate Supported bits for the dw-rockchip driver,
> which doesn't yet do the device configuration to support the L1 Substates.
> 
> This series does the same thing, but in the DWC core so it applies to all
> DWC-based drivers.  Drivers that do support L1 Substates (currently
> tegra194 and qcom) indicate that by setting "dw_pcie.l1ss_support", and the
> DWC core will leave the L1 PM Substate Supported bits alone.
> 
> This also includes Shawn's patches to add the dw-rockchip support for L1
> Substates.
> 
> The problem this fixes is that users are currently able to enable L1
> Substates, e.g., by
> 
>   - building with with CONFIG_PCIEASPM_POWER_SUPERSAVE=y
>   - booting with "pcie_aspm.policy=powersupersave"
>   - echo powersupersave > /sys/module/pcie_aspm/parameters/policy
>   - echo 1 > /sys/bus/pci/devices/.../link/l1_1_aspm
> 
> but this breaks devices if the platform doesn't support CLKREQ# or lacks
> Root Port configuration.  This series avoids that problem by preventing the
> kernel from enabling L1.x in the first place.
> 
> 
> Bjorn Helgaas (2):
>   PCI: dwc: Advertise L1 PM Substates only if driver requests it
>   PCI: tegra194: Remove unnecessary L1SS disable code
> 
> Shawn Lin (2):
>   PCI: dw-rockchip: Configure L1SS support
>   arm64: dts: rockchip: Add PCIe clkreq stuff for RK3588 EVB1

I applied these (except for the arm64: dts: patch) to
pci/controller/dwc, planned for v6.19.  Same as posted here except I
dropped dw_pcie_hide_unsupported_l1ss() from
dw_pcie_ep_init_registers().

>  .../boot/dts/rockchip/rk3588-evb1-v10.dts     |  7 ++-
>  .../pci/controller/dwc/pcie-designware-ep.c   |  2 +
>  .../pci/controller/dwc/pcie-designware-host.c |  2 +
>  drivers/pci/controller/dwc/pcie-designware.c  | 24 ++++++++++
>  drivers/pci/controller/dwc/pcie-designware.h  |  2 +
>  drivers/pci/controller/dwc/pcie-dw-rockchip.c | 40 ++++++++++++++++
>  drivers/pci/controller/dwc/pcie-qcom.c        |  2 +
>  drivers/pci/controller/dwc/pcie-tegra194.c    | 48 ++++---------------
>  8 files changed, 85 insertions(+), 42 deletions(-)
> 
> -- 
> 2.43.0
> 


From shawn.lin at rock-chips.com  Mon Nov 24 17:53:52 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Tue, 25 Nov 2025 09:53:52 +0800
Subject: [PATCH 2/2] PCI: dw-rockchip: Change get_lttssm() to provide L1ss info
In-Reply-To: <1764035632-180821-1-git-send-email-shawn.lin@rock-chips.com>
References: <1764035632-180821-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1764035632-180821-2-git-send-email-shawn.lin@rock-chips.com>

This patch renames rockchip_pcie_get_ltssm() to rockchip_pcie_get_ltssm_reg()
and adds rockchip_pcie_get_ltssm() to get_lttssm() callback to in order to
show the proper L1 substates. The PCIE_CLIENT_LTSSM_STATUS[5:0] register returns
the same ltssm layout as enum dw_pcie_ltssm. So we only need to tell L1ss apart
and return the proper value defined in pcie-designware.h.

cat /sys/kernel/debug/dwc_pcie_a40000000.pcie/ltssm_status
L1_2 (0x142)

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
---
 drivers/pci/controller/dwc/pcie-dw-rockchip.c | 28 ++++++++++++++++---
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
index f8605fe61a41..019d4f4f26a6 100644
--- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
+++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
@@ -68,6 +68,11 @@
 #define  PCIE_CLKREQ_NOT_READY		FIELD_PREP_WM16(BIT(0), 0)
 #define  PCIE_CLKREQ_PULL_DOWN		FIELD_PREP_WM16(GENMASK(13, 12), 1)
 
+/* RASDES TBA infomation */
+#define PCIE_CLIENT_CDM_RASDES_TBA_INFO_CMN	0x154
+#define  PCIE_CLIENT_CDM_RASDES_TBA_L1_1	BIT(4)
+#define  PCIE_CLIENT_CDM_RASDES_TBA_L1_2	BIT(5)
+
 /* Hot Reset Control Register */
 #define PCIE_CLIENT_HOT_RESET_CTRL	0x180
 #define  PCIE_LTSSM_APP_DLY2_EN		BIT(1)
@@ -181,11 +186,25 @@ static int rockchip_pcie_init_irq_domain(struct rockchip_pcie *rockchip)
 	return 0;
 }
 
-static u32 rockchip_pcie_get_ltssm(struct rockchip_pcie *rockchip)
+static u32 rockchip_pcie_get_ltssm_reg(struct rockchip_pcie *rockchip)
 {
 	return rockchip_pcie_readl_apb(rockchip, PCIE_CLIENT_LTSSM_STATUS);
 }
 
+static enum dw_pcie_ltssm rockchip_pcie_get_ltssm(struct dw_pcie *pci)
+{
+	struct rockchip_pcie *rockchip = to_rockchip_pcie(pci);
+	u32 val = rockchip_pcie_readl_apb(rockchip, PCIE_CLIENT_CDM_RASDES_TBA_INFO_CMN);
+
+	if (val & PCIE_CLIENT_CDM_RASDES_TBA_L1_1)
+		return DW_PCIE_LTSSM_L1_1;
+	else if (val & PCIE_CLIENT_CDM_RASDES_TBA_L1_2)
+		return DW_PCIE_LTSSM_L1_2;
+	else
+		return rockchip_pcie_get_ltssm_reg(rockchip) &
+			PCIE_LTSSM_STATUS_MASK;
+}
+
 static void rockchip_pcie_enable_ltssm(struct rockchip_pcie *rockchip)
 {
 	rockchip_pcie_writel_apb(rockchip, PCIE_CLIENT_ENABLE_LTSSM,
@@ -201,7 +220,7 @@ static void rockchip_pcie_disable_ltssm(struct rockchip_pcie *rockchip)
 static bool rockchip_pcie_link_up(struct dw_pcie *pci)
 {
 	struct rockchip_pcie *rockchip = to_rockchip_pcie(pci);
-	u32 val = rockchip_pcie_get_ltssm(rockchip);
+	u32 val = rockchip_pcie_get_ltssm_reg(rockchip);
 
 	return FIELD_GET(PCIE_LINKUP_MASK, val) == PCIE_LINKUP;
 }
@@ -485,6 +504,7 @@ static const struct dw_pcie_ops dw_pcie_ops = {
 	.link_up = rockchip_pcie_link_up,
 	.start_link = rockchip_pcie_start_link,
 	.stop_link = rockchip_pcie_stop_link,
+	.get_ltssm = rockchip_pcie_get_ltssm,
 };
 
 static irqreturn_t rockchip_pcie_rc_sys_irq_thread(int irq, void *arg)
@@ -499,7 +519,7 @@ static irqreturn_t rockchip_pcie_rc_sys_irq_thread(int irq, void *arg)
 	rockchip_pcie_writel_apb(rockchip, reg, PCIE_CLIENT_INTR_STATUS_MISC);
 
 	dev_dbg(dev, "PCIE_CLIENT_INTR_STATUS_MISC: %#x\n", reg);
-	dev_dbg(dev, "LTSSM_STATUS: %#x\n", rockchip_pcie_get_ltssm(rockchip));
+	dev_dbg(dev, "LTSSM_STATUS: %#x\n", rockchip_pcie_get_ltssm_reg(rockchip));
 
 	if (reg & PCIE_RDLH_LINK_UP_CHGED) {
 		if (rockchip_pcie_link_up(pci)) {
@@ -526,7 +546,7 @@ static irqreturn_t rockchip_pcie_ep_sys_irq_thread(int irq, void *arg)
 	rockchip_pcie_writel_apb(rockchip, reg, PCIE_CLIENT_INTR_STATUS_MISC);
 
 	dev_dbg(dev, "PCIE_CLIENT_INTR_STATUS_MISC: %#x\n", reg);
-	dev_dbg(dev, "LTSSM_STATUS: %#x\n", rockchip_pcie_get_ltssm(rockchip));
+	dev_dbg(dev, "LTSSM_STATUS: %#x\n", rockchip_pcie_get_ltssm_reg(rockchip));
 
 	if (reg & PCIE_LINK_REQ_RST_NOT_INT) {
 		dev_dbg(dev, "hot reset or link-down reset\n");
-- 
2.43.0



From shawn.lin at rock-chips.com  Mon Nov 24 17:53:51 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Tue, 25 Nov 2025 09:53:51 +0800
Subject: [PATCH 1/2] PCI: dwc: Add L1ss context to ltssm_status of debugfs
Message-ID: <1764035632-180821-1-git-send-email-shawn.lin@rock-chips.com>

dwc core couldn't distinguish ltssm status among L1.0, L1.1 and L1.2.
But the variant driver may implement additional register to tell them
apart. So this patch adds two pseudo definitions for variant drivers to
transltae their internal L1 substates for debugfs to show.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
---
This patch is based on latest pci controller/dwc branch given that L1ss support
for Rockchip has been applied.

 drivers/pci/controller/dwc/pcie-designware-debugfs.c | 2 ++
 drivers/pci/controller/dwc/pcie-designware.h         | 4 ++++
 2 files changed, 6 insertions(+)

diff --git a/drivers/pci/controller/dwc/pcie-designware-debugfs.c b/drivers/pci/controller/dwc/pcie-designware-debugfs.c
index 0fbf86c0b97e..df98fee69892 100644
--- a/drivers/pci/controller/dwc/pcie-designware-debugfs.c
+++ b/drivers/pci/controller/dwc/pcie-designware-debugfs.c
@@ -485,6 +485,8 @@ static const char *ltssm_status_string(enum dw_pcie_ltssm ltssm)
 	DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_RCVRY_EQ1);
 	DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_RCVRY_EQ2);
 	DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_RCVRY_EQ3);
+	DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_L1_1);
+	DW_PCIE_LTSSM_NAME(DW_PCIE_LTSSM_L1_2);
 	default:
 		str = "DW_PCIE_LTSSM_UNKNOWN";
 		break;
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index d3dc0cd8e7b5..3f4611882e29 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -380,6 +380,10 @@ enum dw_pcie_ltssm {
 	DW_PCIE_LTSSM_RCVRY_EQ2 = 0x22,
 	DW_PCIE_LTSSM_RCVRY_EQ3 = 0x23,
 
+	/* Variant drivers provide pseudo L1 substates from get_ltssm()*/
+	DW_PCIE_LTSSM_L1_1 = 0x141,
+	DW_PCIE_LTSSM_L1_2 = 0x142,
+
 	DW_PCIE_LTSSM_UNKNOWN = 0xFFFFFFFF,
 };
 
-- 
2.43.0



From chaoyi.chen at rock-chips.com  Mon Nov 24 18:23:02 2025
From: chaoyi.chen at rock-chips.com (Chaoyi Chen)
Date: Tue, 25 Nov 2025 10:23:02 +0800
Subject: [PATCH v10 01/11] usb: typec: Add notifier functions
In-Reply-To: <2025112448-brush-porcupine-c851@gregkh>
References: <20251120022343.250-1-kernel@airkyi.com>
 <20251120022343.250-2-kernel@airkyi.com>
 <2025112102-laurel-mulch-58e4@gregkh>
 <462ad1bd-7eec-4f26-b383-96b049e14559@rock-chips.com>
 <2025112402-unopposed-polio-e6e9@gregkh>
 <a80483de-518d-45d5-b46a-9b70cca5b236@rock-chips.com>
 <2025112448-brush-porcupine-c851@gregkh>
Message-ID: <c9cb7b79-37c8-4fef-97a6-7d6b8898f9c4@rock-chips.com>

On 11/25/2025 12:33 AM, Greg Kroah-Hartman wrote:
> On Mon, Nov 24, 2025 at 04:05:53PM +0800, Chaoyi Chen wrote:
>> Hi Greg,
>>
>> On 11/24/2025 3:10 PM, Greg Kroah-Hartman wrote:
>>
>>> On Mon, Nov 24, 2025 at 09:40:03AM +0800, Chaoyi Chen wrote:
>>>> Hi Greg,
>>>>
>>>> On 11/21/2025 10:07 PM, Greg Kroah-Hartman wrote:
>>>>> On Thu, Nov 20, 2025 at 10:23:33AM +0800, Chaoyi Chen wrote:
>>>>>> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
>>>>>>
>>>>>> Some other part of kernel may want to know the event of typec bus.
>>>>> Be specific, WHAT part of the kernel will need to know this?
>>>> For now, it is DRM.
>>> Then say this.
>> Okay, please refer to the discussion below.
>>
>>>>> And why a new notifier, why not just use the existing notifiers that you
>>>>> already have?  And what is this going to be used for?
>>>> We have discussed this before, but the current bus notifier cannot achieve the expected notification [0].
>>>>
>>>> [0] https://lore.kernel.org/all/aPsuLREPS_FEV3DS at kuha.fi.intel.com/
>>> Then you need to document the heck out of this in the changelog text.
>>> But I'm still not quite understanding why the bus notifier does not work
>>> here, as you only want this information if the usb device is bound to
>>> the bus there, you do not want to know this if it did not complete.
>>>
>>> That thread says you want this not "too late", but why?  What is the
>>> problem there, and how will you handle your code getting loaded after
>>> the typec code is loaded?  Notifier callbacks don't work for that
>>> situation, right?
>> In fact, the typec_register_altmode() function generates two
>> registered events.?The first one is the registered event of the port
>> device, and the second one is the registered event of the partner
>> device.?The second one event only occurs after a Type-C device is
>> inserted.
>> The bus notifier event does not actually take effect for the port
>> device, because it only sets the bus for the partner device:
>>
>>  ? ? /* The partners are bind to drivers */
>>  ? ? if (is_typec_partner(parent))
>>  ? ? ? ? alt->adev.dev.bus = &typec_bus;
> Setting the bus is correct, then it needs to be registered with the
> driver core so the bus link shows up (and a driver is bound to it.)
> That is when the bus notifier can happen, right?
Yes, this is valid for the partner device. But for the port device, since the bus is not specified here, the corresponding bus notifier will not take effect.

>
>> I hope it's not too late. In fact, the notifier here will notify DRM to establish a bridge chain.
> What is a "bridge chain"?
In DRM, the bridge chain is often used to describe the chain connection relationship
of the output of multi level display conversion chips. The bridge chain we are referring to here
is actually a chain? structure formed by connecting various devices using a simple transparent bridge [0].

For example, the schematic diagram of a bridge chain is as follows:

DP controller bridge -> DP PHY bridge -> onnn,nb7vpq904m retimer bridge -> fsa4480 analog audio switch bridge -> fusb302 HPD bridge

Here, apart from the DP controller bridge, the rest are transparent DRM bridges, which are used solely to
describe the link relationships between various devices.


[0] https://patchwork.freedesktop.org/patch/msgid/20231203114333.1305826-2-dmitry.baryshkov at linaro.org
>
>> The downstream DP controller driver hopes to obtain the fwnode of the last-level Type-C device
>> through this bridge chain to create a DRM connector. And when a device is inserted,
>> drivers/usb/typec/altmodes/displayport.c can notify the HPD (Hot Plug Detect) event.
> But aren't you just the driver for the "partner device"?
>
> If not, why isn't a real device being created that you then bind to,
> what "fake" type of thing are you attempting to do here that would
> require you to do this out-of-band?
The HPD event is pass by drm_connector_oob_hotplug_event(), which does not use the device in Type-C.
This function will find the corresponding DRM connector device, and the lookup of the DRM connector is
done through the fwnode.

And the partner device and the port device have the same fwnode.

>
>> If relying on the second event, the bridge chain may never be established, and the operations of the DP driver will be
>> always deferred. Furthermore, other parts of the display controller driver will also be deferred accordingly.
> What operations?  What exactly is delayed?  You should not be touching a
> device before you have it on your bus, right?
To complete the HPD operation, it is necessary to create a drm connector device that
has the appropriate fwnode. This operation will be carried out by the DP controller driver.

As you can see, since it cross multiple devices, we need to set the fwnode to the last device fusb302.
This requires relying on the bridge chain. We can register bridges for multiple devices and then connect
them to form a chain. The connection process is completed through drm_bridge_attach().

A brief example of the process of establishing a bridge chain is as follows, starting from the last bridge:

step1: fusb302 HPD bridge
step2: fsa4480 analog audio switch bridge -> fusb302 HPD bridge
step3: onnn,nb7vpq904m retimer bridge -> fsa4480 analog audio switch bridge -> fusb302 HPD bridge
step4: DP PHY bridge -> onnn,nb7vpq904m retimer bridge -> fsa4480 analog audio switch bridge -> fusb302 HPD bridge
step5: DP controller bridge -> DP PHY bridge -> onnn,nb7vpq904m retimer bridge -> fsa4480 analog audio switch bridge -> fusb302 HPD bridge

Step 1 is the most crucial, because essentially, regardless of whether we use notifiers or not, what we ultimately want to achieve is to create an HPD bridge.
The DP controller needs to wait for the subsequent bridge chain to be established because it needs to know the connection relationships of the devices.

The question now is when to create the HPD bridge, during the registration of the port device or during the registration of the partner device.
If it's the latter, then the delay occurs here.

And I don't think I'm touching the Type-C device here. I'm just using the bridge chain to get a suitable fwnode and create a suitable DRM connector device.
The subsequent Type-C HPD events will be on the DRM connector device.

This solution is somewhat complex, and I apologize once again for any confusion caused earlier.

>
>>>>> Notifiers are a pain, and should almost never be added.  Use real
>>>>> function calls instead.
>>>> In v6, I used direct function calls, but had to switch to notifiers because couldn't resolve the dependencies between DRM and Type-C [1]. Do you have any good ideas? Thank you.
>>> Only allow this DRM code to be built if typec code is enabled, do NOT
>>> use a select, use a depends in the drm code.
>> Sorry, I didn't get your point. Does this mean that the current notifiers approach still needs to be changed to direct function calls?
> If you somehow convince me that the existing bus notifiers will not
> work, yes :)
>
>> If so, then based on the previous discussion, typec should not depend
>> on any DRM components. Does this mean that we should add the if
>> (IS_REACHABLE(CONFIG_DRM_AUX_BRIDGE)) before the direct function call?
> No, do it properly like any other function call to another subsystem.
>
>> Additionally, the current version of CONFIG_DRM_AUX_BRIDGE is selected
>> by the DP driver in patch9.
> Don't do "select" if at all possible, always try to do "depends on".
Thank you for clarifying this. However, CONFIG_DRM_AUX_BRIDGE is not exposed in the menu, and it is not intended for the end user to select it by design. Therefore, I think there still needs to be some place to select it?

-- 
Best,
Chaoyi




From shawn.lin at rock-chips.com  Mon Nov 24 19:02:03 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Tue, 25 Nov 2025 11:02:03 +0800
Subject: [PATCH] mmc: sdhci-of-dwcmshc: Fix command queue support for
 RK3576
In-Reply-To: <20251121-rockchip-emmc-cqe-rk3576-fix-v1-1-a77805f40072@collabora.com>
References: <20251121-rockchip-emmc-cqe-rk3576-fix-v1-1-a77805f40072@collabora.com>
Message-ID: <784f6364-e49d-4452-91c0-c8f24706951b@rock-chips.com>

? 2025/11/22 ??? 0:26, Sebastian Reichel ??:
> When I added command queue engine (CQE) support for the Rockchip eMMC
> controller, I missed that RK3576 has a separate platform data struct.
> While things are working fine on RK3588 (I tested the ROCK 5B) and
> the suspend issue is fixed on the RK3576 (I tested the Sige5), this
> results in stability issues. By also adding the necessary hooks for
> the RK3576 platform the following problems can be avoided:
> 

Reviewed-by: Shawn Lin <shawn.lin at rock-chips.com>

> [   15.606895] mmc0: running CQE recovery
> [   15.616189] mmc0: running CQE recovery
> [...]
> [   25.911484] mmc0: running CQE recovery
> [   25.926305] mmc0: running CQE recovery
> [   25.927468] mmc0: running CQE recovery
> [...]
> [   26.255719] mmc0: running CQE recovery
> [   26.257162] ------------[ cut here ]------------
> [   26.257581] mmc0: cqhci: spurious TCN for tag 31
> [   26.258034] WARNING: CPU: 0 PID: 0 at drivers/mmc/host/cqhci-core.c:796 cqhci_irq+0x440/0x68c
> [   26.263786] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.18.0-rc6-gd984ebbf0d15 #1 PREEMPT
> [   26.264561] Hardware name: ArmSoM Sige5 (DT)
> [...]
> [   26.272748] Call trace:
> [   26.272964]  cqhci_irq+0x440/0x68c (P)
> [   26.273296]  dwcmshc_cqe_irq_handler+0x54/0x88
> [   26.273689]  sdhci_irq+0xbc/0x1200
> [   26.273991]  __handle_irq_event_percpu+0x54/0x1d0
> [...]
> 
> Note that the above problems do not necessarily happen with every boot.
> 
> Reported-by: Adrian Hunter <adrian.hunter at intel.com>
> Closes: https://lore.kernel.org/linux-rockchip/01949bc9-4873-498b-ac7d-f008393ccc4c at intel.com/
> Fixes: fda1e0af7c28f ("mmc: sdhci-of-dwcmshc: Add command queue support for rockchip SOCs")
> Signed-off-by: Sebastian Reichel <sebastian.reichel at collabora.com>
> ---
> Sorry for the delay in sending this :)
> ---
>   drivers/mmc/host/sdhci-of-dwcmshc.c | 1 +
>   1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c
> index c66a8dfad47c..ee0008d91b98 100644
> --- a/drivers/mmc/host/sdhci-of-dwcmshc.c
> +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c
> @@ -1767,6 +1767,7 @@ static const struct dwcmshc_pltfm_data sdhci_dwcmshc_rk3576_pdata = {
>   		.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
>   			   SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN,
>   	},
> +	.cqhci_host_ops = &rk35xx_cqhci_ops,
>   	.init = dwcmshc_rk35xx_init,
>   	.postinit = dwcmshc_rk3576_postinit,
>   };
> 
> ---
> base-commit: dcbce328d3a2d87770133834210cf328c083d480
> change-id: 20251121-rockchip-emmc-cqe-rk3576-fix-ec8ac72e6e32
> 
> Best regards,



From devnull+guptarud.gmail.com at kernel.org  Mon Nov 24 19:47:00 2025
From: devnull+guptarud.gmail.com at kernel.org (Rudraksha Gupta via B4 Relay)
Date: Mon, 24 Nov 2025 19:47:00 -0800
Subject: [PATCH v5 1/4] arm64: dts: rockchip: Add light/proximity sensor to
 Pinephone Pro
In-Reply-To: <20251124-ppp_light_accel_mag_vol-down-v5-0-f9a10a0a50eb@gmail.com>
References: <20251124-ppp_light_accel_mag_vol-down-v5-0-f9a10a0a50eb@gmail.com>
Message-ID: <20251124-ppp_light_accel_mag_vol-down-v5-1-f9a10a0a50eb@gmail.com>

From: Ondrej Jirman <megi at xff.cz>

Pinephone Pro uses STK3311 according to the schematics.

Tests:
~ $ monitor-sensor --light
    // When the sensor is exposed, it get's fluctating values such as
    Light changed: 1.800000 (lux)
    Light changed: 1.700000 (lux)
    Light changed: 1.800000 (lux)
    Light changed: 1.700000 (lux)
    Light changed: 1.600000 (lux)
    Light changed: 1.100000 (lux)
    // When covering the sensor, it prints a low value and stops printing
    Light changed: 0.200000 (lux)

~ $ monitor-sensor --proximity
    // When it goes away from an object
    Proximity value changed: 0
    // When it comes near an object
    Proximity value changed: 1

Co-developed-by: Martijn Braam <martijn at brixit.nl>
Signed-off-by: Martijn Braam <martijn at brixit.nl>
Co-developed-by: Kamil Trzci?ski <ayufan at ayufan.eu>
Signed-off-by: Kamil Trzci?ski <ayufan at ayufan.eu>
Signed-off-by: Ondrej Jirman <megi at xff.cz>
Signed-off-by: Rudraksha Gupta <guptarud at gmail.com>
---
 arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts b/arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts
index 6f97e57f36f5..2d2858ee149e 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts
@@ -520,6 +520,16 @@ touchscreen at 14 {
 		touchscreen-size-x = <720>;
 		touchscreen-size-y = <1440>;
 	};
+
+	light-sensor at 48 {
+		compatible = "sensortek,stk3311";
+		proximity-near-level = <300>;
+		reg = <0x48>;
+		interrupt-parent = <&gpio4>;
+		interrupts = <RK_PD3 IRQ_TYPE_EDGE_FALLING>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&light_int_l>;
+	};
 };
 
 &i2c4 {
@@ -689,6 +699,12 @@ vcc1v8_codec_en: vcc1v8-codec-en {
 		};
 	};
 
+	stk3311 {
+		light_int_l: light-int-l {
+			rockchip,pins = <4 RK_PD3 RK_FUNC_GPIO &pcfg_input_pull_up>;
+		};
+	};
+
 	wireless-bluetooth {
 		bt_wake_pin: bt-wake-pin {
 			rockchip,pins = <2 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;

-- 
2.52.0




From devnull+guptarud.gmail.com at kernel.org  Mon Nov 24 19:47:01 2025
From: devnull+guptarud.gmail.com at kernel.org (Rudraksha Gupta via B4 Relay)
Date: Mon, 24 Nov 2025 19:47:01 -0800
Subject: [PATCH v5 2/4] arm64: dts: rockchip: Add accelerometer sensor to
 Pinephone Pro
In-Reply-To: <20251124-ppp_light_accel_mag_vol-down-v5-0-f9a10a0a50eb@gmail.com>
References: <20251124-ppp_light_accel_mag_vol-down-v5-0-f9a10a0a50eb@gmail.com>
Message-ID: <20251124-ppp_light_accel_mag_vol-down-v5-2-f9a10a0a50eb@gmail.com>

From: Ondrej Jirman <megi at xff.cz>

Pinephone Pro uses mpu6500 according to the schematic. This was verified
via `monitor-sensor --accel`. While rotating the device, the output was
correct (eg. when it was face up, left edge was up, vertical, etc.).

Co-developed-by: Martijn Braam <martijn at brixit.nl>
Signed-off-by: Martijn Braam <martijn at brixit.nl>
Co-developed-by: Kamil Trzci?ski <ayufan at ayufan.eu>
Signed-off-by: Kamil Trzci?ski <ayufan at ayufan.eu>
Signed-off-by: Ondrej Jirman <megi at xff.cz>
Signed-off-by: Rudraksha Gupta <guptarud at gmail.com>
Reviewed-by: Pavel Machek <pavel at ucw.cz>
---
 arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts b/arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts
index 2d2858ee149e..f8c74b43ae9f 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts
@@ -543,7 +543,13 @@ mpu6500 at 68 {
 		reg = <0x68>;
 		interrupt-parent = <&gpio1>;
 		interrupts = <RK_PC6 IRQ_TYPE_LEVEL_LOW>;
+		vdd-supply = <&vcc_1v8>;
 		vddio-supply = <&vcc_1v8>;
+
+		mount-matrix =
+			"1", "0", "0",
+			"0", "-1", "0",
+			"0", "0", "-1";
 	};
 };
 

-- 
2.52.0




From devnull+guptarud.gmail.com at kernel.org  Mon Nov 24 19:46:59 2025
From: devnull+guptarud.gmail.com at kernel.org (Rudraksha Gupta via B4 Relay)
Date: Mon, 24 Nov 2025 19:46:59 -0800
Subject: [PATCH v5 0/4] Upstreaming Pinephone Pro Patches
Message-ID: <20251124-ppp_light_accel_mag_vol-down-v5-0-f9a10a0a50eb@gmail.com>

Throughout the years, many have contributed to the Pinephone Pro (ppp)
development. Unfortunately, these patches are scattered around various
repositories in different states.

I will be attempting to upstream these patches. I will start off with the
following small series:
- Add light/proximity sensor support
  - Link: https://codeberg.org/megi/linux/commit/f171bc7013bc7ad3de9af817bfbcbfa548ebe01c
- Add accelerometer sensor support
  - Link: https://codeberg.org/megi/linux/commit/b0bb7633e073a6760fa213b8c4a78ea2e73c7bf1
- Add magnetometer sensor support
  - Link: https://codeberg.org/megi/linux/commit/2f7e67f451f16eaf15b81aa1dbdf126d54927d35
- Add mount-matrix for magnetometer
  - Link: https://codeberg.org/megi/linux/commit/d7cd2eab931e32fa94408a96d73b4e6c0616107a
- Fix voltage threshold for volume down key
  - Link: https://codeberg.org/megi/linux/commit/7c496a5cc27ed4e38b740f36c2d8b2c62f80ae54

Signed-off-by: Rudraksha Gupta <guptarud at gmail.com>
---
Changes in v5:
- use monitor-sensor to verify accelerometer's mount-matrix, lux, proximity
- use Leonardo's compass add to verify the compass's mount matrix
- Link to v4: https://lore.kernel.org/r/20250929-ppp_light_accel_mag_vol-down-v4-0-6598f22d3451 at gmail.com

Changes in v4:
- remove leda-supply and vdd-supply from dts to suppress warning
- credit Martijn and Kamil for the light sensor and accelerometer patches
  - Link: https://fosstodon.org/@martijnbraam/115272859701389599
  - Link: https://codeberg.org/megi/linux/commit/fc5660685ebe4ecf60226bfa27a1ce47c1c1d020
- combine the magnetometer related patches
- corrected accelerometer's mount matrix to Documentation/devicetree/bindings/iio/mount-matrix.txt
- filled out commit messages
- rebased onto v6.17
- Link to v3: https://lore.kernel.org/r/20250921-ppp_light_accel_mag_vol-down-v3-0-7af6651f77e4 at gmail.com

Changes in v3:
- change magnetometer mount matrix
- update volume button threshold
- Link to v2: https://lore.kernel.org/r/20250921-ppp_light_accel_mag_vol-down-v2-0-e6bcc6ca74ae at gmail.com

Changes in v2:
- remove usb-typec node in dts from light/proximity sensor patch
- Link to v1: https://lore.kernel.org/r/20250920-ppp_light_accel_mag_vol-down-v1-0-c8bbcd3e2e94 at gmail.com

---
Ondrej Jirman (4):
      arm64: dts: rockchip: Add light/proximity sensor to Pinephone Pro
      arm64: dts: rockchip: Add accelerometer sensor to Pinephone Pro
      arm64: dts: rockchip: Add magnetometer sensor to Pinephone Pro
      arm64: dts: rockchip: Fix voltage threshold for volume keys for Pinephone Pro

 .../boot/dts/rockchip/rk3399-pinephone-pro.dts     | 41 ++++++++++++++++++++--
 1 file changed, 39 insertions(+), 2 deletions(-)
---
base-commit: e5f0a698b34ed76002dc5cff3804a61c80233a7a
change-id: 20250920-ppp_light_accel_mag_vol-down-817c84fdae8d

Best regards,
-- 
Rudraksha Gupta <guptarud at gmail.com>




From devnull+guptarud.gmail.com at kernel.org  Mon Nov 24 19:47:03 2025
From: devnull+guptarud.gmail.com at kernel.org (Rudraksha Gupta via B4 Relay)
Date: Mon, 24 Nov 2025 19:47:03 -0800
Subject: [PATCH v5 4/4] arm64: dts: rockchip: Fix voltage threshold for
 volume keys for Pinephone Pro
In-Reply-To: <20251124-ppp_light_accel_mag_vol-down-v5-0-f9a10a0a50eb@gmail.com>
References: <20251124-ppp_light_accel_mag_vol-down-v5-0-f9a10a0a50eb@gmail.com>
Message-ID: <20251124-ppp_light_accel_mag_vol-down-v5-4-f9a10a0a50eb@gmail.com>

From: Ondrej Jirman <megi at xff.cz>

Previously sometimes pressing the volume-down button would register as
a volume-up button. Match the thresholds as shown in the Pinephone Pro
schematic.

Tests:

~ $ evtest
    // Mashed the volume down ~100 times with varying intensity
    Event: time xxx, type 1 (EV_KEY), code 114 (KEY_VOLUMEDOWN), value 1
    Event: time xxx, type 1 (EV_KEY), code 114 (KEY_VOLUMEDOWN), value 0
    // Mashed the volume up ~100 times with varying intensity
    Event: time xxx, type 1 (EV_KEY), code 115 (KEY_VOLUMEUP), value 1
    Event: time xxx, type 1 (EV_KEY), code 115 (KEY_VOLUMEUP), value 0

Signed-off-by: Ondrej Jirman <megi at xff.cz>
Signed-off-by: Rudraksha Gupta <guptarud at gmail.com>
Reviewed-by: Pavel Machek <pavel at ucw.cz>
---
 arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts b/arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts
index 03721d71766c..5de08a155d10 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts
@@ -40,13 +40,13 @@ adc-keys {
 		button-up {
 			label = "Volume Up";
 			linux,code = <KEY_VOLUMEUP>;
-			press-threshold-microvolt = <100000>;
+			press-threshold-microvolt = <2000>;
 		};
 
 		button-down {
 			label = "Volume Down";
 			linux,code = <KEY_VOLUMEDOWN>;
-			press-threshold-microvolt = <600000>;
+			press-threshold-microvolt = <300000>;
 		};
 	};
 

-- 
2.52.0




From devnull+guptarud.gmail.com at kernel.org  Mon Nov 24 19:47:02 2025
From: devnull+guptarud.gmail.com at kernel.org (Rudraksha Gupta via B4 Relay)
Date: Mon, 24 Nov 2025 19:47:02 -0800
Subject: [PATCH v5 3/4] arm64: dts: rockchip: Add magnetometer sensor to
 Pinephone Pro
In-Reply-To: <20251124-ppp_light_accel_mag_vol-down-v5-0-f9a10a0a50eb@gmail.com>
References: <20251124-ppp_light_accel_mag_vol-down-v5-0-f9a10a0a50eb@gmail.com>
Message-ID: <20251124-ppp_light_accel_mag_vol-down-v5-3-f9a10a0a50eb@gmail.com>

From: Ondrej Jirman <megi at xff.cz>

Pinephone Pro uses AF8133J according to the schematic.

The mount-matrix was added by Leonardo on top of Ondrej's work of adding
the magnetometer. It was verified with Leonardo's compass app:

https://gitlab.com/lgtrombetta/compass

Co-developed-by: Leonardo G. Trombetta <lgtrombetta at gmx.com>
Signed-off-by: Leonardo G. Trombetta <lgtrombetta at gmx.com>
Signed-off-by: Ondrej Jirman <megi at xff.cz>
Signed-off-by: Rudraksha Gupta <guptarud at gmail.com>
Reviewed-by: Pavel Machek <pavel at ucw.cz>
---
 arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts b/arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts
index f8c74b43ae9f..03721d71766c 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts
@@ -553,6 +553,21 @@ mpu6500 at 68 {
 	};
 };
 
+&i2c4 {
+	af8133j: compass at 1c {
+		compatible = "voltafield,af8133j";
+		reg = <0x1c>;
+		reset-gpios = <&gpio1 RK_PA1 GPIO_ACTIVE_LOW>;
+		avdd-supply = <&vcc_3v0>;
+		dvdd-supply = <&vcc_1v8>;
+
+		mount-matrix =
+			"0", "1", "0",
+			"-1", "0", "0",
+			"0", "0", "1";
+	};
+};
+
 &io_domains {
 	bt656-supply = <&vcc1v8_dvp>;
 	audio-supply = <&vcca1v8_codec>;

-- 
2.52.0




From mani at kernel.org  Mon Nov 24 21:25:05 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Tue, 25 Nov 2025 10:55:05 +0530
Subject: [PATCH v2 1/4] PCI: dwc: Advertise L1 PM Substates only if
 driver requests it
In-Reply-To: <20251124211903.GA2712341@bhelgaas>
References: <wja7vxtg7bqq2udepl5r3mvgg5swvuqtuzk6cnimgcbw2aegqs@hru6yzg4xx3o>
 <20251124211903.GA2712341@bhelgaas>
Message-ID: <swchohhrkhyuzukrtonu4f3bzx3h6mha23rt6twqict42we2za@pq5hwfa75fps>

On Mon, Nov 24, 2025 at 03:19:03PM -0600, Bjorn Helgaas wrote:
> On Thu, Nov 20, 2025 at 01:10:56PM +0530, Manivannan Sadhasivam wrote:
> > On Tue, Nov 18, 2025 at 03:42:15PM -0600, Bjorn Helgaas wrote:
> > > From: Bjorn Helgaas <bhelgaas at google.com>
> > > 
> > > L1 PM Substates require the CLKREQ# signal and may also require
> > > device-specific support.  If CLKREQ# is not supported or driver support is
> > > lacking, enabling L1.1 or L1.2 may cause errors when accessing devices,
> > > e.g.,
> > > 
> > >   nvme nvme0: controller is down; will reset: CSTS=0xffffffff, PCI_STATUS=0x10
> > > 
> > > If the kernel is built with CONFIG_PCIEASPM_POWER_SUPERSAVE=y or users
> > > enable L1.x via sysfs, users may trip over these errors even if L1
> > > Substates haven't been enabled by firmware or the driver.
> > > 
> > > To prevent such errors, disable advertising the L1 PM Substates unless the
> > > driver sets "dw_pcie.l1ss_support" to indicate that it knows CLKREQ# is
> > > present and any device-specific configuration has been done.
> > 
> > Going by this reasoning, why can't we enable L1 PM Substates for
> > these platforms by default?
> 
> I think we can, in a separate series.  I don't have time to deal with
> this before the v6.19 merge window, but you can certainly do that.
> 

I will take it up. Not sure if I can do it for v6.19 though.

- Mani

-- 
????????? ????????


From heikki.krogerus at linux.intel.com  Tue Nov 25 02:06:13 2025
From: heikki.krogerus at linux.intel.com (Heikki Krogerus)
Date: Tue, 25 Nov 2025 12:06:13 +0200
Subject: [PATCH v10 01/11] usb: typec: Add notifier functions
In-Reply-To: <c9cb7b79-37c8-4fef-97a6-7d6b8898f9c4@rock-chips.com>
References: <20251120022343.250-1-kernel@airkyi.com>
 <20251120022343.250-2-kernel@airkyi.com>
 <2025112102-laurel-mulch-58e4@gregkh>
 <462ad1bd-7eec-4f26-b383-96b049e14559@rock-chips.com>
 <2025112402-unopposed-polio-e6e9@gregkh>
 <a80483de-518d-45d5-b46a-9b70cca5b236@rock-chips.com>
 <2025112448-brush-porcupine-c851@gregkh>
 <c9cb7b79-37c8-4fef-97a6-7d6b8898f9c4@rock-chips.com>
Message-ID: <aSV_lQYJPxN7oBM-@kuha>

Tue, Nov 25, 2025 at 10:23:02AM +0800, Chaoyi Chen kirjoitti:
> On 11/25/2025 12:33 AM, Greg Kroah-Hartman wrote:
> > On Mon, Nov 24, 2025 at 04:05:53PM +0800, Chaoyi Chen wrote:
> > > Hi Greg,
> > > 
> > > On 11/24/2025 3:10 PM, Greg Kroah-Hartman wrote:
> > > 
> > > > On Mon, Nov 24, 2025 at 09:40:03AM +0800, Chaoyi Chen wrote:
> > > > > Hi Greg,
> > > > > 
> > > > > On 11/21/2025 10:07 PM, Greg Kroah-Hartman wrote:
> > > > > > On Thu, Nov 20, 2025 at 10:23:33AM +0800, Chaoyi Chen wrote:
> > > > > > > From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> > > > > > > 
> > > > > > > Some other part of kernel may want to know the event of typec bus.
> > > > > > Be specific, WHAT part of the kernel will need to know this?
> > > > > For now, it is DRM.
> > > > Then say this.
> > > Okay, please refer to the discussion below.
> > > 
> > > > > > And why a new notifier, why not just use the existing notifiers that you
> > > > > > already have?  And what is this going to be used for?
> > > > > We have discussed this before, but the current bus notifier cannot achieve the expected notification [0].
> > > > > 
> > > > > [0] https://lore.kernel.org/all/aPsuLREPS_FEV3DS at kuha.fi.intel.com/
> > > > Then you need to document the heck out of this in the changelog text.
> > > > But I'm still not quite understanding why the bus notifier does not work
> > > > here, as you only want this information if the usb device is bound to
> > > > the bus there, you do not want to know this if it did not complete.
> > > > 
> > > > That thread says you want this not "too late", but why?  What is the
> > > > problem there, and how will you handle your code getting loaded after
> > > > the typec code is loaded?  Notifier callbacks don't work for that
> > > > situation, right?
> > > In fact, the typec_register_altmode() function generates two
> > > registered events.?The first one is the registered event of the port
> > > device, and the second one is the registered event of the partner
> > > device.?The second one event only occurs after a Type-C device is
> > > inserted.
> > > The bus notifier event does not actually take effect for the port
> > > device, because it only sets the bus for the partner device:
> > > 
> > >  ? ? /* The partners are bind to drivers */
> > >  ? ? if (is_typec_partner(parent))
> > >  ? ? ? ? alt->adev.dev.bus = &typec_bus;
> > Setting the bus is correct, then it needs to be registered with the
> > driver core so the bus link shows up (and a driver is bound to it.)
> > That is when the bus notifier can happen, right?
> Yes, this is valid for the partner device. But for the port device, since the bus is not specified here, the corresponding bus notifier will not take effect.

Perhaps we should just fix this part and make also the port altmodes
part of the bus.

Some background, in case this is not clear; the port alternate mode
devices represent the capability of the ports to support specific
alternate modes. The partner alternate mode devices do the same
for the partner devices attached to the ports, but on top of the
showing the capability, they are also used for the alternate mode
specific communication using the USB Power Delivery VDM (vendor
defined messages). That's why only the partner altmodes are bound
to the generic alternate mode drivers.

And that's why the hack where the port altmodes are not added to the
bus. But maybe it's not needed.

Chaoyi, can you try the attached patch?

> > > I hope it's not too late. In fact, the notifier here will notify DRM to establish a bridge chain.
> > What is a "bridge chain"?
> In DRM, the bridge chain is often used to describe the chain connection relationship
> of the output of multi level display conversion chips. The bridge chain we are referring to here
> is actually a chain? structure formed by connecting various devices using a simple transparent bridge [0].
> 
> For example, the schematic diagram of a bridge chain is as follows:
> 
> DP controller bridge -> DP PHY bridge -> onnn,nb7vpq904m retimer bridge -> fsa4480 analog audio switch bridge -> fusb302 HPD bridge
> 
> Here, apart from the DP controller bridge, the rest are transparent DRM bridges, which are used solely to
> describe the link relationships between various devices.
> 
> 
> [0] https://patchwork.freedesktop.org/patch/msgid/20231203114333.1305826-2-dmitry.baryshkov at linaro.org
> > 
> > > The downstream DP controller driver hopes to obtain the fwnode of the last-level Type-C device
> > > through this bridge chain to create a DRM connector. And when a device is inserted,
> > > drivers/usb/typec/altmodes/displayport.c can notify the HPD (Hot Plug Detect) event.
> > But aren't you just the driver for the "partner device"?
> > 
> > If not, why isn't a real device being created that you then bind to,
> > what "fake" type of thing are you attempting to do here that would
> > require you to do this out-of-band?
> The HPD event is pass by drm_connector_oob_hotplug_event(), which does not use the device in Type-C.
> This function will find the corresponding DRM connector device, and the lookup of the DRM connector is
> done through the fwnode.
> 
> And the partner device and the port device have the same fwnode.
> 
> > 
> > > If relying on the second event, the bridge chain may never be established, and the operations of the DP driver will be
> > > always deferred. Furthermore, other parts of the display controller driver will also be deferred accordingly.
> > What operations?  What exactly is delayed?  You should not be touching a
> > device before you have it on your bus, right?
> To complete the HPD operation, it is necessary to create a drm connector device that
> has the appropriate fwnode. This operation will be carried out by the DP controller driver.
> 
> As you can see, since it cross multiple devices, we need to set the fwnode to the last device fusb302.
> This requires relying on the bridge chain. We can register bridges for multiple devices and then connect
> them to form a chain. The connection process is completed through drm_bridge_attach().
> 
> A brief example of the process of establishing a bridge chain is as follows, starting from the last bridge:
> 
> step1: fusb302 HPD bridge
> step2: fsa4480 analog audio switch bridge -> fusb302 HPD bridge
> step3: onnn,nb7vpq904m retimer bridge -> fsa4480 analog audio switch bridge -> fusb302 HPD bridge
> step4: DP PHY bridge -> onnn,nb7vpq904m retimer bridge -> fsa4480 analog audio switch bridge -> fusb302 HPD bridge
> step5: DP controller bridge -> DP PHY bridge -> onnn,nb7vpq904m retimer bridge -> fsa4480 analog audio switch bridge -> fusb302 HPD bridge
> 
> Step 1 is the most crucial, because essentially, regardless of whether we use notifiers or not, what we ultimately want to achieve is to create an HPD bridge.
> The DP controller needs to wait for the subsequent bridge chain to be established because it needs to know the connection relationships of the devices.
> 
> The question now is when to create the HPD bridge, during the registration of the port device or during the registration of the partner device.
> If it's the latter, then the delay occurs here.
> 
> And I don't think I'm touching the Type-C device here. I'm just using the bridge chain to get a suitable fwnode and create a suitable DRM connector device.
> The subsequent Type-C HPD events will be on the DRM connector device.
> 
> This solution is somewhat complex, and I apologize once again for any confusion caused earlier.
> 
> > 
> > > > > > Notifiers are a pain, and should almost never be added.  Use real
> > > > > > function calls instead.
> > > > > In v6, I used direct function calls, but had to switch to notifiers because couldn't resolve the dependencies between DRM and Type-C [1]. Do you have any good ideas? Thank you.
> > > > Only allow this DRM code to be built if typec code is enabled, do NOT
> > > > use a select, use a depends in the drm code.
> > > Sorry, I didn't get your point. Does this mean that the current notifiers approach still needs to be changed to direct function calls?
> > If you somehow convince me that the existing bus notifiers will not
> > work, yes :)
> > 
> > > If so, then based on the previous discussion, typec should not depend
> > > on any DRM components. Does this mean that we should add the if
> > > (IS_REACHABLE(CONFIG_DRM_AUX_BRIDGE)) before the direct function call?
> > No, do it properly like any other function call to another subsystem.
> > 
> > > Additionally, the current version of CONFIG_DRM_AUX_BRIDGE is selected
> > > by the DP driver in patch9.
> > Don't do "select" if at all possible, always try to do "depends on".
> Thank you for clarifying this. However, CONFIG_DRM_AUX_BRIDGE is not exposed in the menu, and it is not intended for the end user to select it by design. Therefore, I think there still needs to be some place to select it?

You don't "select TYPEC", you already "depend on TYPEC", so you are
all set with this one.

thanks,

-- 
heikki
-------------- next part --------------
>From 8cca23b3064bf8b33e316245732a8baf834142d2 Mon Sep 17 00:00:00 2001
From: Heikki Krogerus <heikki.krogerus at linux.intel.com>
Date: Tue, 25 Nov 2025 10:38:04 +0100
Subject: [PATCH] usb: typec: Set the bus also for the port altmodes

The port altmodes can't be bound to the altmode drivers
because the altmode drivers are meant for partner
commuication using the VDM (vendor defined messages), but
they can still be part of the bus. The bus will make sure
that the normal bus notifications are available also with
the port altmodes.

Signed-off-by: Heikki Krogerus <heikki.krogerus at linux.intel.com>
---
 drivers/usb/typec/bus.c   | 24 +++++++++++++++++++++++-
 drivers/usb/typec/class.c |  4 +---
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/typec/bus.c b/drivers/usb/typec/bus.c
index a884cec9ab7e..1daf7a353c01 100644
--- a/drivers/usb/typec/bus.c
+++ b/drivers/usb/typec/bus.c
@@ -445,7 +445,23 @@ static struct attribute *typec_attrs[] = {
 	&dev_attr_description.attr,
 	NULL
 };
-ATTRIBUTE_GROUPS(typec);
+
+static umode_t typec_is_visible(struct kobject *kobj, struct attribute *attr, int n)
+{
+	if (is_typec_port(kobj_to_dev(kobj)->parent))
+		return 0;
+	return attr->mode;
+}
+
+static const struct attribute_group typec_group = {
+	.is_visible = typec_is_visible,
+	.attrs = typec_attrs,
+};
+
+static const struct attribute_group *typec_groups[] = {
+	&typec_group,
+	NULL
+};
 
 static int typec_match(struct device *dev, const struct device_driver *driver)
 {
@@ -453,6 +469,9 @@ static int typec_match(struct device *dev, const struct device_driver *driver)
 	struct typec_altmode *altmode = to_typec_altmode(dev);
 	const struct typec_device_id *id;
 
+	if (is_typec_port(dev->parent))
+		return 0;
+
 	for (id = drv->id_table; id->svid; id++)
 		if (id->svid == altmode->svid)
 			return 1;
@@ -469,6 +488,9 @@ static int typec_uevent(const struct device *dev, struct kobj_uevent_env *env)
 	if (add_uevent_var(env, "MODE=%u", altmode->mode))
 		return -ENOMEM;
 
+	if (is_typec_port(dev->parent))
+		return 0;
+
 	return add_uevent_var(env, "MODALIAS=typec:id%04X", altmode->svid);
 }
 
diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
index 9b2647cb199b..26bf76328487 100644
--- a/drivers/usb/typec/class.c
+++ b/drivers/usb/typec/class.c
@@ -584,9 +584,7 @@ typec_register_altmode(struct device *parent,
 	if (!is_port)
 		typec_altmode_set_partner(alt);
 
-	/* The partners are bind to drivers */
-	if (is_typec_partner(parent))
-		alt->adev.dev.bus = &typec_bus;
+	alt->adev.dev.bus = &typec_bus;
 
 	/* Plug alt modes need a class to generate udev events. */
 	if (is_typec_plug(parent))
-- 
2.50.1


From chaoyi.chen at rock-chips.com  Tue Nov 25 02:54:37 2025
From: chaoyi.chen at rock-chips.com (Chaoyi Chen)
Date: Tue, 25 Nov 2025 18:54:37 +0800
Subject: [PATCH v10 01/11] usb: typec: Add notifier functions
In-Reply-To: <aSV_lQYJPxN7oBM-@kuha>
References: <20251120022343.250-1-kernel@airkyi.com>
 <20251120022343.250-2-kernel@airkyi.com>
 <2025112102-laurel-mulch-58e4@gregkh>
 <462ad1bd-7eec-4f26-b383-96b049e14559@rock-chips.com>
 <2025112402-unopposed-polio-e6e9@gregkh>
 <a80483de-518d-45d5-b46a-9b70cca5b236@rock-chips.com>
 <2025112448-brush-porcupine-c851@gregkh>
 <c9cb7b79-37c8-4fef-97a6-7d6b8898f9c4@rock-chips.com> <aSV_lQYJPxN7oBM-@kuha>
Message-ID: <d970873f-eb76-432e-a881-72b2c5cb2a9c@rock-chips.com>

On 11/25/2025 6:06 PM, Heikki Krogerus wrote:
> Tue, Nov 25, 2025 at 10:23:02AM +0800, Chaoyi Chen kirjoitti:
>> On 11/25/2025 12:33 AM, Greg Kroah-Hartman wrote:
>>> On Mon, Nov 24, 2025 at 04:05:53PM +0800, Chaoyi Chen wrote:
>>>> Hi Greg,
>>>>
>>>> On 11/24/2025 3:10 PM, Greg Kroah-Hartman wrote:
>>>>
>>>>> On Mon, Nov 24, 2025 at 09:40:03AM +0800, Chaoyi Chen wrote:
>>>>>> Hi Greg,
>>>>>>
>>>>>> On 11/21/2025 10:07 PM, Greg Kroah-Hartman wrote:
>>>>>>> On Thu, Nov 20, 2025 at 10:23:33AM +0800, Chaoyi Chen wrote:
>>>>>>>> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
>>>>>>>>
>>>>>>>> Some other part of kernel may want to know the event of typec bus.
>>>>>>> Be specific, WHAT part of the kernel will need to know this?
>>>>>> For now, it is DRM.
>>>>> Then say this.
>>>> Okay, please refer to the discussion below.
>>>>
>>>>>>> And why a new notifier, why not just use the existing notifiers that you
>>>>>>> already have?  And what is this going to be used for?
>>>>>> We have discussed this before, but the current bus notifier cannot achieve the expected notification [0].
>>>>>>
>>>>>> [0] https://lore.kernel.org/all/aPsuLREPS_FEV3DS at kuha.fi.intel.com/
>>>>> Then you need to document the heck out of this in the changelog text.
>>>>> But I'm still not quite understanding why the bus notifier does not work
>>>>> here, as you only want this information if the usb device is bound to
>>>>> the bus there, you do not want to know this if it did not complete.
>>>>>
>>>>> That thread says you want this not "too late", but why?  What is the
>>>>> problem there, and how will you handle your code getting loaded after
>>>>> the typec code is loaded?  Notifier callbacks don't work for that
>>>>> situation, right?
>>>> In fact, the typec_register_altmode() function generates two
>>>> registered events. The first one is the registered event of the port
>>>> device, and the second one is the registered event of the partner
>>>> device. The second one event only occurs after a Type-C device is
>>>> inserted.
>>>> The bus notifier event does not actually take effect for the port
>>>> device, because it only sets the bus for the partner device:
>>>>
>>>>      /* The partners are bind to drivers */
>>>>      if (is_typec_partner(parent))
>>>>          alt->adev.dev.bus = &typec_bus;
>>> Setting the bus is correct, then it needs to be registered with the
>>> driver core so the bus link shows up (and a driver is bound to it.)
>>> That is when the bus notifier can happen, right?
>> Yes, this is valid for the partner device. But for the port device, since the bus is not specified here, the corresponding bus notifier will not take effect.
> 
> Perhaps we should just fix this part and make also the port altmodes
> part of the bus.
> 
> Some background, in case this is not clear; the port alternate mode
> devices represent the capability of the ports to support specific
> alternate modes. The partner alternate mode devices do the same
> for the partner devices attached to the ports, but on top of the
> showing the capability, they are also used for the alternate mode
> specific communication using the USB Power Delivery VDM (vendor
> defined messages). That's why only the partner altmodes are bound
> to the generic alternate mode drivers.
> 
> And that's why the hack where the port altmodes are not added to the
> bus. But maybe it's not needed.
> 
> Chaoyi, can you try the attached patch?
> 

Thank you for providing the background information. Maybe this is what
we really want. I will try this in v11 :)

>>>> I hope it's not too late. In fact, the notifier here will notify DRM to establish a bridge chain.
>>> What is a "bridge chain"?
>> In DRM, the bridge chain is often used to describe the chain connection relationship
>> of the output of multi level display conversion chips. The bridge chain we are referring to here
>> is actually a chain  structure formed by connecting various devices using a simple transparent bridge [0].
>>
>> For example, the schematic diagram of a bridge chain is as follows:
>>
>> DP controller bridge -> DP PHY bridge -> onnn,nb7vpq904m retimer bridge -> fsa4480 analog audio switch bridge -> fusb302 HPD bridge
>>
>> Here, apart from the DP controller bridge, the rest are transparent DRM bridges, which are used solely to
>> describe the link relationships between various devices.
>>
>>
>> [0] https://patchwork.freedesktop.org/patch/msgid/20231203114333.1305826-2-dmitry.baryshkov at linaro.org
>>>
>>>> The downstream DP controller driver hopes to obtain the fwnode of the last-level Type-C device
>>>> through this bridge chain to create a DRM connector. And when a device is inserted,
>>>> drivers/usb/typec/altmodes/displayport.c can notify the HPD (Hot Plug Detect) event.
>>> But aren't you just the driver for the "partner device"?
>>>
>>> If not, why isn't a real device being created that you then bind to,
>>> what "fake" type of thing are you attempting to do here that would
>>> require you to do this out-of-band?
>> The HPD event is pass by drm_connector_oob_hotplug_event(), which does not use the device in Type-C.
>> This function will find the corresponding DRM connector device, and the lookup of the DRM connector is
>> done through the fwnode.
>>
>> And the partner device and the port device have the same fwnode.
>>
>>>
>>>> If relying on the second event, the bridge chain may never be established, and the operations of the DP driver will be
>>>> always deferred. Furthermore, other parts of the display controller driver will also be deferred accordingly.
>>> What operations?  What exactly is delayed?  You should not be touching a
>>> device before you have it on your bus, right?
>> To complete the HPD operation, it is necessary to create a drm connector device that
>> has the appropriate fwnode. This operation will be carried out by the DP controller driver.
>>
>> As you can see, since it cross multiple devices, we need to set the fwnode to the last device fusb302.
>> This requires relying on the bridge chain. We can register bridges for multiple devices and then connect
>> them to form a chain. The connection process is completed through drm_bridge_attach().
>>
>> A brief example of the process of establishing a bridge chain is as follows, starting from the last bridge:
>>
>> step1: fusb302 HPD bridge
>> step2: fsa4480 analog audio switch bridge -> fusb302 HPD bridge
>> step3: onnn,nb7vpq904m retimer bridge -> fsa4480 analog audio switch bridge -> fusb302 HPD bridge
>> step4: DP PHY bridge -> onnn,nb7vpq904m retimer bridge -> fsa4480 analog audio switch bridge -> fusb302 HPD bridge
>> step5: DP controller bridge -> DP PHY bridge -> onnn,nb7vpq904m retimer bridge -> fsa4480 analog audio switch bridge -> fusb302 HPD bridge
>>
>> Step 1 is the most crucial, because essentially, regardless of whether we use notifiers or not, what we ultimately want to achieve is to create an HPD bridge.
>> The DP controller needs to wait for the subsequent bridge chain to be established because it needs to know the connection relationships of the devices.
>>
>> The question now is when to create the HPD bridge, during the registration of the port device or during the registration of the partner device.
>> If it's the latter, then the delay occurs here.
>>
>> And I don't think I'm touching the Type-C device here. I'm just using the bridge chain to get a suitable fwnode and create a suitable DRM connector device.
>> The subsequent Type-C HPD events will be on the DRM connector device.
>>
>> This solution is somewhat complex, and I apologize once again for any confusion caused earlier.
>>
>>>
>>>>>>> Notifiers are a pain, and should almost never be added.  Use real
>>>>>>> function calls instead.
>>>>>> In v6, I used direct function calls, but had to switch to notifiers because couldn't resolve the dependencies between DRM and Type-C [1]. Do you have any good ideas? Thank you.
>>>>> Only allow this DRM code to be built if typec code is enabled, do NOT
>>>>> use a select, use a depends in the drm code.
>>>> Sorry, I didn't get your point. Does this mean that the current notifiers approach still needs to be changed to direct function calls?
>>> If you somehow convince me that the existing bus notifiers will not
>>> work, yes :)
>>>
>>>> If so, then based on the previous discussion, typec should not depend
>>>> on any DRM components. Does this mean that we should add the if
>>>> (IS_REACHABLE(CONFIG_DRM_AUX_BRIDGE)) before the direct function call?
>>> No, do it properly like any other function call to another subsystem.
>>>
>>>> Additionally, the current version of CONFIG_DRM_AUX_BRIDGE is selected
>>>> by the DP driver in patch9.
>>> Don't do "select" if at all possible, always try to do "depends on".
>> Thank you for clarifying this. However, CONFIG_DRM_AUX_BRIDGE is not exposed in the menu, and it is not intended for the end user to select it by design. Therefore, I think there still needs to be some place to select it?
> 
> You don't "select TYPEC", you already "depend on TYPEC", so you are
> all set with this one.
> 
> thanks,
> 

Ah, it is.

-- 
Best, 
Chaoyi


From gregkh at linuxfoundation.org  Tue Nov 25 03:49:29 2025
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Tue, 25 Nov 2025 12:49:29 +0100
Subject: [PATCH v10 01/11] usb: typec: Add notifier functions
In-Reply-To: <aSV_lQYJPxN7oBM-@kuha>
References: <20251120022343.250-1-kernel@airkyi.com>
 <20251120022343.250-2-kernel@airkyi.com>
 <2025112102-laurel-mulch-58e4@gregkh>
 <462ad1bd-7eec-4f26-b383-96b049e14559@rock-chips.com>
 <2025112402-unopposed-polio-e6e9@gregkh>
 <a80483de-518d-45d5-b46a-9b70cca5b236@rock-chips.com>
 <2025112448-brush-porcupine-c851@gregkh>
 <c9cb7b79-37c8-4fef-97a6-7d6b8898f9c4@rock-chips.com>
 <aSV_lQYJPxN7oBM-@kuha>
Message-ID: <2025112554-uncaring-curator-642a@gregkh>

> +static umode_t typec_is_visible(struct kobject *kobj, struct attribute *attr, int n)
> +{
> +	if (is_typec_port(kobj_to_dev(kobj)->parent))

Why look at the parent?  Doesn't the device have a type that should show
this?

Otherwise, looks good to me.

thanks,

greg k-h


From ulf.hansson at linaro.org  Tue Nov 25 05:00:16 2025
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 25 Nov 2025 14:00:16 +0100
Subject: [PATCH] mmc: sdhci-of-dwcmshc: Fix command queue support for RK3576
In-Reply-To: <20251121-rockchip-emmc-cqe-rk3576-fix-v1-1-a77805f40072@collabora.com>
References: <20251121-rockchip-emmc-cqe-rk3576-fix-v1-1-a77805f40072@collabora.com>
Message-ID: <CAPDyKFp4oNWQn3xW3+GGbGmi8U7H98Bbos0vRqaQPaht54nZ=w@mail.gmail.com>

On Fri, 21 Nov 2025 at 17:27, Sebastian Reichel
<sebastian.reichel at collabora.com> wrote:
>
> When I added command queue engine (CQE) support for the Rockchip eMMC
> controller, I missed that RK3576 has a separate platform data struct.
> While things are working fine on RK3588 (I tested the ROCK 5B) and
> the suspend issue is fixed on the RK3576 (I tested the Sige5), this
> results in stability issues. By also adding the necessary hooks for
> the RK3576 platform the following problems can be avoided:
>
> [   15.606895] mmc0: running CQE recovery
> [   15.616189] mmc0: running CQE recovery
> [...]
> [   25.911484] mmc0: running CQE recovery
> [   25.926305] mmc0: running CQE recovery
> [   25.927468] mmc0: running CQE recovery
> [...]
> [   26.255719] mmc0: running CQE recovery
> [   26.257162] ------------[ cut here ]------------
> [   26.257581] mmc0: cqhci: spurious TCN for tag 31
> [   26.258034] WARNING: CPU: 0 PID: 0 at drivers/mmc/host/cqhci-core.c:796 cqhci_irq+0x440/0x68c
> [   26.263786] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.18.0-rc6-gd984ebbf0d15 #1 PREEMPT
> [   26.264561] Hardware name: ArmSoM Sige5 (DT)
> [...]
> [   26.272748] Call trace:
> [   26.272964]  cqhci_irq+0x440/0x68c (P)
> [   26.273296]  dwcmshc_cqe_irq_handler+0x54/0x88
> [   26.273689]  sdhci_irq+0xbc/0x1200
> [   26.273991]  __handle_irq_event_percpu+0x54/0x1d0
> [...]
>
> Note that the above problems do not necessarily happen with every boot.
>
> Reported-by: Adrian Hunter <adrian.hunter at intel.com>
> Closes: https://lore.kernel.org/linux-rockchip/01949bc9-4873-498b-ac7d-f008393ccc4c at intel.com/
> Fixes: fda1e0af7c28f ("mmc: sdhci-of-dwcmshc: Add command queue support for rockchip SOCs")
> Signed-off-by: Sebastian Reichel <sebastian.reichel at collabora.com>

Applied for next, thanks!

Kind regards
Uffe


> ---
> Sorry for the delay in sending this :)
> ---
>  drivers/mmc/host/sdhci-of-dwcmshc.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c
> index c66a8dfad47c..ee0008d91b98 100644
> --- a/drivers/mmc/host/sdhci-of-dwcmshc.c
> +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c
> @@ -1767,6 +1767,7 @@ static const struct dwcmshc_pltfm_data sdhci_dwcmshc_rk3576_pdata = {
>                 .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
>                            SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN,
>         },
> +       .cqhci_host_ops = &rk35xx_cqhci_ops,
>         .init = dwcmshc_rk35xx_init,
>         .postinit = dwcmshc_rk3576_postinit,
>  };
>
> ---
> base-commit: dcbce328d3a2d87770133834210cf328c083d480
> change-id: 20251121-rockchip-emmc-cqe-rk3576-fix-ec8ac72e6e32
>
> Best regards,
> --
> Sebastian Reichel <sebastian.reichel at collabora.com>
>


From shawn.lin at rock-chips.com  Tue Nov 25 05:58:36 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Tue, 25 Nov 2025 21:58:36 +0800
Subject: [PATCH 2/2] mmc: sdhci-of-dwcmshc: reduce CIT for better
 performance
In-Reply-To: <1762933460-204066-2-git-send-email-shawn.lin@rock-chips.com>
References: <1762933460-204066-1-git-send-email-shawn.lin@rock-chips.com>
 <1762933460-204066-2-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <7b05327d-fc76-471e-9148-3dfc0cd17623@rock-chips.com>

? 2025/11/12 ??? 15:44, Shawn Lin ??:
> CQHCI_SSC1.CIT indicates to the CQE the polling period to use for
> periodic SEND_QUEUE_STATUS (CMD13) polling. Some eMMCs have only one
> hardware queue, and CMD13 can only query one slot at a time for data
> transmission, which cannot be processed in parallel. Modifying the
> CMD13 query interval can increase the query frequency and improve
> random write performance.
> 

Ping...

Adrain acked these two patches, so will them be candidates for 6.19
given the merge windows is coming soon?

> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
> ---
> 
>   drivers/mmc/host/cqhci.h            | 1 +
>   drivers/mmc/host/sdhci-of-dwcmshc.c | 5 +++++
>   2 files changed, 6 insertions(+)
> 
> diff --git a/drivers/mmc/host/cqhci.h b/drivers/mmc/host/cqhci.h
> index ce189a1..3668856 100644
> --- a/drivers/mmc/host/cqhci.h
> +++ b/drivers/mmc/host/cqhci.h
> @@ -93,6 +93,7 @@
>   /* send status config 1 */
>   #define CQHCI_SSC1			0x40
>   #define CQHCI_SSC1_CBC_MASK		GENMASK(19, 16)
> +#define CQHCI_SSC1_CIT_MASK		GENMASK(15, 0)
>   
>   /* send status config 2 */
>   #define CQHCI_SSC2			0x44
> diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c
> index e276a4e..cad5165 100644
> --- a/drivers/mmc/host/sdhci-of-dwcmshc.c
> +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c
> @@ -631,6 +631,11 @@ static void rk35xx_sdhci_cqe_pre_enable(struct mmc_host *mmc)
>   	struct dwcmshc_priv *dwc_priv = sdhci_pltfm_priv(pltfm_host);
>   	u32 reg;
>   
> +	/* Set Send Status Command Idle Timer to 10.66us (256 * 1 / 24) */
> +	reg = sdhci_readl(host, dwc_priv->vendor_specific_area2 + CQHCI_SSC1);
> +	reg = (reg & ~CQHCI_SSC1_CIT_MASK) | 0x0100;
> +	sdhci_writel(host, reg, dwc_priv->vendor_specific_area2 + CQHCI_SSC1);
> +
>   	reg = sdhci_readl(host, dwc_priv->vendor_specific_area2 + CQHCI_CFG);
>   	reg |= CQHCI_ENABLE;
>   	sdhci_writel(host, reg, dwc_priv->vendor_specific_area2 + CQHCI_CFG);



From Ludovic.Desroches at microchip.com  Tue Nov 25 06:39:58 2025
From: Ludovic.Desroches at microchip.com (Ludovic.Desroches at microchip.com)
Date: Tue, 25 Nov 2025 14:39:58 +0000
Subject: [PATCH v6 03/25] drm/gem-dma: Compute dumb-buffer sizes with
 drm_mode_size_dumb()
In-Reply-To: <20250821081918.79786-4-tzimmermann@suse.de>
References: <20250821081918.79786-1-tzimmermann@suse.de>
 <20250821081918.79786-4-tzimmermann@suse.de>
Message-ID: <52600bf4-2c1c-49a6-82c5-b31818141a43@microchip.com>

On 8/21/25 10:17, Thomas Zimmermann wrote:
> Call drm_mode_size_dumb() to compute dumb-buffer scanline pitch and
> buffer size. Align the pitch to a multiple of 8.
> 
> Push the current calculation into the only direct caller imx. Imx's
> hardware requires the framebuffer width to be aligned to 8. The
> driver's current approach is actually incorrect, as it only guarantees
> this implicitly and requires bpp to be a multiple of 8 already. A
> later commit will fix this problem by aligning the scanline pitch
> such that an aligned width still fits into each scanline's memory.
> 
> A number of other drivers are build on top of gem-dma helpers and
> implement their own dumb-buffer allocation. These drivers invoke
> drm_gem_dma_dumb_create_internal(), which is not affected by this
> commit.
> 
> v5:
> - avoid reset of arguments (Tomi)
> 
> Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
> Reviewed-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
> ---
>   drivers/gpu/drm/drm_gem_dma_helper.c     | 7 +++++--
>   drivers/gpu/drm/imx/ipuv3/imx-drm-core.c | 4 +++-
>   2 files changed, 8 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_gem_dma_helper.c b/drivers/gpu/drm/drm_gem_dma_helper.c
> index 4f0320df858f..ab1a70b1d6f1 100644
> --- a/drivers/gpu/drm/drm_gem_dma_helper.c
> +++ b/drivers/gpu/drm/drm_gem_dma_helper.c
> @@ -20,6 +20,7 @@
>   #include <drm/drm.h>
>   #include <drm/drm_device.h>
>   #include <drm/drm_drv.h>
> +#include <drm/drm_dumb_buffers.h>
>   #include <drm/drm_gem_dma_helper.h>
>   #include <drm/drm_vma_manager.h>
>   
> @@ -304,9 +305,11 @@ int drm_gem_dma_dumb_create(struct drm_file *file_priv,
>   			    struct drm_mode_create_dumb *args)
>   {
>   	struct drm_gem_dma_object *dma_obj;
> +	int ret;
>   
> -	args->pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
> -	args->size = args->pitch * args->height;
> +	ret = drm_mode_size_dumb(drm, args, SZ_8, 0);
> +	if (ret)
> +		return ret;

Hi,

Was it intentional for this change to alter the pitch?

The alignment requirement has been updated?from 8-bit alignment to 
64-bit alignment. Since the pitch is expressed in bytes, we should pass 
SZ_1 instead of SZ_8 for hw_patch_align.

For example, for an 850?480 framebuffer at 16 bpp, the pitch should be 
1700 bytes. With the new alignment, the pitch becomes 1704 bytes.

Please let me know if you?d like me to submit a fix.

Regards,
Ludovic


>   
>   	dma_obj = drm_gem_dma_create_with_handle(file_priv, drm, args->size,
>   						 &args->handle);
> diff --git a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c b/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
> index ec5fd9a01f1e..af4a30311e18 100644
> --- a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
> +++ b/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
> @@ -145,8 +145,10 @@ static int imx_drm_dumb_create(struct drm_file *file_priv,
>   	int ret;
>   
>   	args->width = ALIGN(width, 8);
> +	args->pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
> +	args->size = args->pitch * args->height;
>   
> -	ret = drm_gem_dma_dumb_create(file_priv, drm, args);
> +	ret = drm_gem_dma_dumb_create_internal(file_priv, drm, args);
>   	if (ret)
>   		return ret;
>   


From tzimmermann at suse.de  Tue Nov 25 07:03:46 2025
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Tue, 25 Nov 2025 16:03:46 +0100
Subject: [PATCH v6 03/25] drm/gem-dma: Compute dumb-buffer sizes with
 drm_mode_size_dumb()
In-Reply-To: <52600bf4-2c1c-49a6-82c5-b31818141a43@microchip.com>
References: <20250821081918.79786-1-tzimmermann@suse.de>
 <20250821081918.79786-4-tzimmermann@suse.de>
 <52600bf4-2c1c-49a6-82c5-b31818141a43@microchip.com>
Message-ID: <a11c195d-197c-45a4-962a-e2336c7360c2@suse.de>

Hi

Am 25.11.25 um 15:39 schrieb Ludovic.Desroches at microchip.com:
> On 8/21/25 10:17, Thomas Zimmermann wrote:
>> Call drm_mode_size_dumb() to compute dumb-buffer scanline pitch and
>> buffer size. Align the pitch to a multiple of 8.

I missed a chance to explain it here. :/

>>
>> Push the current calculation into the only direct caller imx. Imx's
>> hardware requires the framebuffer width to be aligned to 8. The
>> driver's current approach is actually incorrect, as it only guarantees
>> this implicitly and requires bpp to be a multiple of 8 already. A
>> later commit will fix this problem by aligning the scanline pitch
>> such that an aligned width still fits into each scanline's memory.
>>
>> A number of other drivers are build on top of gem-dma helpers and
>> implement their own dumb-buffer allocation. These drivers invoke
>> drm_gem_dma_dumb_create_internal(), which is not affected by this
>> commit.
>>
>> v5:
>> - avoid reset of arguments (Tomi)
>>
>> Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
>> Reviewed-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
>> ---
>>    drivers/gpu/drm/drm_gem_dma_helper.c     | 7 +++++--
>>    drivers/gpu/drm/imx/ipuv3/imx-drm-core.c | 4 +++-
>>    2 files changed, 8 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_gem_dma_helper.c b/drivers/gpu/drm/drm_gem_dma_helper.c
>> index 4f0320df858f..ab1a70b1d6f1 100644
>> --- a/drivers/gpu/drm/drm_gem_dma_helper.c
>> +++ b/drivers/gpu/drm/drm_gem_dma_helper.c
>> @@ -20,6 +20,7 @@
>>    #include <drm/drm.h>
>>    #include <drm/drm_device.h>
>>    #include <drm/drm_drv.h>
>> +#include <drm/drm_dumb_buffers.h>
>>    #include <drm/drm_gem_dma_helper.h>
>>    #include <drm/drm_vma_manager.h>
>>    
>> @@ -304,9 +305,11 @@ int drm_gem_dma_dumb_create(struct drm_file *file_priv,
>>    			    struct drm_mode_create_dumb *args)
>>    {
>>    	struct drm_gem_dma_object *dma_obj;
>> +	int ret;
>>    
>> -	args->pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
>> -	args->size = args->pitch * args->height;
>> +	ret = drm_mode_size_dumb(drm, args, SZ_8, 0);
>> +	if (ret)
>> +		return ret;
> Hi,
>
> Was it intentional for this change to alter the pitch?

Most hardware does not need the pitch to be of a certain alignment. But 
these buffers are possibly shared with other hardware, which sometimes 
needs alignment to certain values. Using SZ_8 improves compatible with 
that hardware.

>
> The alignment requirement has been updated?from 8-bit alignment to
> 64-bit alignment. Since the pitch is expressed in bytes, we should pass
> SZ_1 instead of SZ_8 for hw_patch_align.
>
> For example, for an 850?480 framebuffer at 16 bpp, the pitch should be
> 1700 bytes. With the new alignment, the pitch becomes 1704 bytes.

Many display modes have an 8-byte alignment in their width. 850 pixels 
is somewhat of an exception.

>
> Please let me know if you?d like me to submit a fix.

Do you see a bug with your hardware? Unless this creates a real problem, 
I'd like to keep it as it is now.

Best regards
Thomas

>
> Regards,
> Ludovic
>
>
>>    
>>    	dma_obj = drm_gem_dma_create_with_handle(file_priv, drm, args->size,
>>    						 &args->handle);
>> diff --git a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c b/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
>> index ec5fd9a01f1e..af4a30311e18 100644
>> --- a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
>> +++ b/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
>> @@ -145,8 +145,10 @@ static int imx_drm_dumb_create(struct drm_file *file_priv,
>>    	int ret;
>>    
>>    	args->width = ALIGN(width, 8);
>> +	args->pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
>> +	args->size = args->pitch * args->height;
>>    
>> -	ret = drm_gem_dma_dumb_create(file_priv, drm, args);
>> +	ret = drm_gem_dma_dumb_create_internal(file_priv, drm, args);
>>    	if (ret)
>>    		return ret;
>>    

-- 
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 N?rnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG N?rnberg)




From theo.lebrun at bootlin.com  Tue Nov 25 07:28:04 2025
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Tue, 25 Nov 2025 16:28:04 +0100
Subject: [PATCH 1/2] phy: rockchip: inno-usb2: fix disconnection in
 gadget mode
In-Reply-To: <20250722-rk3308-fix-usb-gadget-phy-disconnect-v1-1-239872f05f17@bootlin.com>
References: <20250722-rk3308-fix-usb-gadget-phy-disconnect-v1-0-239872f05f17@bootlin.com> <20250722-rk3308-fix-usb-gadget-phy-disconnect-v1-1-239872f05f17@bootlin.com>
Message-ID: <DEHVRC8CY12S.3LSC6UVSMU0C1@bootlin.com>

Hello Luca,

On Tue Jul 22, 2025 at 10:43 AM CEST, Luca Ceresoli wrote:
> From: Louis Chauvet <louis.chauvet at bootlin.com>
>
> When the OTG USB port is used to power to SoC, configured as peripheral and

typo: is used to power *the* SoC

> used in gadget mode, there is a disconnection about 6 seconds after the
> gadget is configured and enumerated.
>
> The problem was observed on a Radxa Rock Pi S board, which can only be
> powered by the only USB-C connector. That connector is the only one usable

"which can only be powered by the only USB-C connector"
double "only" makes it a super exclusive connector!

> in gadget mode. This implies the USB cable is connected from before boot
> and never disconnects while the kernel runs.
>
> The problem happens because of the PHY driver code flow, summarized as:
>
>  * UDC start code (triggered via configfs at any time after boot)
>    -> phy_init
>        -> rockchip_usb2phy_init
>            -> schedule_delayed_work(otg_sm_work [A], 6 sec)
>    -> phy_power_on
>        -> rockchip_usb2phy_power_on
>            -> enable clock
>            -> rockchip_usb2phy_reset
>
>  * Now the gadget interface is up and running.
>
>  * 6 seconds later otg_sm_work starts [A]
>    -> rockchip_usb2phy_otg_sm_work():
>        if (B_IDLE state && VBUS present && ...):
>            schedule_delayed_work(&rport->chg_work [B], 0);
>
>  * immediately the chg_detect_work starts [B]
>    -> rockchip_chg_detect_work():
>        if chg_state is UNDEFINED:
>            if (!rport->suspended):
>                rockchip_usb2phy_power_off() <--- [X]
>
> At [X], the PHY is powered off, causing a disconnection. This quickly
> triggers a new connection and following re-enumeration, but any connection
> that had been established during the 6 seconds is broken.
>
> The code already checks for !rport->suspended, so add a guard for VBUS as
> well to avoid a disconnection when a cable is connected.

Your commit message was clear but I was missing one key point: what
rport->suspended means. It isn't what I first thought. Instead it means
phy is powered off. Naming is bad but unrelated to your series. Maybe
add a comment to your commit message like the following?

  The code already checks for !rport->suspended (PHY is powered on), ...

> Fixes: 98898f3bc83c ("phy: rockchip-inno-usb2: support otg-port for rk3399")
> Closes: https://lore.kernel.org/lkml/20250414185458.7767aabc at booty/
> Co-developed-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
> Signed-off-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
> Signed-off-by: Louis Chauvet <louis.chauvet at bootlin.com>

I believe there is an issue with your SoB ordering. It is meant to
signal the path's route from author into the kernel tree. In that
sense, it should start with author followed by you as submitter. Then
the maintainer will append its own.

Documentation/process/submitting-patches.rst is semi-explicitly writing
that out:
> Any further SoBs [...] following the author's SoB [...]
https://elixir.bootlin.com/linux/v6.17.9/source/Documentation/process/submitting-patches.rst#L449-L453

One good way to check is that all maintainers always append their SoB
rather than prepend.

With that,

Reviewed-by: Th?o Lebrun <theo.lebrun at bootlin.com>

Thanks,

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com



From theo.lebrun at bootlin.com  Tue Nov 25 07:39:01 2025
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Tue, 25 Nov 2025 16:39:01 +0100
Subject: [PATCH 2/2] phy: rockchip: inno-usb2: fix communication
 disruption in gadget mode
In-Reply-To: <20250722-rk3308-fix-usb-gadget-phy-disconnect-v1-2-239872f05f17@bootlin.com>
References: <20250722-rk3308-fix-usb-gadget-phy-disconnect-v1-0-239872f05f17@bootlin.com> <20250722-rk3308-fix-usb-gadget-phy-disconnect-v1-2-239872f05f17@bootlin.com>
Message-ID: <DEHVZPZVWVTR.314J3P86OLG6X@bootlin.com>

Hello Luca,

On Tue Jul 22, 2025 at 10:43 AM CEST, Luca Ceresoli wrote:
> When the OTG USB port is used to power to SoC, configured as peripheral and
> used in gadget mode, communication stops without notice about 6 seconds
> after the gadget is configured and enumerated.
>
> The problem was observed on a Radxa Rock Pi S board, which can only be
> powered by the only USB-C connector. That connector is the only one usable
> in gadget mode. This implies the USB cable is connected from before boot
> and never disconnects while the kernel runs.
>
> The related code flow in the PHY driver code can be summarized as:
>
>  * UDC start code (triggered via configfs at any time after boot)
>    -> phy_init
>        -> rockchip_usb2phy_init
>            -> schedule_delayed_work(otg_sm_work [A], 6 sec)
>    -> phy_power_on
>        -> rockchip_usb2phy_power_on
>            -> enable clock
>            -> rockchip_usb2phy_reset

The above code flow summary was important for [PATCH 1/2] but it feels
like not as important for [PATCH 2/2], could you drop or summarise it?
The key point is that the below DCD sequence has invalid assumptions
and does side effects that don't fit if VBUS is already present. I feel
like it distracted me from the main point that is chg_det.opmode
writes.

>  * Now the gadget interface is up and running.
>
>  * 6 seconds later otg_sm_work starts [A]
>    -> rockchip_usb2phy_otg_sm_work():
>        if (B_IDLE state && VBUS present && ...):
>            schedule_delayed_work(&rport->chg_work [B], 0);
>
>  * immediately the chg_detect_work starts [B]
>    -> rockchip_chg_detect_work():
>        if chg_state is UNDEFINED:
>             property_enable(base, &rphy->phy_cfg->chg_det.opmode, false); [Y]
>
>  * rockchip_chg_detect_work() changes state and re-triggers itself a few
>    times until it reached the DETECTED state:
>    -> rockchip_chg_detect_work():
>        if chg_state is DETECTED:
>             property_enable(base, &rphy->phy_cfg->chg_det.opmode, true); [Z]
>
> At [Y] there is no disconnection and the USB device appears still present
> to userspace, but all existing communications stop. E.g. using a CDC serial
> gadget, the /dev/tty* devices are still present on both host and device,
> but no data is transferred anymore. The later call with a 'true' argument
> at [Z] does not restore it.

You mention "there is no disconnection" but that sounds irrelevant to
this precise commit. The issue at hand is a communication halt.

> Due to the lack of documentation, what chg_det.opmode does exactly is not
> clear, however by code inspection it seems reasonable that is disables
> something needed to keep the communication working, and testing proves that
> disabling these lines lefs gadget mode keep working. So prevent changes to
> chg_det.opmode when there is a cable connected (VBUS present).

"lefs" -> "let's", I think

With those nits

Reviewed-by: Th?o Lebrun <theo.lebrun at bootlin.com>

Thanks,

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com



From ulf.hansson at linaro.org  Tue Nov 25 08:02:00 2025
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 25 Nov 2025 17:02:00 +0100
Subject: [PATCH 2/2] mmc: sdhci-of-dwcmshc: reduce CIT for better performance
In-Reply-To: <7b05327d-fc76-471e-9148-3dfc0cd17623@rock-chips.com>
References: <1762933460-204066-1-git-send-email-shawn.lin@rock-chips.com>
 <1762933460-204066-2-git-send-email-shawn.lin@rock-chips.com> <7b05327d-fc76-471e-9148-3dfc0cd17623@rock-chips.com>
Message-ID: <CAPDyKFrx_5cnyFeLRhoia2aHK9Cxo+fp_kKhyQ526xE02_+vSA@mail.gmail.com>

On Tue, 25 Nov 2025 at 14:58, Shawn Lin <shawn.lin at rock-chips.com> wrote:
>
> ? 2025/11/12 ??? 15:44, Shawn Lin ??:
> > CQHCI_SSC1.CIT indicates to the CQE the polling period to use for
> > periodic SEND_QUEUE_STATUS (CMD13) polling. Some eMMCs have only one
> > hardware queue, and CMD13 can only query one slot at a time for data
> > transmission, which cannot be processed in parallel. Modifying the
> > CMD13 query interval can increase the query frequency and improve
> > random write performance.
> >
>
> Ping...
>
> Adrain acked these two patches, so will them be candidates for 6.19
> given the merge windows is coming soon?

Looks like I simply failed to see them. Possibly because there was
cover-letter, which makes it harder for me to follow all the different
series.

Anyway, I tried to apply them, but there are conflicts that I am not
sure I can resolve easily by myself. Would you mind doing a re-base
and post a new version, then I can apply them asap.

Kind regards
Uffe

>
> > Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
> > ---
> >
> >   drivers/mmc/host/cqhci.h            | 1 +
> >   drivers/mmc/host/sdhci-of-dwcmshc.c | 5 +++++
> >   2 files changed, 6 insertions(+)
> >
> > diff --git a/drivers/mmc/host/cqhci.h b/drivers/mmc/host/cqhci.h
> > index ce189a1..3668856 100644
> > --- a/drivers/mmc/host/cqhci.h
> > +++ b/drivers/mmc/host/cqhci.h
> > @@ -93,6 +93,7 @@
> >   /* send status config 1 */
> >   #define CQHCI_SSC1                  0x40
> >   #define CQHCI_SSC1_CBC_MASK         GENMASK(19, 16)
> > +#define CQHCI_SSC1_CIT_MASK          GENMASK(15, 0)
> >
> >   /* send status config 2 */
> >   #define CQHCI_SSC2                  0x44
> > diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c
> > index e276a4e..cad5165 100644
> > --- a/drivers/mmc/host/sdhci-of-dwcmshc.c
> > +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c
> > @@ -631,6 +631,11 @@ static void rk35xx_sdhci_cqe_pre_enable(struct mmc_host *mmc)
> >       struct dwcmshc_priv *dwc_priv = sdhci_pltfm_priv(pltfm_host);
> >       u32 reg;
> >
> > +     /* Set Send Status Command Idle Timer to 10.66us (256 * 1 / 24) */
> > +     reg = sdhci_readl(host, dwc_priv->vendor_specific_area2 + CQHCI_SSC1);
> > +     reg = (reg & ~CQHCI_SSC1_CIT_MASK) | 0x0100;
> > +     sdhci_writel(host, reg, dwc_priv->vendor_specific_area2 + CQHCI_SSC1);
> > +
> >       reg = sdhci_readl(host, dwc_priv->vendor_specific_area2 + CQHCI_CFG);
> >       reg |= CQHCI_ENABLE;
> >       sdhci_writel(host, reg, dwc_priv->vendor_specific_area2 + CQHCI_CFG);
>


From ulf.hansson at linaro.org  Tue Nov 25 08:05:46 2025
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 25 Nov 2025 17:05:46 +0100
Subject: [PATCH 2/2] mmc: sdhci-of-dwcmshc: reduce CIT for better performance
In-Reply-To: <CAPDyKFrx_5cnyFeLRhoia2aHK9Cxo+fp_kKhyQ526xE02_+vSA@mail.gmail.com>
References: <1762933460-204066-1-git-send-email-shawn.lin@rock-chips.com>
 <1762933460-204066-2-git-send-email-shawn.lin@rock-chips.com>
 <7b05327d-fc76-471e-9148-3dfc0cd17623@rock-chips.com> <CAPDyKFrx_5cnyFeLRhoia2aHK9Cxo+fp_kKhyQ526xE02_+vSA@mail.gmail.com>
Message-ID: <CAPDyKFoBezDP9DsCFVhS3n+Vm0rQv_Hs2g5svyD2KQ5A-rezwg@mail.gmail.com>

On Tue, 25 Nov 2025 at 17:02, Ulf Hansson <ulf.hansson at linaro.org> wrote:
>
> On Tue, 25 Nov 2025 at 14:58, Shawn Lin <shawn.lin at rock-chips.com> wrote:
> >
> > ? 2025/11/12 ??? 15:44, Shawn Lin ??:
> > > CQHCI_SSC1.CIT indicates to the CQE the polling period to use for
> > > periodic SEND_QUEUE_STATUS (CMD13) polling. Some eMMCs have only one
> > > hardware queue, and CMD13 can only query one slot at a time for data
> > > transmission, which cannot be processed in parallel. Modifying the
> > > CMD13 query interval can increase the query frequency and improve
> > > random write performance.
> > >
> >
> > Ping...
> >
> > Adrain acked these two patches, so will them be candidates for 6.19
> > given the merge windows is coming soon?
>
> Looks like I simply failed to see them. Possibly because there was
> cover-letter, which makes it harder for me to follow all the different

/s/cover-letter/no cover-letter

[...]

Kind regards
Uffe


From shawn.lin at rock-chips.com  Tue Nov 25 15:26:39 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Wed, 26 Nov 2025 07:26:39 +0800
Subject: [PATCH v2 1/2] mmc: sdhci-of-dwcmshc: Disable internal clock auto gate for Rockchip SOCs
In-Reply-To: <1764113200-237279-1-git-send-email-shawn.lin@rock-chips.com>
References: <1764113200-237279-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1764113200-237279-2-git-send-email-shawn.lin@rock-chips.com>

Enabling CMDQ support can lead to random occurrences of the error log when
there are RPMB access and data flush executed:

"mmc2: Timeout waiting for hardware interrupt."

Enabling CMDQ and then issuing a DCMD as the final command before disabling
it causes the eMMC controller to auto-gate its internal clock. Chip simulation
shows this results in a state machine mismatch after CMDQ mode exit, triggering
data-timeout errors for all subsequent read and write operations.

Therefore, the auto-clock-gate function must be disabled whenever CMDQ is
enabled.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
Acked-by: Adrian Hunter <adrian.hunter at intel.com>
---

Changes in v2:
- rebase and add acked-by tag

 drivers/mmc/host/sdhci-of-dwcmshc.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c
index c66a8df..e276a4e 100644
--- a/drivers/mmc/host/sdhci-of-dwcmshc.c
+++ b/drivers/mmc/host/sdhci-of-dwcmshc.c
@@ -713,10 +713,11 @@ static void dwcmshc_rk3568_set_clock(struct sdhci_host *host, unsigned int clock
 
 	sdhci_set_clock(host, clock);
 
-	/* Disable cmd conflict check */
+	/* Disable cmd conflict check and internal clock gate */
 	reg = dwc_priv->vendor_specific_area1 + DWCMSHC_HOST_CTRL3;
 	extra = sdhci_readl(host, reg);
 	extra &= ~BIT(0);
+	extra |= BIT(4);
 	sdhci_writel(host, extra, reg);
 
 	if (clock <= 52000000) {
-- 
2.7.4



From shawn.lin at rock-chips.com  Tue Nov 25 15:26:38 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Wed, 26 Nov 2025 07:26:38 +0800
Subject: [PATCH v2 0/2] sdhci-of-dwcmshc improvement and fix for Rockchip SoCs
Message-ID: <1764113200-237279-1-git-send-email-shawn.lin@rock-chips.com>

This's v2 of these two patches which adds ack-by tags collected and
rebase on top of linux-next.

The first patch fixes the auto-gating problem of dwc IP when using CQE.
The second one improves the performance of CQE by reducing CIT.


Changes in v2:
- rebase and add acked-by tag

Shawn Lin (2):
  mmc: sdhci-of-dwcmshc: Disable internal clock auto gate for Rockchip
    SOCs
  mmc: sdhci-of-dwcmshc: reduce CIT for better performance

 drivers/mmc/host/cqhci.h            | 1 +
 drivers/mmc/host/sdhci-of-dwcmshc.c | 8 +++++++-
 2 files changed, 8 insertions(+), 1 deletion(-)

-- 
2.7.4



From shawn.lin at rock-chips.com  Tue Nov 25 15:26:40 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Wed, 26 Nov 2025 07:26:40 +0800
Subject: [PATCH v2 2/2] mmc: sdhci-of-dwcmshc: reduce CIT for better performance
In-Reply-To: <1764113200-237279-1-git-send-email-shawn.lin@rock-chips.com>
References: <1764113200-237279-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1764113200-237279-3-git-send-email-shawn.lin@rock-chips.com>

CQHCI_SSC1.CIT indicates to the CQE the polling period to use for
periodic SEND_QUEUE_STATUS (CMD13) polling. Some eMMCs have only one
hardware queue, and CMD13 can only query one slot at a time for data
transmission, which cannot be processed in parallel. Modifying the
CMD13 query interval can increase the query frequency and improve
random write performance.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>

Acked-by: Adrian Hunter <adrian.hunter at intel.com>
---

Changes in v2:
- rebase and add acked-by tag

 drivers/mmc/host/cqhci.h            | 1 +
 drivers/mmc/host/sdhci-of-dwcmshc.c | 5 +++++
 2 files changed, 6 insertions(+)

diff --git a/drivers/mmc/host/cqhci.h b/drivers/mmc/host/cqhci.h
index ce189a1..3668856 100644
--- a/drivers/mmc/host/cqhci.h
+++ b/drivers/mmc/host/cqhci.h
@@ -93,6 +93,7 @@
 /* send status config 1 */
 #define CQHCI_SSC1			0x40
 #define CQHCI_SSC1_CBC_MASK		GENMASK(19, 16)
+#define CQHCI_SSC1_CIT_MASK		GENMASK(15, 0)
 
 /* send status config 2 */
 #define CQHCI_SSC2			0x44
diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c
index e276a4e..cad5165 100644
--- a/drivers/mmc/host/sdhci-of-dwcmshc.c
+++ b/drivers/mmc/host/sdhci-of-dwcmshc.c
@@ -631,6 +631,11 @@ static void rk35xx_sdhci_cqe_pre_enable(struct mmc_host *mmc)
 	struct dwcmshc_priv *dwc_priv = sdhci_pltfm_priv(pltfm_host);
 	u32 reg;
 
+	/* Set Send Status Command Idle Timer to 10.66us (256 * 1 / 24) */
+	reg = sdhci_readl(host, dwc_priv->vendor_specific_area2 + CQHCI_SSC1);
+	reg = (reg & ~CQHCI_SSC1_CIT_MASK) | 0x0100;
+	sdhci_writel(host, reg, dwc_priv->vendor_specific_area2 + CQHCI_SSC1);
+
 	reg = sdhci_readl(host, dwc_priv->vendor_specific_area2 + CQHCI_CFG);
 	reg |= CQHCI_ENABLE;
 	sdhci_writel(host, reg, dwc_priv->vendor_specific_area2 + CQHCI_CFG);
-- 
2.7.4



From shawn.lin at rock-chips.com  Tue Nov 25 15:35:29 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Wed, 26 Nov 2025 07:35:29 +0800
Subject: [PATCH 2/2] mmc: sdhci-of-dwcmshc: reduce CIT for better
 performance
In-Reply-To: <CAPDyKFrx_5cnyFeLRhoia2aHK9Cxo+fp_kKhyQ526xE02_+vSA@mail.gmail.com>
References: <1762933460-204066-1-git-send-email-shawn.lin@rock-chips.com>
 <1762933460-204066-2-git-send-email-shawn.lin@rock-chips.com>
 <7b05327d-fc76-471e-9148-3dfc0cd17623@rock-chips.com>
 <CAPDyKFrx_5cnyFeLRhoia2aHK9Cxo+fp_kKhyQ526xE02_+vSA@mail.gmail.com>
Message-ID: <ac6e55f4-faa6-4c41-a141-976fe0b15507@rock-chips.com>



? 2025/11/26 ??? 0:02, Ulf Hansson ??:
> On Tue, 25 Nov 2025 at 14:58, Shawn Lin <shawn.lin at rock-chips.com> wrote:
>>
>> ? 2025/11/12 ??? 15:44, Shawn Lin ??:
>>> CQHCI_SSC1.CIT indicates to the CQE the polling period to use for
>>> periodic SEND_QUEUE_STATUS (CMD13) polling. Some eMMCs have only one
>>> hardware queue, and CMD13 can only query one slot at a time for data
>>> transmission, which cannot be processed in parallel. Modifying the
>>> CMD13 query interval can increase the query frequency and improve
>>> random write performance.
>>>
>>
>> Ping...
>>
>> Adrain acked these two patches, so will them be candidates for 6.19
>> given the merge windows is coming soon?
> 
> Looks like I simply failed to see them. Possibly because there was
> cover-letter, which makes it harder for me to follow all the different
> series.
> 
> Anyway, I tried to apply them, but there are conflicts that I am not
> sure I can resolve easily by myself. Would you mind doing a re-base
> and post a new version, then I can apply them asap.
> 

Thanks Ulf. I just did a rebase on top of linux-next and posted a new
version[1].

[1] 
https://lore.kernel.org/all/1764113200-237279-1-git-send-email-shawn.lin at rock-chips.com/


> Kind regards
> Uffe
> 
>>
>>> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
>>> ---
>>>
>>>    drivers/mmc/host/cqhci.h            | 1 +
>>>    drivers/mmc/host/sdhci-of-dwcmshc.c | 5 +++++
>>>    2 files changed, 6 insertions(+)
>>>
>>> diff --git a/drivers/mmc/host/cqhci.h b/drivers/mmc/host/cqhci.h
>>> index ce189a1..3668856 100644
>>> --- a/drivers/mmc/host/cqhci.h
>>> +++ b/drivers/mmc/host/cqhci.h
>>> @@ -93,6 +93,7 @@
>>>    /* send status config 1 */
>>>    #define CQHCI_SSC1                  0x40
>>>    #define CQHCI_SSC1_CBC_MASK         GENMASK(19, 16)
>>> +#define CQHCI_SSC1_CIT_MASK          GENMASK(15, 0)
>>>
>>>    /* send status config 2 */
>>>    #define CQHCI_SSC2                  0x44
>>> diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c
>>> index e276a4e..cad5165 100644
>>> --- a/drivers/mmc/host/sdhci-of-dwcmshc.c
>>> +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c
>>> @@ -631,6 +631,11 @@ static void rk35xx_sdhci_cqe_pre_enable(struct mmc_host *mmc)
>>>        struct dwcmshc_priv *dwc_priv = sdhci_pltfm_priv(pltfm_host);
>>>        u32 reg;
>>>
>>> +     /* Set Send Status Command Idle Timer to 10.66us (256 * 1 / 24) */
>>> +     reg = sdhci_readl(host, dwc_priv->vendor_specific_area2 + CQHCI_SSC1);
>>> +     reg = (reg & ~CQHCI_SSC1_CIT_MASK) | 0x0100;
>>> +     sdhci_writel(host, reg, dwc_priv->vendor_specific_area2 + CQHCI_SSC1);
>>> +
>>>        reg = sdhci_readl(host, dwc_priv->vendor_specific_area2 + CQHCI_CFG);
>>>        reg |= CQHCI_ENABLE;
>>>        sdhci_writel(host, reg, dwc_priv->vendor_specific_area2 + CQHCI_CFG);
>>
> 



From chaoyi.chen at rock-chips.com  Tue Nov 25 17:46:19 2025
From: chaoyi.chen at rock-chips.com (Chaoyi Chen)
Date: Wed, 26 Nov 2025 09:46:19 +0800
Subject: [PATCH v10 01/11] usb: typec: Add notifier functions
In-Reply-To: <2025112554-uncaring-curator-642a@gregkh>
References: <20251120022343.250-1-kernel@airkyi.com>
 <20251120022343.250-2-kernel@airkyi.com>
 <2025112102-laurel-mulch-58e4@gregkh>
 <462ad1bd-7eec-4f26-b383-96b049e14559@rock-chips.com>
 <2025112402-unopposed-polio-e6e9@gregkh>
 <a80483de-518d-45d5-b46a-9b70cca5b236@rock-chips.com>
 <2025112448-brush-porcupine-c851@gregkh>
 <c9cb7b79-37c8-4fef-97a6-7d6b8898f9c4@rock-chips.com> <aSV_lQYJPxN7oBM-@kuha>
 <2025112554-uncaring-curator-642a@gregkh>
Message-ID: <cbb38c08-6937-4b7d-a0b0-d5ca6c17f466@rock-chips.com>

On 11/25/2025 7:49 PM, Greg Kroah-Hartman wrote:
>> +static umode_t typec_is_visible(struct kobject *kobj, struct attribute *attr, int n)
>> +{
>> +	if (is_typec_port(kobj_to_dev(kobj)->parent))
> 
> Why look at the parent?  Doesn't the device have a type that should show
> this?
> 
> Otherwise, looks good to me.

They have same deivce type "typec_altmode_dev_type".
The parent device has a different device type to distinguish between
port device and partner device.

> 
> thanks,
> 
> greg k-h
> 
> 

-- 
Best, 
Chaoyi


From chaoyi.chen at rock-chips.com  Tue Nov 25 18:13:58 2025
From: chaoyi.chen at rock-chips.com (Chaoyi Chen)
Date: Wed, 26 Nov 2025 10:13:58 +0800
Subject: [PATCH v10 03/11] drm/bridge: Implement generic USB Type-C DP HPD
 bridge
In-Reply-To: <20251120022343.250-4-kernel@airkyi.com>
References: <20251120022343.250-1-kernel@airkyi.com>
 <20251120022343.250-4-kernel@airkyi.com>
Message-ID: <db9541d3-bc5c-4907-9dc5-965810ef92d9@rock-chips.com>

Hi Heikki,

On 11/20/2025 10:23 AM, Chaoyi Chen wrote:
> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> 

[...]

> 
>  drivers/gpu/drm/bridge/Kconfig                | 10 ++++
>  drivers/gpu/drm/bridge/Makefile               |  1 +
>  .../gpu/drm/bridge/aux-hpd-typec-dp-bridge.c  | 50 +++++++++++++++++++
>  3 files changed, 61 insertions(+)
>  create mode 100644 drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
> 
> +
> +static int drm_typec_bus_event(struct notifier_block *nb,
> +			       unsigned long action, void *data)
> +{
> +	struct typec_altmode *alt = (struct typec_altmode *)data;
> +
> +	if (action != TYPEC_ALTMODE_REGISTERED)
> +		goto done;
> +
> +	if (is_typec_partner(&alt->dev) || alt->svid != USB_TYPEC_DP_SID)
> +		goto done;

It should be "is_typec_partner(alt->dev.parent)".
Sorry, I didn't notice this earlier. I will fix this in v11.

> +
> +	/*
> +	 * alt->dev.parent->parent : USB-C controller device
> +	 * alt->dev.parent         : USB-C connector device
> +	 */
> +	drm_dp_hpd_bridge_register(alt->dev.parent->parent,
> +				   to_of_node(alt->dev.parent->fwnode));
> +
> +done:
> +	return NOTIFY_OK;
> +}
> +

-- 
Best, 
Chaoyi


From Ludovic.Desroches at microchip.com  Tue Nov 25 22:24:38 2025
From: Ludovic.Desroches at microchip.com (Ludovic.Desroches at microchip.com)
Date: Wed, 26 Nov 2025 06:24:38 +0000
Subject: [PATCH v6 03/25] drm/gem-dma: Compute dumb-buffer sizes with
 drm_mode_size_dumb()
In-Reply-To: <a11c195d-197c-45a4-962a-e2336c7360c2@suse.de>
References: <20250821081918.79786-1-tzimmermann@suse.de>
 <20250821081918.79786-4-tzimmermann@suse.de>
 <52600bf4-2c1c-49a6-82c5-b31818141a43@microchip.com>
 <a11c195d-197c-45a4-962a-e2336c7360c2@suse.de>
Message-ID: <2fbe0d43-67c5-4816-aff0-c23ac1507ec5@microchip.com>

On 11/25/25 16:03, Thomas Zimmermann wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know 
> the content is safe
> 
> Hi
> 
> Am 25.11.25 um 15:39 schrieb Ludovic.Desroches at microchip.com:
>> On 8/21/25 10:17, Thomas Zimmermann wrote:
>>> Call drm_mode_size_dumb() to compute dumb-buffer scanline pitch and
>>> buffer size. Align the pitch to a multiple of 8.
> 
> I missed a chance to explain it here. :/

I was wondering if it was 8-bits or 8-bytes.

> 
>>>
>>> Push the current calculation into the only direct caller imx. Imx's
>>> hardware requires the framebuffer width to be aligned to 8. The
>>> driver's current approach is actually incorrect, as it only guarantees
>>> this implicitly and requires bpp to be a multiple of 8 already. A
>>> later commit will fix this problem by aligning the scanline pitch
>>> such that an aligned width still fits into each scanline's memory.
>>>
>>> A number of other drivers are build on top of gem-dma helpers and
>>> implement their own dumb-buffer allocation. These drivers invoke
>>> drm_gem_dma_dumb_create_internal(), which is not affected by this
>>> commit.
>>>
>>> v5:
>>> - avoid reset of arguments (Tomi)
>>>
>>> Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
>>> Reviewed-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
>>> ---
>>> ?? drivers/gpu/drm/drm_gem_dma_helper.c???? | 7 +++++--
>>> ?? drivers/gpu/drm/imx/ipuv3/imx-drm-core.c | 4 +++-
>>> ?? 2 files changed, 8 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/drm_gem_dma_helper.c b/drivers/gpu/drm/ 
>>> drm_gem_dma_helper.c
>>> index 4f0320df858f..ab1a70b1d6f1 100644
>>> --- a/drivers/gpu/drm/drm_gem_dma_helper.c
>>> +++ b/drivers/gpu/drm/drm_gem_dma_helper.c
>>> @@ -20,6 +20,7 @@
>>> ?? #include <drm/drm.h>
>>> ?? #include <drm/drm_device.h>
>>> ?? #include <drm/drm_drv.h>
>>> +#include <drm/drm_dumb_buffers.h>
>>> ?? #include <drm/drm_gem_dma_helper.h>
>>> ?? #include <drm/drm_vma_manager.h>
>>>
>>> @@ -304,9 +305,11 @@ int drm_gem_dma_dumb_create(struct drm_file 
>>> *file_priv,
>>> ???????????????????????? struct drm_mode_create_dumb *args)
>>> ?? {
>>> ???? struct drm_gem_dma_object *dma_obj;
>>> +??? int ret;
>>>
>>> -??? args->pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
>>> -??? args->size = args->pitch * args->height;
>>> +??? ret = drm_mode_size_dumb(drm, args, SZ_8, 0);
>>> +??? if (ret)
>>> +??????????? return ret;
>> Hi,
>>
>> Was it intentional for this change to alter the pitch?
> 
> Most hardware does not need the pitch to be of a certain alignment. But
> these buffers are possibly shared with other hardware, which sometimes
> needs alignment to certain values. Using SZ_8 improves compatible with
> that hardware.
> 
>>
>> The alignment requirement has been updated?from 8-bit alignment to
>> 64-bit alignment. Since the pitch is expressed in bytes, we should pass
>> SZ_1 instead of SZ_8 for hw_patch_align.
>>
>> For example, for an 850?480 framebuffer at 16 bpp, the pitch should be
>> 1700 bytes. With the new alignment, the pitch becomes 1704 bytes.
> 
> Many display modes have an 8-byte alignment in their width. 850 pixels
> is somewhat of an exception.

Indeed, but overlay-type planes are often used to display windows that 
are not the same size as the screen, and therefore potentially not on 
8-bytes aligned.

> 
>>
>> Please let me know if you?d like me to submit a fix.
> 
> Do you see a bug with your hardware? Unless this creates a real problem,
> I'd like to keep it as it is now.

Yes, that?s how I noticed this change. I have an application that 
requests a framebuffer larger than my screen, in this case 850x480 in 
RGB565 for an 800x480 display. So I have a pitch of 1700 bytes. Now it?s 
using a pitch of 1704, which shifts my lines.

Regards,
Ludovic

> 
> Best regards
> Thomas
> 
>>
>> Regards,
>> Ludovic
>>
>>
>>>
>>> ???? dma_obj = drm_gem_dma_create_with_handle(file_priv, drm, args- 
>>> >size,
>>> ????????????????????????????????????????????? &args->handle);
>>> diff --git a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c b/drivers/gpu/ 
>>> drm/imx/ipuv3/imx-drm-core.c
>>> index ec5fd9a01f1e..af4a30311e18 100644
>>> --- a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
>>> +++ b/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
>>> @@ -145,8 +145,10 @@ static int imx_drm_dumb_create(struct drm_file 
>>> *file_priv,
>>> ???? int ret;
>>>
>>> ???? args->width = ALIGN(width, 8);
>>> +??? args->pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
>>> +??? args->size = args->pitch * args->height;
>>>
>>> -??? ret = drm_gem_dma_dumb_create(file_priv, drm, args);
>>> +??? ret = drm_gem_dma_dumb_create_internal(file_priv, drm, args);
>>> ???? if (ret)
>>> ???????????? return ret;
>>>
> 
> -- 
> -- 
> Thomas Zimmermann
> Graphics Driver Developer
> SUSE Software Solutions Germany GmbH
> Frankenstr. 146, 90461 N?rnberg, Germany, www.suse.com
> GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG 
> N?rnberg)
> 
> 



From tzimmermann at suse.de  Tue Nov 25 23:40:09 2025
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Wed, 26 Nov 2025 08:40:09 +0100
Subject: [PATCH v6 03/25] drm/gem-dma: Compute dumb-buffer sizes with
 drm_mode_size_dumb()
In-Reply-To: <2fbe0d43-67c5-4816-aff0-c23ac1507ec5@microchip.com>
References: <20250821081918.79786-1-tzimmermann@suse.de>
 <20250821081918.79786-4-tzimmermann@suse.de>
 <52600bf4-2c1c-49a6-82c5-b31818141a43@microchip.com>
 <a11c195d-197c-45a4-962a-e2336c7360c2@suse.de>
 <2fbe0d43-67c5-4816-aff0-c23ac1507ec5@microchip.com>
Message-ID: <58b768ad-00fb-4fe5-924c-9cf6ec12f75c@suse.de>

Hi

Am 26.11.25 um 07:24 schrieb Ludovic.Desroches at microchip.com:
> On 11/25/25 16:03, Thomas Zimmermann wrote:
>> EXTERNAL EMAIL: Do not click links or open attachments unless you know
>> the content is safe
>>
>> Hi
>>
>> Am 25.11.25 um 15:39 schrieb Ludovic.Desroches at microchip.com:
>>> On 8/21/25 10:17, Thomas Zimmermann wrote:
>>>> Call drm_mode_size_dumb() to compute dumb-buffer scanline pitch and
>>>> buffer size. Align the pitch to a multiple of 8.
>> I missed a chance to explain it here. :/
> I was wondering if it was 8-bits or 8-bytes.
>
>>>> Push the current calculation into the only direct caller imx. Imx's
>>>> hardware requires the framebuffer width to be aligned to 8. The
>>>> driver's current approach is actually incorrect, as it only guarantees
>>>> this implicitly and requires bpp to be a multiple of 8 already. A
>>>> later commit will fix this problem by aligning the scanline pitch
>>>> such that an aligned width still fits into each scanline's memory.
>>>>
>>>> A number of other drivers are build on top of gem-dma helpers and
>>>> implement their own dumb-buffer allocation. These drivers invoke
>>>> drm_gem_dma_dumb_create_internal(), which is not affected by this
>>>> commit.
>>>>
>>>> v5:
>>>> - avoid reset of arguments (Tomi)
>>>>
>>>> Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
>>>> Reviewed-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
>>>> ---
>>>>  ?? drivers/gpu/drm/drm_gem_dma_helper.c???? | 7 +++++--
>>>>  ?? drivers/gpu/drm/imx/ipuv3/imx-drm-core.c | 4 +++-
>>>>  ?? 2 files changed, 8 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/drm_gem_dma_helper.c b/drivers/gpu/drm/
>>>> drm_gem_dma_helper.c
>>>> index 4f0320df858f..ab1a70b1d6f1 100644
>>>> --- a/drivers/gpu/drm/drm_gem_dma_helper.c
>>>> +++ b/drivers/gpu/drm/drm_gem_dma_helper.c
>>>> @@ -20,6 +20,7 @@
>>>>  ?? #include <drm/drm.h>
>>>>  ?? #include <drm/drm_device.h>
>>>>  ?? #include <drm/drm_drv.h>
>>>> +#include <drm/drm_dumb_buffers.h>
>>>>  ?? #include <drm/drm_gem_dma_helper.h>
>>>>  ?? #include <drm/drm_vma_manager.h>
>>>>
>>>> @@ -304,9 +305,11 @@ int drm_gem_dma_dumb_create(struct drm_file
>>>> *file_priv,
>>>>  ???????????????????????? struct drm_mode_create_dumb *args)
>>>>  ?? {
>>>>  ???? struct drm_gem_dma_object *dma_obj;
>>>> +??? int ret;
>>>>
>>>> -??? args->pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
>>>> -??? args->size = args->pitch * args->height;
>>>> +??? ret = drm_mode_size_dumb(drm, args, SZ_8, 0);
>>>> +??? if (ret)
>>>> +??????????? return ret;
>>> Hi,
>>>
>>> Was it intentional for this change to alter the pitch?
>> Most hardware does not need the pitch to be of a certain alignment. But
>> these buffers are possibly shared with other hardware, which sometimes
>> needs alignment to certain values. Using SZ_8 improves compatible with
>> that hardware.
>>
>>> The alignment requirement has been updated?from 8-bit alignment to
>>> 64-bit alignment. Since the pitch is expressed in bytes, we should pass
>>> SZ_1 instead of SZ_8 for hw_patch_align.
>>>
>>> For example, for an 850?480 framebuffer at 16 bpp, the pitch should be
>>> 1700 bytes. With the new alignment, the pitch becomes 1704 bytes.
>> Many display modes have an 8-byte alignment in their width. 850 pixels
>> is somewhat of an exception.
> Indeed, but overlay-type planes are often used to display windows that
> are not the same size as the screen, and therefore potentially not on
> 8-bytes aligned.
>
>>> Please let me know if you?d like me to submit a fix.
>> Do you see a bug with your hardware? Unless this creates a real problem,
>> I'd like to keep it as it is now.
> Yes, that?s how I noticed this change. I have an application that
> requests a framebuffer larger than my screen, in this case 850x480 in
> RGB565 for an 800x480 display. So I have a pitch of 1700 bytes. Now it?s
> using a pitch of 1704, which shifts my lines.

Honestly, your application is broken. The ioctl returns the pitch value 
to user space and that's what the program should use. Some hardware has 
hard constraints on the pitch, so you will sooner or later run into the 
same problem again.

Anyway, feel free to submit a patch to call drm_mode_size_dumb() without 
SZ_8. The best value would be 0, so that the function picks a default by 
itself. Since you're at it, maybe also look at patches 4 and 5 of this 
series. They have similar code for other memory managers.

Best regards
Thomas

>
> Regards,
> Ludovic
>
>> Best regards
>> Thomas
>>
>>> Regards,
>>> Ludovic
>>>
>>>
>>>>  ???? dma_obj = drm_gem_dma_create_with_handle(file_priv, drm, args-
>>>>> size,
>>>>  ????????????????????????????????????????????? &args->handle);
>>>> diff --git a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c b/drivers/gpu/
>>>> drm/imx/ipuv3/imx-drm-core.c
>>>> index ec5fd9a01f1e..af4a30311e18 100644
>>>> --- a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
>>>> +++ b/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
>>>> @@ -145,8 +145,10 @@ static int imx_drm_dumb_create(struct drm_file
>>>> *file_priv,
>>>>  ???? int ret;
>>>>
>>>>  ???? args->width = ALIGN(width, 8);
>>>> +??? args->pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
>>>> +??? args->size = args->pitch * args->height;
>>>>
>>>> -??? ret = drm_gem_dma_dumb_create(file_priv, drm, args);
>>>> +??? ret = drm_gem_dma_dumb_create_internal(file_priv, drm, args);
>>>>  ???? if (ret)
>>>>  ???????????? return ret;
>>>>
>> -- 
>> -- 
>> Thomas Zimmermann
>> Graphics Driver Developer
>> SUSE Software Solutions Germany GmbH
>> Frankenstr. 146, 90461 N?rnberg, Germany, www.suse.com
>> GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG
>> N?rnberg)
>>
>>
>

-- 
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 N?rnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG N?rnberg)




From kernel at airkyi.com  Wed Nov 26 00:33:43 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Wed, 26 Nov 2025 16:33:43 +0800
Subject: [PATCH 0/2] iommu/rockchip: Add support for multiple interface clocks
Message-ID: <20251126083345.88-1-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

Hi,

Some rockchip iommus require extra clocks besides aclk and interface
clock, such as the iommus for NPU and RKVENC in RK3576.

This series adds support for these extra clocks, which are called
`iface_x`.

Chaoyi Chen (2):
  dt-bindings: iommu: rockchip: Add support for multiple interface
    clocks
  iommu/rockchip: Use devm_clk_bulk_get_all() to get multiple iface
    clock

 .../bindings/iommu/rockchip,iommu.yaml        |  8 ++++++++
 drivers/iommu/rockchip-iommu.c                | 20 ++++---------------
 2 files changed, 12 insertions(+), 16 deletions(-)

--
2.51.1



From kernel at airkyi.com  Wed Nov 26 00:33:45 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Wed, 26 Nov 2025 16:33:45 +0800
Subject: [PATCH 2/2] iommu/rockchip: Use devm_clk_bulk_get_all() to get multiple iface clock
In-Reply-To: <20251126083345.88-1-kernel@airkyi.com>
References: <20251126083345.88-1-kernel@airkyi.com>
Message-ID: <20251126083345.88-3-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

The iommu found on RK3576 NPU/RKVDEC may contains more than one
interface clock.

Just use devm_clk_bulk_get_all() to get all the clocks and use them.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---
 drivers/iommu/rockchip-iommu.c | 20 ++++----------------
 1 file changed, 4 insertions(+), 16 deletions(-)

diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 0861dd469bd8..76f71fb679f8 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -93,11 +93,6 @@ struct rk_iommu_domain {
 	struct iommu_domain domain;
 };
 
-/* list of clocks required by IOMMU */
-static const char * const rk_iommu_clocks[] = {
-	"aclk", "iface",
-};
-
 struct rk_iommu_ops {
 	phys_addr_t (*pt_address)(u32 dte);
 	u32 (*mk_dtentries)(dma_addr_t pt_dma);
@@ -1236,25 +1231,18 @@ static int rk_iommu_probe(struct platform_device *pdev)
 	iommu->reset_disabled = device_property_read_bool(dev,
 					"rockchip,disable-mmu-reset");
 
-	iommu->num_clocks = ARRAY_SIZE(rk_iommu_clocks);
-	iommu->clocks = devm_kcalloc(iommu->dev, iommu->num_clocks,
-				     sizeof(*iommu->clocks), GFP_KERNEL);
-	if (!iommu->clocks)
-		return -ENOMEM;
-
-	for (i = 0; i < iommu->num_clocks; ++i)
-		iommu->clocks[i].id = rk_iommu_clocks[i];
-
 	/*
 	 * iommu clocks should be present for all new devices and devicetrees
 	 * but there are older devicetrees without clocks out in the wild.
 	 * So clocks as optional for the time being.
 	 */
-	err = devm_clk_bulk_get(iommu->dev, iommu->num_clocks, iommu->clocks);
+	err = devm_clk_bulk_get_all(dev, &iommu->clocks);
 	if (err == -ENOENT)
 		iommu->num_clocks = 0;
-	else if (err)
+	else if (err < 0)
 		return err;
+	else
+		iommu->num_clocks = err;
 
 	err = clk_bulk_prepare(iommu->num_clocks, iommu->clocks);
 	if (err)
-- 
2.51.1



From kernel at airkyi.com  Wed Nov 26 00:33:44 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Wed, 26 Nov 2025 16:33:44 +0800
Subject: [PATCH 1/2] dt-bindings: iommu: rockchip: Add support for multiple interface clocks
In-Reply-To: <20251126083345.88-1-kernel@airkyi.com>
References: <20251126083345.88-1-kernel@airkyi.com>
Message-ID: <20251126083345.88-2-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

The iommu found on RK3576 NPU/RKVDEC may contains more than one
interface clock.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---
 .../devicetree/bindings/iommu/rockchip,iommu.yaml         | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/iommu/rockchip,iommu.yaml b/Documentation/devicetree/bindings/iommu/rockchip,iommu.yaml
index 6ce41d11ff5e..11cc22a0b1d3 100644
--- a/Documentation/devicetree/bindings/iommu/rockchip,iommu.yaml
+++ b/Documentation/devicetree/bindings/iommu/rockchip,iommu.yaml
@@ -42,14 +42,22 @@ properties:
     minItems: 1
 
   clocks:
+    minItems: 2
     items:
       - description: Core clock
       - description: Interface clock
+      - description: Interface clock 1
+      - description: Interface clock 2
+      - description: Interface clock 3
 
   clock-names:
+    minItems: 2
     items:
       - const: aclk
       - const: iface
+      - const: iface_1
+      - const: iface_2
+      - const: iface_3
 
   "#iommu-cells":
     const: 0
-- 
2.51.1



From jonas at kwiboo.se  Wed Nov 26 00:40:29 2025
From: jonas at kwiboo.se (Jonas Karlman)
Date: Wed, 26 Nov 2025 09:40:29 +0100
Subject: [PATCH] arm64: dts: rockchip: Enable i2c2 on Orange Pi 3B
In-Reply-To: <20251120-orangepi3-enable-i2c2-v1-1-2e023a74012a@rootcommit.com>
References: <20251120-orangepi3-enable-i2c2-v1-1-2e023a74012a@rootcommit.com>
Message-ID: <d66f81e4-9d9f-4df8-916b-e6f68c85d813@kwiboo.se>

Hi Michael,

On 11/20/2025 8:00 PM, Michael Opdenacker wrote:
> Enable the "i2c2" bus on header pins 3 (I2C_SDA_M1)
> and 5 (I2C2_SCL_M1) of the Orange Pi 3B board.
> 
> As documented on http://www.orangepi.org/img/pi3b/0719-pi3b-19.png
> such pins are the only ones offering I2C functionality
> without conflicting with other SoC blocks.

This is strictly not true, these pins are by default used as GPIO, this
patch change them to use the I2C2 func, something that should normally
be enabled in an overlay.

Functions for these pins:

	func 0		func 1

	GPIO4_B4_d	I2C2_SDA_M1
	GPIO4_B5_d	I2C2_SCL_M1

> 
> Signed-off-by: Michael Opdenacker <michael.opdenacker at rootcommit.com>
> ---
>  arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b.dtsi | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b.dtsi
> index d539570f531e..e2f0ccc6dbe7 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b.dtsi
> @@ -435,6 +435,11 @@ regulator-state-mem {
>  	};
>  };
>  
> +&i2c2 {
> +	pinctrl-0 = <&i2c2m1_xfer>;

pinctrl-names should also be added here.

> +	status = "okay";

As mentioned above, this should be enabled in an DT overlay not in the
board DT.

Regards,
Jonas

> +};
> +
>  &i2s0_8ch {
>  	status = "okay";
>  };
> 
> ---
> base-commit: 8e621c9a337555c914cf1664605edfaa6f839774
> change-id: 20251120-orangepi3-enable-i2c2-fe6d25ec681a
> 
> Best regards,



From michael.opdenacker at rootcommit.com  Wed Nov 26 00:49:16 2025
From: michael.opdenacker at rootcommit.com (Michael Opdenacker)
Date: Wed, 26 Nov 2025 08:49:16 +0000 (UTC)
Subject: [PATCH] arm64: dts: rockchip: Enable i2c2 on Orange Pi 3B
In-Reply-To: <d66f81e4-9d9f-4df8-916b-e6f68c85d813@kwiboo.se>
References: <20251120-orangepi3-enable-i2c2-v1-1-2e023a74012a@rootcommit.com>
 <d66f81e4-9d9f-4df8-916b-e6f68c85d813@kwiboo.se>
Message-ID: <45aac7ef-a5dc-4e93-bb11-30bb88259974@rootcommit.com>

Hi Jonas

Thanks for the review!

On 11/26/25 09:40, Jonas Karlman wrote:
> Hi Michael,
>
> On 11/20/2025 8:00 PM, Michael Opdenacker wrote:
>> Enable the "i2c2" bus on header pins 3 (I2C_SDA_M1)
>> and 5 (I2C2_SCL_M1) of the Orange Pi 3B board.
>>
>> As documented on http://www.orangepi.org/img/pi3b/0719-pi3b-19.png
>> such pins are the only ones offering I2C functionality
>> without conflicting with other SoC blocks.
> This is strictly not true, these pins are by default used as GPIO, this
> patch change them to use the I2C2 func, something that should normally
> be enabled in an overlay.
>
> Functions for these pins:
>
> 	func 0		func 1
>
> 	GPIO4_B4_d	I2C2_SDA_M1
> 	GPIO4_B5_d	I2C2_SCL_M1


Correct. My idea was that GPIOs are easy to get on other pins, and I 
found that I2C2 on such pins would be a convenient default.

>
>> Signed-off-by: Michael Opdenacker <michael.opdenacker at rootcommit.com>
>> ---
>>   arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b.dtsi | 5 +++++
>>   1 file changed, 5 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b.dtsi
>> index d539570f531e..e2f0ccc6dbe7 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b.dtsi
>> +++ b/arch/arm64/boot/dts/rockchip/rk3566-orangepi-3b.dtsi
>> @@ -435,6 +435,11 @@ regulator-state-mem {
>>   	};
>>   };
>>   
>> +&i2c2 {
>> +	pinctrl-0 = <&i2c2m1_xfer>;
> pinctrl-names should also be added here.


Actually, the "pinctrl-names" property is already available in the 
definition of i2c2. That's why I didn't add it again.

>
>> +	status = "okay";
> As mentioned above, this should be enabled in an DT overlay not in the
> board DT.

I don't mind if my patch is removed, no hard feelings :)

BTW, is there a convenient location for sharing overlays like these? 
Some overlays are sometimes tricky to develop, and sharing them with 
others is useful for the community.? I guess the question was asked 
before, but I don't know its answer :)

Thanks again
Cheers
Michael.

-- 
Michael Opdenacker
Root Commit
Yocto Project and OpenEmbedded Training course - Learn by doing:
https://rootcommit.com/training/yocto/



From Ludovic.Desroches at microchip.com  Wed Nov 26 01:29:08 2025
From: Ludovic.Desroches at microchip.com (Ludovic.Desroches at microchip.com)
Date: Wed, 26 Nov 2025 09:29:08 +0000
Subject: [PATCH v6 03/25] drm/gem-dma: Compute dumb-buffer sizes with
 drm_mode_size_dumb()
In-Reply-To: <58b768ad-00fb-4fe5-924c-9cf6ec12f75c@suse.de>
References: <20250821081918.79786-1-tzimmermann@suse.de>
 <20250821081918.79786-4-tzimmermann@suse.de>
 <52600bf4-2c1c-49a6-82c5-b31818141a43@microchip.com>
 <a11c195d-197c-45a4-962a-e2336c7360c2@suse.de>
 <2fbe0d43-67c5-4816-aff0-c23ac1507ec5@microchip.com>
 <58b768ad-00fb-4fe5-924c-9cf6ec12f75c@suse.de>
Message-ID: <09cdbc92-63db-473e-8c5b-5ca9ac3c6a2a@microchip.com>

On 11/26/25 08:40, Thomas Zimmermann wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know 
> the content is safe
> 
> Hi
> 
> Am 26.11.25 um 07:24 schrieb Ludovic.Desroches at microchip.com:
>> On 11/25/25 16:03, Thomas Zimmermann wrote:
>>> EXTERNAL EMAIL: Do not click links or open attachments unless you know
>>> the content is safe
>>>
>>> Hi
>>>
>>> Am 25.11.25 um 15:39 schrieb Ludovic.Desroches at microchip.com:
>>>> On 8/21/25 10:17, Thomas Zimmermann wrote:
>>>>> Call drm_mode_size_dumb() to compute dumb-buffer scanline pitch and
>>>>> buffer size. Align the pitch to a multiple of 8.
>>> I missed a chance to explain it here. :/
>> I was wondering if it was 8-bits or 8-bytes.
>>
>>>>> Push the current calculation into the only direct caller imx. Imx's
>>>>> hardware requires the framebuffer width to be aligned to 8. The
>>>>> driver's current approach is actually incorrect, as it only guarantees
>>>>> this implicitly and requires bpp to be a multiple of 8 already. A
>>>>> later commit will fix this problem by aligning the scanline pitch
>>>>> such that an aligned width still fits into each scanline's memory.
>>>>>
>>>>> A number of other drivers are build on top of gem-dma helpers and
>>>>> implement their own dumb-buffer allocation. These drivers invoke
>>>>> drm_gem_dma_dumb_create_internal(), which is not affected by this
>>>>> commit.
>>>>>
>>>>> v5:
>>>>> - avoid reset of arguments (Tomi)
>>>>>
>>>>> Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
>>>>> Reviewed-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
>>>>> ---
>>>>> ??? drivers/gpu/drm/drm_gem_dma_helper.c???? | 7 +++++--
>>>>> ??? drivers/gpu/drm/imx/ipuv3/imx-drm-core.c | 4 +++-
>>>>> ??? 2 files changed, 8 insertions(+), 3 deletions(-)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/drm_gem_dma_helper.c b/drivers/gpu/drm/
>>>>> drm_gem_dma_helper.c
>>>>> index 4f0320df858f..ab1a70b1d6f1 100644
>>>>> --- a/drivers/gpu/drm/drm_gem_dma_helper.c
>>>>> +++ b/drivers/gpu/drm/drm_gem_dma_helper.c
>>>>> @@ -20,6 +20,7 @@
>>>>> ??? #include <drm/drm.h>
>>>>> ??? #include <drm/drm_device.h>
>>>>> ??? #include <drm/drm_drv.h>
>>>>> +#include <drm/drm_dumb_buffers.h>
>>>>> ??? #include <drm/drm_gem_dma_helper.h>
>>>>> ??? #include <drm/drm_vma_manager.h>
>>>>>
>>>>> @@ -304,9 +305,11 @@ int drm_gem_dma_dumb_create(struct drm_file
>>>>> *file_priv,
>>>>> ????????????????????????? struct drm_mode_create_dumb *args)
>>>>> ??? {
>>>>> ????? struct drm_gem_dma_object *dma_obj;
>>>>> +??? int ret;
>>>>>
>>>>> -??? args->pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
>>>>> -??? args->size = args->pitch * args->height;
>>>>> +??? ret = drm_mode_size_dumb(drm, args, SZ_8, 0);
>>>>> +??? if (ret)
>>>>> +??????????? return ret;
>>>> Hi,
>>>>
>>>> Was it intentional for this change to alter the pitch?
>>> Most hardware does not need the pitch to be of a certain alignment. But
>>> these buffers are possibly shared with other hardware, which sometimes
>>> needs alignment to certain values. Using SZ_8 improves compatible with
>>> that hardware.
>>>
>>>> The alignment requirement has been updated?from 8-bit alignment to
>>>> 64-bit alignment. Since the pitch is expressed in bytes, we should pass
>>>> SZ_1 instead of SZ_8 for hw_patch_align.
>>>>
>>>> For example, for an 850?480 framebuffer at 16 bpp, the pitch should be
>>>> 1700 bytes. With the new alignment, the pitch becomes 1704 bytes.
>>> Many display modes have an 8-byte alignment in their width. 850 pixels
>>> is somewhat of an exception.
>> Indeed, but overlay-type planes are often used to display windows that
>> are not the same size as the screen, and therefore potentially not on
>> 8-bytes aligned.
>>
>>>> Please let me know if you?d like me to submit a fix.
>>> Do you see a bug with your hardware? Unless this creates a real problem,
>>> I'd like to keep it as it is now.
>> Yes, that?s how I noticed this change. I have an application that
>> requests a framebuffer larger than my screen, in this case 850x480 in
>> RGB565 for an 800x480 display. So I have a pitch of 1700 bytes. Now it?s
>> using a pitch of 1704, which shifts my lines.
> 
> Honestly, your application is broken. The ioctl returns the pitch value
> to user space and that's what the program should use. Some hardware has
> hard constraints on the pitch, so you will sooner or later run into the
> same problem again.

Yes, I?m currently trying to find where the pitch information is being 
lost, given that we do correctly retrieve the value provided by the 
kernel after the ioctl.

> 
> Anyway, feel free to submit a patch to call drm_mode_size_dumb() without
> SZ_8. The best value would be 0, so that the function picks a default by
> itself. Since you're at it, maybe also look at patches 4 and 5 of this
> series. They have similar code for other memory managers.

I have no strong opinion about this 8-bytes alignment if it was 
intended. This could potentially break other applications that had been 
working until now, even if it does indeed reveal an issue on the 
application side. And it can result in larger buffers without it 
necessarily being needed.

I'll prepare patches and we'll see where that leads.

Regards,
Ludovic

> 
> Best regards
> Thomas
> 
>>
>> Regards,
>> Ludovic
>>
>>> Best regards
>>> Thomas
>>>
>>>> Regards,
>>>> Ludovic
>>>>
>>>>
>>>>> ????? dma_obj = drm_gem_dma_create_with_handle(file_priv, drm, args-
>>>>>> size,
>>>>> ?????????????????????????????????????????????? &args->handle);
>>>>> diff --git a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c b/drivers/gpu/
>>>>> drm/imx/ipuv3/imx-drm-core.c
>>>>> index ec5fd9a01f1e..af4a30311e18 100644
>>>>> --- a/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
>>>>> +++ b/drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
>>>>> @@ -145,8 +145,10 @@ static int imx_drm_dumb_create(struct drm_file
>>>>> *file_priv,
>>>>> ????? int ret;
>>>>>
>>>>> ????? args->width = ALIGN(width, 8);
>>>>> +??? args->pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
>>>>> +??? args->size = args->pitch * args->height;
>>>>>
>>>>> -??? ret = drm_gem_dma_dumb_create(file_priv, drm, args);
>>>>> +??? ret = drm_gem_dma_dumb_create_internal(file_priv, drm, args);
>>>>> ????? if (ret)
>>>>> ????????????? return ret;
>>>>>
>>> -- 
>>> -- 
>>> Thomas Zimmermann
>>> Graphics Driver Developer
>>> SUSE Software Solutions Germany GmbH
>>> Frankenstr. 146, 90461 N?rnberg, Germany, www.suse.com
>>> GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG
>>> N?rnberg)
>>>
>>>
>>
> 
> -- 
> -- 
> Thomas Zimmermann
> Graphics Driver Developer
> SUSE Software Solutions Germany GmbH
> Frankenstr. 146, 90461 N?rnberg, Germany, www.suse.com
> GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG 
> N?rnberg)
> 
> 


From heikki.krogerus at linux.intel.com  Wed Nov 26 01:42:43 2025
From: heikki.krogerus at linux.intel.com (Heikki Krogerus)
Date: Wed, 26 Nov 2025 11:42:43 +0200
Subject: [PATCH v10 01/11] usb: typec: Add notifier functions
In-Reply-To: <cbb38c08-6937-4b7d-a0b0-d5ca6c17f466@rock-chips.com>
References: <20251120022343.250-2-kernel@airkyi.com>
 <2025112102-laurel-mulch-58e4@gregkh>
 <462ad1bd-7eec-4f26-b383-96b049e14559@rock-chips.com>
 <2025112402-unopposed-polio-e6e9@gregkh>
 <a80483de-518d-45d5-b46a-9b70cca5b236@rock-chips.com>
 <2025112448-brush-porcupine-c851@gregkh>
 <c9cb7b79-37c8-4fef-97a6-7d6b8898f9c4@rock-chips.com>
 <aSV_lQYJPxN7oBM-@kuha>
 <2025112554-uncaring-curator-642a@gregkh>
 <cbb38c08-6937-4b7d-a0b0-d5ca6c17f466@rock-chips.com>
Message-ID: <aSbLkwPG0dUzZvql@kuha>

Wed, Nov 26, 2025 at 09:46:19AM +0800, Chaoyi Chen kirjoitti:
> On 11/25/2025 7:49 PM, Greg Kroah-Hartman wrote:
> >> +static umode_t typec_is_visible(struct kobject *kobj, struct attribute *attr, int n)
> >> +{
> >> +	if (is_typec_port(kobj_to_dev(kobj)->parent))
> > 
> > Why look at the parent?  Doesn't the device have a type that should show
> > this?
> > 
> > Otherwise, looks good to me.
> 
> They have same deivce type "typec_altmode_dev_type".
> The parent device has a different device type to distinguish between
> port device and partner device.

I was already wondering would it make sense to provide separate device
types for the port, and also plug, alternate modes, but I'm not sure
if that's the right thing to do.

There is a plan to register an "altmode" also for the USB4 mode,
which of course is not an alternate mode. So USB4 will definitely need a
separate device type.

So if we supply separate device types for the port, plug and partner
alternate modes, we need to supply separate device types for port, plug
and partner USB4 mode as well.

We certainly can still do that, but I'm just not sure if it makes
sense?

I'll prepare a new version for this and include a separate patch where
instead of defining separate device types for the port and plug
alternate modes I'll just supply helpers is_port_alternate_mode() and
is_plug_alternate_mode().

thanks,

-- 
heikki


From linux.amoon at gmail.com  Wed Nov 26 02:33:37 2025
From: linux.amoon at gmail.com (Anand Moon)
Date: Wed, 26 Nov 2025 16:03:37 +0530
Subject: [RFC v1 1/5] PCI: rockchip: Fix Link Control register offset and
 enable ASPM/CLKREQ
In-Reply-To: <CANAwSgStRZW322X3H_B4wK5CthFube_4MBUBw=U1BRjyRGeu9g@mail.gmail.com>
References: <CANAwSgRHuwoQjr95sXp-X97=L-X3vqUPxjR5=2jNtFZA+4gnwQ@mail.gmail.com>
 <20251120034437.GA2625966@bhelgaas> <CANAwSgStRZW322X3H_B4wK5CthFube_4MBUBw=U1BRjyRGeu9g@mail.gmail.com>
Message-ID: <CANAwSgQMfu2E+oR0Yi9siKA-PZJ_nyDVCQF=Ua7REHcMRDo0Fg@mail.gmail.com>

Hi All,

On Thu, 20 Nov 2025 at 19:28, Anand Moon <linux.amoon at gmail.com> wrote:
>
> Hi Bjorn,
>
> Thanks for your input.
>
> On Thu, 20 Nov 2025 at 09:14, Bjorn Helgaas <helgaas at kernel.org> wrote:
> >
> > On Wed, Nov 19, 2025 at 07:49:06PM +0530, Anand Moon wrote:
> > > On Tue, 18 Nov 2025 at 23:20, Bjorn Helgaas <helgaas at kernel.org> wrote:
> > > > On Mon, Nov 17, 2025 at 11:40:09PM +0530, Anand Moon wrote:
> > > > > As per the RK3399 TRM (Part 2, 17.6.6.1.31), the Link Control register
> > > > > (RC_CONFIG_LC) resides at an offset of 0xd0 within the Root Complex (RC)
> > > > > configuration space, not at the offset of the PCI Express Capability List
> > > > > (0xc0). Following changes correct the register offset to use
> > > > > PCIE_RC_CONFIG_LC (0xd0) to configure link control.
> > > ...
> >
> > > > Don't do two things at once in the same patch.  Fix the register
> > > > offset in one patch.  Actually, as I mentioned at [1], there's a lot
> > > > of fixing to do there, and I'm not even going to consider other
> > > > changes until the #define mess is cleaned up.
> >
> > > > [1] https://lore.kernel.org/r/20251118005056.GA2541796 at bhelgaas
> > >
> > > According to the RK3399 Technical Reference Manual (TRM), and pci_regs.h
> > > already includes the correct, pre-defined offsets for all PCI Express
> > > device types
> > > and their capabilities registers. To avoid overlapping register mappings,
> > > we should explicitly remove the addition of manual offsets within the code.
> >
> > > Here is the example. Is this the correct approach?
> >
> > > -       status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_CR +
> > > PCI_EXP_LNKCTL);
> > > +       status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LC);
> > >         status |= (PCI_EXP_LNKCTL_LBMIE | PCI_EXP_LNKCTL_LABIE);
> > > -       rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_CR +
> > > PCI_EXP_LNKCTL);
> > > +       rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LC);
> >
> > No.  The call should include PCI_EXP_LNKCTL because that's what we
> > grep for when we want to see where Link Control is updated.
> >
> > See my example from [1] above:
> >
> >   rockchip_pcie_read(rockchip, ROCKCHIP_RP_PCIE_CAP + PCI_EXP_DEVCAP)
> >   rockchip_pcie_read(rockchip, ROCKCHIP_RP_PCIE_CAP + PCI_EXP_LNKCTL)
> >
> > You should have a single #define for the offset of the PCIe
> > Capability, e.g., ROCKCHIP_RP_PCIE_CAP.  Every access to registers in
> > that capability would use ROCKCHIP_RP_PCIE_CAP and the relevant
> > PCI_EXP_* offset, e.g., PCI_EXP_DEVCAP, PCI_EXP_DEVCTL,
> > PCI_EXP_DEVSTA, PCI_EXP_LNKCAP, PCI_EXP_LNKCTL, PCI_EXP_LNKSTA, etc.
> >
> I apologize for not fully understanding the issue earlier. I did not
> carefully review your email,
>  which caused me to overlook the required changes.
>
> So, as per the TRM
>
> 17.6.4.5.1 PCI Express Capability List Register
> Propname?PCI Express Capability List Register
> Address?@0xc0
>
> #define PCIE_EP_CONFIG_DID_VID          (PCIE_EP_CONFIG_BASE + 0x00)
> #define PCIE_EP_CONFIG_LCS              (PCIE_EP_CONFIG_BASE + 0xd0)
> #define PCIE_RC_CONFIG_RID_CCR          (PCIE_RC_CONFIG_BASE + 0x08)
> #define PCIE_RC_CONFIG_CR               (PCIE_RC_CONFIG_BASE + 0xc0)
> #define ROCKCHIP_RP_PCIE_CAP            (PCIE_RC_CONFIG_BASE + 0xc0)
> /* Link Control and Status Register */
> #define PCIE_RC_CONFIG_LC               (ROCKCHIP_RP_PCIE_CAP + 0xd0)
> /* Device Control */
> #define PCIE_RC_CONFIG_DC               (ROCKCHIP_RP_PCIE_CAP + 0xc8)
> /* Slot Capability Register */
> #define PCIE_RC_CONFIG_SC               (ROCKCHIP_RP_PCIE_CAP + 0xd4)
> /* Link Control 2 Register */
> #define PCIE_RC_CONFIG_LC2              (ROCKCHIP_RP_PCIE_CAP + 0xf0)
> /* Linkwidth Control Register */
> #define PCIE_RC_CONFIG_LWC              (ROCKCHIP_RP_PCIE_CAP + 0x50)
>
> And then use these like this.
>
> status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LC + PCI_EXP_LNKCTL);
> status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_DC + PCI_EXP_DEVCTL);
> status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_SC + PCI_EXP_DEVCAP);
> status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LC2 + PCI_EXP_LNKCTL2);
> status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LWC + PCI_EXP_LNKCTL);
>
> If you agree that this approach correctly resolves the issue,
> I would prefer to confirm now to prevent further iterative changes
> that might confuse.
>
I was making some changes to the system when my device stopped working,
The lspci utility started crashing with a segmentation fault.

$ sudo lspci -vvv
[sudo] password for alarm:
Segmentation fault         sudo lspci -vvv

# dmesg logs

[   21.225526] rockchip-pm-domain
ff310000.power-management:power-controller: sync_state() pending due
to ff660000.video-codec
[   34.935331] Internal error: synchronous external abort:
0000000096000210 [#1]  SMP
[   34.936027] Modules linked in: 8021q garp mrp stp llc af_alg
brcmfmac_wcc snd_soc_hdmi_codec hantro_vpu dw_hdmi_i2s_audio
dw_hdmi_cec rockchip_rga hci_uart v4l2_vp9 rockchipdrm brcmfmac
brcmutil btqca dw_hdmi_qp snd_soc_simple_card nvme v4l2_h264
snd_soc_audio_graph_card analogix_dp videobuf2_dma_sg v4l2_jpeg
snd_soc_es8316 btbcm snd_soc_simple_card_utils dw_mipi_dsi nvme_core
snd_soc_spdif_tx snd_soc_rockchip_i2s videobuf2_dma_contig
v4l2_mem2mem drm_dp_aux_bus bluetooth snd_soc_core dw_hdmi
videobuf2_memops drm_display_helper panfrost videobuf2_v4l2
snd_compress dwmac_rk videodev ecdh_generic cec snd_pcm_dmaengine
drm_shmem_helper ax88179_178a stmmac_platform drm_client_lib snd_pcm
ecc gpu_sched drm_dma_helper videobuf2_common usbnet rockchip_saradc
stmmac drm_kms_helper pwrseq_core snd_timer reset_gpio
phy_rockchip_pcie mc industrialio_triggered_buffer snd rockchip_dfi
rockchip_thermal coresight_cpu_debug soundcore rtc_rk808 kfifo_buf
pcs_xpcs coresight pcie_rockchip_host sha256 cfg80211 rfkill drm fuse
backlight
[   34.936326]  dm_mod ipv6
[   34.944344] CPU: 1 UID: 0 PID: 796 Comm: lspci Tainted: G   M
         6.18.0-rc7-dirty #1 PREEMPT
[   34.945187] Tainted: [M]=MACHINE_CHECK
[   34.945518] Hardware name: Radxa ROCK Pi 4B+ (DT)
[   34.945932] pstate: 600000c5 (nZCv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[   34.946545] pc : rockchip_pcie_rd_conf+0x178/0x27c [pcie_rockchip_host]
[   34.947138] lr : rockchip_pcie_rd_conf+0x170/0x27c [pcie_rockchip_host]
[   34.947722] sp : ffff8000848b3bc0
[   34.948015] x29: ffff8000848b3bc0 x28: ffff0000013e30c0 x27: 0000000000000000
[   34.948652] x26: 000000000000000f x25: ffff0000013e30c0 x24: 0000000000000040
[   34.949287] x23: 0000000000000040 x22: ffff8000848b3c44 x21: ffff8000848b3bf4
[   34.949920] x20: ffff800082100000 x19: 0000000000000004 x18: 0000000000000000
[   34.950555] x17: 0000000000000000 x16: ffffc37c34322808 x15: 0000000000000000
[   34.951188] x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000
[   34.951821] x11: 0000000000000000 x10: 0000000000000000 x9 : 0000000000000000
[   34.952454] x8 : 0000000000000000 x7 : ffff0000084093c0 x6 : ffff000009cd7000
[   34.953087] x5 : ffff000009cd7800 x4 : ffff800085000000 x3 : 0000000000c00008
[   34.953722] x2 : 000000000080000a x1 : ffff800085c00008 x0 : ffff800085c0000c
[   34.954356] Call trace:
[   34.954576]  rockchip_pcie_rd_conf+0x178/0x27c [pcie_rockchip_host] (P)
[   34.955164]  pci_user_read_config_dword+0x7c/0x120
[   34.955598]  pci_read_config+0xe4/0x2a0
[   34.955944]  sysfs_kf_bin_read+0x7c/0xbc
[   34.956298]  kernfs_fop_read_iter+0xb0/0x1bc
[   34.956679]  vfs_read+0x230/0x320
[   34.956981]  __arm64_sys_pread64+0xac/0xd4
[   34.957350]  invoke_syscall+0x48/0x10c
[   34.957691]  el0_svc_common.constprop.0+0x40/0xe0
[   34.958113]  do_el0_svc+0x1c/0x28
[   34.958414]  el0_svc+0x34/0xec
[   34.958694]  el0t_64_sync_handler+0xa0/0xe4
[   34.959070]  el0t_64_sync+0x198/0x19c
[   34.959405] Code: 52800141 940000ae 7100127f 54fff801 (b9400294)
[   34.959940] ---[ end trace 0000000000000000 ]---
[   34.960349] note: lspci[796] exited with irqs disabled
[   34.960879] note: lspci[796] exited with preempt_count 1

Either I am doing something wrong, or it's broken; I am not getting
this to work.

Upon further investigation, the issue was narrowed down to a specific
modification
that I made locally,

According to section 17.6.6.1.32 of the manual, the Power Limit Value
and Power Limit Scale fields
are part of the Slot Capability Register, not the Device Capability Register.

This assumption led to the segmentation fault because the code was attempting to
access invalid memory addresses.

Do you think these are valid changes? Because this change caused a
freeze on the NVMe device.

$ git  diff drivers/pci/controller/pcie-rockchip-host.c
diff --git a/drivers/pci/controller/pcie-rockchip-host.c
b/drivers/pci/controller/pcie-rockchip-host.c
index ee1822ca01db..743a04e36a1c 100644
--- a/drivers/pci/controller/pcie-rockchip-host.c
+++ b/drivers/pci/controller/pcie-rockchip-host.c
@@ -270,10 +270,10 @@ static void rockchip_pcie_set_power_limit(struct
rockchip_pcie *rockchip)
                power = power / 10;
        }

-       status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_CR +
PCI_EXP_DEVCAP);
+       status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_CR +
PCI_EXP_SLTCAP);
        status |= FIELD_PREP(PCI_EXP_DEVCAP_PWR_VAL, power);
        status |= FIELD_PREP(PCI_EXP_DEVCAP_PWR_SCL, scale);
-       rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_CR +
PCI_EXP_DEVCAP);
+       rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_CR +
PCI_EXP_SLTCAP);
 }

Thanks
-Anand


From ulf.hansson at linaro.org  Wed Nov 26 02:57:04 2025
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Wed, 26 Nov 2025 11:57:04 +0100
Subject: [PATCH v2 0/2] sdhci-of-dwcmshc improvement and fix for Rockchip SoCs
In-Reply-To: <1764113200-237279-1-git-send-email-shawn.lin@rock-chips.com>
References: <1764113200-237279-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <CAPDyKFrO=xft4pHn-hiTRDK4kcEvv_ANfdyT6fmeZBxjc10h1Q@mail.gmail.com>

On Wed, 26 Nov 2025 at 00:27, Shawn Lin <shawn.lin at rock-chips.com> wrote:
>
> This's v2 of these two patches which adds ack-by tags collected and
> rebase on top of linux-next.
>
> The first patch fixes the auto-gating problem of dwc IP when using CQE.
> The second one improves the performance of CQE by reducing CIT.
>
>
> Changes in v2:
> - rebase and add acked-by tag
>
> Shawn Lin (2):
>   mmc: sdhci-of-dwcmshc: Disable internal clock auto gate for Rockchip
>     SOCs
>   mmc: sdhci-of-dwcmshc: reduce CIT for better performance
>
>  drivers/mmc/host/cqhci.h            | 1 +
>  drivers/mmc/host/sdhci-of-dwcmshc.c | 8 +++++++-
>  2 files changed, 8 insertions(+), 1 deletion(-)
>
> --
> 2.7.4
>

The series applied for next, thanks!

Kind regards
Uffe


From gregkh at linuxfoundation.org  Wed Nov 26 03:44:17 2025
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Wed, 26 Nov 2025 12:44:17 +0100
Subject: [PATCH v10 01/11] usb: typec: Add notifier functions
In-Reply-To: <aSbLkwPG0dUzZvql@kuha>
References: <2025112102-laurel-mulch-58e4@gregkh>
 <462ad1bd-7eec-4f26-b383-96b049e14559@rock-chips.com>
 <2025112402-unopposed-polio-e6e9@gregkh>
 <a80483de-518d-45d5-b46a-9b70cca5b236@rock-chips.com>
 <2025112448-brush-porcupine-c851@gregkh>
 <c9cb7b79-37c8-4fef-97a6-7d6b8898f9c4@rock-chips.com>
 <aSV_lQYJPxN7oBM-@kuha>
 <2025112554-uncaring-curator-642a@gregkh>
 <cbb38c08-6937-4b7d-a0b0-d5ca6c17f466@rock-chips.com>
 <aSbLkwPG0dUzZvql@kuha>
Message-ID: <2025112656-dreamland-retreat-2a65@gregkh>

On Wed, Nov 26, 2025 at 11:42:43AM +0200, Heikki Krogerus wrote:
> Wed, Nov 26, 2025 at 09:46:19AM +0800, Chaoyi Chen kirjoitti:
> > On 11/25/2025 7:49 PM, Greg Kroah-Hartman wrote:
> > >> +static umode_t typec_is_visible(struct kobject *kobj, struct attribute *attr, int n)
> > >> +{
> > >> +	if (is_typec_port(kobj_to_dev(kobj)->parent))
> > > 
> > > Why look at the parent?  Doesn't the device have a type that should show
> > > this?
> > > 
> > > Otherwise, looks good to me.
> > 
> > They have same deivce type "typec_altmode_dev_type".
> > The parent device has a different device type to distinguish between
> > port device and partner device.
> 
> I was already wondering would it make sense to provide separate device
> types for the port, and also plug, alternate modes, but I'm not sure
> if that's the right thing to do.
> 
> There is a plan to register an "altmode" also for the USB4 mode,
> which of course is not an alternate mode. So USB4 will definitely need a
> separate device type.
> 
> So if we supply separate device types for the port, plug and partner
> alternate modes, we need to supply separate device types for port, plug
> and partner USB4 mode as well.
> 
> We certainly can still do that, but I'm just not sure if it makes
> sense?
> 
> I'll prepare a new version for this and include a separate patch where
> instead of defining separate device types for the port and plug
> alternate modes I'll just supply helpers is_port_alternate_mode() and
> is_plug_alternate_mode().

That feels like it would be better in the long run as it would be
easier to "match" on the device type.

thanks,

greg k-h


From s.pueschel at pengutronix.de  Wed Nov 26 03:45:08 2025
From: s.pueschel at pengutronix.de (=?utf-8?q?Sven_P=C3=BCschel?=)
Date: Wed, 26 Nov 2025 12:45:08 +0100
Subject: [PATCH] iommu/rockchip: disable fetch dte time limit
Message-ID: <20251126-spu-iommudtefix-v1-1-f90003dbfcc4@pengutronix.de>

From: Simon Xue <xxm at rock-chips.com>

Disable the Bit 31 of the AUTO_GATING iommu register, as it causes
hangups with the RGA3 (Raster Graphics Acceleration 3) peripheral.
The RGA3 register description of the TRM already states that the bit
must be set to 1. The vendor kernel sets the bit unconditionally to
1 to fix VOP (Video Output Processor) screen black issues. This patch
squashes the 2 vendor kernel commits with the following commit messages:

Master fetch data and cpu update page table may work in parallel, may
have the following procedure:

	master                  cpu
	fetch dte               update page tabl
	        |                       |
	(make dte invalid)  <-  zap iotlb entry
	        |                       |
	fetch dte again
	(make dte invalid)  <-  zap iotlb entry
	        |                       |
	fetch dte again
	(make dte invalid)  <-  zap iotlb entry
	        |                       |
	fetch dte again
	(make iommu block)  <-  zap iotlb entry

New iommu version has the above bug, if fetch dte consecutively four
times, then it will be blocked. Fortunately, we can set bit 31 of
register MMU_AUTO_GATING to 1 to make it work as old version which does
not have this issue.

This issue only appears on RV1126 so far, so make a workaround dedicated
to "rockchip,rv1126" machine type.

iommu/rockchip: fix vop blocked and screen black on RK356X and RK3588

RK3568 and RK3588 has the same issue as RV1126/RV1109 that caused by
dte fetch time limit, So we can set BIT(31) of register 0x24 default
to 1 as a workaround.

Signed-off-by: Simon Xue <xxm at rock-chips.com>
Signed-off-by: Sven P?schel <s.pueschel at pengutronix.de>
---
During testing of a newly developed driver for the RGA3 peripheral [1]
(Raster Graphic Acceleration 3) of the RK3588 some sporadic hangs
have been observed. The upstream rockchip-iommu driver is used to handle
the RGA3 IOMMU register space.

After a closer look at the TRM for the RK3588, the RGA3 iommu register
description of the RGA3_MMU_AUTO_GATING register (offset 0x24) mentions
a mmu_bug_fixed_disable bit, which must be set to 1 but defaults to 0.

Looking at the commits in the vendor kernel, the bit is unconditionally
set to 1 and mentions that it fixes a blocked VOP (Video Output
Processor) [3]. Therefore squash the relevant vendor commits
[2] and [3] into a single patch, combine the commit messages and keep
the Signed-off-by line from the original author.

[1] https://lore.kernel.org/all/20251007-spu-rga3-v1-0-36ad85570402 at pengutronix.de/
[2] https://github.com/rockchip-linux/kernel/commit/7f8158fb41b5cc8e738aaeebc3637c50ebd74cae
[3] https://github.com/rockchip-linux/kernel/commit/6a355e5f9a2069a2309e240791bc3aad63b7324e
---
 drivers/iommu/rockchip-iommu.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 0861dd469bd86..2d0dabb0d101a 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -76,6 +76,8 @@
 #define SPAGE_ORDER 12
 #define SPAGE_SIZE (1 << SPAGE_ORDER)
 
+#define DISABLE_FETCH_DTE_TIME_LIMIT BIT(31)
+
  /*
   * Support mapping any size that fits in one page table:
   *   4 KiB to 4 MiB
@@ -930,6 +932,7 @@ static int rk_iommu_enable(struct rk_iommu *iommu)
 	struct iommu_domain *domain = iommu->domain;
 	struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
 	int ret, i;
+	u32 auto_gate;
 
 	ret = clk_bulk_enable(iommu->num_clocks, iommu->clocks);
 	if (ret)
@@ -948,6 +951,11 @@ static int rk_iommu_enable(struct rk_iommu *iommu)
 			       rk_ops->mk_dtentries(rk_domain->dt_dma));
 		rk_iommu_base_command(iommu->bases[i], RK_MMU_CMD_ZAP_CACHE);
 		rk_iommu_write(iommu->bases[i], RK_MMU_INT_MASK, RK_MMU_IRQ_MASK);
+
+		/* Workaround for iommu blocked, BIT(31) default to 1 */
+		auto_gate = rk_iommu_read(iommu->bases[i], RK_MMU_AUTO_GATING);
+		auto_gate |= DISABLE_FETCH_DTE_TIME_LIMIT;
+		rk_iommu_write(iommu->bases[i], RK_MMU_AUTO_GATING, auto_gate);
 	}
 
 	ret = rk_iommu_enable_paging(iommu);

---
base-commit: 30f09200cc4aefbd8385b01e41bde2e4565a6f0e
change-id: 20251126-spu-iommudtefix-cd0c5244c74a

Best regards,
-- 
Sven P?schel <s.pueschel at pengutronix.de>



From chaoyi.chen at rock-chips.com  Wed Nov 26 03:51:33 2025
From: chaoyi.chen at rock-chips.com (Chaoyi Chen)
Date: Wed, 26 Nov 2025 19:51:33 +0800
Subject: [PATCH v10 01/11] usb: typec: Add notifier functions
In-Reply-To: <2025112656-dreamland-retreat-2a65@gregkh>
References: <2025112102-laurel-mulch-58e4@gregkh>
 <462ad1bd-7eec-4f26-b383-96b049e14559@rock-chips.com>
 <2025112402-unopposed-polio-e6e9@gregkh>
 <a80483de-518d-45d5-b46a-9b70cca5b236@rock-chips.com>
 <2025112448-brush-porcupine-c851@gregkh>
 <c9cb7b79-37c8-4fef-97a6-7d6b8898f9c4@rock-chips.com> <aSV_lQYJPxN7oBM-@kuha>
 <2025112554-uncaring-curator-642a@gregkh>
 <cbb38c08-6937-4b7d-a0b0-d5ca6c17f466@rock-chips.com> <aSbLkwPG0dUzZvql@kuha>
 <2025112656-dreamland-retreat-2a65@gregkh>
Message-ID: <e48e1918-8ee0-4ffe-93d5-e096af241f77@rock-chips.com>

On 11/26/2025 7:44 PM, Greg Kroah-Hartman wrote:
> On Wed, Nov 26, 2025 at 11:42:43AM +0200, Heikki Krogerus wrote:
>> Wed, Nov 26, 2025 at 09:46:19AM +0800, Chaoyi Chen kirjoitti:
>>> On 11/25/2025 7:49 PM, Greg Kroah-Hartman wrote:
>>>>> +static umode_t typec_is_visible(struct kobject *kobj, struct attribute *attr, int n)
>>>>> +{
>>>>> +	if (is_typec_port(kobj_to_dev(kobj)->parent))
>>>>
>>>> Why look at the parent?  Doesn't the device have a type that should show
>>>> this?
>>>>
>>>> Otherwise, looks good to me.
>>>
>>> They have same deivce type "typec_altmode_dev_type".
>>> The parent device has a different device type to distinguish between
>>> port device and partner device.
>>
>> I was already wondering would it make sense to provide separate device
>> types for the port, and also plug, alternate modes, but I'm not sure
>> if that's the right thing to do.
>>
>> There is a plan to register an "altmode" also for the USB4 mode,
>> which of course is not an alternate mode. So USB4 will definitely need a
>> separate device type.
>>
>> So if we supply separate device types for the port, plug and partner
>> alternate modes, we need to supply separate device types for port, plug
>> and partner USB4 mode as well.
>>
>> We certainly can still do that, but I'm just not sure if it makes
>> sense?
>>
>> I'll prepare a new version for this and include a separate patch where
>> instead of defining separate device types for the port and plug
>> alternate modes I'll just supply helpers is_port_alternate_mode() and
>> is_plug_alternate_mode().
> 
> That feels like it would be better in the long run as it would be
> easier to "match" on the device type.
>

It make sense. But now can we first use the current "match" device type
operation and then modify them later?

> thanks,
> 
> greg k-h
> 
> 

-- 
Best, 
Chaoyi


From heikki.krogerus at linux.intel.com  Wed Nov 26 04:26:49 2025
From: heikki.krogerus at linux.intel.com (Heikki Krogerus)
Date: Wed, 26 Nov 2025 14:26:49 +0200
Subject: [PATCH v10 01/11] usb: typec: Add notifier functions
In-Reply-To: <e48e1918-8ee0-4ffe-93d5-e096af241f77@rock-chips.com>
References: <2025112402-unopposed-polio-e6e9@gregkh>
 <a80483de-518d-45d5-b46a-9b70cca5b236@rock-chips.com>
 <2025112448-brush-porcupine-c851@gregkh>
 <c9cb7b79-37c8-4fef-97a6-7d6b8898f9c4@rock-chips.com>
 <aSV_lQYJPxN7oBM-@kuha>
 <2025112554-uncaring-curator-642a@gregkh>
 <cbb38c08-6937-4b7d-a0b0-d5ca6c17f466@rock-chips.com>
 <aSbLkwPG0dUzZvql@kuha>
 <2025112656-dreamland-retreat-2a65@gregkh>
 <e48e1918-8ee0-4ffe-93d5-e096af241f77@rock-chips.com>
Message-ID: <aSbyCR-vFo3mvZ3u@kuha>

Wed, Nov 26, 2025 at 07:51:33PM +0800, Chaoyi Chen kirjoitti:
> On 11/26/2025 7:44 PM, Greg Kroah-Hartman wrote:
> > On Wed, Nov 26, 2025 at 11:42:43AM +0200, Heikki Krogerus wrote:
> >> Wed, Nov 26, 2025 at 09:46:19AM +0800, Chaoyi Chen kirjoitti:
> >>> On 11/25/2025 7:49 PM, Greg Kroah-Hartman wrote:
> >>>>> +static umode_t typec_is_visible(struct kobject *kobj, struct attribute *attr, int n)
> >>>>> +{
> >>>>> +	if (is_typec_port(kobj_to_dev(kobj)->parent))
> >>>>
> >>>> Why look at the parent?  Doesn't the device have a type that should show
> >>>> this?
> >>>>
> >>>> Otherwise, looks good to me.
> >>>
> >>> They have same deivce type "typec_altmode_dev_type".
> >>> The parent device has a different device type to distinguish between
> >>> port device and partner device.
> >>
> >> I was already wondering would it make sense to provide separate device
> >> types for the port, and also plug, alternate modes, but I'm not sure
> >> if that's the right thing to do.
> >>
> >> There is a plan to register an "altmode" also for the USB4 mode,
> >> which of course is not an alternate mode. So USB4 will definitely need a
> >> separate device type.
> >>
> >> So if we supply separate device types for the port, plug and partner
> >> alternate modes, we need to supply separate device types for port, plug
> >> and partner USB4 mode as well.
> >>
> >> We certainly can still do that, but I'm just not sure if it makes
> >> sense?
> >>
> >> I'll prepare a new version for this and include a separate patch where
> >> instead of defining separate device types for the port and plug
> >> alternate modes I'll just supply helpers is_port_alternate_mode() and
> >> is_plug_alternate_mode().
> > 
> > That feels like it would be better in the long run as it would be
> > easier to "match" on the device type.
> >
> 
> It make sense. But now can we first use the current "match" device type
> operation and then modify them later?

Let's do this right from the beginning. Here's a version with the
dedicated device types.

-- 
heikki
-------------- next part --------------
>From c0b2afa035cff0788c68869bf454c43eab2b201f Mon Sep 17 00:00:00 2001
From: Heikki Krogerus <heikki.krogerus at linux.intel.com>
Date: Tue, 25 Nov 2025 10:38:04 +0100
Subject: [PATCH v2] usb: typec: Set the bus also for the port and plug altmodes

The port and plug altmodes can't be bound to the altmode
drivers because the altmode drivers are meant for partner
communication using the VDM (vendor defined messages), but
they can still be part of the bus. The bus will make sure
that the normal bus notifications are available also with
the port altmodes.

The previously used common device type for all alternate
modes is replaced with separate dedicated device types for
port, plug, and partner alternate modes.

Signed-off-by: Heikki Krogerus <heikki.krogerus at linux.intel.com>
---

v2: Added the dedicated device types.

---
 drivers/usb/typec/bus.c   | 24 +++++++++++++++++++++++-
 drivers/usb/typec/bus.h   |  8 ++++++--
 drivers/usb/typec/class.c | 33 ++++++++++++++++++++++-----------
 3 files changed, 51 insertions(+), 14 deletions(-)

diff --git a/drivers/usb/typec/bus.c b/drivers/usb/typec/bus.c
index a884cec9ab7e..048c0edf6ca4 100644
--- a/drivers/usb/typec/bus.c
+++ b/drivers/usb/typec/bus.c
@@ -445,7 +445,23 @@ static struct attribute *typec_attrs[] = {
 	&dev_attr_description.attr,
 	NULL
 };
-ATTRIBUTE_GROUPS(typec);
+
+static umode_t typec_is_visible(struct kobject *kobj, struct attribute *attr, int n)
+{
+	if (is_typec_partner_altmode(kobj_to_dev(kobj)))
+		return attr->mode;
+	return 0;
+}
+
+static const struct attribute_group typec_group = {
+	.is_visible = typec_is_visible,
+	.attrs = typec_attrs,
+};
+
+static const struct attribute_group *typec_groups[] = {
+	&typec_group,
+	NULL
+};
 
 static int typec_match(struct device *dev, const struct device_driver *driver)
 {
@@ -453,6 +469,9 @@ static int typec_match(struct device *dev, const struct device_driver *driver)
 	struct typec_altmode *altmode = to_typec_altmode(dev);
 	const struct typec_device_id *id;
 
+	if (!is_typec_partner_altmode(dev))
+		return 0;
+
 	for (id = drv->id_table; id->svid; id++)
 		if (id->svid == altmode->svid)
 			return 1;
@@ -469,6 +488,9 @@ static int typec_uevent(const struct device *dev, struct kobj_uevent_env *env)
 	if (add_uevent_var(env, "MODE=%u", altmode->mode))
 		return -ENOMEM;
 
+	if (!is_typec_partner_altmode(dev))
+		return 0;
+
 	return add_uevent_var(env, "MODALIAS=typec:id%04X", altmode->svid);
 }
 
diff --git a/drivers/usb/typec/bus.h b/drivers/usb/typec/bus.h
index 643b8c81786d..b58e131450d1 100644
--- a/drivers/usb/typec/bus.h
+++ b/drivers/usb/typec/bus.h
@@ -29,8 +29,12 @@ struct altmode {
 #define to_altmode(d) container_of(d, struct altmode, adev)
 
 extern const struct bus_type typec_bus;
-extern const struct device_type typec_altmode_dev_type;
+extern const struct device_type typec_port_altmode_dev_type;
+extern const struct device_type typec_plug_altmode_dev_type;
+extern const struct device_type typec_partner_altmode_dev_type;
 
-#define is_typec_altmode(_dev_) (_dev_->type == &typec_altmode_dev_type)
+#define is_typec_port_altmode(dev) ((dev)->type == &typec_port_altmode_dev_type)
+#define is_typec_plug_altmode(dev) ((dev)->type == &typec_plug_altmode_dev_type)
+#define is_typec_partner_altmode(dev) ((dev)->type == &typec_partner_altmode_dev_type)
 
 #endif /* __USB_TYPEC_ALTMODE_H__ */
diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
index 9b2647cb199b..d6b88317f8a4 100644
--- a/drivers/usb/typec/class.c
+++ b/drivers/usb/typec/class.c
@@ -235,7 +235,7 @@ static int altmode_match(struct device *dev, const void *data)
 	struct typec_altmode *adev = to_typec_altmode(dev);
 	const struct typec_device_id *id = data;
 
-	if (!is_typec_altmode(dev))
+	if (!is_typec_port_altmode(dev))
 		return 0;
 
 	return (adev->svid == id->svid);
@@ -532,15 +532,28 @@ static void typec_altmode_release(struct device *dev)
 	kfree(alt);
 }
 
-const struct device_type typec_altmode_dev_type = {
-	.name = "typec_alternate_mode",
+const struct device_type typec_port_altmode_dev_type = {
+	.name = "typec_port_alternate_mode",
+	.groups = typec_altmode_groups,
+	.release = typec_altmode_release,
+};
+
+const struct device_type typec_plug_altmode_dev_type = {
+	.name = "typec_plug_alternate_mode",
+	.groups = typec_altmode_groups,
+	.release = typec_altmode_release,
+};
+
+const struct device_type typec_partner_altmode_dev_type = {
+	.name = "typec_partner_alternate_mode",
 	.groups = typec_altmode_groups,
 	.release = typec_altmode_release,
 };
 
 static struct typec_altmode *
 typec_register_altmode(struct device *parent,
-		       const struct typec_altmode_desc *desc)
+		       const struct typec_altmode_desc *desc,
+		       const struct device_type *type)
 {
 	unsigned int id = altmode_id_get(parent);
 	bool is_port = is_typec_port(parent);
@@ -575,7 +588,7 @@ typec_register_altmode(struct device *parent,
 
 	alt->adev.dev.parent = parent;
 	alt->adev.dev.groups = alt->groups;
-	alt->adev.dev.type = &typec_altmode_dev_type;
+	alt->adev.dev.type = type;
 	dev_set_name(&alt->adev.dev, "%s.%u", dev_name(parent), id);
 
 	get_device(alt->adev.dev.parent);
@@ -584,9 +597,7 @@ typec_register_altmode(struct device *parent,
 	if (!is_port)
 		typec_altmode_set_partner(alt);
 
-	/* The partners are bind to drivers */
-	if (is_typec_partner(parent))
-		alt->adev.dev.bus = &typec_bus;
+	alt->adev.dev.bus = &typec_bus;
 
 	/* Plug alt modes need a class to generate udev events. */
 	if (is_typec_plug(parent))
@@ -963,7 +974,7 @@ struct typec_altmode *
 typec_partner_register_altmode(struct typec_partner *partner,
 			       const struct typec_altmode_desc *desc)
 {
-	return typec_register_altmode(&partner->dev, desc);
+	return typec_register_altmode(&partner->dev, desc, &typec_partner_altmode_dev_type);
 }
 EXPORT_SYMBOL_GPL(typec_partner_register_altmode);
 
@@ -1193,7 +1204,7 @@ struct typec_altmode *
 typec_plug_register_altmode(struct typec_plug *plug,
 			    const struct typec_altmode_desc *desc)
 {
-	return typec_register_altmode(&plug->dev, desc);
+	return typec_register_altmode(&plug->dev, desc, &typec_plug_altmode_dev_type);
 }
 EXPORT_SYMBOL_GPL(typec_plug_register_altmode);
 
@@ -2493,7 +2504,7 @@ typec_port_register_altmode(struct typec_port *port,
 		return ERR_CAST(retimer);
 	}
 
-	adev = typec_register_altmode(&port->dev, desc);
+	adev = typec_register_altmode(&port->dev, desc, &typec_port_altmode_dev_type);
 	if (IS_ERR(adev)) {
 		typec_retimer_put(retimer);
 		typec_mux_put(mux);
-- 
2.50.1


From amadeus at jmu.edu.cn  Wed Nov 26 04:40:09 2025
From: amadeus at jmu.edu.cn (Chukun Pan)
Date: Wed, 26 Nov 2025 20:40:09 +0800
Subject: [PATCH 1/1] phy: rockchip: naneng-combphy: use existing DT property check for rk3528
In-Reply-To: <20250910122000.951100-1-amadeus@jmu.edu.cn>
References: <20250910122000.951100-1-amadeus@jmu.edu.cn>
Message-ID: <20251126124009.551884-1-amadeus@jmu.edu.cn>

Hi,

> The naneng-combphy driver already has DT property checks for
> "rockchip,enable-ssc" and "rockchip,ext-refclk", use it for
> the rk3528_combphy_cfg. Also aligned the indentation of the
> rk3528_combphy_grfcfgs parameters (using tabs).

Are there still any issues with this patch?

Thanks,
Chukun


From naoki at radxa.com  Wed Nov 26 05:30:06 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Wed, 26 Nov 2025 22:30:06 +0900
Subject: [PATCH 0/6] PCI: dwc: Revert Link Up IRQ support
In-Reply-To: <aSRli_Mb6qoQ9TZO@ryzen>
References: <20251111105100.869997-8-cassel@kernel.org>
 <mt7miqkipr4dvxemftq6octxqzauueln252ncrcwy6i2t7wfhi@jtwokeilhwsi>
 <aSRli_Mb6qoQ9TZO@ryzen>
Message-ID: <7667E818D7D31A4E+cf7c83d4-b99c-469d-8d46-588fc95b843f@radxa.com>

Hi Niklas,

I apologize for the delayed response.

On 11/24/25 23:02, Niklas Cassel wrote:
> On Mon, Nov 24, 2025 at 06:07:44PM +0530, Manivannan Sadhasivam wrote:
>> While I suggested to revert the link up IRQ patch for rockchip earlier, I didn't
>> expect to drop the support for Qcom. The reason is, on Qcom SoCs, we have not
>> seen a case where people connect a random PCIe switch and saw failures. Most of
>> the Qcom usecases were around the M.2 and other proprietary connectors. There is
>> only one in-house PCIe switch that is being actively used in our products, but
>> so far, none of the bootloaders have turned them ON before kernel booting. So
>> kernel relies on the newly merged pwrctrl driver to do the job. Even though it
>> also suffers from the same resource allocation issue, this series won't help in
>> any way as pwrctrl core performs rescan after the switch power ON, and by that
>> time, it will be very late anyway.
>>
>> So I'm happy to take the rockhip patches from this series as they fix the real
>> issue that people have reported. But once the pwrctrl rework series gets merged,
>> and the rockchip drivers support them, we can bring back the reverted changes.
> 
> FUKAUMI Naoki, just to confirm:
> 
> Neither my suggested approach:
> https://lore.kernel.org/linux-pci/aRHdeVCY3rRmxe80 at ryzen/
> 
> nor Shawn's suggested approach:
> https://lore.kernel.org/linux-pci/dc932773-af5b-4af7-a0d0-8cc72dfbd3c7 at rock-chips.com/
> 
> worked for you?

Yes, I re-tested the two methods mentioned above, separately, on 
v6.18-rc7, but neither of them resolved the issue in my environment 
(ROCK 5C + ASM2806).

> If so, I don't see many alternative but for Mani to apply patch 1 and
> patch 2 from this series.

I believe applying patch 1 and patch 2 should be sufficient.

----

Incidentally, (probably) while applying patch 1 and patch 2, I have 
encountered the following issue several times:

[    1.709614] pcieport 0004:41:00.0: of_irq_parse_pci: failed with rc=134
[    1.710208] pcieport 0004:41:00.0: Unable to change power state from 
D3cold to D0, device inaccessible

I am still investigating this matter, and the conditions under which it 
occurs are currently unknown.

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> Kind regards,
> Niklas
> 



From mani at kernel.org  Wed Nov 26 05:54:15 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Wed, 26 Nov 2025 19:24:15 +0530
Subject: [PATCH 0/6] PCI: dwc: Revert Link Up IRQ support
In-Reply-To: <7667E818D7D31A4E+cf7c83d4-b99c-469d-8d46-588fc95b843f@radxa.com>
References: <20251111105100.869997-8-cassel@kernel.org>
 <mt7miqkipr4dvxemftq6octxqzauueln252ncrcwy6i2t7wfhi@jtwokeilhwsi>
 <aSRli_Mb6qoQ9TZO@ryzen>
 <7667E818D7D31A4E+cf7c83d4-b99c-469d-8d46-588fc95b843f@radxa.com>
Message-ID: <pbcemex3hdu4ryw2r7iy6xxt3chwaytlm2eina7mm4ukjfcagt@x4777z7ral26>

On Wed, Nov 26, 2025 at 10:30:06PM +0900, FUKAUMI Naoki wrote:
> Hi Niklas,
> 
> I apologize for the delayed response.
> 
> On 11/24/25 23:02, Niklas Cassel wrote:
> > On Mon, Nov 24, 2025 at 06:07:44PM +0530, Manivannan Sadhasivam wrote:
> > > While I suggested to revert the link up IRQ patch for rockchip earlier, I didn't
> > > expect to drop the support for Qcom. The reason is, on Qcom SoCs, we have not
> > > seen a case where people connect a random PCIe switch and saw failures. Most of
> > > the Qcom usecases were around the M.2 and other proprietary connectors. There is
> > > only one in-house PCIe switch that is being actively used in our products, but
> > > so far, none of the bootloaders have turned them ON before kernel booting. So
> > > kernel relies on the newly merged pwrctrl driver to do the job. Even though it
> > > also suffers from the same resource allocation issue, this series won't help in
> > > any way as pwrctrl core performs rescan after the switch power ON, and by that
> > > time, it will be very late anyway.
> > > 
> > > So I'm happy to take the rockhip patches from this series as they fix the real
> > > issue that people have reported. But once the pwrctrl rework series gets merged,
> > > and the rockchip drivers support them, we can bring back the reverted changes.
> > 
> > FUKAUMI Naoki, just to confirm:
> > 
> > Neither my suggested approach:
> > https://lore.kernel.org/linux-pci/aRHdeVCY3rRmxe80 at ryzen/
> > 
> > nor Shawn's suggested approach:
> > https://lore.kernel.org/linux-pci/dc932773-af5b-4af7-a0d0-8cc72dfbd3c7 at rock-chips.com/
> > 
> > worked for you?
> 
> Yes, I re-tested the two methods mentioned above, separately, on v6.18-rc7,
> but neither of them resolved the issue in my environment (ROCK 5C +
> ASM2806).
> 
> > If so, I don't see many alternative but for Mani to apply patch 1 and
> > patch 2 from this series.
> 
> I believe applying patch 1 and patch 2 should be sufficient.
> 
> ----
> 
> Incidentally, (probably) while applying patch 1 and patch 2, I have
> encountered the following issue several times:
>

Do you see the below issue *after* applying the patches? I don't know how to
interpret "while applying".
 
> [    1.709614] pcieport 0004:41:00.0: of_irq_parse_pci: failed with rc=134
> [    1.710208] pcieport 0004:41:00.0: Unable to change power state from
> D3cold to D0, device inaccessible
> 

Looks like the device was seen during bus scan, but then it went down
afterwards.

- Mani

-- 
????????? ????????


From helgaas at kernel.org  Wed Nov 26 06:39:52 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Wed, 26 Nov 2025 08:39:52 -0600
Subject: [RFC v1 1/5] PCI: rockchip: Fix Link Control register offset and
 enable ASPM/CLKREQ
In-Reply-To: <CANAwSgQMfu2E+oR0Yi9siKA-PZJ_nyDVCQF=Ua7REHcMRDo0Fg@mail.gmail.com>
Message-ID: <20251126143952.GA2825566@bhelgaas>

On Wed, Nov 26, 2025 at 04:03:37PM +0530, Anand Moon wrote:
> On Thu, 20 Nov 2025 at 19:28, Anand Moon <linux.amoon at gmail.com> wrote:
> > On Thu, 20 Nov 2025 at 09:14, Bjorn Helgaas <helgaas at kernel.org> wrote:
> > > On Wed, Nov 19, 2025 at 07:49:06PM +0530, Anand Moon wrote:
> > > > On Tue, 18 Nov 2025 at 23:20, Bjorn Helgaas <helgaas at kernel.org> wrote:
> > > > > On Mon, Nov 17, 2025 at 11:40:09PM +0530, Anand Moon wrote:
> > > > > > As per the RK3399 TRM (Part 2, 17.6.6.1.31), the Link Control register
> > > > > > (RC_CONFIG_LC) resides at an offset of 0xd0 within the Root Complex (RC)
> > > > > > configuration space, not at the offset of the PCI Express Capability List
> > > > > > (0xc0). Following changes correct the register offset to use
> > > > > > PCIE_RC_CONFIG_LC (0xd0) to configure link control.
> > > > ...
> > >
> > > > > Don't do two things at once in the same patch.  Fix the register
> > > > > offset in one patch.  Actually, as I mentioned at [1], there's a lot
> > > > > of fixing to do there, and I'm not even going to consider other
> > > > > changes until the #define mess is cleaned up.
> > >
> > > > > [1] https://lore.kernel.org/r/20251118005056.GA2541796 at bhelgaas
> > > >
> > > > According to the RK3399 Technical Reference Manual (TRM), and pci_regs.h
> > > > already includes the correct, pre-defined offsets for all PCI Express
> > > > device types
> > > > and their capabilities registers. To avoid overlapping register mappings,
> > > > we should explicitly remove the addition of manual offsets within the code.
> > >
> > > > Here is the example. Is this the correct approach?
> > >
> > > > -       status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_CR +
> > > > PCI_EXP_LNKCTL);
> > > > +       status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LC);
> > > >         status |= (PCI_EXP_LNKCTL_LBMIE | PCI_EXP_LNKCTL_LABIE);
> > > > -       rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_CR +
> > > > PCI_EXP_LNKCTL);
> > > > +       rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LC);
> > >
> > > No.  The call should include PCI_EXP_LNKCTL because that's what we
> > > grep for when we want to see where Link Control is updated.
> > >
> > > See my example from [1] above:
> > >
> > >   rockchip_pcie_read(rockchip, ROCKCHIP_RP_PCIE_CAP + PCI_EXP_DEVCAP)
> > >   rockchip_pcie_read(rockchip, ROCKCHIP_RP_PCIE_CAP + PCI_EXP_LNKCTL)
> > >
> > > You should have a single #define for the offset of the PCIe
> > > Capability, e.g., ROCKCHIP_RP_PCIE_CAP.  Every access to registers in
> > > that capability would use ROCKCHIP_RP_PCIE_CAP and the relevant
> > > PCI_EXP_* offset, e.g., PCI_EXP_DEVCAP, PCI_EXP_DEVCTL,
> > > PCI_EXP_DEVSTA, PCI_EXP_LNKCAP, PCI_EXP_LNKCTL, PCI_EXP_LNKSTA, etc.
> > >
> > I apologize for not fully understanding the issue earlier. I did not
> > carefully review your email,
> >  which caused me to overlook the required changes.
> >
> > So, as per the TRM
> >
> > 17.6.4.5.1 PCI Express Capability List Register
> > Propname?PCI Express Capability List Register
> > Address?@0xc0
> >
> > #define PCIE_EP_CONFIG_DID_VID          (PCIE_EP_CONFIG_BASE + 0x00)
> > #define PCIE_EP_CONFIG_LCS              (PCIE_EP_CONFIG_BASE + 0xd0)
> > #define PCIE_RC_CONFIG_RID_CCR          (PCIE_RC_CONFIG_BASE + 0x08)
> > #define PCIE_RC_CONFIG_CR               (PCIE_RC_CONFIG_BASE + 0xc0)
> > #define ROCKCHIP_RP_PCIE_CAP            (PCIE_RC_CONFIG_BASE + 0xc0)
> > /* Link Control and Status Register */
> > #define PCIE_RC_CONFIG_LC               (ROCKCHIP_RP_PCIE_CAP + 0xd0)
> > /* Device Control */
> > #define PCIE_RC_CONFIG_DC               (ROCKCHIP_RP_PCIE_CAP + 0xc8)
> > /* Slot Capability Register */
> > #define PCIE_RC_CONFIG_SC               (ROCKCHIP_RP_PCIE_CAP + 0xd4)
> > /* Link Control 2 Register */
> > #define PCIE_RC_CONFIG_LC2              (ROCKCHIP_RP_PCIE_CAP + 0xf0)
> > /* Linkwidth Control Register */
> > #define PCIE_RC_CONFIG_LWC              (ROCKCHIP_RP_PCIE_CAP + 0x50)
> >
> > And then use these like this.
> >
> > status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LC + PCI_EXP_LNKCTL);
> > status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_DC + PCI_EXP_DEVCTL);
> > status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_SC + PCI_EXP_DEVCAP);
> > status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LC2 + PCI_EXP_LNKCTL2);
> > status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LWC + PCI_EXP_LNKCTL);
> >
> > If you agree that this approach correctly resolves the issue,
> > I would prefer to confirm now to prevent further iterative changes
> > that might confuse.
> >
> I was making some changes to the system when my device stopped working,
> The lspci utility started crashing with a segmentation fault.
> 
> $ sudo lspci -vvv
> [sudo] password for alarm:
> Segmentation fault         sudo lspci -vvv
> 
> # dmesg logs
> 
> [   21.225526] rockchip-pm-domain
> ff310000.power-management:power-controller: sync_state() pending due
> to ff660000.video-codec
> [   34.935331] Internal error: synchronous external abort:
> 0000000096000210 [#1]  SMP
> [   34.936027] Modules linked in: 8021q garp mrp stp llc af_alg
> brcmfmac_wcc snd_soc_hdmi_codec hantro_vpu dw_hdmi_i2s_audio
> dw_hdmi_cec rockchip_rga hci_uart v4l2_vp9 rockchipdrm brcmfmac
> brcmutil btqca dw_hdmi_qp snd_soc_simple_card nvme v4l2_h264
> snd_soc_audio_graph_card analogix_dp videobuf2_dma_sg v4l2_jpeg
> snd_soc_es8316 btbcm snd_soc_simple_card_utils dw_mipi_dsi nvme_core
> snd_soc_spdif_tx snd_soc_rockchip_i2s videobuf2_dma_contig
> v4l2_mem2mem drm_dp_aux_bus bluetooth snd_soc_core dw_hdmi
> videobuf2_memops drm_display_helper panfrost videobuf2_v4l2
> snd_compress dwmac_rk videodev ecdh_generic cec snd_pcm_dmaengine
> drm_shmem_helper ax88179_178a stmmac_platform drm_client_lib snd_pcm
> ecc gpu_sched drm_dma_helper videobuf2_common usbnet rockchip_saradc
> stmmac drm_kms_helper pwrseq_core snd_timer reset_gpio
> phy_rockchip_pcie mc industrialio_triggered_buffer snd rockchip_dfi
> rockchip_thermal coresight_cpu_debug soundcore rtc_rk808 kfifo_buf
> pcs_xpcs coresight pcie_rockchip_host sha256 cfg80211 rfkill drm fuse
> backlight
> [   34.936326]  dm_mod ipv6
> [   34.944344] CPU: 1 UID: 0 PID: 796 Comm: lspci Tainted: G   M
>          6.18.0-rc7-dirty #1 PREEMPT
> [   34.945187] Tainted: [M]=MACHINE_CHECK
> [   34.945518] Hardware name: Radxa ROCK Pi 4B+ (DT)
> [   34.945932] pstate: 600000c5 (nZCv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> [   34.946545] pc : rockchip_pcie_rd_conf+0x178/0x27c [pcie_rockchip_host]
> [   34.947138] lr : rockchip_pcie_rd_conf+0x170/0x27c [pcie_rockchip_host]
> [   34.947722] sp : ffff8000848b3bc0
> [   34.948015] x29: ffff8000848b3bc0 x28: ffff0000013e30c0 x27: 0000000000000000
> [   34.948652] x26: 000000000000000f x25: ffff0000013e30c0 x24: 0000000000000040
> [   34.949287] x23: 0000000000000040 x22: ffff8000848b3c44 x21: ffff8000848b3bf4
> [   34.949920] x20: ffff800082100000 x19: 0000000000000004 x18: 0000000000000000
> [   34.950555] x17: 0000000000000000 x16: ffffc37c34322808 x15: 0000000000000000
> [   34.951188] x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000
> [   34.951821] x11: 0000000000000000 x10: 0000000000000000 x9 : 0000000000000000
> [   34.952454] x8 : 0000000000000000 x7 : ffff0000084093c0 x6 : ffff000009cd7000
> [   34.953087] x5 : ffff000009cd7800 x4 : ffff800085000000 x3 : 0000000000c00008
> [   34.953722] x2 : 000000000080000a x1 : ffff800085c00008 x0 : ffff800085c0000c
> [   34.954356] Call trace:
> [   34.954576]  rockchip_pcie_rd_conf+0x178/0x27c [pcie_rockchip_host] (P)
> [   34.955164]  pci_user_read_config_dword+0x7c/0x120
> [   34.955598]  pci_read_config+0xe4/0x2a0
> [   34.955944]  sysfs_kf_bin_read+0x7c/0xbc
> [   34.956298]  kernfs_fop_read_iter+0xb0/0x1bc
> [   34.956679]  vfs_read+0x230/0x320
> [   34.956981]  __arm64_sys_pread64+0xac/0xd4
> [   34.957350]  invoke_syscall+0x48/0x10c
> [   34.957691]  el0_svc_common.constprop.0+0x40/0xe0
> [   34.958113]  do_el0_svc+0x1c/0x28
> [   34.958414]  el0_svc+0x34/0xec
> [   34.958694]  el0t_64_sync_handler+0xa0/0xe4
> [   34.959070]  el0t_64_sync+0x198/0x19c
> [   34.959405] Code: 52800141 940000ae 7100127f 54fff801 (b9400294)
> [   34.959940] ---[ end trace 0000000000000000 ]---
> [   34.960349] note: lspci[796] exited with irqs disabled
> [   34.960879] note: lspci[796] exited with preempt_count 1
> 
> Either I am doing something wrong, or it's broken; I am not getting
> this to work.
> 
> Upon further investigation, the issue was narrowed down to a
> specific modification that I made locally,
> 
> According to section 17.6.6.1.32 of the manual, the Power Limit
> Value and Power Limit Scale fields are part of the Slot Capability
> Register, not the Device Capability Register.
> 
> This assumption led to the segmentation fault because the code was
> attempting to access invalid memory addresses.
> 
> Do you think these are valid changes? Because this change caused a
> freeze on the NVMe device.

I'm not surprised that there might be issues related to registers in
the PCIe Capability.  I'm actually surprised that this driver works at
all, given the incredible mess.

So I'm not going to bother trying to fix this piecemeal as with the
patch below.  Every single access to DEVCAP/DEVCTL/DEVSTA,
SLTCAP/SLTCTL/SLTSTA, etc needs to be made rational.  There's a single
base address that works for all of them because the Rockchip register
layout matches the PCIe Capability layout.  I've already outlined in
detail what needs to be done.  I'll try to find time to actually
implement this, but it probably won't be for at least a few days.

> $ git  diff drivers/pci/controller/pcie-rockchip-host.c
> diff --git a/drivers/pci/controller/pcie-rockchip-host.c
> b/drivers/pci/controller/pcie-rockchip-host.c
> index ee1822ca01db..743a04e36a1c 100644
> --- a/drivers/pci/controller/pcie-rockchip-host.c
> +++ b/drivers/pci/controller/pcie-rockchip-host.c
> @@ -270,10 +270,10 @@ static void rockchip_pcie_set_power_limit(struct
> rockchip_pcie *rockchip)
>                 power = power / 10;
>         }
> 
> -       status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_CR +
> PCI_EXP_DEVCAP);
> +       status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_CR +
> PCI_EXP_SLTCAP);
>         status |= FIELD_PREP(PCI_EXP_DEVCAP_PWR_VAL, power);
>         status |= FIELD_PREP(PCI_EXP_DEVCAP_PWR_SCL, scale);
> -       rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_CR +
> PCI_EXP_DEVCAP);
> +       rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_CR +
> PCI_EXP_SLTCAP);
>  }
> 
> Thanks
> -Anand


From michael.riesch at collabora.com  Wed Nov 26 12:27:29 2025
From: michael.riesch at collabora.com (Michael Riesch)
Date: Wed, 26 Nov 2025 21:27:29 +0100
Subject: [PATCH next] media: rockchip: rkcif: fix off by one bugs
In-Reply-To: <aR17UkYsfAxCZ4fe@stanley.mountain>
References: <aR17UkYsfAxCZ4fe@stanley.mountain>
Message-ID: <f53af05d-ac10-43d5-8563-dadafbeb2379@collabora.com>

Hi Dan,

Thanks for the patch, good catch!

On 11/19/25 09:09, Dan Carpenter wrote:
> Change these comparisons from > vs >= to avoid accessing one element
> beyond the end of the arrays.
> 
> Fixes: 1f2353f5a1af ("media: rockchip: rkcif: add support for rk3568 vicap mipi capture")
> Signed-off-by: Dan Carpenter <dan.carpenter at linaro.org>

Reviewed-by: Michael Riesch <michael.riesch at collabora.com>

Best regards,
Michael

> ---
>  .../media/platform/rockchip/rkcif/rkcif-capture-mipi.c | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.c b/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.c
> index 1b81bcc067ef..a933df682acc 100644
> --- a/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.c
> +++ b/drivers/media/platform/rockchip/rkcif/rkcif-capture-mipi.c
> @@ -489,8 +489,8 @@ static inline unsigned int rkcif_mipi_get_reg(struct rkcif_interface *interface,
>  
>  	block = interface->index - RKCIF_MIPI_BASE;
>  
> -	if (WARN_ON_ONCE(block > RKCIF_MIPI_MAX - RKCIF_MIPI_BASE) ||
> -	    WARN_ON_ONCE(index > RKCIF_MIPI_REGISTER_MAX))
> +	if (WARN_ON_ONCE(block >= RKCIF_MIPI_MAX - RKCIF_MIPI_BASE) ||
> +	    WARN_ON_ONCE(index >= RKCIF_MIPI_REGISTER_MAX))
>  		return RKCIF_REGISTER_NOTSUPPORTED;
>  
>  	offset = rkcif->match_data->mipi->blocks[block].offset;
> @@ -510,9 +510,9 @@ static inline unsigned int rkcif_mipi_id_get_reg(struct rkcif_stream *stream,
>  	block = stream->interface->index - RKCIF_MIPI_BASE;
>  	id = stream->id;
>  
> -	if (WARN_ON_ONCE(block > RKCIF_MIPI_MAX - RKCIF_MIPI_BASE) ||
> -	    WARN_ON_ONCE(id > RKCIF_ID_MAX) ||
> -	    WARN_ON_ONCE(index > RKCIF_MIPI_ID_REGISTER_MAX))
> +	if (WARN_ON_ONCE(block >= RKCIF_MIPI_MAX - RKCIF_MIPI_BASE) ||
> +	    WARN_ON_ONCE(id >= RKCIF_ID_MAX) ||
> +	    WARN_ON_ONCE(index >= RKCIF_MIPI_ID_REGISTER_MAX))
>  		return RKCIF_REGISTER_NOTSUPPORTED;
>  
>  	offset = rkcif->match_data->mipi->blocks[block].offset;



From michael.riesch at collabora.com  Wed Nov 26 12:57:31 2025
From: michael.riesch at collabora.com (Michael Riesch)
Date: Wed, 26 Nov 2025 21:57:31 +0100
Subject: [PATCH v2 2/3] media: rockchip: add driver for the rockchip mipi
 csi-2 receiver
In-Reply-To: <aRzub5Ak6DZpO5f/@lizhi-Precision-Tower-5810>
References: <20251114-rockchip-mipi-receiver-v2-0-eb9b43377fc4@collabora.com>
 <20251114-rockchip-mipi-receiver-v2-2-eb9b43377fc4@collabora.com>
 <aRyplYZOrGsSxSlp@lizhi-Precision-Tower-5810>
 <554971e1-6fde-4b2c-a2de-fe178358a4e3@collabora.com>
 <aRzub5Ak6DZpO5f/@lizhi-Precision-Tower-5810>
Message-ID: <87049b4c-df7d-454b-a7f4-073975a7ee94@collabora.com>

Hi Frank,

On 11/18/25 23:08, Frank Li wrote:
> On Tue, Nov 18, 2025 at 07:59:14PM +0100, Michael Riesch wrote:
>> Hi Frank,
>>
>> On 11/18/25 18:15, Frank Li wrote:
>>> On Tue, Nov 18, 2025 at 12:12:26PM +0100, Michael Riesch via B4 Relay wrote:
>>>> From: Michael Riesch <michael.riesch at collabora.com>
>>>>
>>>> [...]
>>>> +#define CSI2HOST_N_LANES     0x04
>>>> +#define CSI2HOST_CSI2_RESETN 0x10
>>>> +#define CSI2HOST_PHY_STATE   0x14
>>>> +#define CSI2HOST_ERR1	     0x20
>>>> +#define CSI2HOST_ERR2	     0x24
>>>> +#define CSI2HOST_MSK1	     0x28
>>>> +#define CSI2HOST_MSK2	     0x2c
>>>> +#define CSI2HOST_CONTROL     0x40
>>>
>>> Look like that is designware CSI2 controller, can we build common library
>>> for all dwc csi2 controller, instead of every vendor create individual one.
>>>
>>> First try at
>>> https://lore.kernel.org/linux-media/20250821-95_cam-v3-21-c9286fbb34b9 at nxp.com/
>>>
>>> Toshiba have similar patch
>>> https://lore.kernel.org/linux-media/aPZd39riAxqfw3mT at lizhi-Precision-Tower-5810/
>>>
>>> Frank
>>
>> This has been discussed already a while ago:
>> https://lore.kernel.org/all/20250507083837.GA11152 at pendragon.ideasonboard.com/
> 
> https://lore.kernel.org/all/20250702093806.GF16835 at pendragon.ideasonboard.com/
> 
> Laurent Pinchart prevent imx93 DWC CSI2 driver at Jul, your discussion at
> May, I think Laurent Pinchart change the mind.
> 
> We can choose not base on imx6, but we should create a standard dwc2 under
> drivers/media/platform/synopsys/

In principle, I agree with refactoring out common code. However, I am
not sure how similar these IP cores really are. Again, the answer I
received from Rockchip states that this is *not* a Synopsys IP core.

Can you maybe test whether the Rockchip MIPI CSI-2 Receiver driver in
this series works on your hardware? Then we will know if (and what)
parts can be shared.

Best regards,
Michael


> 
> Laurent Pinchart:
> 
> 	Can you provide direction?
> 
> Frank
> 
>>
>> Bottom line from Laurent:
>>
>> "Let's keep this driver Rockchip-specific then. Thanks for checking."
>>
>>>  [...]
>> Best regards,
>> Michael



From naoki at radxa.com  Wed Nov 26 15:35:37 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Thu, 27 Nov 2025 08:35:37 +0900
Subject: [PATCH 0/6] PCI: dwc: Revert Link Up IRQ support
In-Reply-To: <pbcemex3hdu4ryw2r7iy6xxt3chwaytlm2eina7mm4ukjfcagt@x4777z7ral26>
References: <20251111105100.869997-8-cassel@kernel.org>
 <mt7miqkipr4dvxemftq6octxqzauueln252ncrcwy6i2t7wfhi@jtwokeilhwsi>
 <aSRli_Mb6qoQ9TZO@ryzen>
 <7667E818D7D31A4E+cf7c83d4-b99c-469d-8d46-588fc95b843f@radxa.com>
 <pbcemex3hdu4ryw2r7iy6xxt3chwaytlm2eina7mm4ukjfcagt@x4777z7ral26>
Message-ID: <A528C970F1441854+e82f1fbb-b82e-436c-9336-7b34f515b67b@radxa.com>

Hi Mani,

On 11/26/25 22:54, Manivannan Sadhasivam wrote:
> On Wed, Nov 26, 2025 at 10:30:06PM +0900, FUKAUMI Naoki wrote:
>> Hi Niklas,
>>
>> I apologize for the delayed response.
>>
>> On 11/24/25 23:02, Niklas Cassel wrote:
>>> On Mon, Nov 24, 2025 at 06:07:44PM +0530, Manivannan Sadhasivam wrote:
>>>> While I suggested to revert the link up IRQ patch for rockchip earlier, I didn't
>>>> expect to drop the support for Qcom. The reason is, on Qcom SoCs, we have not
>>>> seen a case where people connect a random PCIe switch and saw failures. Most of
>>>> the Qcom usecases were around the M.2 and other proprietary connectors. There is
>>>> only one in-house PCIe switch that is being actively used in our products, but
>>>> so far, none of the bootloaders have turned them ON before kernel booting. So
>>>> kernel relies on the newly merged pwrctrl driver to do the job. Even though it
>>>> also suffers from the same resource allocation issue, this series won't help in
>>>> any way as pwrctrl core performs rescan after the switch power ON, and by that
>>>> time, it will be very late anyway.
>>>>
>>>> So I'm happy to take the rockhip patches from this series as they fix the real
>>>> issue that people have reported. But once the pwrctrl rework series gets merged,
>>>> and the rockchip drivers support them, we can bring back the reverted changes.
>>>
>>> FUKAUMI Naoki, just to confirm:
>>>
>>> Neither my suggested approach:
>>> https://lore.kernel.org/linux-pci/aRHdeVCY3rRmxe80 at ryzen/
>>>
>>> nor Shawn's suggested approach:
>>> https://lore.kernel.org/linux-pci/dc932773-af5b-4af7-a0d0-8cc72dfbd3c7 at rock-chips.com/
>>>
>>> worked for you?
>>
>> Yes, I re-tested the two methods mentioned above, separately, on v6.18-rc7,
>> but neither of them resolved the issue in my environment (ROCK 5C +
>> ASM2806).
>>
>>> If so, I don't see many alternative but for Mani to apply patch 1 and
>>> patch 2 from this series.
>>
>> I believe applying patch 1 and patch 2 should be sufficient.
>>
>> ----
>>
>> Incidentally, (probably) while applying patch 1 and patch 2, I have
>> encountered the following issue several times:
>>
> 
> Do you see the below issue *after* applying the patches? I don't know how to
> interpret "while applying".
>   
>> [    1.709614] pcieport 0004:41:00.0: of_irq_parse_pci: failed with rc=134
>> [    1.710208] pcieport 0004:41:00.0: Unable to change power state from
>> D3cold to D0, device inaccessible
>>
> 
> Looks like the device was seen during bus scan, but then it went down
> afterwards.

Sorry, I meant "after". But I guess it occurred with vanilla kernel in 
the past:

  https://lore.kernel.org/linux-pci/4487DA40249CC821+19232169-a096-4737-bc6a-5cec9592d65f at radxa.com/
  https://gist.github.com/RadxaNaoki/b42252ce3209d9f6bc2d4c90c71956ae#file-gistfile1-txt-L551

This time I unset CONFIG_PCI_DYNAMIC_OF_NODES, but this error occurred 
at same location when kernel oops occurred.

It might be a problem with ROCK 5C, (or *my* ROCK 5C), so I'll test 
again with ROCK 5B.

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> - Mani
> 



From helgaas at kernel.org  Wed Nov 26 15:54:32 2025
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Wed, 26 Nov 2025 17:54:32 -0600
Subject: [PATCH v6 1/2] PCI: Configure Root Port MPS during host probing
In-Reply-To: <20251104165125.174168-2-18255117159@163.com>
Message-ID: <20251126235432.GA2726707@bhelgaas>

On Wed, Nov 05, 2025 at 12:51:24AM +0800, Hans Zhang wrote:
> Current PCIe initialization logic may leave Root Ports (root bridges)
> operating with non-optimal Maximum Payload Size (MPS) settings. Existing
> code in pci_configure_mps() returns early for devices without an upstream
> bridge (!bridge) which includes Root Ports, so their MPS values remain
> at firmware/hardware defaults. This fails to utilize the controller's full
> capabilities, leading to suboptimal data transfer efficiency across the
> PCIe hierarchy.
> 
> With this patch, during the host controller probing phase:
> - When PCIe bus tuning is enabled (not PCIE_BUS_TUNE_OFF), and
> - The device is a Root Port without an upstream bridge (!bridge),
> The Root Port's MPS is set to its hardware-supported maximum value
> (128 << dev->pcie_mpss).
> 
> Note that this initial maximum MPS setting may be reduced later, during
> downstream device enumeration, if any downstream device does not suppor
> the Root Port's maximum MPS.
> 
> This change ensures Root Ports are properly initialized before downstream
> devices negotiate MPS, while maintaining backward compatibility via the
> PCIE_BUS_TUNE_OFF check.

"Properly" is sort of a junk word for me because all it really says is
we were stupid before, and we're smarter now, but it doesn't explain
exactly *what* was wrong and why this new thing is "proper."

It's obvious that the Max_Payload_Size power-on default (128 bytes) is
suboptimal in some situations, so you don't even need to say that.
And I think 128 bytes *is* optimal in the PCIE_BUS_PEER2PEER case.

s/Root Ports (root bridges)/Root Ports/
s/bridge (!bridge)/bridge/     # a couple times
s/hardware-supported//         # unnecessary
s/(128 << dev->pcie_mpss)//    # we can read the spec
s/suppor/support/

> Suggested-by: Niklas Cassel <cassel at kernel.org>
> Suggested-by: Manivannan Sadhasivam <mani at kernel.org>
> Signed-off-by: Hans Zhang <18255117159 at 163.com>
> ---
>  drivers/pci/probe.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index 0ce98e18b5a8..2459def3af9b 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -2196,6 +2196,18 @@ static void pci_configure_mps(struct pci_dev *dev)
>  		return;
>  	}
>  
> +	/*
> +	 * Unless MPS strategy is PCIE_BUS_TUNE_OFF (don't touch MPS at all),
> +	 * start off by setting Root Ports' MPS to MPSS. This only applies to
> +	 * Root Ports without an upstream bridge (root bridges), as other Root
> +	 * Ports will have downstream bridges.

I can't parse this sentence.  *No* Root Port has an upstream bridge.
So I don't know what "other Root Ports" would be or why they would
have downstream bridges (any Root Port is likely to have downstream
endpoints or bridges).

> +	   ... Depending on the MPS strategy
> +	 * and MPSS of downstream devices, the Root Port's MPS may be
> +	 * overridden later.
> +	 */
> +	if (!bridge && pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT &&
> +	    pcie_bus_config != PCIE_BUS_TUNE_OFF)
> +		pcie_set_mps(dev, 128 << dev->pcie_mpss);
> +
>  	if (!bridge || !pci_is_pcie(bridge))
>  		return;
>  
> -- 
> 2.34.1
> 


From shawn.lin at rock-chips.com  Wed Nov 26 20:32:44 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Thu, 27 Nov 2025 12:32:44 +0800
Subject: [PATCH] iommu/rockchip: disable fetch dte time limit
In-Reply-To: <20251126-spu-iommudtefix-v1-1-f90003dbfcc4@pengutronix.de>
References: <20251126-spu-iommudtefix-v1-1-f90003dbfcc4@pengutronix.de>
Message-ID: <075100c0-b4af-4077-bd3c-dd9407524671@rock-chips.com>

? 2025/11/26 ??? 19:45, Sven P?schel ??:
> From: Simon Xue <xxm at rock-chips.com>
> 
> Disable the Bit 31 of the AUTO_GATING iommu register, as it causes
> hangups with the RGA3 (Raster Graphics Acceleration 3) peripheral.
> The RGA3 register description of the TRM already states that the bit
> must be set to 1. The vendor kernel sets the bit unconditionally to
> 1 to fix VOP (Video Output Processor) screen black issues. This patch
> squashes the 2 vendor kernel commits with the following commit messages:
> 
> Master fetch data and cpu update page table may work in parallel, may
> have the following procedure:
> 
> 	master                  cpu
> 	fetch dte               update page tabl
> 	        |                       |
> 	(make dte invalid)  <-  zap iotlb entry
> 	        |                       |
> 	fetch dte again
> 	(make dte invalid)  <-  zap iotlb entry
> 	        |                       |
> 	fetch dte again
> 	(make dte invalid)  <-  zap iotlb entry
> 	        |                       |
> 	fetch dte again
> 	(make iommu block)  <-  zap iotlb entry
> 
> New iommu version has the above bug, if fetch dte consecutively four
> times, then it will be blocked. Fortunately, we can set bit 31 of
> register MMU_AUTO_GATING to 1 to make it work as old version which does
> not have this issue.
> 
> This issue only appears on RV1126 so far, so make a workaround dedicated
> to "rockchip,rv1126" machine type.
> 
> iommu/rockchip: fix vop blocked and screen black on RK356X and RK3588
> 
> RK3568 and RK3588 has the same issue as RV1126/RV1109 that caused by
> dte fetch time limit, So we can set BIT(31) of register 0x24 default
> to 1 as a workaround.
> 
> Signed-off-by: Simon Xue <xxm at rock-chips.com>
> Signed-off-by: Sven P?schel <s.pueschel at pengutronix.de>
> ---
> During testing of a newly developed driver for the RGA3 peripheral [1]
> (Raster Graphic Acceleration 3) of the RK3588 some sporadic hangs
> have been observed. The upstream rockchip-iommu driver is used to handle
> the RGA3 IOMMU register space.
> 
> After a closer look at the TRM for the RK3588, the RGA3 iommu register
> description of the RGA3_MMU_AUTO_GATING register (offset 0x24) mentions

It's 0xF24 per RGA3 chapter.

> a mmu_bug_fixed_disable bit, which must be set to 1 but defaults to 0.
> 
> Looking at the commits in the vendor kernel, the bit is unconditionally
> set to 1 and mentions that it fixes a blocked VOP (Video Output
> Processor) [3]. Therefore squash the relevant vendor commits
> [2] and [3] into a single patch, combine the commit messages and keep
> the Signed-off-by line from the original author.
> 
> [1] https://lore.kernel.org/all/20251007-spu-rga3-v1-0-36ad85570402 at pengutronix.de/
> [2] https://github.com/rockchip-linux/kernel/commit/7f8158fb41b5cc8e738aaeebc3637c50ebd74cae
> [3] https://github.com/rockchip-linux/kernel/commit/6a355e5f9a2069a2309e240791bc3aad63b7324e
> ---
>   drivers/iommu/rockchip-iommu.c | 8 ++++++++
>   1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
> index 0861dd469bd86..2d0dabb0d101a 100644
> --- a/drivers/iommu/rockchip-iommu.c
> +++ b/drivers/iommu/rockchip-iommu.c
> @@ -76,6 +76,8 @@
>   #define SPAGE_ORDER 12
>   #define SPAGE_SIZE (1 << SPAGE_ORDER)
>   
> +#define DISABLE_FETCH_DTE_TIME_LIMIT BIT(31)
> +
>    /*
>     * Support mapping any size that fits in one page table:
>     *   4 KiB to 4 MiB
> @@ -930,6 +932,7 @@ static int rk_iommu_enable(struct rk_iommu *iommu)
>   	struct iommu_domain *domain = iommu->domain;
>   	struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
>   	int ret, i;
> +	u32 auto_gate;
>   
>   	ret = clk_bulk_enable(iommu->num_clocks, iommu->clocks);
>   	if (ret)
> @@ -948,6 +951,11 @@ static int rk_iommu_enable(struct rk_iommu *iommu)
>   			       rk_ops->mk_dtentries(rk_domain->dt_dma));
>   		rk_iommu_base_command(iommu->bases[i], RK_MMU_CMD_ZAP_CACHE);
>   		rk_iommu_write(iommu->bases[i], RK_MMU_INT_MASK, RK_MMU_IRQ_MASK);
> +
> +		/* Workaround for iommu blocked, BIT(31) default to 1 */
> +		auto_gate = rk_iommu_read(iommu->bases[i], RK_MMU_AUTO_GATING);
> +		auto_gate |= DISABLE_FETCH_DTE_TIME_LIMIT;
> +		rk_iommu_write(iommu->bases[i], RK_MMU_AUTO_GATING, auto_gate);
>   	}
>   
>   	ret = rk_iommu_enable_paging(iommu);
> 
> ---
> base-commit: 30f09200cc4aefbd8385b01e41bde2e4565a6f0e
> change-id: 20251126-spu-iommudtefix-cd0c5244c74a
> 
> Best regards,



From linux.amoon at gmail.com  Wed Nov 26 23:34:45 2025
From: linux.amoon at gmail.com (Anand Moon)
Date: Thu, 27 Nov 2025 13:04:45 +0530
Subject: [RFC v1 1/5] PCI: rockchip: Fix Link Control register offset and
 enable ASPM/CLKREQ
In-Reply-To: <20251126143952.GA2825566@bhelgaas>
References: <CANAwSgQMfu2E+oR0Yi9siKA-PZJ_nyDVCQF=Ua7REHcMRDo0Fg@mail.gmail.com>
 <20251126143952.GA2825566@bhelgaas>
Message-ID: <CANAwSgSGnSNUr5bKRimBs+aAi6XdvMJxB8Oc=z4Tz-5eLA+twA@mail.gmail.com>

Hi Bjorn

On Wed, 26 Nov 2025 at 20:09, Bjorn Helgaas <helgaas at kernel.org> wrote:
>
> On Wed, Nov 26, 2025 at 04:03:37PM +0530, Anand Moon wrote:
> > On Thu, 20 Nov 2025 at 19:28, Anand Moon <linux.amoon at gmail.com> wrote:
> > > On Thu, 20 Nov 2025 at 09:14, Bjorn Helgaas <helgaas at kernel.org> wrote:
> > > > On Wed, Nov 19, 2025 at 07:49:06PM +0530, Anand Moon wrote:
> > > > > On Tue, 18 Nov 2025 at 23:20, Bjorn Helgaas <helgaas at kernel.org> wrote:
> > > > > > On Mon, Nov 17, 2025 at 11:40:09PM +0530, Anand Moon wrote:
> > > > > > > As per the RK3399 TRM (Part 2, 17.6.6.1.31), the Link Control register
> > > > > > > (RC_CONFIG_LC) resides at an offset of 0xd0 within the Root Complex (RC)
> > > > > > > configuration space, not at the offset of the PCI Express Capability List
> > > > > > > (0xc0). Following changes correct the register offset to use
> > > > > > > PCIE_RC_CONFIG_LC (0xd0) to configure link control.
> > > > > ...
> > > >
> > > > > > Don't do two things at once in the same patch.  Fix the register
> > > > > > offset in one patch.  Actually, as I mentioned at [1], there's a lot
> > > > > > of fixing to do there, and I'm not even going to consider other
> > > > > > changes until the #define mess is cleaned up.
> > > >
> > > > > > [1] https://lore.kernel.org/r/20251118005056.GA2541796 at bhelgaas
> > > > >
> > > > > According to the RK3399 Technical Reference Manual (TRM), and pci_regs.h
> > > > > already includes the correct, pre-defined offsets for all PCI Express
> > > > > device types
> > > > > and their capabilities registers. To avoid overlapping register mappings,
> > > > > we should explicitly remove the addition of manual offsets within the code.
> > > >
> > > > > Here is the example. Is this the correct approach?
> > > >
> > > > > -       status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_CR +
> > > > > PCI_EXP_LNKCTL);
> > > > > +       status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LC);
> > > > >         status |= (PCI_EXP_LNKCTL_LBMIE | PCI_EXP_LNKCTL_LABIE);
> > > > > -       rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_CR +
> > > > > PCI_EXP_LNKCTL);
> > > > > +       rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LC);
> > > >
> > > > No.  The call should include PCI_EXP_LNKCTL because that's what we
> > > > grep for when we want to see where Link Control is updated.
> > > >
> > > > See my example from [1] above:
> > > >
> > > >   rockchip_pcie_read(rockchip, ROCKCHIP_RP_PCIE_CAP + PCI_EXP_DEVCAP)
> > > >   rockchip_pcie_read(rockchip, ROCKCHIP_RP_PCIE_CAP + PCI_EXP_LNKCTL)
> > > >
> > > > You should have a single #define for the offset of the PCIe
> > > > Capability, e.g., ROCKCHIP_RP_PCIE_CAP.  Every access to registers in
> > > > that capability would use ROCKCHIP_RP_PCIE_CAP and the relevant
> > > > PCI_EXP_* offset, e.g., PCI_EXP_DEVCAP, PCI_EXP_DEVCTL,
> > > > PCI_EXP_DEVSTA, PCI_EXP_LNKCAP, PCI_EXP_LNKCTL, PCI_EXP_LNKSTA, etc.
> > > >
> > > I apologize for not fully understanding the issue earlier. I did not
> > > carefully review your email,
> > >  which caused me to overlook the required changes.
> > >
> > > So, as per the TRM
> > >
> > > 17.6.4.5.1 PCI Express Capability List Register
> > > Propname?PCI Express Capability List Register
> > > Address?@0xc0
> > >
> > > #define PCIE_EP_CONFIG_DID_VID          (PCIE_EP_CONFIG_BASE + 0x00)
> > > #define PCIE_EP_CONFIG_LCS              (PCIE_EP_CONFIG_BASE + 0xd0)
> > > #define PCIE_RC_CONFIG_RID_CCR          (PCIE_RC_CONFIG_BASE + 0x08)
> > > #define PCIE_RC_CONFIG_CR               (PCIE_RC_CONFIG_BASE + 0xc0)
> > > #define ROCKCHIP_RP_PCIE_CAP            (PCIE_RC_CONFIG_BASE + 0xc0)
> > > /* Link Control and Status Register */
> > > #define PCIE_RC_CONFIG_LC               (ROCKCHIP_RP_PCIE_CAP + 0xd0)
> > > /* Device Control */
> > > #define PCIE_RC_CONFIG_DC               (ROCKCHIP_RP_PCIE_CAP + 0xc8)
> > > /* Slot Capability Register */
> > > #define PCIE_RC_CONFIG_SC               (ROCKCHIP_RP_PCIE_CAP + 0xd4)
> > > /* Link Control 2 Register */
> > > #define PCIE_RC_CONFIG_LC2              (ROCKCHIP_RP_PCIE_CAP + 0xf0)
> > > /* Linkwidth Control Register */
> > > #define PCIE_RC_CONFIG_LWC              (ROCKCHIP_RP_PCIE_CAP + 0x50)
> > >
> > > And then use these like this.
> > >
> > > status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LC + PCI_EXP_LNKCTL);
> > > status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_DC + PCI_EXP_DEVCTL);
> > > status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_SC + PCI_EXP_DEVCAP);
> > > status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LC2 + PCI_EXP_LNKCTL2);
> > > status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LWC + PCI_EXP_LNKCTL);
> > >
> > > If you agree that this approach correctly resolves the issue,
> > > I would prefer to confirm now to prevent further iterative changes
> > > that might confuse.
> > >
> > I was making some changes to the system when my device stopped working,
> > The lspci utility started crashing with a segmentation fault.
> >
> > $ sudo lspci -vvv
> > [sudo] password for alarm:
> > Segmentation fault         sudo lspci -vvv
> >
> > # dmesg logs
> >
> > [   21.225526] rockchip-pm-domain
> > ff310000.power-management:power-controller: sync_state() pending due
> > to ff660000.video-codec
> > [   34.935331] Internal error: synchronous external abort:
> > 0000000096000210 [#1]  SMP
> > [   34.936027] Modules linked in: 8021q garp mrp stp llc af_alg
> > brcmfmac_wcc snd_soc_hdmi_codec hantro_vpu dw_hdmi_i2s_audio
> > dw_hdmi_cec rockchip_rga hci_uart v4l2_vp9 rockchipdrm brcmfmac
> > brcmutil btqca dw_hdmi_qp snd_soc_simple_card nvme v4l2_h264
> > snd_soc_audio_graph_card analogix_dp videobuf2_dma_sg v4l2_jpeg
> > snd_soc_es8316 btbcm snd_soc_simple_card_utils dw_mipi_dsi nvme_core
> > snd_soc_spdif_tx snd_soc_rockchip_i2s videobuf2_dma_contig
> > v4l2_mem2mem drm_dp_aux_bus bluetooth snd_soc_core dw_hdmi
> > videobuf2_memops drm_display_helper panfrost videobuf2_v4l2
> > snd_compress dwmac_rk videodev ecdh_generic cec snd_pcm_dmaengine
> > drm_shmem_helper ax88179_178a stmmac_platform drm_client_lib snd_pcm
> > ecc gpu_sched drm_dma_helper videobuf2_common usbnet rockchip_saradc
> > stmmac drm_kms_helper pwrseq_core snd_timer reset_gpio
> > phy_rockchip_pcie mc industrialio_triggered_buffer snd rockchip_dfi
> > rockchip_thermal coresight_cpu_debug soundcore rtc_rk808 kfifo_buf
> > pcs_xpcs coresight pcie_rockchip_host sha256 cfg80211 rfkill drm fuse
> > backlight
> > [   34.936326]  dm_mod ipv6
> > [   34.944344] CPU: 1 UID: 0 PID: 796 Comm: lspci Tainted: G   M
> >          6.18.0-rc7-dirty #1 PREEMPT
> > [   34.945187] Tainted: [M]=MACHINE_CHECK
> > [   34.945518] Hardware name: Radxa ROCK Pi 4B+ (DT)
> > [   34.945932] pstate: 600000c5 (nZCv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> > [   34.946545] pc : rockchip_pcie_rd_conf+0x178/0x27c [pcie_rockchip_host]
> > [   34.947138] lr : rockchip_pcie_rd_conf+0x170/0x27c [pcie_rockchip_host]
> > [   34.947722] sp : ffff8000848b3bc0
> > [   34.948015] x29: ffff8000848b3bc0 x28: ffff0000013e30c0 x27: 0000000000000000
> > [   34.948652] x26: 000000000000000f x25: ffff0000013e30c0 x24: 0000000000000040
> > [   34.949287] x23: 0000000000000040 x22: ffff8000848b3c44 x21: ffff8000848b3bf4
> > [   34.949920] x20: ffff800082100000 x19: 0000000000000004 x18: 0000000000000000
> > [   34.950555] x17: 0000000000000000 x16: ffffc37c34322808 x15: 0000000000000000
> > [   34.951188] x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000
> > [   34.951821] x11: 0000000000000000 x10: 0000000000000000 x9 : 0000000000000000
> > [   34.952454] x8 : 0000000000000000 x7 : ffff0000084093c0 x6 : ffff000009cd7000
> > [   34.953087] x5 : ffff000009cd7800 x4 : ffff800085000000 x3 : 0000000000c00008
> > [   34.953722] x2 : 000000000080000a x1 : ffff800085c00008 x0 : ffff800085c0000c
> > [   34.954356] Call trace:
> > [   34.954576]  rockchip_pcie_rd_conf+0x178/0x27c [pcie_rockchip_host] (P)
> > [   34.955164]  pci_user_read_config_dword+0x7c/0x120
> > [   34.955598]  pci_read_config+0xe4/0x2a0
> > [   34.955944]  sysfs_kf_bin_read+0x7c/0xbc
> > [   34.956298]  kernfs_fop_read_iter+0xb0/0x1bc
> > [   34.956679]  vfs_read+0x230/0x320
> > [   34.956981]  __arm64_sys_pread64+0xac/0xd4
> > [   34.957350]  invoke_syscall+0x48/0x10c
> > [   34.957691]  el0_svc_common.constprop.0+0x40/0xe0
> > [   34.958113]  do_el0_svc+0x1c/0x28
> > [   34.958414]  el0_svc+0x34/0xec
> > [   34.958694]  el0t_64_sync_handler+0xa0/0xe4
> > [   34.959070]  el0t_64_sync+0x198/0x19c
> > [   34.959405] Code: 52800141 940000ae 7100127f 54fff801 (b9400294)
> > [   34.959940] ---[ end trace 0000000000000000 ]---
> > [   34.960349] note: lspci[796] exited with irqs disabled
> > [   34.960879] note: lspci[796] exited with preempt_count 1
> >
> > Either I am doing something wrong, or it's broken; I am not getting
> > this to work.
> >
> > Upon further investigation, the issue was narrowed down to a
> > specific modification that I made locally,
> >
> > According to section 17.6.6.1.32 of the manual, the Power Limit
> > Value and Power Limit Scale fields are part of the Slot Capability
> > Register, not the Device Capability Register.
> >
> > This assumption led to the segmentation fault because the code was
> > attempting to access invalid memory addresses.
> >
> > Do you think these are valid changes? Because this change caused a
> > freeze on the NVMe device.
>
> I'm not surprised that there might be issues related to registers in
> the PCIe Capability.  I'm actually surprised that this driver works at
> all, given the incredible mess.
>
> So I'm not going to bother trying to fix this piecemeal as with the
> patch below.  Every single access to DEVCAP/DEVCTL/DEVSTA,
> SLTCAP/SLTCTL/SLTSTA, etc needs to be made rational.  There's a single
> base address that works for all of them because the Rockchip register
> layout matches the PCIe Capability layout.  I've already outlined in
> detail what needs to be done.  I'll try to find time to actually
> implement this, but it probably won't be for at least a few days.
>

Alright, I'll wait for your update. I need to test some code changes.

Thanks
-Anand


From naoki at radxa.com  Wed Nov 26 23:34:53 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Thu, 27 Nov 2025 16:34:53 +0900
Subject: [PATCH 0/6] PCI: dwc: Revert Link Up IRQ support
In-Reply-To: <7667E818D7D31A4E+cf7c83d4-b99c-469d-8d46-588fc95b843f@radxa.com>
References: <20251111105100.869997-8-cassel@kernel.org>
 <mt7miqkipr4dvxemftq6octxqzauueln252ncrcwy6i2t7wfhi@jtwokeilhwsi>
 <aSRli_Mb6qoQ9TZO@ryzen>
 <7667E818D7D31A4E+cf7c83d4-b99c-469d-8d46-588fc95b843f@radxa.com>
Message-ID: <F11F0D13437B012D+0c15c5ca-f64f-49f1-9ff5-26b88d59ff59@radxa.com>

Hi all,

I'm very sorry, but my ROCK 5C appears to be unreliable. (It worked fine 
with vanilla v6.13, so I thought it was fine.)

I replaced it with another 5C (Lite), and now every method (Niklas's 
patch, Shawn's patch, and applying patch 1 and 2) seems to work.

Testing with the 5C Lite is still not enough, further testing is 
required, but I will probably need to revise my test results.

(Those seem to work on ROCK 5A/5B, but they also need further testing.)

I truly apologize for my unreliable testing.

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

On 11/26/25 22:30, FUKAUMI Naoki wrote:
> Hi Niklas,
> 
> I apologize for the delayed response.
> 
> On 11/24/25 23:02, Niklas Cassel wrote:
>> On Mon, Nov 24, 2025 at 06:07:44PM +0530, Manivannan Sadhasivam wrote:
>>> While I suggested to revert the link up IRQ patch for rockchip 
>>> earlier, I didn't
>>> expect to drop the support for Qcom. The reason is, on Qcom SoCs, we 
>>> have not
>>> seen a case where people connect a random PCIe switch and saw 
>>> failures. Most of
>>> the Qcom usecases were around the M.2 and other proprietary 
>>> connectors. There is
>>> only one in-house PCIe switch that is being actively used in our 
>>> products, but
>>> so far, none of the bootloaders have turned them ON before kernel 
>>> booting. So
>>> kernel relies on the newly merged pwrctrl driver to do the job. Even 
>>> though it
>>> also suffers from the same resource allocation issue, this series 
>>> won't help in
>>> any way as pwrctrl core performs rescan after the switch power ON, 
>>> and by that
>>> time, it will be very late anyway.
>>>
>>> So I'm happy to take the rockhip patches from this series as they fix 
>>> the real
>>> issue that people have reported. But once the pwrctrl rework series 
>>> gets merged,
>>> and the rockchip drivers support them, we can bring back the reverted 
>>> changes.
>>
>> FUKAUMI Naoki, just to confirm:
>>
>> Neither my suggested approach:
>> https://lore.kernel.org/linux-pci/aRHdeVCY3rRmxe80 at ryzen/
>>
>> nor Shawn's suggested approach:
>> https://lore.kernel.org/linux-pci/dc932773-af5b-4af7- 
>> a0d0-8cc72dfbd3c7 at rock-chips.com/
>>
>> worked for you?
> 
> Yes, I re-tested the two methods mentioned above, separately, on v6.18- 
> rc7, but neither of them resolved the issue in my environment (ROCK 5C + 
> ASM2806).
> 
>> If so, I don't see many alternative but for Mani to apply patch 1 and
>> patch 2 from this series.
> 
> I believe applying patch 1 and patch 2 should be sufficient.
> 
> ----
> 
> Incidentally, (probably) while applying patch 1 and patch 2, I have 
> encountered the following issue several times:
> 
> [??? 1.709614] pcieport 0004:41:00.0: of_irq_parse_pci: failed with rc=134
> [??? 1.710208] pcieport 0004:41:00.0: Unable to change power state from 
> D3cold to D0, device inaccessible
> 
> I am still investigating this matter, and the conditions under which it 
> occurs are currently unknown.
> 
> Best regards,
> 
> -- 
> FUKAUMI Naoki
> Radxa Computer (Shenzhen) Co., Ltd.
> 
>> Kind regards,
>> Niklas
>>
> 



From cassel at kernel.org  Wed Nov 26 23:43:41 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Thu, 27 Nov 2025 08:43:41 +0100
Subject: [PATCH 0/6] PCI: dwc: Revert Link Up IRQ support
In-Reply-To: <F11F0D13437B012D+0c15c5ca-f64f-49f1-9ff5-26b88d59ff59@radxa.com>
References: <20251111105100.869997-8-cassel@kernel.org>
 <mt7miqkipr4dvxemftq6octxqzauueln252ncrcwy6i2t7wfhi@jtwokeilhwsi>
 <aSRli_Mb6qoQ9TZO@ryzen>
 <7667E818D7D31A4E+cf7c83d4-b99c-469d-8d46-588fc95b843f@radxa.com>
 <F11F0D13437B012D+0c15c5ca-f64f-49f1-9ff5-26b88d59ff59@radxa.com>
Message-ID: <aSgBLQ7rDOiEFhMB@ryzen>

Hello FUKAUMI Naoki,

On Thu, Nov 27, 2025 at 04:34:53PM +0900, FUKAUMI Naoki wrote:
> Hi all,
> 
> I'm very sorry, but my ROCK 5C appears to be unreliable. (It worked fine
> with vanilla v6.13, so I thought it was fine.)
> 
> I replaced it with another 5C (Lite), and now every method (Niklas's patch,
> Shawn's patch, and applying patch 1 and 2) seems to work.

Could you please give us some more information.

Does the Rock 5C Lite have a PCIe switch?

Does Rock 5C Lite work fine with the current code in mainline?
(i.e. with bus enumeration when Link Up IRQ is triggered).


Kind regards,
Niklas


From krzk at kernel.org  Wed Nov 26 23:49:07 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Thu, 27 Nov 2025 08:49:07 +0100
Subject: [PATCH 1/2] dt-bindings: iommu: rockchip: Add support for
 multiple interface clocks
In-Reply-To: <20251126083345.88-2-kernel@airkyi.com>
References: <20251126083345.88-1-kernel@airkyi.com>
 <20251126083345.88-2-kernel@airkyi.com>
Message-ID: <20251127-enigmatic-faithful-viper-baefa2@kuoka>

On Wed, Nov 26, 2025 at 04:33:44PM +0800, Chaoyi Chen wrote:
> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> 
> The iommu found on RK3576 NPU/RKVDEC may contains more than one
> interface clock.

So you need to restrict this per each variant. See writign schema doc in
DT dir.

Best regards,
Krzysztof



From chaoyi.chen at rock-chips.com  Thu Nov 27 00:02:20 2025
From: chaoyi.chen at rock-chips.com (Chaoyi Chen)
Date: Thu, 27 Nov 2025 16:02:20 +0800
Subject: [PATCH 1/2] dt-bindings: iommu: rockchip: Add support for
 multiple interface clocks
In-Reply-To: <20251127-enigmatic-faithful-viper-baefa2@kuoka>
References: <20251126083345.88-1-kernel@airkyi.com>
 <20251126083345.88-2-kernel@airkyi.com>
 <20251127-enigmatic-faithful-viper-baefa2@kuoka>
Message-ID: <324ba201-8cfb-4a7c-87c8-366f657ffd8a@rock-chips.com>

On 11/27/2025 3:49 PM, Krzysztof Kozlowski wrote:
> On Wed, Nov 26, 2025 at 04:33:44PM +0800, Chaoyi Chen wrote:
>> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
>>
>> The iommu found on RK3576 NPU/RKVDEC may contains more than one
>> interface clock.
> 
> So you need to restrict this per each variant. See writign schema doc in
> DT dir.

Oh, I will rewrite it in v2. Thank you.


> 
> Best regards,
> Krzysztof
> 
> 
> 

-- 
Best, 
Chaoyi


From adam.drzewiecki at vexro.pl  Thu Nov 27 01:10:34 2025
From: adam.drzewiecki at vexro.pl (Adam Drzewiecki)
Date: Thu, 27 Nov 2025 09:10:34 GMT
Subject: =?UTF-8?Q?Pytanie_o_samoch=C3=B3d_?=
Message-ID: <20251127084500-0.1.ou.4mrs0.0.h59f6hqefa@vexro.pl>

Dzie? dobry,

Czy interesuje Pa?stwa rozwi?zanie umo?liwiaj?ce monitorowanie samochod?w firmowych oraz optymalizacj? koszt?w ich utrzymania? 


Pozdrawiam
Adam Drzewiecki


From luca.ceresoli at bootlin.com  Thu Nov 27 01:22:18 2025
From: luca.ceresoli at bootlin.com (Luca Ceresoli)
Date: Thu, 27 Nov 2025 10:22:18 +0100
Subject: [PATCH 1/2] phy: rockchip: inno-usb2: fix disconnection in
 gadget mode
In-Reply-To: <DEHVRC8CY12S.3LSC6UVSMU0C1@bootlin.com>
References: <20250722-rk3308-fix-usb-gadget-phy-disconnect-v1-0-239872f05f17@bootlin.com> <20250722-rk3308-fix-usb-gadget-phy-disconnect-v1-1-239872f05f17@bootlin.com> <DEHVRC8CY12S.3LSC6UVSMU0C1@bootlin.com>
Message-ID: <DEJD8DJZFNZO.11B1UBXJBN7MO@bootlin.com>

Hi Th?o,

thanks for reviewing this series!

On Tue Nov 25, 2025 at 4:28 PM CET, Th?o Lebrun wrote:
[...]
>> The problem was observed on a Radxa Rock Pi S board, which can only be
>> powered by the only USB-C connector. That connector is the only one usable
>
> "which can only be powered by the only USB-C connector"
> double "only" makes it a super exclusive connector!

Hehe, indeed! :-)

>> The code already checks for !rport->suspended, so add a guard for VBUS as
>> well to avoid a disconnection when a cable is connected.
>
> Your commit message was clear but I was missing one key point: what
> rport->suspended means. It isn't what I first thought. Instead it means
> phy is powered off. Naming is bad but unrelated to your series. Maybe
> add a comment to your commit message like the following?
>
>   The code already checks for !rport->suspended (PHY is powered on), ...

You are right. I have added a slightly longer text:

  The code already checks for !rport->suspended (which, somewhat
  counter-intuitively, means the PHY is powered on), ...

Still worth your Reviewed-by?

I fixed the other issues you have reported, for patch 2 as well.

I also added the Cc: stable at vger.kernel.org line, which I noticed being
missing.

Luca

--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From theo.lebrun at bootlin.com  Thu Nov 27 01:48:26 2025
From: theo.lebrun at bootlin.com (=?utf-8?q?Th=C3=A9o_Lebrun?=)
Date: Thu, 27 Nov 2025 10:48:26 +0100
Subject: [PATCH 1/2] phy: rockchip: inno-usb2: fix disconnection in
 gadget mode
In-Reply-To: <DEJD8DJZFNZO.11B1UBXJBN7MO@bootlin.com>
References: <20250722-rk3308-fix-usb-gadget-phy-disconnect-v1-0-239872f05f17@bootlin.com> <20250722-rk3308-fix-usb-gadget-phy-disconnect-v1-1-239872f05f17@bootlin.com> <DEHVRC8CY12S.3LSC6UVSMU0C1@bootlin.com> <DEJD8DJZFNZO.11B1UBXJBN7MO@bootlin.com>
Message-ID: <DEJDSE73CJES.2AB8YSKLW6VE1@bootlin.com>

On Thu Nov 27, 2025 at 10:22 AM CET, Luca Ceresoli wrote:
> On Tue Nov 25, 2025 at 4:28 PM CET, Th?o Lebrun wrote:
>>> The code already checks for !rport->suspended, so add a guard for VBUS as
>>> well to avoid a disconnection when a cable is connected.
>>
>> Your commit message was clear but I was missing one key point: what
>> rport->suspended means. It isn't what I first thought. Instead it means
>> phy is powered off. Naming is bad but unrelated to your series. Maybe
>> add a comment to your commit message like the following?
>>
>>   The code already checks for !rport->suspended (PHY is powered on), ...
>
> You are right. I have added a slightly longer text:
>
>   The code already checks for !rport->suspended (which, somewhat
>   counter-intuitively, means the PHY is powered on), ...
>
> Still worth your Reviewed-by?

Even more so.

> I fixed the other issues you have reported, for patch 2 as well.
>
> I also added the Cc: stable at vger.kernel.org line, which I noticed being
> missing.

I never add that Cc trailer and only rely on `Fixes:`. I thought it
used to be documented as an alternative to that Cc trailer but it does
not show up in `git log -p Documentation/process/stable-kernel-rules.rst`

There is one indirect mention of "scripts that look for commits
containing a 'Fixes:' tag":
https://elixir.bootlin.com/linux/v6.17.9/source/Documentation/process/stable-kernel-rules.rst#L132-L134

Anyway, you do right by explicitly tagging `Cc: stable at ...`.

Thanks,

--
Th?o Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com



From luca.ceresoli at bootlin.com  Thu Nov 27 02:18:45 2025
From: luca.ceresoli at bootlin.com (Luca Ceresoli)
Date: Thu, 27 Nov 2025 11:18:45 +0100
Subject: [PATCH 1/2] phy: rockchip: inno-usb2: fix disconnection in
 gadget mode
In-Reply-To: <DEJDSE73CJES.2AB8YSKLW6VE1@bootlin.com>
References: <20250722-rk3308-fix-usb-gadget-phy-disconnect-v1-0-239872f05f17@bootlin.com> <20250722-rk3308-fix-usb-gadget-phy-disconnect-v1-1-239872f05f17@bootlin.com> <DEHVRC8CY12S.3LSC6UVSMU0C1@bootlin.com> <DEJD8DJZFNZO.11B1UBXJBN7MO@bootlin.com> <DEJDSE73CJES.2AB8YSKLW6VE1@bootlin.com>
Message-ID: <DEJEFLKA9IJR.237ZLV8HBD2VS@bootlin.com>

Hi Th?o,

On Thu Nov 27, 2025 at 10:48 AM CET, Th?o Lebrun wrote:
> On Thu Nov 27, 2025 at 10:22 AM CET, Luca Ceresoli wrote:
>> On Tue Nov 25, 2025 at 4:28 PM CET, Th?o Lebrun wrote:
>>>> The code already checks for !rport->suspended, so add a guard for VBUS as
>>>> well to avoid a disconnection when a cable is connected.
>>>
>>> Your commit message was clear but I was missing one key point: what
>>> rport->suspended means. It isn't what I first thought. Instead it means
>>> phy is powered off. Naming is bad but unrelated to your series. Maybe
>>> add a comment to your commit message like the following?
>>>
>>>   The code already checks for !rport->suspended (PHY is powered on), ...
>>
>> You are right. I have added a slightly longer text:
>>
>>   The code already checks for !rport->suspended (which, somewhat
>>   counter-intuitively, means the PHY is powered on), ...
>>
>> Still worth your Reviewed-by?
>
> Even more so.

Thanks, v2 on its way.

>> I also added the Cc: stable at vger.kernel.org line, which I noticed being
>> missing.
>
> I never add that Cc trailer and only rely on `Fixes:`. I thought it
> used to be documented as an alternative to that Cc trailer but it does
> not show up in `git log -p Documentation/process/stable-kernel-rules.rst`
>
> There is one indirect mention of "scripts that look for commits
> containing a 'Fixes:' tag":
> https://elixir.bootlin.com/linux/v6.17.9/source/Documentation/process/stable-kernel-rules.rst#L132-L134
>
> Anyway, you do right by explicitly tagging `Cc: stable at ...`.

Theory says Cc: is needed:

> Note: Attaching a Fixes: tag does not subvert the stable kernel rules
> process nor the requirement to Cc: stable at vger.kernel.org on all stable
> patch candidates.
(https://docs.kernel.org/process/submitting-patches.html#reviewer-s-statement-of-oversight)

But in the practice I happened to forget Cc: stable in the past, the patch
got applied and the Fixes: tag was enough for correct cherry-pick in stable
branches.

Luca

--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From luca.ceresoli at bootlin.com  Thu Nov 27 02:26:15 2025
From: luca.ceresoli at bootlin.com (Luca Ceresoli)
Date: Thu, 27 Nov 2025 11:26:15 +0100
Subject: [PATCH v2 0/2] phy: rockchip: inno-usb2: fix gadget mode
 disconnection after 6 seconds
Message-ID: <20251127-rk3308-fix-usb-gadget-phy-disconnect-v2-0-dac8a02cd2ca@bootlin.com>

The USB OTG port of the RK3308 exibits a bug when:

 - configured as peripheral, and
 - used in gadget mode, and
 - the USB cable is connected since before booting

The symptom is: about 6 seconds after configuring gadget mode the device is
disconnected and then re-enumerated. This happens only once per boot.

Investigation showed that in this configuration the charger detection code
turns off the PHY after 6 seconds. Patch 1 avoids this when a cable is
connected (VBUS present).

After patch 1 the connection is stable but communication stops after 6
seconds. this is addressed by patch 2.

The topic had been discussed in [0]. Thanks Alan and Minas for the
discussion and Louis for having found the 1st issue, leading to patch 1.

[0] https://lore.kernel.org/lkml/20250414185458.7767aabc at booty/

Luca

Signed-off-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
---
Changes in v2:
- Patch 1: Fixed Co-developed-by: and SoB line order
- Added missing Cc: stable at vger.kernel.org
- Added Th?o's Reviewed-by
- Improved commit message
- Patch 2: trimmed discussion about "there is no disconnection" from
  commit message to not distract from the actual issue (writes to
  chg_det.opmode)
- Link to v1: https://lore.kernel.org/r/20250722-rk3308-fix-usb-gadget-phy-disconnect-v1-0-239872f05f17 at bootlin.com

---
Louis Chauvet (1):
      phy: rockchip: inno-usb2: fix disconnection in gadget mode

Luca Ceresoli (1):
      phy: rockchip: inno-usb2: fix communication disruption in gadget mode

 drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)
---
base-commit: cabb748c4b98ef67bbb088be61a2e0c850ebf70d
change-id: 20250718-rk3308-fix-usb-gadget-phy-disconnect-d7de71fb28b4

Best regards,
-- 
Luca Ceresoli <luca.ceresoli at bootlin.com>



From luca.ceresoli at bootlin.com  Thu Nov 27 02:26:16 2025
From: luca.ceresoli at bootlin.com (Luca Ceresoli)
Date: Thu, 27 Nov 2025 11:26:16 +0100
Subject: [PATCH v2 1/2] phy: rockchip: inno-usb2: fix disconnection in
 gadget mode
In-Reply-To: <20251127-rk3308-fix-usb-gadget-phy-disconnect-v2-0-dac8a02cd2ca@bootlin.com>
References: <20251127-rk3308-fix-usb-gadget-phy-disconnect-v2-0-dac8a02cd2ca@bootlin.com>
Message-ID: <20251127-rk3308-fix-usb-gadget-phy-disconnect-v2-1-dac8a02cd2ca@bootlin.com>

From: Louis Chauvet <louis.chauvet at bootlin.com>

When the OTG USB port is used to power the SoC, configured as peripheral
and used in gadget mode, there is a disconnection about 6 seconds after the
gadget is configured and enumerated.

The problem was observed on a Radxa Rock Pi S board, which can only be
powered by the only USB-C connector. That connector is the only one usable
in gadget mode. This implies the USB cable is connected from before boot
and never disconnects while the kernel runs.

The problem happens because of the PHY driver code flow, summarized as:

 * UDC start code (triggered via configfs at any time after boot)
   -> phy_init
       -> rockchip_usb2phy_init
           -> schedule_delayed_work(otg_sm_work [A], 6 sec)
   -> phy_power_on
       -> rockchip_usb2phy_power_on
           -> enable clock
           -> rockchip_usb2phy_reset

 * Now the gadget interface is up and running.

 * 6 seconds later otg_sm_work starts [A]
   -> rockchip_usb2phy_otg_sm_work():
       if (B_IDLE state && VBUS present && ...):
           schedule_delayed_work(&rport->chg_work [B], 0);

 * immediately the chg_detect_work starts [B]
   -> rockchip_chg_detect_work():
       if chg_state is UNDEFINED:
           if (!rport->suspended):
               rockchip_usb2phy_power_off() <--- [X]

At [X], the PHY is powered off, causing a disconnection. This quickly
triggers a new connection and following re-enumeration, but any connection
that had been established during the 6 seconds is broken.

The code already checks for !rport->suspended (which, somewhat
counter-intuitively, means the PHY is powered on), so add a guard for VBUS
as well to avoid a disconnection when a cable is connected.

Fixes: 98898f3bc83c ("phy: rockchip-inno-usb2: support otg-port for rk3399")
Cc: stable at vger.kernel.org
Closes: https://lore.kernel.org/lkml/20250414185458.7767aabc at booty/
Signed-off-by: Louis Chauvet <louis.chauvet at bootlin.com>
Co-developed-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
Signed-off-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
Reviewed-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index b0f23690ec30..0106d7b7ae24 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -821,14 +821,16 @@ static void rockchip_chg_detect_work(struct work_struct *work)
 		container_of(work, struct rockchip_usb2phy_port, chg_work.work);
 	struct rockchip_usb2phy *rphy = dev_get_drvdata(rport->phy->dev.parent);
 	struct regmap *base = get_reg_base(rphy);
-	bool is_dcd, tmout, vout;
+	bool is_dcd, tmout, vout, vbus_attach;
 	unsigned long delay;
 
+	vbus_attach = property_enabled(rphy->grf, &rport->port_cfg->utmi_bvalid);
+
 	dev_dbg(&rport->phy->dev, "chg detection work state = %d\n",
 		rphy->chg_state);
 	switch (rphy->chg_state) {
 	case USB_CHG_STATE_UNDEFINED:
-		if (!rport->suspended)
+		if (!rport->suspended && !vbus_attach)
 			rockchip_usb2phy_power_off(rport->phy);
 		/* put the controller in non-driving mode */
 		property_enable(base, &rphy->phy_cfg->chg_det.opmode, false);

-- 
2.51.1



From luca.ceresoli at bootlin.com  Thu Nov 27 02:26:17 2025
From: luca.ceresoli at bootlin.com (Luca Ceresoli)
Date: Thu, 27 Nov 2025 11:26:17 +0100
Subject: [PATCH v2 2/2] phy: rockchip: inno-usb2: fix communication
 disruption in gadget mode
In-Reply-To: <20251127-rk3308-fix-usb-gadget-phy-disconnect-v2-0-dac8a02cd2ca@bootlin.com>
References: <20251127-rk3308-fix-usb-gadget-phy-disconnect-v2-0-dac8a02cd2ca@bootlin.com>
Message-ID: <20251127-rk3308-fix-usb-gadget-phy-disconnect-v2-2-dac8a02cd2ca@bootlin.com>

When the OTG USB port is used to power to SoC, configured as peripheral and
used in gadget mode, communication stops without notice about 6 seconds
after the gadget is configured and enumerated.

The problem was observed on a Radxa Rock Pi S board, which can only be
powered by the only USB-C connector. That connector is the only one usable
in gadget mode. This implies the USB cable is connected from before boot
and never disconnects while the kernel runs.

The related code flow in the PHY driver code can be summarized as:

 * the first time chg_detect_work starts (6 seconds after gadget is
   configured and enumerated)
   -> rockchip_chg_detect_work():
       if chg_state is UNDEFINED:
          property_enable(base, &rphy->phy_cfg->chg_det.opmode, false); [Y]

 * rockchip_chg_detect_work() changes state and re-triggers itself a few
   times until it reaches the DETECTED state:
   -> rockchip_chg_detect_work():
       if chg_state is DETECTED:
          property_enable(base, &rphy->phy_cfg->chg_det.opmode, true); [Z]

At [Y] all existing communications stop. E.g. using a CDC serial gadget,
the /dev/tty* devices are still present on both host and device, but no
data is transferred anymore. The later call with a 'true' argument at [Z]
does not restore it.

Due to the lack of documentation, what chg_det.opmode does exactly is not
clear, however by code inspection it seems reasonable that is disables
something needed to keep the communication working, and testing proves that
disabling these lines lets gadget mode keep working. So prevent changes to
chg_det.opmode when there is a cable connected (VBUS present).

Fixes: 98898f3bc83c ("phy: rockchip-inno-usb2: support otg-port for rk3399")
Cc: stable at vger.kernel.org
Closes: https://lore.kernel.org/lkml/20250414185458.7767aabc at booty/
Signed-off-by: Luca Ceresoli <luca.ceresoli at bootlin.com>
Reviewed-by: Th?o Lebrun <theo.lebrun at bootlin.com>
---
 drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
index 0106d7b7ae24..e5efae7b0135 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
@@ -833,7 +833,8 @@ static void rockchip_chg_detect_work(struct work_struct *work)
 		if (!rport->suspended && !vbus_attach)
 			rockchip_usb2phy_power_off(rport->phy);
 		/* put the controller in non-driving mode */
-		property_enable(base, &rphy->phy_cfg->chg_det.opmode, false);
+		if (!vbus_attach)
+			property_enable(base, &rphy->phy_cfg->chg_det.opmode, false);
 		/* Start DCD processing stage 1 */
 		rockchip_chg_enable_dcd(rphy, true);
 		rphy->chg_state = USB_CHG_STATE_WAIT_FOR_DCD;
@@ -896,7 +897,8 @@ static void rockchip_chg_detect_work(struct work_struct *work)
 		fallthrough;
 	case USB_CHG_STATE_DETECTED:
 		/* put the controller in normal mode */
-		property_enable(base, &rphy->phy_cfg->chg_det.opmode, true);
+		if (!vbus_attach)
+			property_enable(base, &rphy->phy_cfg->chg_det.opmode, true);
 		rockchip_usb2phy_otg_sm_work(&rport->otg_sm_work.work);
 		dev_dbg(&rport->phy->dev, "charger = %s\n",
 			 chg_to_string(rphy->chg_type));

-- 
2.51.1



From naoki at radxa.com  Thu Nov 27 03:02:23 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Thu, 27 Nov 2025 20:02:23 +0900
Subject: [PATCH 0/6] PCI: dwc: Revert Link Up IRQ support
In-Reply-To: <aSgBLQ7rDOiEFhMB@ryzen>
References: <20251111105100.869997-8-cassel@kernel.org>
 <mt7miqkipr4dvxemftq6octxqzauueln252ncrcwy6i2t7wfhi@jtwokeilhwsi>
 <aSRli_Mb6qoQ9TZO@ryzen>
 <7667E818D7D31A4E+cf7c83d4-b99c-469d-8d46-588fc95b843f@radxa.com>
 <F11F0D13437B012D+0c15c5ca-f64f-49f1-9ff5-26b88d59ff59@radxa.com>
 <aSgBLQ7rDOiEFhMB@ryzen>
Message-ID: <53C4D04AE30D7004+12cd5747-7bde-409d-bc02-fcf86a47cc44@radxa.com>

Hi Niklas,

On 11/27/25 16:43, Niklas Cassel wrote:
> Hello FUKAUMI Naoki,
> 
> On Thu, Nov 27, 2025 at 04:34:53PM +0900, FUKAUMI Naoki wrote:
>> Hi all,
>>
>> I'm very sorry, but my ROCK 5C appears to be unreliable. (It worked fine
>> with vanilla v6.13, so I thought it was fine.)
>>
>> I replaced it with another 5C (Lite), and now every method (Niklas's patch,
>> Shawn's patch, and applying patch 1 and 2) seems to work.
> 
> Could you please give us some more information.

Sorry for the confusion.

> Does the Rock 5C Lite have a PCIe switch?

ROCK 5C and 5C Lite use the same board design, only SoC is different, 
but there is no difference regarding PCIe functionality.

They have a PCIe 2.1 connector, and I've been testing a HAT with ASM2806 
via PCIe 2.1 connector.

> Does Rock 5C Lite work fine with the current code in mainline?
> (i.e. with bus enumeration when Link Up IRQ is triggered).

No, bus enumeration behind ASM2806 on ROCK 5C Lite (and any other 
RK358x-based boards I have) is not working with vanilla kernel.

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> Kind regards,
> Niklas
> 




From alchark at gmail.com  Thu Nov 27 03:46:30 2025
From: alchark at gmail.com (Alexey Charkov)
Date: Thu, 27 Nov 2025 15:46:30 +0400
Subject: [PATCH] arm64: dts: rockchip: enable UFS controller on
 FriendlyElec NanoPi M5
Message-ID: <20251127-nanopi-m5-ufs-v1-1-0d28d157712c@gmail.com>

The NanoPi M5 board supports pluggable UFS modules using the UFSHC
inside its Rockchip RK3576 SoC.

Enable the respective devicetree node.

Board specific supply regulators are not added, because they are all
non-gateable descendants of other regulators marked always-on.

Signed-off-by: Alexey Charkov <alchark at gmail.com>
---
 arch/arm64/boot/dts/rockchip/rk3576-nanopi-m5.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3576-nanopi-m5.dts b/arch/arm64/boot/dts/rockchip/rk3576-nanopi-m5.dts
index cce34c541f7c..6b8518c49835 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576-nanopi-m5.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3576-nanopi-m5.dts
@@ -906,6 +906,10 @@ &uart0 {
 	status = "okay";
 };
 
+&ufshc {
+	status = "okay";
+};
+
 &usbdp_phy {
 	status = "okay";
 };

---
base-commit: 663d0d1af3faefe673cabf4b6b077149a87ad71f
change-id: 20251127-nanopi-m5-ufs-52f2c5070167

Best regards,
-- 
Alexey Charkov <alchark at gmail.com>



From greg at kroah.com  Thu Nov 27 04:20:02 2025
From: greg at kroah.com (Greg KH)
Date: Thu, 27 Nov 2025 13:20:02 +0100
Subject: [PATCH 1/2] phy: rockchip: inno-usb2: fix disconnection in
 gadget mode
In-Reply-To: <DEJEFLKA9IJR.237ZLV8HBD2VS@bootlin.com>
References: <20250722-rk3308-fix-usb-gadget-phy-disconnect-v1-0-239872f05f17@bootlin.com>
 <20250722-rk3308-fix-usb-gadget-phy-disconnect-v1-1-239872f05f17@bootlin.com>
 <DEHVRC8CY12S.3LSC6UVSMU0C1@bootlin.com>
 <DEJD8DJZFNZO.11B1UBXJBN7MO@bootlin.com>
 <DEJDSE73CJES.2AB8YSKLW6VE1@bootlin.com>
 <DEJEFLKA9IJR.237ZLV8HBD2VS@bootlin.com>
Message-ID: <2025112725-enviably-ground-9342@gregkh>

On Thu, Nov 27, 2025 at 11:18:45AM +0100, Luca Ceresoli wrote:
> Hi Th?o,
> 
> On Thu Nov 27, 2025 at 10:48 AM CET, Th?o Lebrun wrote:
> > On Thu Nov 27, 2025 at 10:22 AM CET, Luca Ceresoli wrote:
> >> On Tue Nov 25, 2025 at 4:28 PM CET, Th?o Lebrun wrote:
> >>>> The code already checks for !rport->suspended, so add a guard for VBUS as
> >>>> well to avoid a disconnection when a cable is connected.
> >>>
> >>> Your commit message was clear but I was missing one key point: what
> >>> rport->suspended means. It isn't what I first thought. Instead it means
> >>> phy is powered off. Naming is bad but unrelated to your series. Maybe
> >>> add a comment to your commit message like the following?
> >>>
> >>>   The code already checks for !rport->suspended (PHY is powered on), ...
> >>
> >> You are right. I have added a slightly longer text:
> >>
> >>   The code already checks for !rport->suspended (which, somewhat
> >>   counter-intuitively, means the PHY is powered on), ...
> >>
> >> Still worth your Reviewed-by?
> >
> > Even more so.
> 
> Thanks, v2 on its way.
> 
> >> I also added the Cc: stable at vger.kernel.org line, which I noticed being
> >> missing.
> >
> > I never add that Cc trailer and only rely on `Fixes:`. I thought it
> > used to be documented as an alternative to that Cc trailer but it does
> > not show up in `git log -p Documentation/process/stable-kernel-rules.rst`
> >
> > There is one indirect mention of "scripts that look for commits
> > containing a 'Fixes:' tag":
> > https://elixir.bootlin.com/linux/v6.17.9/source/Documentation/process/stable-kernel-rules.rst#L132-L134
> >
> > Anyway, you do right by explicitly tagging `Cc: stable at ...`.
> 
> Theory says Cc: is needed:
> 
> > Note: Attaching a Fixes: tag does not subvert the stable kernel rules
> > process nor the requirement to Cc: stable at vger.kernel.org on all stable
> > patch candidates.
> (https://docs.kernel.org/process/submitting-patches.html#reviewer-s-statement-of-oversight)
> 
> But in the practice I happened to forget Cc: stable in the past, the patch
> got applied and the Fixes: tag was enough for correct cherry-pick in stable
> branches.

That is never guaranteed, it is a "best effort only when the stable
maintainers are bored" type of thing.  Always be explicit, and use cc:
stable, as the documentation has stated for the last 17+ years :)

thanks,

greg k-h


From quentin.schulz at cherry.de  Thu Nov 27 05:28:58 2025
From: quentin.schulz at cherry.de (Quentin Schulz)
Date: Thu, 27 Nov 2025 14:28:58 +0100
Subject: [PATCH 2/2] arm64: dts: rockchip: enable NPU on rk3588-jaguar
In-Reply-To: <20250812085213.1071106-2-heiko@sntech.de>
References: <20250812085213.1071106-1-heiko@sntech.de>
 <20250812085213.1071106-2-heiko@sntech.de>
Message-ID: <3d9ef351-9eb9-41b1-beff-7a1deb73927b@cherry.de>

Hi Heiko,

On 8/12/25 10:52 AM, Heiko Stuebner wrote:
> From: Heiko Stuebner <heiko.stuebner at cherry.de>
> 
> Enable the NPU cores and their mmus and wire up the supply-regulator.
> The regulator itself was already defined, but it does not need to be
> always on - the npu can control it.
> 

My apologies for the time it took me to review and test this.

I tested with aarch64 defconfig + DRM_ACCEL_ROCKET=m loosely following 
the instructions from https://docs.mesa3d.org/teflon.html and the script 
finishes, so I guess that means it works.

I have managed to get an Oops with another defconfig, but that is not 
related to DT so not a blocker for merging this.

Thus:

Reviewed-by: Quentin Schulz <quentin.schulz at cherry.de>
Tested-by: Quentin Schulz <quentin.schulz at cherry.de>

Note that I have the same remark about regulator-boot-on property in 
vdd_npu_s0 I made[1] for Tiger here.

[1] 
https://lore.kernel.org/linux-rockchip/d784230e-49f4-49e9-be4a-bc7c00020cfb at cherry.de/

Thanks!
Quentin


From cassel at kernel.org  Thu Nov 27 05:43:18 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Thu, 27 Nov 2025 14:43:18 +0100
Subject: [PATCH] PCI: dwc: Make Link Up IRQ logic handle already powered on PCIe switches
Message-ID: <20251127134318.3655052-2-cassel@kernel.org>

The DWC glue drivers always call pci_host_probe() during probe(), which
will allocate upstream bridge resources and enumerate the bus.

For controllers without Link Up IRQ support, pci_host_probe() is called
after dw_pcie_wait_for_link(), which will also wait the time required by
the PCIe specification before performing PCI Configuration Space reads.

For controllers with Link Up IRQ support, the pci_host_probe() call (which
will perform PCI Configuration Space reads) is done without any of the
delays mandated by the PCIe specification.

For controllers with Link Up IRQ support, since the pci_host_probe() call
is done without any delay (link training might still be ongoing), it is
very unlikely that this scan will find any devices. Once the Link Up IRQ
triggers, the Link Up IRQ handler will call pci_rescan_bus().

This works fine for PCIe endpoints connected to the Root Port, since they
don't extend the bus. However, if the pci_rescan_bus() call detects a PCIe
switch, then there will be a problem when the downstream busses starts
showing up, because the PCIe controller is not hotplug capable, so we are
not allowed to extend the subordinate bus number after the initial scan,
resulting in error messages such as:

pci_bus 0004:43: busn_res: can not insert [bus 43-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci_bus 0004:43: busn_res: [bus 43-41] end is updated to 43
pci_bus 0004:43: busn_res: can not insert [bus 43] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci 0004:42:00.0: devices behind bridge are unusable because [bus 43] cannot be assigned for them
pci_bus 0004:44: busn_res: can not insert [bus 44-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci_bus 0004:44: busn_res: [bus 44-41] end is updated to 44
pci_bus 0004:44: busn_res: can not insert [bus 44] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci 0004:42:02.0: devices behind bridge are unusable because [bus 44] cannot be assigned for them
pci_bus 0004:45: busn_res: can not insert [bus 45-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci_bus 0004:45: busn_res: [bus 45-41] end is updated to 45
pci_bus 0004:45: busn_res: can not insert [bus 45] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci 0004:42:06.0: devices behind bridge are unusable because [bus 45] cannot be assigned for them
pci_bus 0004:46: busn_res: can not insert [bus 46-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci_bus 0004:46: busn_res: [bus 46-41] end is updated to 46
pci_bus 0004:46: busn_res: can not insert [bus 46] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci 0004:42:0e.0: devices behind bridge are unusable because [bus 46] cannot be assigned for them
pci_bus 0004:42: busn_res: [bus 42-41] end is updated to 46
pci_bus 0004:42: busn_res: can not insert [bus 42-46] under [bus 41] (conflicts with (null) [bus 41])
pci 0004:41:00.0: devices behind bridge are unusable because [bus 42-46] cannot be assigned for them
pcieport 0004:40:00.0: bridge has subordinate 41 but max busn 46

While we would like to set the is_hotplug_bridge flag
(quirk_hotplug_bridge()), many embedded SoCs that use the DWC controller
have synthesized the controller without hot-plug support.
Thus, the Link Up IRQ logic is only mimicking hot-plug functionality, i.e.
it is not compliant with the PCI Hot-Plug Specification, so we cannot make
use of the is_hotplug_bridge flag.

In order to let the Link Up IRQ logic handle PCIe switches that are already
powered on (PCIe switches that not powered on already need to implement a
pwrctrl driver), don't perform a pci_host_probe() call during probe()
(which disregards the delays required by the PCIe specification).

Instead let the first Link Up IRQ call pci_host_probe(). Any follow up
Link Up IRQ will call pci_rescan_bus().

Fixes: ec9fd499b9c6 ("PCI: dw-rockchip: Don't wait for link since we can detect Link Up")
Fixes: 0e0b45ab5d77 ("PCI: dw-rockchip: Enumerate endpoints based on dll_link_up IRQ")
Reported-by: FUKAUMI Naoki <naoki at radxa.com>
Closes: https://lore.kernel.org/linux-pci/1E8E4DB773970CB5+5a52c9e1-01b8-4872-99b7-021099f04031 at radxa.com/
Signed-off-by: Niklas Cassel <cassel at kernel.org>
---
 .../pci/controller/dwc/pcie-designware-host.c | 70 ++++++++++++++++---
 drivers/pci/controller/dwc/pcie-designware.h  |  5 ++
 drivers/pci/controller/dwc/pcie-dw-rockchip.c |  5 +-
 drivers/pci/controller/dwc/pcie-qcom.c        |  5 +-
 4 files changed, 68 insertions(+), 17 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index e92513c5bda51..8654346729574 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -565,6 +565,59 @@ static int dw_pcie_host_get_resources(struct dw_pcie_rp *pp)
 	return 0;
 }
 
+static int dw_pcie_host_initial_scan(struct dw_pcie_rp *pp)
+{
+	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+	struct pci_host_bridge *bridge = pp->bridge;
+	int ret;
+
+	ret = pci_host_probe(bridge);
+	if (ret)
+		return ret;
+
+	if (pp->ops->post_init)
+		pp->ops->post_init(pp);
+
+	dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
+
+	return 0;
+}
+
+void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp)
+{
+	if (!pp->initial_linkup_irq_done) {
+		int ret;
+
+		ret = dw_pcie_host_initial_scan(pp);
+		if (ret) {
+			struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+			struct device *dev = pci->dev;
+
+			dev_err(dev, "Initial scan from IRQ failed: %d\n", ret);
+
+			dw_pcie_stop_link(pci);
+
+			dw_pcie_edma_remove(pci);
+
+			if (pp->has_msi_ctrl)
+				dw_pcie_free_msi(pp);
+
+			if (pp->ops->deinit)
+				pp->ops->deinit(pp);
+
+			if (pp->cfg)
+				pci_ecam_free(pp->cfg);
+		} else {
+			pp->initial_linkup_irq_done = true;
+		}
+	} else {
+		/* Rescan the bus to enumerate endpoint devices */
+		pci_lock_rescan_remove();
+		pci_rescan_bus(pp->bridge->bus);
+		pci_unlock_rescan_remove();
+	}
+}
+
 int dw_pcie_host_init(struct dw_pcie_rp *pp)
 {
 	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
@@ -669,18 +722,17 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
 	 * If there is no Link Up IRQ, we should not bypass the delay
 	 * because that would require users to manually rescan for devices.
 	 */
-	if (!pp->use_linkup_irq)
+	if (!pp->use_linkup_irq) {
 		/* Ignore errors, the link may come up later */
 		dw_pcie_wait_for_link(pci);
 
-	ret = pci_host_probe(bridge);
-	if (ret)
-		goto err_stop_link;
-
-	if (pp->ops->post_init)
-		pp->ops->post_init(pp);
-
-	dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
+		/*
+		 * For platforms with Link Up IRQ, initial scan will be done
+		 * on first Link Up IRQ.
+		 */
+		if (dw_pcie_host_initial_scan(pp))
+			goto err_stop_link;
+	}
 
 	return 0;
 
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index e995f692a1ecd..a31bd93490dcd 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -427,6 +427,7 @@ struct dw_pcie_rp {
 	int			msg_atu_index;
 	struct resource		*msg_res;
 	bool			use_linkup_irq;
+	bool			initial_linkup_irq_done;
 	struct pci_eq_presets	presets;
 	struct pci_config_window *cfg;
 	bool			ecam_enabled;
@@ -807,6 +808,7 @@ void dw_pcie_msi_init(struct dw_pcie_rp *pp);
 int dw_pcie_msi_host_init(struct dw_pcie_rp *pp);
 void dw_pcie_free_msi(struct dw_pcie_rp *pp);
 int dw_pcie_setup_rc(struct dw_pcie_rp *pp);
+void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp);
 int dw_pcie_host_init(struct dw_pcie_rp *pp);
 void dw_pcie_host_deinit(struct dw_pcie_rp *pp);
 int dw_pcie_allocate_domains(struct dw_pcie_rp *pp);
@@ -844,6 +846,9 @@ static inline int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
 	return 0;
 }
 
+static inline void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp)
+{ }
+
 static inline int dw_pcie_host_init(struct dw_pcie_rp *pp)
 {
 	return 0;
diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
index 3e2752c7dd096..8f2cc1ef25e3d 100644
--- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
+++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
@@ -466,10 +466,7 @@ static irqreturn_t rockchip_pcie_rc_sys_irq_thread(int irq, void *arg)
 		if (rockchip_pcie_link_up(pci)) {
 			msleep(PCIE_RESET_CONFIG_WAIT_MS);
 			dev_dbg(dev, "Received Link up event. Starting enumeration!\n");
-			/* Rescan the bus to enumerate endpoint devices */
-			pci_lock_rescan_remove();
-			pci_rescan_bus(pp->bridge->bus);
-			pci_unlock_rescan_remove();
+			dw_pcie_handle_link_up_irq(pp);
 		}
 	}
 
diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index c48a20602d7fa..2d8aca6630949 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -1617,10 +1617,7 @@ static irqreturn_t qcom_pcie_global_irq_thread(int irq, void *data)
 	if (FIELD_GET(PARF_INT_ALL_LINK_UP, status)) {
 		msleep(PCIE_RESET_CONFIG_WAIT_MS);
 		dev_dbg(dev, "Received Link up event. Starting enumeration!\n");
-		/* Rescan the bus to enumerate endpoint devices */
-		pci_lock_rescan_remove();
-		pci_rescan_bus(pp->bridge->bus);
-		pci_unlock_rescan_remove();
+		dw_pcie_handle_link_up_irq(pp);
 
 		qcom_pcie_icc_opp_update(pcie);
 	} else {
-- 
2.52.0



From foss+kernel at 0leil.net  Thu Nov 27 06:36:19 2025
From: foss+kernel at 0leil.net (Quentin Schulz)
Date: Thu, 27 Nov 2025 15:36:19 +0100
Subject: [PATCH] Revert "arm64: dts: rockchip: fix audio-supply for Rock Pi
 4"
Message-ID: <20251127-rock-pi-4-io-domain-apio5-v1-1-9cb92793f734@cherry.de>

From: Quentin Schulz <quentin.schulz at cherry.de>

This reverts commit 8240e87f16d17a9592c9d67857a3dcdbcb98f10d.

The original commit claimed that APIO5 IO domain (supplied with
audio-supply) is supplied by RK808-D Buck 4 as stated in the schematics.

The linked PDF has two non-schematics pages where APIO5 indeed is said
to be 1.8V. Reading the actual schematics[1][2][3][4][5][6][7][8], this
is actually wrong as APIO5 is supplied VCC_3V0 which is LDO8 from
RK808-D and is 3.0V instead of 1.8V from vcca1v8_codec.

This fixes the console disappearing in U-Boot, where the Device Tree is
imported from the Linux kernel repo, when the IO domain driver is built,
as reported by Heinrich[9]. As to why this breaks the console while the
serial is not exposed on any of the pins on the bank in the APIO5
domain, that is a well-kept secret by the SoC for now.

The issue "fixed" by the original commit will need to be fixed another
way.

[1] https://dl.radxa.com/rockpi4/docs/hw/rockpi4/4ap/radxa_rock_4ap_v1600_schematic.pdf
[2] https://dl.radxa.com/rockpi4/docs/hw/rockpi4/4ap/radxa_rock_4ap_v1730_schematic.pdf
[3] https://dl.radxa.com/rockpi4/docs/hw/rockpi4/4bp/radxa_rock_4bp_v1600_schematic.pdf
[4] https://dl.radxa.com/rockpi4/docs/hw/rockpi4/4bp/radxa_rock_4bp_v1730_schematic.pdf
[5] https://dl.radxa.com/rockpi4/docs/hw/rockpi4/ROCK-4-SE-V1.53-SCH.pdf
[6] https://dl.radxa.com/rockpi4/docs/hw/rockpi4/4b/ROCK_4B_v1.52_SCH.pdf
[7] https://dl.radxa.com/rockpi4/docs/hw/rockpi4/4a/ROCK_4A_V1.52_SCH.pdf
[8] https://dl.radxa.com/rockpi4/docs/hw/rockpi4/rockpi4_v13_sch_20181112.pdf
[9] https://lore.kernel.org/u-boot/e7b7b905-4a6c-4342-b1a5-0ad32a5837cf at gmx.de/

Cc: stable at vger.kernel.org
Reported-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
Signed-off-by: Quentin Schulz <quentin.schulz at cherry.de>
---
Note: I do not own any of the Rock Pi 4 variants so I cannot work on
fixing the original issue report by Alex.
---
 arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
index 046dbe3290178..fda7ea87e4efc 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
@@ -516,7 +516,7 @@ &i2s2 {
 };
 
 &io_domains {
-	audio-supply = <&vcca1v8_codec>;
+	audio-supply = <&vcc_3v0>;
 	bt656-supply = <&vcc_3v0>;
 	gpio1830-supply = <&vcc_3v0>;
 	sdmmc-supply = <&vcc_sdio>;

---
base-commit: 765e56e41a5af2d456ddda6cbd617b9d3295ab4e
change-id: 20251127-rock-pi-4-io-domain-apio5-26bc2afa8224

Best regards,
-- 
Quentin Schulz <quentin.schulz at cherry.de>



From s.shtylyov at omp.ru  Thu Nov 27 06:43:55 2025
From: s.shtylyov at omp.ru (Sergey Shtylyov)
Date: Thu, 27 Nov 2025 17:43:55 +0300
Subject: [PATCH] drm/rockchip: vop: avoid division by 0 in scl_cal_scale*()
Message-ID: <8753beda-f74c-41b5-b9ad-823fdf227215@omp.ru>

In scl_cal_scale*(), if the dst parameter equals 1, then division by 0
will happen. We'll have to add a check for the destination rectangle's
width/height being < 2 in vop_plane_atomic_check(), just like the VOP2
driver has to check for the width/height being < 4...

Found by Linux Verification Center (linuxtesting.org) with the Svace static
analysis tool.

Fixes: 4c156c21c794 ("drm/rockchip: vop: support plane scale")
Signed-off-by: Sergey Shtylyov <s.shtylyov at omp.ru>
Cc: stable at vger.kernel.org

---
The patch is against the drm-misc-fixes branch of the DRM kernel.git repo
on gitlab.freedesktop.org.  It replaces [1] for which I've got no neither
feedback nor testing...

[1] https://lore.kernel.org/all/40da59f8-10e9-49b0-9f25-1474067625f6 at omp.ru/

 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |   11 +++++++++++
 1 file changed, 11 insertions(+)

Index: kernel/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
===================================================================
--- kernel.orig/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ kernel/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -817,6 +817,7 @@ static int vop_plane_atomic_check(struct
 	struct drm_framebuffer *fb = new_plane_state->fb;
 	struct vop_win *vop_win = to_vop_win(plane);
 	const struct vop_win_data *win = vop_win->data;
+	struct drm_rect *dest = &new_plane_state->dst;
 	int ret;
 	int min_scale = win->phy->scl ? FRAC_16_16(1, 8) :
 					DRM_PLANE_NO_SCALING;
@@ -844,6 +845,16 @@ static int vop_plane_atomic_check(struct
 	if (ret < 0)
 		return ret;
 
+	if (win->phy->scl) {
+		/* Disallow width/height < 2 to avoid division by 0. */
+		if (drm_rect_width(dest) < 2 || drm_rect_height(dest) < 2) {
+			DRM_DEBUG_KMS("Invalid dest size: %dx%d, min size is 2x2\n",
+				      drm_rect_width(dest), drm_rect_height(dest));
+			new_plane_state->visible = false;
+			return 0;
+		}
+	}
+
 	/*
 	 * Src.x1 can be odd when do clip, but yuv plane start point
 	 * need align with 2 pixel.


From jonas at kwiboo.se  Thu Nov 27 07:10:38 2025
From: jonas at kwiboo.se (Jonas Karlman)
Date: Thu, 27 Nov 2025 16:10:38 +0100
Subject: [PATCH] Revert "arm64: dts: rockchip: fix audio-supply for Rock
 Pi 4"
In-Reply-To: <20251127-rock-pi-4-io-domain-apio5-v1-1-9cb92793f734@cherry.de>
References: <20251127-rock-pi-4-io-domain-apio5-v1-1-9cb92793f734@cherry.de>
Message-ID: <ab1d240f-4130-4088-9ead-9fb562ee9ad2@kwiboo.se>

Hi Quentin,

On 11/27/2025 3:36 PM, Quentin Schulz wrote:
> From: Quentin Schulz <quentin.schulz at cherry.de>
> 
> This reverts commit 8240e87f16d17a9592c9d67857a3dcdbcb98f10d.
> 
> The original commit claimed that APIO5 IO domain (supplied with
> audio-supply) is supplied by RK808-D Buck 4 as stated in the schematics.
> 
> The linked PDF has two non-schematics pages where APIO5 indeed is said
> to be 1.8V. Reading the actual schematics[1][2][3][4][5][6][7][8], this
> is actually wrong as APIO5 is supplied VCC_3V0 which is LDO8 from
> RK808-D and is 3.0V instead of 1.8V from vcca1v8_codec.
> 
> This fixes the console disappearing in U-Boot, where the Device Tree is
> imported from the Linux kernel repo, when the IO domain driver is built,
> as reported by Heinrich[9]. As to why this breaks the console while the
> serial is not exposed on any of the pins on the bank in the APIO5
> domain, that is a well-kept secret by the SoC for now.
> 
> The issue "fixed" by the original commit will need to be fixed another
> way.
> 
> [1] https://dl.radxa.com/rockpi4/docs/hw/rockpi4/4ap/radxa_rock_4ap_v1600_schematic.pdf
> [2] https://dl.radxa.com/rockpi4/docs/hw/rockpi4/4ap/radxa_rock_4ap_v1730_schematic.pdf
> [3] https://dl.radxa.com/rockpi4/docs/hw/rockpi4/4bp/radxa_rock_4bp_v1600_schematic.pdf
> [4] https://dl.radxa.com/rockpi4/docs/hw/rockpi4/4bp/radxa_rock_4bp_v1730_schematic.pdf
> [5] https://dl.radxa.com/rockpi4/docs/hw/rockpi4/ROCK-4-SE-V1.53-SCH.pdf
> [6] https://dl.radxa.com/rockpi4/docs/hw/rockpi4/4b/ROCK_4B_v1.52_SCH.pdf
> [7] https://dl.radxa.com/rockpi4/docs/hw/rockpi4/4a/ROCK_4A_V1.52_SCH.pdf
> [8] https://dl.radxa.com/rockpi4/docs/hw/rockpi4/rockpi4_v13_sch_20181112.pdf
> [9] https://lore.kernel.org/u-boot/e7b7b905-4a6c-4342-b1a5-0ad32a5837cf at gmx.de/
> 
> Cc: stable at vger.kernel.org
> Reported-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
> Signed-off-by: Quentin Schulz <quentin.schulz at cherry.de>
> ---
> Note: I do not own any of the Rock Pi 4 variants so I cannot work on
> fixing the original issue report by Alex.
> ---
>  arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
> index 046dbe3290178..fda7ea87e4efc 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
> @@ -516,7 +516,7 @@ &i2s2 {
>  };
>  
>  &io_domains {
> -	audio-supply = <&vcca1v8_codec>;
> +	audio-supply = <&vcc_3v0>;

This revert/patch seem to be identical to the following patch from a
month ago:

https://lore.kernel.org/all/20251027005220.22298-1-naoki at radxa.com/

Regards,
Jonas

>  	bt656-supply = <&vcc_3v0>;
>  	gpio1830-supply = <&vcc_3v0>;
>  	sdmmc-supply = <&vcc_sdio>;
> 
> ---
> base-commit: 765e56e41a5af2d456ddda6cbd617b9d3295ab4e
> change-id: 20251127-rock-pi-4-io-domain-apio5-26bc2afa8224
> 
> Best regards,



From quentin.schulz at cherry.de  Thu Nov 27 07:20:56 2025
From: quentin.schulz at cherry.de (Quentin Schulz)
Date: Thu, 27 Nov 2025 16:20:56 +0100
Subject: [PATCH] arm64: dts: rockchip: Fix audio-supply for ROCK Pi 4
In-Reply-To: <20251027005220.22298-1-naoki@radxa.com>
References: <20251027005220.22298-1-naoki@radxa.com>
Message-ID: <acfc2185-0cb9-4620-abdb-ee25028e8374@cherry.de>

Hi Naoki,

On 10/27/25 1:52 AM, FUKAUMI Naoki wrote:
> This reverts commit 8240e87f16d17 ("arm64: dts: rockchip: fix
> audio-supply for Rock Pi 4").
> 
> Fix the APIO5_VDD power supply to vcc_3v0 as per the schematics[1][2]
> [3][4][5].
> 
> This fixes the SPI-NOR flash probe failure when the blue LED is on[6],
> and the garbled serial console output on Linux.
> 
> The ES8316 headphone and microphone are confirmed to work correctly
> after this fix.
> 
> [1] https://dl.radxa.com/rockpi4/docs/hw/rockpi4/4a/ROCK_4A_V1.52_SCH.pdf p.14
> [2] https://dl.radxa.com/rockpi4/docs/hw/rockpi4/4ap/radxa_rock_4ap_v1730_schematic.pdf p.14
> [3] https://dl.radxa.com/rockpi4/docs/hw/rockpi4/4b/ROCK_4B_v1.52_SCH.pdf p.14
> [4] https://dl.radxa.com/rockpi4/docs/hw/rockpi4/4bp/radxa_rock_4bp_v1730_schematic.pdf p.14
> [5] https://dl.radxa.com/rockpi4/docs/hw/rockpi4/ROCK-4-SE-V1.53-SCH.pdf p.14
> 
> [6]
> => led blue:status off
> => sf probe
> SF: Detected w25q128 with page size 256 Bytes, erase size 4 KiB, total 16 MiB
> => led blue:status on
> => sf probe
> jedec_spi_nor flash at 0: unrecognized JEDEC id bytes: ff, ff, ff
> Failed to initialize SPI flash at 1:0 (error -2)
> 
> Fixes: 7ebfd4f6b52a6 ("arm64: dts: rockchip: add LED for ROCK Pi 4A/B/C/A+/B+")
> Fixes: 8240e87f16d17 ("arm64: dts: rockchip: fix audio-supply for Rock Pi 4")
> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>

I came to the same conclusion in 
https://lore.kernel.org/linux-rockchip/20251127-rock-pi-4-io-domain-apio5-v1-1-9cb92793f734 at cherry.de/ 
(thanks Jonas for letting me know, should have checked before sending 
the revert :/), so

Reviewed-by: Quentin Schulz <quentin.schulz at cherry.de>

+Cc Heinrich who reported[1] a bug in U-Boot this patch fixes so they 
can give their Tested-by/Reviewed-by if they want to.

[1] 
https://lore.kernel.org/u-boot/e7b7b905-4a6c-4342-b1a5-0ad32a5837cf at gmx.de/

Thanks,
Quentin


From heinrich.schuchardt at canonical.com  Thu Nov 27 07:52:43 2025
From: heinrich.schuchardt at canonical.com (Heinrich Schuchardt)
Date: Thu, 27 Nov 2025 16:52:43 +0100
Subject: [PATCH] arm64: dts: rockchip: Fix audio-supply for ROCK Pi 4
In-Reply-To: <20251027005220.22298-1-naoki@radxa.com>
References: <20251027005220.22298-1-naoki@radxa.com>
Message-ID: <87d6ce91-b2c5-4e96-8103-31df9802786c@canonical.com>

On 10/27/25 01:52, FUKAUMI Naoki wrote:
> This reverts commit 8240e87f16d17 ("arm64: dts: rockchip: fix
> audio-supply for Rock Pi 4").
> 
> Fix the APIO5_VDD power supply to vcc_3v0 as per the schematics[1][2]
> [3][4][5].
> 
> This fixes the SPI-NOR flash probe failure when the blue LED is on[6],
> and the garbled serial console output on Linux.
> 
> The ES8316 headphone and microphone are confirmed to work correctly
> after this fix.
> 
> [1] https://dl.radxa.com/rockpi4/docs/hw/rockpi4/4a/ROCK_4A_V1.52_SCH.pdf p.14
> [2] https://dl.radxa.com/rockpi4/docs/hw/rockpi4/4ap/radxa_rock_4ap_v1730_schematic.pdf p.14
> [3] https://dl.radxa.com/rockpi4/docs/hw/rockpi4/4b/ROCK_4B_v1.52_SCH.pdf p.14
> [4] https://dl.radxa.com/rockpi4/docs/hw/rockpi4/4bp/radxa_rock_4bp_v1730_schematic.pdf p.14
> [5] https://dl.radxa.com/rockpi4/docs/hw/rockpi4/ROCK-4-SE-V1.53-SCH.pdf p.14
> 
> [6]
> => led blue:status off
> => sf probe
> SF: Detected w25q128 with page size 256 Bytes, erase size 4 KiB, total 16 MiB
> => led blue:status on
> => sf probe
> jedec_spi_nor flash at 0: unrecognized JEDEC id bytes: ff, ff, ff
> Failed to initialize SPI flash at 1:0 (error -2)
> 
> Fixes: 7ebfd4f6b52a6 ("arm64: dts: rockchip: add LED for ROCK Pi 4A/B/C/A+/B+")
> Fixes: 8240e87f16d17 ("arm64: dts: rockchip: fix audio-supply for Rock Pi 4")
> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
> ---
>   arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
> index 046dbe3290178..fda7ea87e4efc 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
> @@ -516,7 +516,7 @@ &i2s2 {
>   };
>   
>   &io_domains {
> -	audio-supply = <&vcca1v8_codec>;
> +	audio-supply = <&vcc_3v0>;
>   	bt656-supply = <&vcc_3v0>;
>   	gpio1830-supply = <&vcc_3v0>;
>   	sdmmc-supply = <&vcc_sdio>;


U-Boot uses the same device-tree as Linux. I applied the change in 
U-Boot and it fixes the following problems in U-Boot for me:

* The serial console is not usable after the supply voltages are set.
* Early initialization of the video output fails.

Tested-by: Heinrich Schuchardt <heinrich.schuchardt at canonical.com>


From 18255117159 at 163.com  Thu Nov 27 08:58:07 2025
From: 18255117159 at 163.com (Hans Zhang)
Date: Fri, 28 Nov 2025 00:58:07 +0800
Subject: [PATCH v6 1/2] PCI: Configure Root Port MPS during host probing
In-Reply-To: <20251126235432.GA2726707@bhelgaas>
References: <20251126235432.GA2726707@bhelgaas>
Message-ID: <74a61ccd-c694-44d7-a54c-a40da2df823e@163.com>

Hi Bjorn,

Thank you very much for your reply and the problems you pointed out. The 
next version will modify it.

Best regards,
Hans

On 2025/11/27 07:54, Bjorn Helgaas wrote:
> On Wed, Nov 05, 2025 at 12:51:24AM +0800, Hans Zhang wrote:
>> Current PCIe initialization logic may leave Root Ports (root bridges)
>> operating with non-optimal Maximum Payload Size (MPS) settings. Existing
>> code in pci_configure_mps() returns early for devices without an upstream
>> bridge (!bridge) which includes Root Ports, so their MPS values remain
>> at firmware/hardware defaults. This fails to utilize the controller's full
>> capabilities, leading to suboptimal data transfer efficiency across the
>> PCIe hierarchy.
>>
>> With this patch, during the host controller probing phase:
>> - When PCIe bus tuning is enabled (not PCIE_BUS_TUNE_OFF), and
>> - The device is a Root Port without an upstream bridge (!bridge),
>> The Root Port's MPS is set to its hardware-supported maximum value
>> (128 << dev->pcie_mpss).
>>
>> Note that this initial maximum MPS setting may be reduced later, during
>> downstream device enumeration, if any downstream device does not suppor
>> the Root Port's maximum MPS.
>>
>> This change ensures Root Ports are properly initialized before downstream
>> devices negotiate MPS, while maintaining backward compatibility via the
>> PCIE_BUS_TUNE_OFF check.
> 
> "Properly" is sort of a junk word for me because all it really says is
> we were stupid before, and we're smarter now, but it doesn't explain
> exactly *what* was wrong and why this new thing is "proper."
> 
> It's obvious that the Max_Payload_Size power-on default (128 bytes) is
> suboptimal in some situations, so you don't even need to say that.
> And I think 128 bytes *is* optimal in the PCIE_BUS_PEER2PEER case.
> 
> s/Root Ports (root bridges)/Root Ports/
> s/bridge (!bridge)/bridge/     # a couple times
> s/hardware-supported//         # unnecessary
> s/(128 << dev->pcie_mpss)//    # we can read the spec
> s/suppor/support/
> 
>> Suggested-by: Niklas Cassel <cassel at kernel.org>
>> Suggested-by: Manivannan Sadhasivam <mani at kernel.org>
>> Signed-off-by: Hans Zhang <18255117159 at 163.com>
>> ---
>>   drivers/pci/probe.c | 12 ++++++++++++
>>   1 file changed, 12 insertions(+)
>>
>> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
>> index 0ce98e18b5a8..2459def3af9b 100644
>> --- a/drivers/pci/probe.c
>> +++ b/drivers/pci/probe.c
>> @@ -2196,6 +2196,18 @@ static void pci_configure_mps(struct pci_dev *dev)
>>   		return;
>>   	}
>>   
>> +	/*
>> +	 * Unless MPS strategy is PCIE_BUS_TUNE_OFF (don't touch MPS at all),
>> +	 * start off by setting Root Ports' MPS to MPSS. This only applies to
>> +	 * Root Ports without an upstream bridge (root bridges), as other Root
>> +	 * Ports will have downstream bridges.
> 
> I can't parse this sentence.  *No* Root Port has an upstream bridge.
> So I don't know what "other Root Ports" would be or why they would
> have downstream bridges (any Root Port is likely to have downstream
> endpoints or bridges).
> 
>> +	   ... Depending on the MPS strategy
>> +	 * and MPSS of downstream devices, the Root Port's MPS may be
>> +	 * overridden later.
>> +	 */
>> +	if (!bridge && pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT &&
>> +	    pcie_bus_config != PCIE_BUS_TUNE_OFF)
>> +		pcie_set_mps(dev, 128 << dev->pcie_mpss);
>> +
>>   	if (!bridge || !pci_is_pcie(bridge))
>>   		return;
>>   
>> -- 
>> 2.34.1
>>



From 18255117159 at 163.com  Thu Nov 27 09:09:08 2025
From: 18255117159 at 163.com (Hans Zhang)
Date: Fri, 28 Nov 2025 01:09:08 +0800
Subject: [PATCH v7 2/2] PCI: dwc: Remove redundant MPS configuration
In-Reply-To: <20251127170908.14850-1-18255117159@163.com>
References: <20251127170908.14850-1-18255117159@163.com>
Message-ID: <20251127170908.14850-3-18255117159@163.com>

The Meson PCIe controller driver manually configures maximum payload
size (MPS) through meson_set_max_payload, duplicating functionality now
centralized in the PCI core.  Deprecating redundant code simplifies the
driver and aligns it with the consolidated MPS management strategy,
improving long-term maintainability.

Signed-off-by: Hans Zhang <18255117159 at 163.com>
---
 drivers/pci/controller/dwc/pci-meson.c | 17 -----------------
 1 file changed, 17 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-meson.c b/drivers/pci/controller/dwc/pci-meson.c
index 787469d1b396..3d12e1a9bb0c 100644
--- a/drivers/pci/controller/dwc/pci-meson.c
+++ b/drivers/pci/controller/dwc/pci-meson.c
@@ -261,22 +261,6 @@ static int meson_size_to_payload(struct meson_pcie *mp, int size)
 	return fls(size) - 8;
 }
 
-static void meson_set_max_payload(struct meson_pcie *mp, int size)
-{
-	struct dw_pcie *pci = &mp->pci;
-	u32 val;
-	u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
-	int max_payload_size = meson_size_to_payload(mp, size);
-
-	val = dw_pcie_readl_dbi(pci, offset + PCI_EXP_DEVCTL);
-	val &= ~PCI_EXP_DEVCTL_PAYLOAD;
-	dw_pcie_writel_dbi(pci, offset + PCI_EXP_DEVCTL, val);
-
-	val = dw_pcie_readl_dbi(pci, offset + PCI_EXP_DEVCTL);
-	val |= PCIE_CAP_MAX_PAYLOAD_SIZE(max_payload_size);
-	dw_pcie_writel_dbi(pci, offset + PCI_EXP_DEVCTL, val);
-}
-
 static void meson_set_max_rd_req_size(struct meson_pcie *mp, int size)
 {
 	struct dw_pcie *pci = &mp->pci;
@@ -381,7 +365,6 @@ static int meson_pcie_host_init(struct dw_pcie_rp *pp)
 
 	pp->bridge->ops = &meson_pci_ops;
 
-	meson_set_max_payload(mp, MAX_PAYLOAD_SIZE);
 	meson_set_max_rd_req_size(mp, MAX_READ_REQ_SIZE);
 
 	return 0;
-- 
2.34.1



From 18255117159 at 163.com  Thu Nov 27 09:09:07 2025
From: 18255117159 at 163.com (Hans Zhang)
Date: Fri, 28 Nov 2025 01:09:07 +0800
Subject: [PATCH v7 1/2] PCI: Configure Root Port MPS during host probing
In-Reply-To: <20251127170908.14850-1-18255117159@163.com>
References: <20251127170908.14850-1-18255117159@163.com>
Message-ID: <20251127170908.14850-2-18255117159@163.com>

Current PCIe initialization logic may leave Root Ports operating with
non-optimal Maximum Payload Size (MPS) settings. The existing code in
pci_configure_mps() returns early for devices without an upstream bridge
which includes Root Ports, so their MPS values remain at firmware
defaults. This fails to utilize the controller's full capabilities,
leading to suboptimal data transfer efficiency across the PCIe hierarchy.

With this patch, during the host controller probing phase:
- When PCIe bus tuning is enabled (not PCIE_BUS_TUNE_OFF) and not
  PCIE_BUS_PEER2PEER (which requires the default 128 bytes for optimal
  peer-to-peer operation), and
- The device is a Root Port, the Root Port's MPS is set to its maximum
  supported value.

Note that this initial maximum MPS setting may be reduced later, during
downstream device enumeration, if any downstream device does not support
the Root Port's maximum MPS.

This change ensures Root Ports are initialized to their maximum MPS before
downstream devices negotiate MPS, while maintaining backward compatibility
via the PCIE_BUS_TUNE_OFF check and not interfering with the
PCIE_BUS_PEER2PEER strategy.

Suggested-by: Niklas Cassel <cassel at kernel.org>
Suggested-by: Manivannan Sadhasivam <mani at kernel.org>
Signed-off-by: Hans Zhang <18255117159 at 163.com>
Tested-by: Mahesh Vaidya <mahesh.vaidya at altera.com>
Tested-by: Shawn Lin <shawn.lin at rock-chips.com>
---
 drivers/pci/probe.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 9cd032dff31e..3970d964d868 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -2203,6 +2203,18 @@ static void pci_configure_mps(struct pci_dev *dev)
 		return;
 	}
 
+	/*
+	 * Unless MPS strategy is PCIE_BUS_TUNE_OFF (don't touch MPS at all) or
+	 * PCIE_BUS_PEER2PEER (use minimum MPS for peer-to-peer), set Root Ports'
+	 * MPS to their maximum supported value. Depending on the MPS strategy
+	 * and MPSS of downstream devices, a Root Port's MPS may be reduced
+	 * later during device enumeration.
+	 */
+	if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT &&
+	    pcie_bus_config != PCIE_BUS_TUNE_OFF &&
+	    pcie_bus_config != PCIE_BUS_PEER2PEER)
+		pcie_set_mps(dev, 128 << dev->pcie_mpss);
+
 	if (!bridge || !pci_is_pcie(bridge))
 		return;
 
-- 
2.34.1



From 18255117159 at 163.com  Thu Nov 27 09:09:06 2025
From: 18255117159 at 163.com (Hans Zhang)
Date: Fri, 28 Nov 2025 01:09:06 +0800
Subject: [PATCH v7 0/2] PCI: Configure Root Port MPS during host probing
Message-ID: <20251127170908.14850-1-18255117159@163.com>

Current PCIe initialization exhibits a key optimization gap: Root Ports
may operate with non-optimal Maximum Payload Size (MPS) settings. While
downstream device configuration is handled during bus enumeration, Root
Port MPS values inherited from firmware or hardware defaults often fail
to utilize the full capabilities supported by controller hardware. This
results in suboptimal data transfer efficiency throughout the PCIe
hierarchy.

This patch series addresses this by:

1. Core PCI enhancement (Patch 1):
- Proactively configures Root Port MPS during host controller probing
- Sets initial MPS to hardware maximum (128 << dev->pcie_mpss)
- Conditional on PCIe bus tuning being enabled (PCIE_BUS_TUNE_OFF unset)
  and not in PCIE_BUS_PEER2PEER mode (which requires default 128 bytes)
- Maintains backward compatibility via PCIE_BUS_TUNE_OFF check
- Preserves standard MPS negotiation during downstream enumeration

2. Driver cleanup (Patch 2):
- Removes redundant MPS configuration from Meson PCIe controller driver
- Functionality is now centralized in PCI core
- Simplifies driver maintenance long-term

---
Changes in v7:
- Exclude PCIE_BUS_PEER2PEER mode from Root Port MPS configuration
- Remove redundant check for upstream bridge (Root Ports don't have one)
- Improve commit message and code comments as per Bjorn.

Changes for v6:
https://patchwork.kernel.org/project/linux-pci/patch/20251104165125.174168-1-18255117159 at 163.com/

- Modify the commit message and comments. (Bjorn)
- Patch 1/2 code logic: Add !bridge check to configure MPS only for Root Ports
  without an upstream bridge (root bridges), avoiding incorrect handling of
  non-root-bridge Root Ports (Niklas).

Changes for v5:
https://patchwork.kernel.org/project/linux-pci/patch/20250620155507.1022099-1-18255117159 at 163.com/

- Use pcie_set_mps directly instead of pcie_write_mps.
- The patch 1 commit message were modified.

Changes for v4:
https://patchwork.kernel.org/project/linux-pci/patch/20250510155607.390687-1-18255117159 at 163.com/

- The patch [v4 1/2] add a comment to explain why it was done this way.
- The patch [v4 2/2] have not been modified.
- Drop patch [v3 3/3]. The Maintainer of the pci-aardvark.c file suggests
  that this patch cannot be submitted. In addition, Mani also suggests
  dropping this patch until this series of issues is resolved.

Changes for v3:
https://patchwork.kernel.org/project/linux-pci/patch/20250506173439.292460-1-18255117159 at 163.com/

- The new split is patch 2/3 and 3/3.
- Modify the patch 1/3 according to Niklas' suggestion.

Changes for v2:
https://patchwork.kernel.org/project/linux-pci/patch/20250425095708.32662-1-18255117159 at 163.com/

- According to the Maintainer's suggestion, limit the setting of MPS
  changes to platforms with controller drivers.
- Delete the MPS code set by the SOC manufacturer.
---

Hans Zhang (2):
  PCI: Configure Root Port MPS during host probing
  PCI: dwc: Remove redundant MPS configuration

 drivers/pci/controller/dwc/pci-meson.c | 17 -----------------
 drivers/pci/probe.c                    | 12 ++++++++++++
 2 files changed, 12 insertions(+), 17 deletions(-)


base-commit: 765e56e41a5af2d456ddda6cbd617b9d3295ab4e
-- 
2.34.1



From ariel.dalessandro at collabora.com  Thu Nov 27 10:15:47 2025
From: ariel.dalessandro at collabora.com (Ariel D'Alessandro)
Date: Thu, 27 Nov 2025 15:15:47 -0300
Subject: [PATCH v2 03/12] dt-bindings: net: Convert Marvell 8897/8997
 bindings to DT schema
In-Reply-To: <CAL_Jsq+eeiw9oaqQPWt2=rZSX98Pak_oB=tfQFvEehwLZ=S52g@mail.gmail.com>
References: <20250911151001.108744-1-ariel.dalessandro@collabora.com>
 <20250911151001.108744-4-ariel.dalessandro@collabora.com>
 <20250912140619.GA1293647-robh@kernel.org>
 <fb20e4fe-df0a-4089-a7cf-e82bfe1f8e00@collabora.com>
 <CAL_Jsq+eeiw9oaqQPWt2=rZSX98Pak_oB=tfQFvEehwLZ=S52g@mail.gmail.com>
Message-ID: <2dd059f5-96d4-44a1-84be-b14dce28cf06@collabora.com>

Hi Rob,

On 11/24/25 3:54 PM, Rob Herring wrote:
> On Wed, Oct 1, 2025 at 12:28?PM Ariel D'Alessandro
> <ariel.dalessandro at collabora.com> wrote:
>>
>> Rob,
>>
>> On 9/12/25 11:06 AM, Rob Herring wrote:
>>> On Thu, Sep 11, 2025 at 12:09:52PM -0300, Ariel D'Alessandro wrote:
>>>> Convert the existing text-based DT bindings for Marvell 8897/8997
>>>> (sd8897/sd8997) bluetooth devices controller to a DT schema.
>>>>
>>>> While here:
>>>>
>>>> * bindings for "usb1286,204e" (USB interface) are dropped from the DT
>>>>     schema definition as these are currently documented in file [0].
>>>> * DT binding users are updated to use bluetooth generic name
>>>>     recommendation.
>>>>
>>>> [0] Documentation/devicetree/bindings/net/btusb.txt
>>>>
>>>> Signed-off-by: Ariel D'Alessandro <ariel.dalessandro at collabora.com>
>>>> ---
>>>>    .../net/bluetooth/marvell,sd8897-bt.yaml      | 79 ++++++++++++++++++
>>>>    .../devicetree/bindings/net/btusb.txt         |  2 +-
>>>>    .../bindings/net/marvell-bt-8xxx.txt          | 83 -------------------
>>>
>>>>    .../dts/rockchip/rk3288-veyron-fievel.dts     |  2 +-
>>>>    .../boot/dts/rockchip/rk3288-veyron-jaq.dts   |  2 +-
>>>>    arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi  |  2 +-
>>>
>>> .dts files should be separate patches. Please send the bindings patches
>>> separately per subsystem so subsystem maintainers can apply them. All
>>> the Mediatek dts changes can be 1 series.
>>
>> Ack, will fix in v3.
> 
> Are you going to send v3 still?

Yes, will be sending out v3 asap, with the remaining changes.
Sorry for the delay.

-- 
Ariel D'Alessandro
Software Engineer

Collabora Ltd.
Platinum Building, St John's Innovation Park, Cambridge CB4 0DS, UK 
Registered in England & Wales, no. 5513718



From shawn.lin at rock-chips.com  Thu Nov 27 17:06:13 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Fri, 28 Nov 2025 09:06:13 +0800
Subject: [PATCH] PCI: dwc: Make Link Up IRQ logic handle already powered
 on PCIe switches
In-Reply-To: <20251127134318.3655052-2-cassel@kernel.org>
References: <20251127134318.3655052-2-cassel@kernel.org>
Message-ID: <dbe6975d-9b99-4493-9145-b2db382fd468@rock-chips.com>

? 2025/11/27 ??? 21:43, Niklas Cassel ??:
> The DWC glue drivers always call pci_host_probe() during probe(), which
> will allocate upstream bridge resources and enumerate the bus.
> 
> For controllers without Link Up IRQ support, pci_host_probe() is called
> after dw_pcie_wait_for_link(), which will also wait the time required by
> the PCIe specification before performing PCI Configuration Space reads.
> 
> For controllers with Link Up IRQ support, the pci_host_probe() call (which
> will perform PCI Configuration Space reads) is done without any of the
> delays mandated by the PCIe specification.
> 
> For controllers with Link Up IRQ support, since the pci_host_probe() call
> is done without any delay (link training might still be ongoing), it is
> very unlikely that this scan will find any devices. Once the Link Up IRQ
> triggers, the Link Up IRQ handler will call pci_rescan_bus().
> 
> This works fine for PCIe endpoints connected to the Root Port, since they
> don't extend the bus. However, if the pci_rescan_bus() call detects a PCIe
> switch, then there will be a problem when the downstream busses starts
> showing up, because the PCIe controller is not hotplug capable, so we are
> not allowed to extend the subordinate bus number after the initial scan,
> resulting in error messages such as:
> 
> pci_bus 0004:43: busn_res: can not insert [bus 43-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:43: busn_res: [bus 43-41] end is updated to 43
> pci_bus 0004:43: busn_res: can not insert [bus 43] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:00.0: devices behind bridge are unusable because [bus 43] cannot be assigned for them
> pci_bus 0004:44: busn_res: can not insert [bus 44-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:44: busn_res: [bus 44-41] end is updated to 44
> pci_bus 0004:44: busn_res: can not insert [bus 44] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:02.0: devices behind bridge are unusable because [bus 44] cannot be assigned for them
> pci_bus 0004:45: busn_res: can not insert [bus 45-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:45: busn_res: [bus 45-41] end is updated to 45
> pci_bus 0004:45: busn_res: can not insert [bus 45] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:06.0: devices behind bridge are unusable because [bus 45] cannot be assigned for them
> pci_bus 0004:46: busn_res: can not insert [bus 46-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:46: busn_res: [bus 46-41] end is updated to 46
> pci_bus 0004:46: busn_res: can not insert [bus 46] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:0e.0: devices behind bridge are unusable because [bus 46] cannot be assigned for them
> pci_bus 0004:42: busn_res: [bus 42-41] end is updated to 46
> pci_bus 0004:42: busn_res: can not insert [bus 42-46] under [bus 41] (conflicts with (null) [bus 41])
> pci 0004:41:00.0: devices behind bridge are unusable because [bus 42-46] cannot be assigned for them
> pcieport 0004:40:00.0: bridge has subordinate 41 but max busn 46
> 
> While we would like to set the is_hotplug_bridge flag
> (quirk_hotplug_bridge()), many embedded SoCs that use the DWC controller
> have synthesized the controller without hot-plug support.
> Thus, the Link Up IRQ logic is only mimicking hot-plug functionality, i.e.
> it is not compliant with the PCI Hot-Plug Specification, so we cannot make
> use of the is_hotplug_bridge flag.
> 
> In order to let the Link Up IRQ logic handle PCIe switches that are already
> powered on (PCIe switches that not powered on already need to implement a
> pwrctrl driver), don't perform a pci_host_probe() call during probe()
> (which disregards the delays required by the PCIe specification).
> 
> Instead let the first Link Up IRQ call pci_host_probe(). Any follow up
> Link Up IRQ will call pci_rescan_bus().
> 

Thanks for fixing this, I'v tested it on RK3588S-EVB1 with both of PCIe
switch + 2 NVMe and NVMe directly connected.

FWIW,
Tested-by: Shawn Lin <shawn.lin at rock-chips.com>

> Fixes: ec9fd499b9c6 ("PCI: dw-rockchip: Don't wait for link since we can detect Link Up")
> Fixes: 0e0b45ab5d77 ("PCI: dw-rockchip: Enumerate endpoints based on dll_link_up IRQ")
> Reported-by: FUKAUMI Naoki <naoki at radxa.com>
> Closes: https://lore.kernel.org/linux-pci/1E8E4DB773970CB5+5a52c9e1-01b8-4872-99b7-021099f04031 at radxa.com/
> Signed-off-by: Niklas Cassel <cassel at kernel.org>
> ---
>   .../pci/controller/dwc/pcie-designware-host.c | 70 ++++++++++++++++---
>   drivers/pci/controller/dwc/pcie-designware.h  |  5 ++
>   drivers/pci/controller/dwc/pcie-dw-rockchip.c |  5 +-
>   drivers/pci/controller/dwc/pcie-qcom.c        |  5 +-
>   4 files changed, 68 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> index e92513c5bda51..8654346729574 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -565,6 +565,59 @@ static int dw_pcie_host_get_resources(struct dw_pcie_rp *pp)
>   	return 0;
>   }
>   
> +static int dw_pcie_host_initial_scan(struct dw_pcie_rp *pp)
> +{
> +	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> +	struct pci_host_bridge *bridge = pp->bridge;
> +	int ret;
> +
> +	ret = pci_host_probe(bridge);
> +	if (ret)
> +		return ret;
> +
> +	if (pp->ops->post_init)
> +		pp->ops->post_init(pp);
> +
> +	dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
> +
> +	return 0;
> +}
> +
> +void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp)
> +{
> +	if (!pp->initial_linkup_irq_done) {
> +		int ret;
> +
> +		ret = dw_pcie_host_initial_scan(pp);
> +		if (ret) {
> +			struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> +			struct device *dev = pci->dev;
> +
> +			dev_err(dev, "Initial scan from IRQ failed: %d\n", ret);
> +
> +			dw_pcie_stop_link(pci);
> +
> +			dw_pcie_edma_remove(pci);
> +
> +			if (pp->has_msi_ctrl)
> +				dw_pcie_free_msi(pp);
> +
> +			if (pp->ops->deinit)
> +				pp->ops->deinit(pp);
> +
> +			if (pp->cfg)
> +				pci_ecam_free(pp->cfg);
> +		} else {
> +			pp->initial_linkup_irq_done = true;
> +		}
> +	} else {
> +		/* Rescan the bus to enumerate endpoint devices */
> +		pci_lock_rescan_remove();
> +		pci_rescan_bus(pp->bridge->bus);
> +		pci_unlock_rescan_remove();
> +	}
> +}
> +
>   int dw_pcie_host_init(struct dw_pcie_rp *pp)
>   {
>   	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> @@ -669,18 +722,17 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
>   	 * If there is no Link Up IRQ, we should not bypass the delay
>   	 * because that would require users to manually rescan for devices.
>   	 */
> -	if (!pp->use_linkup_irq)
> +	if (!pp->use_linkup_irq) {
>   		/* Ignore errors, the link may come up later */
>   		dw_pcie_wait_for_link(pci);
>   
> -	ret = pci_host_probe(bridge);
> -	if (ret)
> -		goto err_stop_link;
> -
> -	if (pp->ops->post_init)
> -		pp->ops->post_init(pp);
> -
> -	dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
> +		/*
> +		 * For platforms with Link Up IRQ, initial scan will be done
> +		 * on first Link Up IRQ.
> +		 */
> +		if (dw_pcie_host_initial_scan(pp))
> +			goto err_stop_link;
> +	}
>   
>   	return 0;
>   
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> index e995f692a1ecd..a31bd93490dcd 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -427,6 +427,7 @@ struct dw_pcie_rp {
>   	int			msg_atu_index;
>   	struct resource		*msg_res;
>   	bool			use_linkup_irq;
> +	bool			initial_linkup_irq_done;
>   	struct pci_eq_presets	presets;
>   	struct pci_config_window *cfg;
>   	bool			ecam_enabled;
> @@ -807,6 +808,7 @@ void dw_pcie_msi_init(struct dw_pcie_rp *pp);
>   int dw_pcie_msi_host_init(struct dw_pcie_rp *pp);
>   void dw_pcie_free_msi(struct dw_pcie_rp *pp);
>   int dw_pcie_setup_rc(struct dw_pcie_rp *pp);
> +void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp);
>   int dw_pcie_host_init(struct dw_pcie_rp *pp);
>   void dw_pcie_host_deinit(struct dw_pcie_rp *pp);
>   int dw_pcie_allocate_domains(struct dw_pcie_rp *pp);
> @@ -844,6 +846,9 @@ static inline int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
>   	return 0;
>   }
>   
> +static inline void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp)
> +{ }
> +
>   static inline int dw_pcie_host_init(struct dw_pcie_rp *pp)
>   {
>   	return 0;
> diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> index 3e2752c7dd096..8f2cc1ef25e3d 100644
> --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> @@ -466,10 +466,7 @@ static irqreturn_t rockchip_pcie_rc_sys_irq_thread(int irq, void *arg)
>   		if (rockchip_pcie_link_up(pci)) {
>   			msleep(PCIE_RESET_CONFIG_WAIT_MS);
>   			dev_dbg(dev, "Received Link up event. Starting enumeration!\n");
> -			/* Rescan the bus to enumerate endpoint devices */
> -			pci_lock_rescan_remove();
> -			pci_rescan_bus(pp->bridge->bus);
> -			pci_unlock_rescan_remove();
> +			dw_pcie_handle_link_up_irq(pp);
>   		}
>   	}
>   
> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
> index c48a20602d7fa..2d8aca6630949 100644
> --- a/drivers/pci/controller/dwc/pcie-qcom.c
> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> @@ -1617,10 +1617,7 @@ static irqreturn_t qcom_pcie_global_irq_thread(int irq, void *data)
>   	if (FIELD_GET(PARF_INT_ALL_LINK_UP, status)) {
>   		msleep(PCIE_RESET_CONFIG_WAIT_MS);
>   		dev_dbg(dev, "Received Link up event. Starting enumeration!\n");
> -		/* Rescan the bus to enumerate endpoint devices */
> -		pci_lock_rescan_remove();
> -		pci_rescan_bus(pp->bridge->bus);
> -		pci_unlock_rescan_remove();
> +		dw_pcie_handle_link_up_irq(pp);
>   
>   		qcom_pcie_icc_opp_update(pcie);
>   	} else {



From kernel at airkyi.com  Thu Nov 27 18:03:55 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Fri, 28 Nov 2025 10:03:55 +0800
Subject: [PATCH v11 01/11] usb: typec: Set the bus also for the port and plug altmodes
In-Reply-To: <20251128020405.90-1-kernel@airkyi.com>
References: <20251128020405.90-1-kernel@airkyi.com>
Message-ID: <20251128020405.90-2-kernel@airkyi.com>

From: Heikki Krogerus <heikki.krogerus at linux.intel.com>

The port and plug altmodes can't be bound to the altmode
drivers because the altmode drivers are meant for partner
communication using the VDM (vendor defined messages), but
they can still be part of the bus. The bus will make sure
that the normal bus notifications are available also with
the port altmodes.

The previously used common device type for all alternate
modes is replaced with separate dedicated device types for
port, plug, and partner alternate modes.

Signed-off-by: Heikki Krogerus <heikki.krogerus at linux.intel.com>
---
 drivers/usb/typec/bus.c   | 24 +++++++++++++++++++++++-
 drivers/usb/typec/bus.h   |  8 ++++++--
 drivers/usb/typec/class.c | 33 ++++++++++++++++++++++-----------
 3 files changed, 51 insertions(+), 14 deletions(-)

diff --git a/drivers/usb/typec/bus.c b/drivers/usb/typec/bus.c
index a884cec9ab7e..a33da7f458a5 100644
--- a/drivers/usb/typec/bus.c
+++ b/drivers/usb/typec/bus.c
@@ -445,7 +445,23 @@ static struct attribute *typec_attrs[] = {
 	&dev_attr_description.attr,
 	NULL
 };
-ATTRIBUTE_GROUPS(typec);
+
+static umode_t typec_is_visible(struct kobject *kobj, struct attribute *attr, int n)
+{
+	if (is_typec_partner_altmode(kobj_to_dev(kobj)))
+		return attr->mode;
+	return 0;
+}
+
+static const struct attribute_group typec_group = {
+	.is_visible = typec_is_visible,
+	.attrs = typec_attrs,
+};
+
+static const struct attribute_group *typec_groups[] = {
+	&typec_group,
+	NULL
+};
 
 static int typec_match(struct device *dev, const struct device_driver *driver)
 {
@@ -453,6 +469,9 @@ static int typec_match(struct device *dev, const struct device_driver *driver)
 	struct typec_altmode *altmode = to_typec_altmode(dev);
 	const struct typec_device_id *id;
 
+	if (!is_typec_partner_altmode(dev))
+		return 0;
+
 	for (id = drv->id_table; id->svid; id++)
 		if (id->svid == altmode->svid)
 			return 1;
@@ -463,6 +482,9 @@ static int typec_uevent(const struct device *dev, struct kobj_uevent_env *env)
 {
 	const struct typec_altmode *altmode = to_typec_altmode(dev);
 
+	if (!is_typec_partner_altmode(dev))
+		return 0;
+
 	if (add_uevent_var(env, "SVID=%04X", altmode->svid))
 		return -ENOMEM;
 
diff --git a/drivers/usb/typec/bus.h b/drivers/usb/typec/bus.h
index 643b8c81786d..b58e131450d1 100644
--- a/drivers/usb/typec/bus.h
+++ b/drivers/usb/typec/bus.h
@@ -29,8 +29,12 @@ struct altmode {
 #define to_altmode(d) container_of(d, struct altmode, adev)
 
 extern const struct bus_type typec_bus;
-extern const struct device_type typec_altmode_dev_type;
+extern const struct device_type typec_port_altmode_dev_type;
+extern const struct device_type typec_plug_altmode_dev_type;
+extern const struct device_type typec_partner_altmode_dev_type;
 
-#define is_typec_altmode(_dev_) (_dev_->type == &typec_altmode_dev_type)
+#define is_typec_port_altmode(dev) ((dev)->type == &typec_port_altmode_dev_type)
+#define is_typec_plug_altmode(dev) ((dev)->type == &typec_plug_altmode_dev_type)
+#define is_typec_partner_altmode(dev) ((dev)->type == &typec_partner_altmode_dev_type)
 
 #endif /* __USB_TYPEC_ALTMODE_H__ */
diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
index 9b2647cb199b..d6b88317f8a4 100644
--- a/drivers/usb/typec/class.c
+++ b/drivers/usb/typec/class.c
@@ -235,7 +235,7 @@ static int altmode_match(struct device *dev, const void *data)
 	struct typec_altmode *adev = to_typec_altmode(dev);
 	const struct typec_device_id *id = data;
 
-	if (!is_typec_altmode(dev))
+	if (!is_typec_port_altmode(dev))
 		return 0;
 
 	return (adev->svid == id->svid);
@@ -532,15 +532,28 @@ static void typec_altmode_release(struct device *dev)
 	kfree(alt);
 }
 
-const struct device_type typec_altmode_dev_type = {
-	.name = "typec_alternate_mode",
+const struct device_type typec_port_altmode_dev_type = {
+	.name = "typec_port_alternate_mode",
+	.groups = typec_altmode_groups,
+	.release = typec_altmode_release,
+};
+
+const struct device_type typec_plug_altmode_dev_type = {
+	.name = "typec_plug_alternate_mode",
+	.groups = typec_altmode_groups,
+	.release = typec_altmode_release,
+};
+
+const struct device_type typec_partner_altmode_dev_type = {
+	.name = "typec_partner_alternate_mode",
 	.groups = typec_altmode_groups,
 	.release = typec_altmode_release,
 };
 
 static struct typec_altmode *
 typec_register_altmode(struct device *parent,
-		       const struct typec_altmode_desc *desc)
+		       const struct typec_altmode_desc *desc,
+		       const struct device_type *type)
 {
 	unsigned int id = altmode_id_get(parent);
 	bool is_port = is_typec_port(parent);
@@ -575,7 +588,7 @@ typec_register_altmode(struct device *parent,
 
 	alt->adev.dev.parent = parent;
 	alt->adev.dev.groups = alt->groups;
-	alt->adev.dev.type = &typec_altmode_dev_type;
+	alt->adev.dev.type = type;
 	dev_set_name(&alt->adev.dev, "%s.%u", dev_name(parent), id);
 
 	get_device(alt->adev.dev.parent);
@@ -584,9 +597,7 @@ typec_register_altmode(struct device *parent,
 	if (!is_port)
 		typec_altmode_set_partner(alt);
 
-	/* The partners are bind to drivers */
-	if (is_typec_partner(parent))
-		alt->adev.dev.bus = &typec_bus;
+	alt->adev.dev.bus = &typec_bus;
 
 	/* Plug alt modes need a class to generate udev events. */
 	if (is_typec_plug(parent))
@@ -963,7 +974,7 @@ struct typec_altmode *
 typec_partner_register_altmode(struct typec_partner *partner,
 			       const struct typec_altmode_desc *desc)
 {
-	return typec_register_altmode(&partner->dev, desc);
+	return typec_register_altmode(&partner->dev, desc, &typec_partner_altmode_dev_type);
 }
 EXPORT_SYMBOL_GPL(typec_partner_register_altmode);
 
@@ -1193,7 +1204,7 @@ struct typec_altmode *
 typec_plug_register_altmode(struct typec_plug *plug,
 			    const struct typec_altmode_desc *desc)
 {
-	return typec_register_altmode(&plug->dev, desc);
+	return typec_register_altmode(&plug->dev, desc, &typec_plug_altmode_dev_type);
 }
 EXPORT_SYMBOL_GPL(typec_plug_register_altmode);
 
@@ -2493,7 +2504,7 @@ typec_port_register_altmode(struct typec_port *port,
 		return ERR_CAST(retimer);
 	}
 
-	adev = typec_register_altmode(&port->dev, desc);
+	adev = typec_register_altmode(&port->dev, desc, &typec_port_altmode_dev_type);
 	if (IS_ERR(adev)) {
 		typec_retimer_put(retimer);
 		typec_mux_put(mux);
-- 
2.51.1



From kernel at airkyi.com  Thu Nov 27 18:03:58 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Fri, 28 Nov 2025 10:03:58 +0800
Subject: [PATCH v11 04/11] drm/bridge: aux: Add drm_aux_bridge_register_from_node()
In-Reply-To: <20251128020405.90-1-kernel@airkyi.com>
References: <20251128020405.90-1-kernel@airkyi.com>
Message-ID: <20251128020405.90-5-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

The drm_aux_bridge_register() uses the device->of_node as the
bridge->of_node.

This patch adds drm_aux_bridge_register_from_node() to allow
specifying the of_node corresponding to the bridge.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>
---

(no changes since v11)

 drivers/gpu/drm/bridge/aux-bridge.c | 24 ++++++++++++++++++++++--
 include/drm/bridge/aux-bridge.h     |  6 ++++++
 2 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/aux-bridge.c b/drivers/gpu/drm/bridge/aux-bridge.c
index b3e4cdff61d6..52dff4601c2d 100644
--- a/drivers/gpu/drm/bridge/aux-bridge.c
+++ b/drivers/gpu/drm/bridge/aux-bridge.c
@@ -35,6 +35,7 @@ static void drm_aux_bridge_unregister_adev(void *_adev)
 /**
  * drm_aux_bridge_register - Create a simple bridge device to link the chain
  * @parent: device instance providing this bridge
+ * @np: device node pointer corresponding to this bridge instance
  *
  * Creates a simple DRM bridge that doesn't implement any drm_bridge
  * operations. Such bridges merely fill a place in the bridge chain linking
@@ -42,7 +43,7 @@ static void drm_aux_bridge_unregister_adev(void *_adev)
  *
  * Return: zero on success, negative error code on failure
  */
-int drm_aux_bridge_register(struct device *parent)
+int drm_aux_bridge_register_from_node(struct device *parent, struct device_node *np)
 {
 	struct auxiliary_device *adev;
 	int ret;
@@ -62,7 +63,10 @@ int drm_aux_bridge_register(struct device *parent)
 	adev->dev.parent = parent;
 	adev->dev.release = drm_aux_bridge_release;
 
-	device_set_of_node_from_dev(&adev->dev, parent);
+	if (np)
+		device_set_node(&adev->dev, of_fwnode_handle(np));
+	else
+		device_set_of_node_from_dev(&adev->dev, parent);
 
 	ret = auxiliary_device_init(adev);
 	if (ret) {
@@ -80,6 +84,22 @@ int drm_aux_bridge_register(struct device *parent)
 
 	return devm_add_action_or_reset(parent, drm_aux_bridge_unregister_adev, adev);
 }
+EXPORT_SYMBOL_GPL(drm_aux_bridge_register_from_node);
+
+/**
+ * drm_aux_bridge_register - Create a simple bridge device to link the chain
+ * @parent: device instance providing this bridge
+ *
+ * Creates a simple DRM bridge that doesn't implement any drm_bridge
+ * operations. Such bridges merely fill a place in the bridge chain linking
+ * surrounding DRM bridges.
+ *
+ * Return: zero on success, negative error code on failure
+ */
+int drm_aux_bridge_register(struct device *parent)
+{
+	return drm_aux_bridge_register_from_node(parent, NULL);
+}
 EXPORT_SYMBOL_GPL(drm_aux_bridge_register);
 
 struct drm_aux_bridge_data {
diff --git a/include/drm/bridge/aux-bridge.h b/include/drm/bridge/aux-bridge.h
index c2f5a855512f..7dd1f17a1354 100644
--- a/include/drm/bridge/aux-bridge.h
+++ b/include/drm/bridge/aux-bridge.h
@@ -13,11 +13,17 @@ struct auxiliary_device;
 
 #if IS_ENABLED(CONFIG_DRM_AUX_BRIDGE)
 int drm_aux_bridge_register(struct device *parent);
+int drm_aux_bridge_register_from_node(struct device *parent, struct device_node *np);
 #else
 static inline int drm_aux_bridge_register(struct device *parent)
 {
 	return 0;
 }
+
+static inline int drm_aux_bridge_register_from_node(struct device *parent, struct device_node *np)
+{
+	return 0;
+}
 #endif
 
 #if IS_ENABLED(CONFIG_DRM_AUX_HPD_BRIDGE)
-- 
2.51.1



From kernel at airkyi.com  Thu Nov 27 18:03:57 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Fri, 28 Nov 2025 10:03:57 +0800
Subject: [PATCH v11 03/11] drm/bridge: Implement generic USB Type-C DP HPD bridge
In-Reply-To: <20251128020405.90-1-kernel@airkyi.com>
References: <20251128020405.90-1-kernel@airkyi.com>
Message-ID: <20251128020405.90-4-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

The HPD function of Type-C DP is implemented through
drm_connector_oob_hotplug_event(). For embedded DP, it is required
that the DRM connector fwnode corresponds to the Type-C port fwnode.

To describe the relationship between the DP controller and the Type-C
port device, we usually using drm_bridge to build a bridge chain.

Now several USB-C controller drivers have already implemented the DP
HPD bridge function provided by aux-hpd-bridge.c, it will build a DP
HPD bridge on USB-C connector port device.

But this requires the USB-C controller driver to manually register the
HPD bridge. If the driver does not implement this feature, the bridge
will not be create.

So this patch implements a generic DP HPD bridge based on
aux-hpd-bridge.c. It will monitor Type-C bus events, and when a
Type-C port device containing the DP svid is registered, it will
create an HPD bridge for it without the need for the USB-C controller
driver to implement it.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---

Changes in v11:
- Switch to using typec bus notifiers.

(no changes since v10)

Changes in v9:
- Remove the exposed DRM_AUX_HPD_BRIDGE option, and select
DRM_AUX_HPD_TYPEC_BRIDGE when it is available.
- Add more commit comment about problem background.

Changes in v8:
- Merge generic DP HPD bridge into one module.

 drivers/gpu/drm/bridge/Kconfig                | 10 ++++
 drivers/gpu/drm/bridge/Makefile               |  1 +
 .../gpu/drm/bridge/aux-hpd-typec-dp-bridge.c  | 51 +++++++++++++++++++
 3 files changed, 62 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index a250afd8d662..559487aa09a9 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -30,6 +30,16 @@ config DRM_AUX_HPD_BRIDGE
 	  Simple bridge that terminates the bridge chain and provides HPD
 	  support.
 
+if DRM_AUX_HPD_BRIDGE
+config DRM_AUX_HPD_TYPEC_BRIDGE
+	tristate
+	depends on TYPEC || !TYPEC
+	default TYPEC
+	help
+	  Simple bridge that terminates the bridge chain and provides HPD
+	  support. It build bridge on each USB-C connector device node.
+endif
+
 menu "Display Interface Bridges"
 	depends on DRM && DRM_BRIDGE
 
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index c7dc03182e59..a3a0393d2e72 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_DRM_AUX_BRIDGE) += aux-bridge.o
 obj-$(CONFIG_DRM_AUX_HPD_BRIDGE) += aux-hpd-bridge.o
+obj-$(CONFIG_DRM_AUX_HPD_TYPEC_BRIDGE) += aux-hpd-typec-dp-bridge.o
 obj-$(CONFIG_DRM_CHIPONE_ICN6211) += chipone-icn6211.o
 obj-$(CONFIG_DRM_CHRONTEL_CH7033) += chrontel-ch7033.o
 obj-$(CONFIG_DRM_CROS_EC_ANX7688) += cros-ec-anx7688.o
diff --git a/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c b/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
new file mode 100644
index 000000000000..94be3d5f69e9
--- /dev/null
+++ b/drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0+
+#include <linux/of.h>
+#include <linux/usb/typec_altmode.h>
+#include <linux/usb/typec_dp.h>
+
+#include <drm/bridge/aux-bridge.h>
+
+static int drm_typec_bus_event(struct notifier_block *nb,
+			       unsigned long action, void *data)
+{
+	struct device *dev = (struct device *)data;
+	struct typec_altmode *alt = to_typec_altmode(dev);
+
+	if (action != BUS_NOTIFY_ADD_DEVICE)
+		goto done;
+
+	if (is_typec_partner_altmode(&alt->dev) || alt->svid != USB_TYPEC_DP_SID)
+		goto done;
+
+	/*
+	 * alt->dev.parent->parent : USB-C controller device
+	 * alt->dev.parent         : USB-C connector device
+	 */
+	drm_dp_hpd_bridge_register(alt->dev.parent->parent,
+				   to_of_node(alt->dev.parent->fwnode));
+
+done:
+	return NOTIFY_OK;
+}
+
+static struct notifier_block drm_typec_event_nb = {
+	.notifier_call = drm_typec_bus_event,
+};
+
+static void drm_aux_hpd_typec_dp_bridge_module_exit(void)
+{
+	bus_unregister_notifier(&typec_bus, &drm_typec_event_nb);
+}
+
+static int __init drm_aux_hpd_typec_dp_bridge_module_init(void)
+{
+	bus_register_notifier(&typec_bus, &drm_typec_event_nb);
+
+	return 0;
+}
+
+module_init(drm_aux_hpd_typec_dp_bridge_module_init);
+module_exit(drm_aux_hpd_typec_dp_bridge_module_exit);
+
+MODULE_DESCRIPTION("DRM TYPEC DP HPD BRIDGE");
+MODULE_LICENSE("GPL");
-- 
2.51.1



From kernel at airkyi.com  Thu Nov 27 18:03:59 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Fri, 28 Nov 2025 10:03:59 +0800
Subject: [PATCH v11 05/11] dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode-switch
In-Reply-To: <20251128020405.90-1-kernel@airkyi.com>
References: <20251128020405.90-1-kernel@airkyi.com>
Message-ID: <20251128020405.90-6-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

The RK3399 SoC integrates two USB/DP combo PHYs, each of which
supports software-configurable pin mapping and DisplayPort lane
assignment. These capabilities enable the PHY itself to handle both
mode switching and orientation switching, based on the Type-C plug
orientation and USB PD negotiation results.

While an external Type-C controller is still required to detect cable
attachment and report USB PD events, the actual mode and orientation
switching is performed internally by the PHY through software
configuration. This allows the PHY to act as a Type-C multiplexer for
both data role and DP altmode configuration.

To reflect this hardware design, this patch introduces a new
"mode-switch" property for the dp-port node in the device tree bindings.
This property indicates that the connected PHY is capable of handling
Type-C mode switching itself.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
---

(no changes since v5)

Changes in v4:
- Remove "|" in description.

Changes in v3:
- Add more descriptions to clarify the role of the PHY in switching.

Changes in v2:
- Reuse dp-port/usb3-port in rk3399-typec-phy binding.

 .../devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml  | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml b/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml
index 91c011f68cd0..83ebcde096ea 100644
--- a/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml
@@ -51,6 +51,12 @@ properties:
       '#phy-cells':
         const: 0
 
+      mode-switch:
+        description:
+          Indicates the PHY can handle altmode switching. In this case,
+          requires an external USB Type-C controller to report USB PD message.
+        type: boolean
+
       port:
         $ref: /schemas/graph.yaml#/properties/port
         description: Connection to USB Type-C connector
-- 
2.51.1



From kernel at airkyi.com  Thu Nov 27 18:04:00 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Fri, 28 Nov 2025 10:04:00 +0800
Subject: [PATCH v11 06/11] phy: rockchip: phy-rockchip-typec: Add typec_mux/typec_switch support
In-Reply-To: <20251128020405.90-1-kernel@airkyi.com>
References: <20251128020405.90-1-kernel@airkyi.com>
Message-ID: <20251128020405.90-7-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

This patch add support for Type-C Port Controller Manager. Each PHY
will register typec_mux and typec_switch when external Type-C
controller is present. Type-C events are handled by TCPM without
extcon.

The extcon device should still be supported.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---

(no changes since v7)

Changes in v6:
- Fix depend in Kconfig.
- Check DP svid in tcphy_typec_mux_set().
- Remove mode setting in tcphy_orien_sw_set().

(no changes since v5)

Changes in v4:
- Remove notify DP HPD state by USB/DP PHY.

(no changes since v3)

Changes in v2:
- Fix compile error when CONFIG_TYPEC is not enabled.
- Notify DP HPD state by USB/DP PHY.

 drivers/phy/rockchip/Kconfig              |   1 +
 drivers/phy/rockchip/phy-rockchip-typec.c | 368 +++++++++++++++++++++-
 2 files changed, 353 insertions(+), 16 deletions(-)

diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
index 14698571b607..db4adc7c53da 100644
--- a/drivers/phy/rockchip/Kconfig
+++ b/drivers/phy/rockchip/Kconfig
@@ -119,6 +119,7 @@ config PHY_ROCKCHIP_SNPS_PCIE3
 config PHY_ROCKCHIP_TYPEC
 	tristate "Rockchip TYPEC PHY Driver"
 	depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST)
+	depends on TYPEC || TYPEC=n
 	select EXTCON
 	select GENERIC_PHY
 	select RESET_CONTROLLER
diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c
index d9701b6106d5..1f5b4142cbe4 100644
--- a/drivers/phy/rockchip/phy-rockchip-typec.c
+++ b/drivers/phy/rockchip/phy-rockchip-typec.c
@@ -54,6 +54,8 @@
 
 #include <linux/mfd/syscon.h>
 #include <linux/phy/phy.h>
+#include <linux/usb/typec_dp.h>
+#include <linux/usb/typec_mux.h>
 
 #define CMN_SSM_BANDGAP			(0x21 << 2)
 #define CMN_SSM_BIAS			(0x22 << 2)
@@ -286,12 +288,23 @@
 #define RX_DIAG_SC2C_DELAY		(0x81e1 << 2)
 
 #define PMA_LANE_CFG			(0xc000 << 2)
+#define PMA_LANE3_DP_LANE_SEL(x)	(((x) & 0x3) << 14)
+#define PMA_LANE3_INTERFACE_SEL(x)	(((x) & 0x1) << 12)
+#define PMA_LANE2_DP_LANE_SEL(x)	(((x) & 0x3) << 10)
+#define PMA_LANE2_INTERFACE_SEL(x)	(((x) & 0x1) << 8)
+#define PMA_LANE1_DP_LANE_SEL(x)	(((x) & 0x3) << 6)
+#define PMA_LANE1_INTERFACE_SEL(x)	(((x) & 0x1) << 4)
+#define PMA_LANE0_DP_LANE_SEL(x)	(((x) & 0x3) << 2)
+#define PMA_LANE0_INTERFACE_SEL(x)	(((x) & 0x1) << 0)
 #define PIPE_CMN_CTRL1			(0xc001 << 2)
 #define PIPE_CMN_CTRL2			(0xc002 << 2)
 #define PIPE_COM_LOCK_CFG1		(0xc003 << 2)
 #define PIPE_COM_LOCK_CFG2		(0xc004 << 2)
 #define PIPE_RCV_DET_INH		(0xc005 << 2)
 #define DP_MODE_CTL			(0xc008 << 2)
+#define PHY_DP_POWER_STATE_ACK_MASK	GENMASK(7, 4)
+#define PHY_DP_POWER_STATE_ACK_SHIFT	4
+#define PHY_DP_POWER_STATE_MASK		GENMASK(3, 0)
 #define DP_CLK_CTL			(0xc009 << 2)
 #define STS				(0xc00F << 2)
 #define PHY_ISO_CMN_CTRL		(0xc010 << 2)
@@ -327,8 +340,15 @@
 
 #define DP_MODE_A0			BIT(4)
 #define DP_MODE_A2			BIT(6)
-#define DP_MODE_ENTER_A0		0xc101
-#define DP_MODE_ENTER_A2		0xc104
+
+#define DP_MODE_MASK			0xf
+#define DP_MODE_ENTER_A0		BIT(0)
+#define DP_MODE_ENTER_A2		BIT(2)
+#define DP_MODE_ENTER_A3		BIT(3)
+#define DP_MODE_A0_ACK			BIT(4)
+#define DP_MODE_A2_ACK			BIT(6)
+#define DP_MODE_A3_ACK			BIT(7)
+#define DP_LINK_RESET_DEASSERTED	BIT(8)
 
 #define PHY_MODE_SET_TIMEOUT		100000
 
@@ -340,6 +360,31 @@
 #define MODE_DFP_USB			BIT(1)
 #define MODE_DFP_DP			BIT(2)
 
+enum phy_dp_lane_num {
+	PHY_DP_LANE_0 = 0,
+	PHY_DP_LANE_1,
+	PHY_DP_LANE_2,
+	PHY_DP_LANE_3,
+};
+
+enum phy_pma_if {
+	PMA_IF_PIPE_PCS = 0,
+	PMA_IF_PHY_DP,
+};
+
+enum phy_typec_role {
+	TYPEC_PHY_USB = 0,
+	TYPEC_PHY_DP,
+	TYPEC_PHY_MAX,
+};
+
+enum phy_dp_power_state {
+	PHY_DP_POWER_STATE_A0 = 0,
+	PHY_DP_POWER_STATE_A1,
+	PHY_DP_POWER_STATE_A2,
+	PHY_DP_POWER_STATE_A3,
+};
+
 struct usb3phy_reg {
 	u32 offset;
 	u32 enable_bit;
@@ -372,18 +417,22 @@ struct rockchip_typec_phy {
 	struct device *dev;
 	void __iomem *base;
 	struct extcon_dev *extcon;
+	struct typec_mux_dev *mux;
+	struct typec_switch_dev *sw;
 	struct regmap *grf_regs;
 	struct clk *clk_core;
 	struct clk *clk_ref;
 	struct reset_control *uphy_rst;
 	struct reset_control *pipe_rst;
 	struct reset_control *tcphy_rst;
+	struct phy *phys[TYPEC_PHY_MAX];
 	const struct rockchip_usb3phy_port_cfg *port_cfgs;
 	/* mutex to protect access to individual PHYs */
 	struct mutex lock;
 
 	bool flip;
 	u8 mode;
+	u8 new_mode;
 };
 
 struct phy_reg {
@@ -454,6 +503,99 @@ static const struct rockchip_usb3phy_port_cfg rk3399_usb3phy_port_cfgs[] = {
 	{ /* sentinel */ }
 };
 
+static int tcphy_cfg_usb3_to_usb2_only(struct rockchip_typec_phy *tcphy,
+				       bool value);
+
+static int tcphy_dp_set_power_state(struct rockchip_typec_phy *tcphy,
+				    enum phy_dp_power_state state)
+{
+	u32 ack, reg, sts = BIT(state);
+	int ret;
+
+	/*
+	 * Power state changes must not be requested until after the cmn_ready
+	 * signal has gone active.
+	 */
+	reg = readl(tcphy->base + PMA_CMN_CTRL1);
+	if (!(reg & CMN_READY)) {
+		dev_err(tcphy->dev, "cmn_ready in the inactive state\n");
+		return -EINVAL;
+	}
+
+	reg = readl(tcphy->base + DP_MODE_CTL);
+	reg &= ~PHY_DP_POWER_STATE_MASK;
+	reg |= sts;
+	writel(reg, tcphy->base + DP_MODE_CTL);
+
+	ret = readl_poll_timeout(tcphy->base + DP_MODE_CTL,
+				 ack, (((ack & PHY_DP_POWER_STATE_ACK_MASK) >>
+				 PHY_DP_POWER_STATE_ACK_SHIFT) == sts), 10,
+				 PHY_MODE_SET_TIMEOUT);
+	if (ret < 0) {
+		dev_err(tcphy->dev, "failed to enter power state %d\n", state);
+		return ret;
+	}
+
+	return 0;
+}
+
+/*
+ * For the TypeC PHY, the 4 lanes are mapping to the USB TypeC receptacle pins
+ * as follows:
+ *   -------------------------------------------------------------------
+ *	PHY Lanes/Module Pins			TypeC Receptacle Pins
+ *   -------------------------------------------------------------------
+ *	Lane0 (tx_p/m_ln_0)			TX1+/TX1- (pins A2/A3)
+ *	Lane1 (tx_rx_p/m_ln_1)			RX1+/RX1- (pins B11/B10)
+ *	Lane2 (tx_rx_p/m_ln_2)			RX2+/RX2- (pins A11/A10)
+ *	Lane3 (tx_p/m_ln_3)			TX2+/TX2- (pins B2/B3)
+ *   -------------------------------------------------------------------
+ *
+ * USB and DP lanes mapping to TypeC PHY lanes for each of pin assignment
+ * options (normal connector orientation) described in the VESA DisplayPort
+ * Alt Mode on USB TypeC Standard as follows:
+ *
+ * ----------------------------------------------------------------------
+ *	PHY Lanes	A	B	C	D	E	F
+ * ----------------------------------------------------------------------
+ *	  0	       ML1     SSTX    ML2     SSTX    ML2     SSTX
+ *	  1	       ML3     SSRX    ML3     SSRX    ML3     SSRX
+ *	  2	       ML2     ML1     ML0     ML0     ML0     ML0
+ *	  3	       ML0     ML0     ML1     ML1     ML1     ML1
+ * ----------------------------------------------------------------------
+ */
+static void tcphy_set_lane_mapping(struct rockchip_typec_phy *tcphy, u8 mode)
+{
+	/*
+	 * The PMA_LANE_CFG register is used to select whether a PMA lane
+	 * is mapped for USB or PHY DP. The PMA_LANE_CFG register is
+	 * configured based on a normal connector orientation. Logic in the
+	 * PHY automatically handles the flipped connector case based on the
+	 * setting of orientation of TypeC PHY.
+	 */
+	if (mode == MODE_DFP_DP) {
+		/* This maps to VESA DP Alt Mode pin assignments C and E. */
+		writel(PMA_LANE3_DP_LANE_SEL(PHY_DP_LANE_1) |
+		       PMA_LANE3_INTERFACE_SEL(PMA_IF_PHY_DP) |
+		       PMA_LANE2_DP_LANE_SEL(PHY_DP_LANE_0) |
+		       PMA_LANE2_INTERFACE_SEL(PMA_IF_PHY_DP) |
+		       PMA_LANE1_DP_LANE_SEL(PHY_DP_LANE_3) |
+		       PMA_LANE1_INTERFACE_SEL(PMA_IF_PHY_DP) |
+		       PMA_LANE0_DP_LANE_SEL(PHY_DP_LANE_2) |
+		       PMA_LANE0_INTERFACE_SEL(PMA_IF_PHY_DP),
+		       tcphy->base + PMA_LANE_CFG);
+	} else {
+		/* This maps to VESA DP Alt Mode pin assignments D and F. */
+		writel(PMA_LANE3_DP_LANE_SEL(PHY_DP_LANE_1) |
+		       PMA_LANE3_INTERFACE_SEL(PMA_IF_PHY_DP) |
+		       PMA_LANE2_DP_LANE_SEL(PHY_DP_LANE_0) |
+		       PMA_LANE2_INTERFACE_SEL(PMA_IF_PHY_DP) |
+		       PMA_LANE1_INTERFACE_SEL(PMA_IF_PIPE_PCS) |
+		       PMA_LANE0_INTERFACE_SEL(PMA_IF_PIPE_PCS),
+		       tcphy->base + PMA_LANE_CFG);
+	}
+}
+
 static void tcphy_cfg_24m(struct rockchip_typec_phy *tcphy)
 {
 	u32 i, rdata;
@@ -743,8 +885,10 @@ static int tcphy_phy_init(struct rockchip_typec_phy *tcphy, u8 mode)
 	tcphy_dp_aux_set_flip(tcphy);
 
 	tcphy_cfg_24m(tcphy);
+	tcphy_set_lane_mapping(tcphy, mode);
 
 	if (mode == MODE_DFP_DP) {
+		tcphy_cfg_usb3_to_usb2_only(tcphy, true);
 		tcphy_cfg_dp_pll(tcphy);
 		for (i = 0; i < 4; i++)
 			tcphy_dp_cfg_lane(tcphy, i);
@@ -768,7 +912,10 @@ static int tcphy_phy_init(struct rockchip_typec_phy *tcphy, u8 mode)
 		writel(PIN_ASSIGN_D_F, tcphy->base + PMA_LANE_CFG);
 	}
 
-	writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL);
+	val = readl(tcphy->base + DP_MODE_CTL);
+	val &= ~DP_MODE_MASK;
+	val |= DP_MODE_ENTER_A2 | DP_LINK_RESET_DEASSERTED;
+	writel(val, tcphy->base + DP_MODE_CTL);
 
 	reset_control_deassert(tcphy->uphy_rst);
 
@@ -811,8 +958,9 @@ static int tcphy_get_mode(struct rockchip_typec_phy *tcphy)
 	u8 mode;
 	int ret, ufp, dp;
 
+	/* If extcon not exist, try to use tcpm mode */
 	if (!edev)
-		return MODE_DFP_USB;
+		return tcphy->new_mode;
 
 	ufp = extcon_get_state(edev, EXTCON_USB);
 	dp = extcon_get_state(edev, EXTCON_DISP_DP);
@@ -850,6 +998,71 @@ static int tcphy_get_mode(struct rockchip_typec_phy *tcphy)
 	return mode;
 }
 
+#if IS_ENABLED(CONFIG_TYPEC)
+static int tcphy_orien_sw_set(struct typec_switch_dev *sw,
+			      enum typec_orientation orien)
+{
+	struct rockchip_typec_phy *tcphy = typec_switch_get_drvdata(sw);
+
+	mutex_lock(&tcphy->lock);
+
+	if (orien == TYPEC_ORIENTATION_NONE) {
+		tcphy->new_mode = MODE_DISCONNECT;
+		goto unlock_ret;
+	}
+
+	tcphy->flip = (orien == TYPEC_ORIENTATION_REVERSE) ? true : false;
+
+unlock_ret:
+	mutex_unlock(&tcphy->lock);
+	return 0;
+}
+
+static void udphy_orien_switch_unregister(void *data)
+{
+	struct rockchip_typec_phy *tcphy = data;
+
+	typec_switch_unregister(tcphy->sw);
+}
+
+static int tcphy_setup_orien_switch(struct rockchip_typec_phy *tcphy)
+{
+	struct typec_switch_desc sw_desc = { };
+	struct device_node *np;
+	int ret = 0;
+
+	np = of_get_child_by_name(tcphy->dev->of_node, "usb3-port");
+	if (!np)
+		return 0;
+
+	if (!of_property_read_bool(np, "orientation-switch"))
+		goto put_np;
+
+	sw_desc.drvdata = tcphy;
+	sw_desc.fwnode = device_get_named_child_node(tcphy->dev, "usb3-port");
+	sw_desc.set = tcphy_orien_sw_set;
+
+	tcphy->sw = typec_switch_register(tcphy->dev, &sw_desc);
+	if (IS_ERR(tcphy->sw)) {
+		dev_err(tcphy->dev, "Error register typec orientation switch: %ld\n",
+			PTR_ERR(tcphy->sw));
+		ret = PTR_ERR(tcphy->sw);
+		goto put_np;
+	}
+
+	ret = devm_add_action_or_reset(tcphy->dev, udphy_orien_switch_unregister, tcphy);
+
+put_np:
+	of_node_put(np);
+	return ret;
+}
+#else
+static int tcphy_setup_orien_switch(struct rockchip_typec_phy *tcphy)
+{
+	return 0;
+}
+#endif
+
 static int tcphy_cfg_usb3_to_usb2_only(struct rockchip_typec_phy *tcphy,
 				       bool value)
 {
@@ -989,14 +1202,9 @@ static int rockchip_dp_phy_power_on(struct phy *phy)
 
 	tcphy_dp_aux_calibration(tcphy);
 
-	writel(DP_MODE_ENTER_A0, tcphy->base + DP_MODE_CTL);
-
-	ret = readx_poll_timeout(readl, tcphy->base + DP_MODE_CTL,
-				 val, val & DP_MODE_A0, 1000,
-				 PHY_MODE_SET_TIMEOUT);
-	if (ret < 0) {
-		writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL);
-		dev_err(tcphy->dev, "failed to wait TCPHY enter A0\n");
+	ret = tcphy_dp_set_power_state(tcphy, PHY_DP_POWER_STATE_A0);
+	if (ret) {
+		dev_err(tcphy->dev, "failed to enter A0 power state\n");
 		goto power_on_finish;
 	}
 
@@ -1013,6 +1221,7 @@ static int rockchip_dp_phy_power_on(struct phy *phy)
 static int rockchip_dp_phy_power_off(struct phy *phy)
 {
 	struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy);
+	int ret;
 
 	mutex_lock(&tcphy->lock);
 
@@ -1021,7 +1230,11 @@ static int rockchip_dp_phy_power_off(struct phy *phy)
 
 	tcphy->mode &= ~MODE_DFP_DP;
 
-	writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL);
+	ret = tcphy_dp_set_power_state(tcphy, PHY_DP_POWER_STATE_A2);
+	if (ret) {
+		dev_err(tcphy->dev, "failed to enter A2 power state\n");
+		goto unlock;
+	}
 
 	if (tcphy->mode == MODE_DISCONNECT)
 		tcphy_phy_deinit(tcphy);
@@ -1037,6 +1250,93 @@ static const struct phy_ops rockchip_dp_phy_ops = {
 	.owner		= THIS_MODULE,
 };
 
+#if IS_ENABLED(CONFIG_TYPEC)
+static int tcphy_typec_mux_set(struct typec_mux_dev *mux, struct typec_mux_state *state)
+{
+	struct rockchip_typec_phy *tcphy = typec_mux_get_drvdata(mux);
+	struct typec_displayport_data *data;
+	int hpd = 0;
+
+	mutex_lock(&tcphy->lock);
+
+	switch (state->mode) {
+	case TYPEC_STATE_SAFE:
+		fallthrough;
+	case TYPEC_STATE_USB:
+		tcphy->new_mode = MODE_DFP_USB;
+		phy_set_bus_width(tcphy->phys[TYPEC_PHY_DP], 0);
+		break;
+	case TYPEC_DP_STATE_C:
+	case TYPEC_DP_STATE_E:
+		if (state->alt->svid != USB_TYPEC_DP_SID)
+			break;
+		tcphy->new_mode = MODE_DFP_DP;
+		data = state->data;
+		hpd = !!(data->status & DP_STATUS_HPD_STATE);
+		phy_set_bus_width(tcphy->phys[TYPEC_PHY_DP], hpd ? 4 : 0);
+		break;
+	case TYPEC_DP_STATE_D:
+		if (state->alt->svid != USB_TYPEC_DP_SID)
+			break;
+		tcphy->new_mode = MODE_DFP_DP | MODE_DFP_USB;
+		data = state->data;
+		hpd = !!(data->status & DP_STATUS_HPD_STATE);
+		phy_set_bus_width(tcphy->phys[TYPEC_PHY_DP], hpd ? 2 : 0);
+		break;
+	default:
+		break;
+	}
+
+	mutex_unlock(&tcphy->lock);
+
+	return 0;
+}
+
+static void tcphy_typec_mux_unregister(void *data)
+{
+	struct rockchip_typec_phy *tcphy = data;
+
+	typec_mux_unregister(tcphy->mux);
+}
+
+static int tcphy_setup_typec_mux(struct rockchip_typec_phy *tcphy)
+{
+	struct typec_mux_desc mux_desc = {};
+	struct device_node *np;
+	int ret = 0;
+
+	np = of_get_child_by_name(tcphy->dev->of_node, "dp-port");
+	if (!np)
+		return 0;
+
+	if (!of_property_read_bool(np, "mode-switch"))
+		goto put_np;
+
+	mux_desc.drvdata = tcphy;
+	mux_desc.fwnode = device_get_named_child_node(tcphy->dev, "dp-port");
+	mux_desc.set = tcphy_typec_mux_set;
+
+	tcphy->mux = typec_mux_register(tcphy->dev, &mux_desc);
+	if (IS_ERR(tcphy->mux)) {
+		dev_err(tcphy->dev, "Error register typec mux: %ld\n",
+			PTR_ERR(tcphy->mux));
+		ret = PTR_ERR(tcphy->mux);
+		goto put_np;
+	}
+
+	ret = devm_add_action_or_reset(tcphy->dev, tcphy_typec_mux_unregister, tcphy);
+
+put_np:
+	of_node_put(np);
+	return ret;
+}
+#else
+static int tcphy_setup_typec_mux(struct rockchip_typec_phy *tcphy)
+{
+	return 0;
+}
+#endif
+
 static int tcphy_parse_dt(struct rockchip_typec_phy *tcphy,
 			  struct device *dev)
 {
@@ -1095,6 +1395,25 @@ static void typec_phy_pre_init(struct rockchip_typec_phy *tcphy)
 	tcphy->mode = MODE_DISCONNECT;
 }
 
+static int typec_dp_lane_get(struct rockchip_typec_phy *tcphy)
+{
+	int dp_lanes;
+
+	switch (tcphy->new_mode) {
+	case MODE_DFP_DP:
+		dp_lanes = 4;
+		break;
+	case MODE_DFP_DP | MODE_DFP_USB:
+		dp_lanes = 2;
+		break;
+	default:
+		dp_lanes = 0;
+		break;
+	}
+
+	return dp_lanes;
+}
+
 static int rockchip_typec_phy_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -1142,6 +1461,7 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev)
 		return ret;
 
 	tcphy->dev = dev;
+	tcphy->new_mode = MODE_DFP_USB;
 	platform_set_drvdata(pdev, tcphy);
 	mutex_init(&tcphy->lock);
 
@@ -1151,6 +1471,7 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev)
 	if (IS_ERR(tcphy->extcon)) {
 		if (PTR_ERR(tcphy->extcon) == -ENODEV) {
 			tcphy->extcon = NULL;
+			dev_info(dev, "extcon not exist, try to use typec mux\n");
 		} else {
 			if (PTR_ERR(tcphy->extcon) != -EPROBE_DEFER)
 				dev_err(dev, "Invalid or missing extcon\n");
@@ -1158,19 +1479,34 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev)
 		}
 	}
 
+	ret = tcphy_setup_orien_switch(tcphy);
+	if (ret)
+		return ret;
+
+	ret = tcphy_setup_typec_mux(tcphy);
+	if (ret)
+		return ret;
+
 	pm_runtime_enable(dev);
 
 	for_each_available_child_of_node(np, child_np) {
 		struct phy *phy;
 
-		if (of_node_name_eq(child_np, "dp-port"))
+		if (of_node_name_eq(child_np, "dp-port")) {
 			phy = devm_phy_create(dev, child_np,
 					      &rockchip_dp_phy_ops);
-		else if (of_node_name_eq(child_np, "usb3-port"))
+			if (!IS_ERR(phy)) {
+				tcphy->phys[TYPEC_PHY_DP] = phy;
+				phy_set_bus_width(phy, typec_dp_lane_get(tcphy));
+			}
+		} else if (of_node_name_eq(child_np, "usb3-port")) {
 			phy = devm_phy_create(dev, child_np,
 					      &rockchip_usb3_phy_ops);
-		else
+			if (!IS_ERR(phy))
+				tcphy->phys[TYPEC_PHY_USB] = phy;
+		} else {
 			continue;
+		}
 
 		if (IS_ERR(phy)) {
 			dev_err(dev, "failed to create phy: %pOFn\n",
-- 
2.51.1



From kernel at airkyi.com  Thu Nov 27 18:03:54 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Fri, 28 Nov 2025 10:03:54 +0800
Subject: [PATCH v11 00/11] Add Type-C DP support for RK3399 EVB IND board
Message-ID: <20251128020405.90-1-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

This series focuses on adding Type-C DP support for USBDP PHY and DP
driver. The USBDP PHY and DP will perceive the changes in cable status
based on the USB PD and Type-C state machines provided by TCPM. Before
this, the USBDP PHY and DP controller of RK3399 sensed cable state
changes through extcon, and devices such as the RK3399 Gru-Chromebook
rely on them. This series should not break them.

====
1. DisplayPort HPD status notify

Before v7, I implemented a variety of DP HPD status notify. However,
they all had various problems and it was difficult to become a generic
solution.

Under the guidance of Heikki and Dmitry, a decoupled notification
method between the TypeC and DRM subsystems was introduced in v7.
First, a notification is sent when TypeC registers a new altmode.
Then, a generic DP AUX HPD bridge is implemented on the DRM side.

During v7-v10, we added a new notifier in typec to notify the altmode
device register event. With the help of Greg and Heikki, we implemented
the reuse of notifiers for the type bus itself in patch1 of v11.

That makes it redundant for each Type-C controller driver to implement
a similar DP AUX HPD bridge in embedded scenarios.

====
2. Altmode switching and orientation switching for USBDP PHY

For USB Type-C interfaces, an external Type-C controller chip assists
by detecting cable attachment, determining plug orientation, and
reporting USB PD message. The USB/DP combo PHY supports software
configurable pin mapping and DisplayPort lane assignment. Based on
these message, the combo PHY can perform both altmode switching and
orientation switching via software.

The RK3399 EVB IND board has a Type-C interface DisplayPort. It use
fusb302 chip as Type-C controller. The connection diagram is shown below:

fusb302 chip +---> USB2.0 PHY ----> DWC3 USB controller
             |
             +---> USB/DP PHY0 +--> CDN-DP controller
                               |
                               +--> DWC3 USB controller

====
3. Multiple bridge model for RK3399 CDN-DP

The RK3399 has two USB/DP combo PHY and one CDN-DP controller. And
the CDN-DP can be switched to output to one of the PHYs.

USB/DP PHY0 ---+
               | <----> CDN-DP controller
USB/DP PHY1 ---+

In previous versions, if both PHY ports were connected to DP,
the CDN-DP driver would select the first PHY port for output.

On Dmitry's suggestion, we introduced a multi-bridge model to support
flexible selection of the output PHY port. For each PHY port, a
separate encoder and bridge are registered.

The change is based on the DRM AUX HPD bridge, rather than the
extcon approach. This requires the DT to correctly describe the
connections between the first bridge in bridge chain and DP
controller. And Once the first bridge is obtained, we can get the
last bridge corresponding to the USB-C connector, and then set the
DRM connector's fwnode to the corresponding one to enable HPD
notification.

====
Patch1 set the bus also for the port and plug altmodes.
Patch2 export typec bus and typec altmode device types.
Patch3 add generic USB Type-C DP HPD bridge.
Patch4 add new API drm_aux_bridge_register_from_node().
Patch5 add new Type-C mode switch for RK3399 USBDP phy binding.
Patch6 add typec_mux and typec_switch for RK3399 USBDP PHY.
Patch7 add DRM AUX bridge support for RK3399 USBDP PHY.
Patch8 drops CDN-DP's extcon dependency when Type-C is present.
Patch9 add multiple bridges to support PHY port selection.
Patch10 add missing dp_out port for RK3399 CDN-DP.
Patch11 add Type-C DP support for RK3399 EVB IND board.

Changes in v11:
- Link to V10: https://lore.kernel.org/all/20251120022343.250-1-kernel at airkyi.com/
- Switch to using typec bus notifiers.

Changes in v10:
- Link to V9: https://lore.kernel.org/all/20251111105040.94-1-kernel at airkyi.com/
- Notify TYPEC_ALTMODE_UNREGISTERED when altmode removed. 
- Add drm_aux_bridge_register_from_node().
- Fix refcount usage of drm_bridge.

Changes in v9:
- Link to V8: https://lore.kernel.org/all/20251029071435.88-1-kernel at airkyi.com/
- Remove the exposed DRM_AUX_HPD_BRIDGE option, and select
DRM_AUX_HPD_TYPEC_BRIDGE when it is available.
- Add usb role switch for Type-C.
- Remove USB2 PHY in Type-C connection.
- ...

Changes in v8:
- Link to V7: https://lore.kernel.org/all/20251023033009.90-1-kernel at airkyi.com/
- Export all typec device types for identification.
- Merge generic DP HPD bridge into one module.
- Fix coding style.

Changes in v7:
- Link to V6: https://lore.kernel.org/all/20251016022741.91-1-kernel at airkyi.com/
- Add notifier functions for Type-C core.
- Add generic USB Type-C DP HPD bridge.

Changes in v6:
- Link to V5: https://lore.kernel.org/all/20251011033233.97-1-kernel at airkyi.com/
- Fix depend in Kconfig.
- Check DP svid in tcphy_typec_mux_set().
- Remove mode setting in tcphy_orien_sw_set().
- Rename some variable names.
- Attach the DP bridge to the next bridge.

Changes in v5:
- Link to V4: https://lore.kernel.org/all/20250922012039.323-1-kernel at airkyi.com/
- Remove the calls related to `drm_aux_hpd_bridge_notify()`.
- Place the helper functions in the same compilation unit.
- Add more comments about parent device.
- Add DRM AUX bridge support for RK3399 USBDP PHY
- By parsing the HPD bridge chain, set the connector's of_node to the
of_node corresponding to the USB-C connector.
- Return EDID cache when other port is already enabled.

Changes in v4:
- Link to V3: https://lore.kernel.org/all/20250729090032.97-1-kernel at airkyi.com/
- Add default HPD device for DisplayPort altmode.
- Introduce multiple bridges for CDN-DP.
- ...

Changes in v3:
- Link to V2: https://lore.kernel.org/all/20250718062619.99-1-kernel at airkyi.com/
- Add more descriptions to clarify the role of the PHY in switching.
- Fix wrong vdo value.
- Fix port node in usb-c-connector.

Changes in v2:
- Link to V1: https://lore.kernel.org/all/20250715112456.101-1-kernel at airkyi.com/
- Reuse dp-port/usb3-port in rk3399-typec-phy binding.
- Fix compile error when CONFIG_TYPEC is not enabled.
- Notify DP HPD state by USB/DP PHY.
- Ignore duplicate HPD events.
- Add endpoint to link DP PHY and DP controller.
- Fix devicetree coding style.

Chaoyi Chen (10):
  usb: typec: Export typec bus and typec altmode device type
  drm/bridge: Implement generic USB Type-C DP HPD bridge
  drm/bridge: aux: Add drm_aux_bridge_register_from_node()
  dt-bindings: phy: rockchip: rk3399-typec-phy: Support mode-switch
  phy: rockchip: phy-rockchip-typec: Add typec_mux/typec_switch support
  phy: rockchip: phy-rockchip-typec: Add DRM AUX bridge
  drm/rockchip: cdn-dp: Support handle lane info without extcon
  drm/rockchip: cdn-dp: Add multiple bridges to support PHY port
    selection
  arm64: dts: rockchip: Add missing dp_out port for RK3399 CDN-DP
  arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort

Heikki Krogerus (1):
  usb: typec: Set the bus also for the port and plug altmodes

 .../phy/rockchip,rk3399-typec-phy.yaml        |   6 +
 arch/arm64/boot/dts/rockchip/rk3399-base.dtsi |  10 +-
 .../boot/dts/rockchip/rk3399-evb-ind.dts      | 147 +++++++
 drivers/gpu/drm/bridge/Kconfig                |  10 +
 drivers/gpu/drm/bridge/Makefile               |   1 +
 drivers/gpu/drm/bridge/aux-bridge.c           |  24 +-
 .../gpu/drm/bridge/aux-hpd-typec-dp-bridge.c  |  51 +++
 drivers/gpu/drm/rockchip/Kconfig              |   1 +
 drivers/gpu/drm/rockchip/cdn-dp-core.c        | 350 +++++++++++++---
 drivers/gpu/drm/rockchip/cdn-dp-core.h        |  18 +-
 drivers/phy/rockchip/Kconfig                  |   3 +
 drivers/phy/rockchip/phy-rockchip-typec.c     | 373 +++++++++++++++++-
 drivers/usb/typec/bus.c                       |  25 +-
 drivers/usb/typec/bus.h                       |   6 -
 drivers/usb/typec/class.c                     |  36 +-
 include/drm/bridge/aux-bridge.h               |   6 +
 include/linux/usb/typec.h                     |   3 +
 include/linux/usb/typec_altmode.h             |   8 +
 18 files changed, 976 insertions(+), 102 deletions(-)
 create mode 100644 drivers/gpu/drm/bridge/aux-hpd-typec-dp-bridge.c

-- 
2.51.1



From kernel at airkyi.com  Thu Nov 27 18:04:02 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Fri, 28 Nov 2025 10:04:02 +0800
Subject: [PATCH v11 08/11] drm/rockchip: cdn-dp: Support handle lane info without extcon
In-Reply-To: <20251128020405.90-1-kernel@airkyi.com>
References: <20251128020405.90-1-kernel@airkyi.com>
Message-ID: <20251128020405.90-9-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

This patch add support for get PHY lane info without help of extcon.

There is no extcon needed if the Type-C controller is present. In this
case, the lane info can be get from PHY instead of extcon.

The extcon device should still be supported if Type-C controller is
not present.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---

(no changes since v5)

Changes in v4:
- Remove cdn_dp_hpd_notify().

(no changes since v3)

Changes in v2:
- Ignore duplicate HPD events.

 drivers/gpu/drm/rockchip/cdn-dp-core.c | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index b7e3f5dcf8d5..1e27301584a4 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -156,6 +156,9 @@ static int cdn_dp_get_port_lanes(struct cdn_dp_port *port)
 	int dptx;
 	u8 lanes;
 
+	if (!edev)
+		return phy_get_bus_width(port->phy);
+
 	dptx = extcon_get_state(edev, EXTCON_DISP_DP);
 	if (dptx > 0) {
 		extcon_get_property(edev, EXTCON_DISP_DP,
@@ -219,7 +222,7 @@ static bool cdn_dp_check_sink_connection(struct cdn_dp_device *dp)
 	 * some docks need more time to power up.
 	 */
 	while (time_before(jiffies, timeout)) {
-		if (!extcon_get_state(port->extcon, EXTCON_DISP_DP))
+		if (port->extcon && !extcon_get_state(port->extcon, EXTCON_DISP_DP))
 			return false;
 
 		if (!cdn_dp_get_sink_count(dp, &sink_count))
@@ -385,11 +388,14 @@ static int cdn_dp_enable_phy(struct cdn_dp_device *dp, struct cdn_dp_port *port)
 		goto err_power_on;
 	}
 
-	ret = extcon_get_property(port->extcon, EXTCON_DISP_DP,
-				  EXTCON_PROP_USB_TYPEC_POLARITY, &property);
-	if (ret) {
-		DRM_DEV_ERROR(dp->dev, "get property failed\n");
-		goto err_power_on;
+	property.intval = 0;
+	if (port->extcon) {
+		ret = extcon_get_property(port->extcon, EXTCON_DISP_DP,
+					  EXTCON_PROP_USB_TYPEC_POLARITY, &property);
+		if (ret) {
+			DRM_DEV_ERROR(dp->dev, "get property failed\n");
+			goto err_power_on;
+		}
 	}
 
 	port->lanes = cdn_dp_get_port_lanes(port);
@@ -1028,6 +1034,9 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
 	for (i = 0; i < dp->ports; i++) {
 		port = dp->port[i];
 
+		if (!port->extcon)
+			continue;
+
 		port->event_nb.notifier_call = cdn_dp_pd_event;
 		ret = devm_extcon_register_notifier(dp->dev, port->extcon,
 						    EXTCON_DISP_DP,
@@ -1120,14 +1129,14 @@ static int cdn_dp_probe(struct platform_device *pdev)
 		    PTR_ERR(phy) == -EPROBE_DEFER)
 			return -EPROBE_DEFER;
 
-		if (IS_ERR(extcon) || IS_ERR(phy))
+		if (IS_ERR(phy) || PTR_ERR(extcon) != -ENODEV)
 			continue;
 
 		port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
 		if (!port)
 			return -ENOMEM;
 
-		port->extcon = extcon;
+		port->extcon = IS_ERR(extcon) ? NULL : extcon;
 		port->phy = phy;
 		port->dp = dp;
 		port->id = i;
-- 
2.51.1



From kernel at airkyi.com  Thu Nov 27 18:04:01 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Fri, 28 Nov 2025 10:04:01 +0800
Subject: [PATCH v11 07/11] phy: rockchip: phy-rockchip-typec: Add DRM AUX bridge
In-Reply-To: <20251128020405.90-1-kernel@airkyi.com>
References: <20251128020405.90-1-kernel@airkyi.com>
Message-ID: <20251128020405.90-8-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

Using the DRM_AUX_BRIDGE helper to create the transparent DRM bridge
device.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
Reviewed-by: Neil Armstrong <neil.armstrong at linaro.org>
---

(no changes since v11)

Changes in v10:
- Use drm_aux_bridge_register_from_node() instead.

(no changes since v7)

Changes in v6:
- Fix depend in Kconfig.

 drivers/phy/rockchip/Kconfig              | 2 ++
 drivers/phy/rockchip/phy-rockchip-typec.c | 5 +++++
 2 files changed, 7 insertions(+)

diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
index db4adc7c53da..bcb5476222fc 100644
--- a/drivers/phy/rockchip/Kconfig
+++ b/drivers/phy/rockchip/Kconfig
@@ -120,6 +120,8 @@ config PHY_ROCKCHIP_TYPEC
 	tristate "Rockchip TYPEC PHY Driver"
 	depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST)
 	depends on TYPEC || TYPEC=n
+	depends on DRM || DRM=n
+	select DRM_AUX_BRIDGE if DRM_BRIDGE
 	select EXTCON
 	select GENERIC_PHY
 	select RESET_CONTROLLER
diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c
index 1f5b4142cbe4..e31b778c3537 100644
--- a/drivers/phy/rockchip/phy-rockchip-typec.c
+++ b/drivers/phy/rockchip/phy-rockchip-typec.c
@@ -56,6 +56,7 @@
 #include <linux/phy/phy.h>
 #include <linux/usb/typec_dp.h>
 #include <linux/usb/typec_mux.h>
+#include <drm/bridge/aux-bridge.h>
 
 #define CMN_SSM_BANDGAP			(0x21 << 2)
 #define CMN_SSM_BIAS			(0x22 << 2)
@@ -1312,6 +1313,10 @@ static int tcphy_setup_typec_mux(struct rockchip_typec_phy *tcphy)
 	if (!of_property_read_bool(np, "mode-switch"))
 		goto put_np;
 
+	ret = drm_aux_bridge_register_from_node(tcphy->dev, np);
+	if (ret)
+		goto put_np;
+
 	mux_desc.drvdata = tcphy;
 	mux_desc.fwnode = device_get_named_child_node(tcphy->dev, "dp-port");
 	mux_desc.set = tcphy_typec_mux_set;
-- 
2.51.1



From kernel at airkyi.com  Thu Nov 27 18:03:56 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Fri, 28 Nov 2025 10:03:56 +0800
Subject: [PATCH v11 02/11] usb: typec: Export typec bus and typec altmode device type
In-Reply-To: <20251128020405.90-1-kernel@airkyi.com>
References: <20251128020405.90-1-kernel@airkyi.com>
Message-ID: <20251128020405.90-3-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

The DRM may want to register a notifier on the typec bus to know when
a typec altmode device is added, and distinguish between different
types of typec altmode device.

Export these things.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---

Changes in v11:
- Also export typec bus.
- Add more detailed comments.

(no changes since v9)

 drivers/usb/typec/bus.c           |  1 +
 drivers/usb/typec/bus.h           | 10 ----------
 drivers/usb/typec/class.c         |  3 +++
 include/linux/usb/typec.h         |  3 +++
 include/linux/usb/typec_altmode.h |  8 ++++++++
 5 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/drivers/usb/typec/bus.c b/drivers/usb/typec/bus.c
index a33da7f458a5..e84b134a3381 100644
--- a/drivers/usb/typec/bus.c
+++ b/drivers/usb/typec/bus.c
@@ -569,3 +569,4 @@ const struct bus_type typec_bus = {
 	.probe = typec_probe,
 	.remove = typec_remove,
 };
+EXPORT_SYMBOL_GPL(typec_bus);
diff --git a/drivers/usb/typec/bus.h b/drivers/usb/typec/bus.h
index b58e131450d1..7df5deb1dd3a 100644
--- a/drivers/usb/typec/bus.h
+++ b/drivers/usb/typec/bus.h
@@ -5,7 +5,6 @@
 
 #include <linux/usb/typec_altmode.h>
 
-struct bus_type;
 struct typec_mux;
 struct typec_retimer;
 
@@ -28,13 +27,4 @@ struct altmode {
 
 #define to_altmode(d) container_of(d, struct altmode, adev)
 
-extern const struct bus_type typec_bus;
-extern const struct device_type typec_port_altmode_dev_type;
-extern const struct device_type typec_plug_altmode_dev_type;
-extern const struct device_type typec_partner_altmode_dev_type;
-
-#define is_typec_port_altmode(dev) ((dev)->type == &typec_port_altmode_dev_type)
-#define is_typec_plug_altmode(dev) ((dev)->type == &typec_plug_altmode_dev_type)
-#define is_typec_partner_altmode(dev) ((dev)->type == &typec_partner_altmode_dev_type)
-
 #endif /* __USB_TYPEC_ALTMODE_H__ */
diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c
index d6b88317f8a4..c4ff4310ff58 100644
--- a/drivers/usb/typec/class.c
+++ b/drivers/usb/typec/class.c
@@ -537,18 +537,21 @@ const struct device_type typec_port_altmode_dev_type = {
 	.groups = typec_altmode_groups,
 	.release = typec_altmode_release,
 };
+EXPORT_SYMBOL_GPL(typec_port_altmode_dev_type);
 
 const struct device_type typec_plug_altmode_dev_type = {
 	.name = "typec_plug_alternate_mode",
 	.groups = typec_altmode_groups,
 	.release = typec_altmode_release,
 };
+EXPORT_SYMBOL_GPL(typec_plug_altmode_dev_type);
 
 const struct device_type typec_partner_altmode_dev_type = {
 	.name = "typec_partner_alternate_mode",
 	.groups = typec_altmode_groups,
 	.release = typec_altmode_release,
 };
+EXPORT_SYMBOL_GPL(typec_partner_altmode_dev_type);
 
 static struct typec_altmode *
 typec_register_altmode(struct device *parent,
diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h
index 309251572e2e..c6fd46902fce 100644
--- a/include/linux/usb/typec.h
+++ b/include/linux/usb/typec.h
@@ -20,12 +20,15 @@ struct typec_port;
 struct typec_altmode_ops;
 struct typec_cable_ops;
 
+struct bus_type;
 struct fwnode_handle;
 struct device;
 
 struct usb_power_delivery;
 struct usb_power_delivery_desc;
 
+extern const struct bus_type typec_bus;
+
 enum typec_port_type {
 	TYPEC_PORT_SRC,
 	TYPEC_PORT_SNK,
diff --git a/include/linux/usb/typec_altmode.h b/include/linux/usb/typec_altmode.h
index f7db3bd4c90e..9197a4637a93 100644
--- a/include/linux/usb/typec_altmode.h
+++ b/include/linux/usb/typec_altmode.h
@@ -9,6 +9,14 @@
 
 #define MODE_DISCOVERY_MAX	6
 
+extern const struct device_type typec_port_altmode_dev_type;
+extern const struct device_type typec_plug_altmode_dev_type;
+extern const struct device_type typec_partner_altmode_dev_type;
+
+#define is_typec_port_altmode(dev) ((dev)->type == &typec_port_altmode_dev_type)
+#define is_typec_plug_altmode(dev) ((dev)->type == &typec_plug_altmode_dev_type)
+#define is_typec_partner_altmode(dev) ((dev)->type == &typec_partner_altmode_dev_type)
+
 struct typec_altmode_ops;
 
 /**
-- 
2.51.1



From kernel at airkyi.com  Thu Nov 27 18:04:03 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Fri, 28 Nov 2025 10:04:03 +0800
Subject: [PATCH v11 09/11] drm/rockchip: cdn-dp: Add multiple bridges to support PHY port selection
In-Reply-To: <20251128020405.90-1-kernel@airkyi.com>
References: <20251128020405.90-1-kernel@airkyi.com>
Message-ID: <20251128020405.90-10-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

The RK3399 has two USB/DP combo PHY and one CDN-DP controller. And
the CDN-DP can be switched to output to one of the PHYs. If both ports
are plugged into DP, DP will select the first port for output.

This patch adds support for multiple bridges, enabling users to flexibly
select the output port. For each PHY port, a separate encoder and bridge
are registered.

The change is based on the DRM AUX HPD bridge, rather than the
extcon approach. This requires the DT to correctly describe the
connections between the first bridge in bridge chain and DP
controller. For example, the bridge chain may be like this:

PHY aux birdge -> fsa4480 analog audio switch bridge ->
onnn,nb7vpq904m USB reminder bridge -> USB-C controller AUX HPD bridge

In this case, the connection relationships among the PHY aux bridge
and the DP contorller need to be described in DT.

In addition, the cdn_dp_parse_next_bridge_dt() will parses it and
determines whether to register one or two bridges.

Since there is only one DP controller, only one of the PHY ports can
output at a time. The key is how to switch between different PHYs,
which is handled by cdn_dp_switch_port() and cdn_dp_enable().

There are two cases:

1. Neither bridge is enabled. In this case, both bridges can
independently read the EDID, and the PHY port may switch before
reading the EDID.

2. One bridge is already enabled. In this case, other bridges are not
allowed to read the EDID. So we will try to return the cached EDID.

Since the scenario of two ports plug in at the same time is rare,
I don't have a board which support two TypeC connector to test this.
Therefore, I tested forced switching on a single PHY port, as well as
output using a fake PHY port alongside a real PHY port.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---

(no changes since v11)

Changes in v10:
- Fix refcount usage of drm_bridge.
- Remove unused cdn_dp_next_bridge type.

Changes in v9:
- Select DRM_AUX_HPD_BRIDGE when using DP driver.

(no changes since v7)

Changes in v6:
- Rename some variable names.
- Attach the DP bridge to the next bridge.

Changes in v5:
- By parsing the HPD bridge chain, set the connector's of_node to the
of_node corresponding to the USB-C connector.
- Return EDID cache when other port is already enabled.

 drivers/gpu/drm/rockchip/Kconfig       |   1 +
 drivers/gpu/drm/rockchip/cdn-dp-core.c | 325 ++++++++++++++++++++-----
 drivers/gpu/drm/rockchip/cdn-dp-core.h |  18 +-
 3 files changed, 287 insertions(+), 57 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index b7b025814e72..10d9f29a3d44 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -56,6 +56,7 @@ config ROCKCHIP_CDN_DP
 	select DRM_DISPLAY_HELPER
 	select DRM_BRIDGE_CONNECTOR
 	select DRM_DISPLAY_DP_HELPER
+	select DRM_AUX_HPD_BRIDGE
 	help
 	  This selects support for Rockchip SoC specific extensions
 	  for the cdn DP driver. If you want to enable Dp on
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 1e27301584a4..0bc3d248c266 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -27,16 +27,17 @@
 #include "cdn-dp-core.h"
 #include "cdn-dp-reg.h"
 
-static inline struct cdn_dp_device *bridge_to_dp(struct drm_bridge *bridge)
+static int cdn_dp_switch_port(struct cdn_dp_device *dp, struct cdn_dp_port *prev_port,
+			      struct cdn_dp_port *port);
+
+static inline struct cdn_dp_bridge *bridge_to_dp_bridge(struct drm_bridge *bridge)
 {
-	return container_of(bridge, struct cdn_dp_device, bridge);
+	return container_of(bridge, struct cdn_dp_bridge, bridge);
 }
 
-static inline struct cdn_dp_device *encoder_to_dp(struct drm_encoder *encoder)
+static inline struct cdn_dp_device *bridge_to_dp(struct drm_bridge *bridge)
 {
-	struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
-
-	return container_of(rkencoder, struct cdn_dp_device, encoder);
+	return bridge_to_dp_bridge(bridge)->parent;
 }
 
 #define GRF_SOC_CON9		0x6224
@@ -191,14 +192,27 @@ static int cdn_dp_get_sink_count(struct cdn_dp_device *dp, u8 *sink_count)
 static struct cdn_dp_port *cdn_dp_connected_port(struct cdn_dp_device *dp)
 {
 	struct cdn_dp_port *port;
-	int i, lanes;
+	int i, lanes[MAX_PHY];
 
 	for (i = 0; i < dp->ports; i++) {
 		port = dp->port[i];
-		lanes = cdn_dp_get_port_lanes(port);
-		if (lanes)
+		lanes[i] = cdn_dp_get_port_lanes(port);
+		if (!dp->next_bridge_valid)
 			return port;
 	}
+
+	if (dp->next_bridge_valid) {
+		/* If more than one port is available, pick the last active port */
+		if (dp->active_port > 0 && lanes[dp->active_port])
+			return dp->port[dp->active_port];
+
+		/* If the last active port is not available, pick an available port in order */
+		for (i = 0; i < dp->bridge_count; i++) {
+			if (lanes[i])
+				return dp->port[i];
+		}
+	}
+
 	return NULL;
 }
 
@@ -253,12 +267,45 @@ static const struct drm_edid *
 cdn_dp_bridge_edid_read(struct drm_bridge *bridge, struct drm_connector *connector)
 {
 	struct cdn_dp_device *dp = bridge_to_dp(bridge);
-	const struct drm_edid *drm_edid;
+	struct cdn_dp_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
+	struct cdn_dp_port *port = dp->port[dp_bridge->id];
+	struct cdn_dp_port *prev_port;
+	const struct drm_edid *drm_edid = NULL;
+	int i, ret;
 
 	mutex_lock(&dp->lock);
+
+	/* More than one port is available */
+	if (dp->bridge_count > 1 && !port->phy_enabled) {
+		for (i = 0; i < dp->bridge_count; i++) {
+			/* Another port already enable */
+			if (dp->bridge_list[i] != dp_bridge && dp->bridge_list[i]->enabled)
+				goto get_cache;
+			/* Find already enabled port */
+			if (dp->port[i]->phy_enabled)
+				prev_port = dp->port[i];
+		}
+
+		/* Switch to current port */
+		if (prev_port) {
+			ret = cdn_dp_switch_port(dp, prev_port, port);
+			if (ret)
+				goto get_cache;
+		}
+	}
+
 	drm_edid = drm_edid_read_custom(connector, cdn_dp_get_edid_block, dp);
+	/* replace edid cache */
+	if (dp->edid_cache[dp_bridge->id])
+		drm_edid_free(dp->edid_cache[dp_bridge->id]);
+	dp->edid_cache[dp_bridge->id] = drm_edid_dup(drm_edid);
+
 	mutex_unlock(&dp->lock);
+	return drm_edid;
 
+get_cache:
+	drm_edid = drm_edid_dup(dp->edid_cache[dp_bridge->id]);
+	mutex_unlock(&dp->lock);
 	return drm_edid;
 }
 
@@ -267,12 +314,13 @@ cdn_dp_bridge_mode_valid(struct drm_bridge *bridge,
 			 const struct drm_display_info *display_info,
 			 const struct drm_display_mode *mode)
 {
+	struct cdn_dp_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
 	struct cdn_dp_device *dp = bridge_to_dp(bridge);
 	u32 requested, actual, rate, sink_max, source_max = 0;
 	u8 lanes, bpc;
 
 	/* If DP is disconnected, every mode is invalid */
-	if (!dp->connected)
+	if (!dp_bridge->connected || !dp->connected)
 		return MODE_BAD;
 
 	switch (display_info->bpc) {
@@ -550,6 +598,54 @@ static bool cdn_dp_check_link_status(struct cdn_dp_device *dp)
 	return drm_dp_channel_eq_ok(link_status, min(port->lanes, sink_lanes));
 }
 
+static int cdn_dp_switch_port(struct cdn_dp_device *dp, struct cdn_dp_port *prev_port,
+			      struct cdn_dp_port *port)
+{
+	int ret;
+
+	if (dp->active)
+		return 0;
+
+	ret = cdn_dp_disable_phy(dp, prev_port);
+	if (ret)
+		goto out;
+	ret = cdn_dp_enable_phy(dp, port);
+	if (ret)
+		goto out;
+
+	ret = cdn_dp_get_sink_capability(dp);
+	if (ret) {
+		cdn_dp_disable_phy(dp, port);
+		goto out;
+	}
+
+	dp->active = true;
+	dp->lanes = port->lanes;
+
+	if (!cdn_dp_check_link_status(dp)) {
+		dev_info(dp->dev, "Connected with sink; re-train link\n");
+
+		ret = cdn_dp_train_link(dp);
+		if (ret) {
+			dev_err(dp->dev, "Training link failed: %d\n", ret);
+			goto out;
+		}
+
+		ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE);
+		if (ret) {
+			dev_err(dp->dev, "Failed to idle video %d\n", ret);
+			goto out;
+		}
+
+		ret = cdn_dp_config_video(dp);
+		if (ret)
+			dev_err(dp->dev, "Failed to configure video: %d\n", ret);
+	}
+
+out:
+	return ret;
+}
+
 static void cdn_dp_display_info_update(struct cdn_dp_device *dp,
 				       struct drm_display_info *display_info)
 {
@@ -571,6 +667,7 @@ static void cdn_dp_display_info_update(struct cdn_dp_device *dp,
 static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_atomic_state *state)
 {
 	struct cdn_dp_device *dp = bridge_to_dp(bridge);
+	struct cdn_dp_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
 	struct drm_connector *connector;
 	int ret, val;
 
@@ -580,7 +677,7 @@ static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_at
 
 	cdn_dp_display_info_update(dp, &connector->display_info);
 
-	ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, &dp->encoder.encoder);
+	ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, &dp_bridge->encoder.encoder);
 	if (ret < 0) {
 		DRM_DEV_ERROR(dp->dev, "Could not get vop id, %d", ret);
 		return;
@@ -599,6 +696,9 @@ static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_at
 
 	mutex_lock(&dp->lock);
 
+	if (dp->next_bridge_valid)
+		dp->active_port = dp_bridge->id;
+
 	ret = cdn_dp_enable(dp);
 	if (ret) {
 		DRM_DEV_ERROR(dp->dev, "Failed to enable bridge %d\n",
@@ -631,6 +731,7 @@ static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_at
 		goto out;
 	}
 
+	dp_bridge->enabled = true;
 out:
 	mutex_unlock(&dp->lock);
 }
@@ -638,9 +739,11 @@ static void cdn_dp_bridge_atomic_enable(struct drm_bridge *bridge, struct drm_at
 static void cdn_dp_bridge_atomic_disable(struct drm_bridge *bridge, struct drm_atomic_state *state)
 {
 	struct cdn_dp_device *dp = bridge_to_dp(bridge);
+	struct cdn_dp_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
 	int ret;
 
 	mutex_lock(&dp->lock);
+	dp_bridge->enabled = false;
 
 	if (dp->active) {
 		ret = cdn_dp_disable(dp);
@@ -827,6 +930,16 @@ static int cdn_dp_audio_mute_stream(struct drm_bridge *bridge,
 	return ret;
 }
 
+static void cdn_dp_bridge_hpd_notify(struct drm_bridge *bridge,
+			   enum drm_connector_status status)
+{
+	struct cdn_dp_bridge *dp_bridge = bridge_to_dp_bridge(bridge);
+	struct cdn_dp_device *dp = bridge_to_dp(bridge);
+
+	dp->bridge_list[dp_bridge->id]->connected = status == connector_status_connected;
+	schedule_work(&dp->event_work);
+}
+
 static const struct drm_bridge_funcs cdn_dp_bridge_funcs = {
 	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
 	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
@@ -837,6 +950,7 @@ static const struct drm_bridge_funcs cdn_dp_bridge_funcs = {
 	.atomic_disable = cdn_dp_bridge_atomic_disable,
 	.mode_valid = cdn_dp_bridge_mode_valid,
 	.mode_set = cdn_dp_bridge_mode_set,
+	.hpd_notify = cdn_dp_bridge_hpd_notify,
 
 	.dp_audio_prepare = cdn_dp_audio_prepare,
 	.dp_audio_mute_stream = cdn_dp_audio_mute_stream,
@@ -885,7 +999,8 @@ static void cdn_dp_pd_event_work(struct work_struct *work)
 {
 	struct cdn_dp_device *dp = container_of(work, struct cdn_dp_device,
 						event_work);
-	int ret;
+	bool connected;
+	int i, ret;
 
 	mutex_lock(&dp->lock);
 
@@ -944,9 +1059,12 @@ static void cdn_dp_pd_event_work(struct work_struct *work)
 
 out:
 	mutex_unlock(&dp->lock);
-	drm_bridge_hpd_notify(&dp->bridge,
-			      dp->connected ? connector_status_connected
-					    : connector_status_disconnected);
+	for (i = 0; i < dp->bridge_count; i++) {
+		connected = dp->connected && dp->bridge_list[i]->connected;
+		drm_bridge_hpd_notify(&dp->bridge_list[i]->bridge,
+				      connected ? connector_status_connected
+						: connector_status_disconnected);
+	}
 }
 
 static int cdn_dp_pd_event(struct notifier_block *nb,
@@ -966,28 +1084,16 @@ static int cdn_dp_pd_event(struct notifier_block *nb,
 	return NOTIFY_DONE;
 }
 
-static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
+static int cdn_bridge_add(struct device *dev,
+			  struct drm_bridge *bridge,
+			  struct drm_bridge *next_bridge,
+			  struct drm_encoder *encoder)
 {
 	struct cdn_dp_device *dp = dev_get_drvdata(dev);
-	struct drm_encoder *encoder;
+	struct drm_device *drm_dev = dp->drm_dev;
+	struct drm_bridge *last_bridge __free(drm_bridge_put) = NULL;
 	struct drm_connector *connector;
-	struct cdn_dp_port *port;
-	struct drm_device *drm_dev = data;
-	int ret, i;
-
-	ret = cdn_dp_parse_dt(dp);
-	if (ret < 0)
-		return ret;
-
-	dp->drm_dev = drm_dev;
-	dp->connected = false;
-	dp->active = false;
-	dp->active_port = -1;
-	dp->fw_loaded = false;
-
-	INIT_WORK(&dp->event_work, cdn_dp_pd_event_work);
-
-	encoder = &dp->encoder.encoder;
+	int ret;
 
 	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
 							     dev->of_node);
@@ -1002,26 +1108,35 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
 
 	drm_encoder_helper_add(encoder, &cdn_dp_encoder_helper_funcs);
 
-	dp->bridge.ops =
-			DRM_BRIDGE_OP_DETECT |
-			DRM_BRIDGE_OP_EDID |
-			DRM_BRIDGE_OP_HPD |
-			DRM_BRIDGE_OP_DP_AUDIO;
-	dp->bridge.of_node = dp->dev->of_node;
-	dp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
-	dp->bridge.hdmi_audio_dev = dp->dev;
-	dp->bridge.hdmi_audio_max_i2s_playback_channels = 8;
-	dp->bridge.hdmi_audio_spdif_playback = 1;
-	dp->bridge.hdmi_audio_dai_port = -1;
-
-	ret = devm_drm_bridge_add(dev, &dp->bridge);
+	bridge->ops =
+		DRM_BRIDGE_OP_DETECT |
+		DRM_BRIDGE_OP_EDID |
+		DRM_BRIDGE_OP_HPD |
+		DRM_BRIDGE_OP_DP_AUDIO;
+	bridge->of_node = dp->dev->of_node;
+	bridge->type = DRM_MODE_CONNECTOR_DisplayPort;
+	bridge->hdmi_audio_dev = dp->dev;
+	bridge->hdmi_audio_max_i2s_playback_channels = 8;
+	bridge->hdmi_audio_spdif_playback = 1;
+	bridge->hdmi_audio_dai_port = -1;
+
+	ret = devm_drm_bridge_add(dev, bridge);
 	if (ret)
 		return ret;
 
-	ret = drm_bridge_attach(encoder, &dp->bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+	ret = drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
 	if (ret)
 		return ret;
 
+	if (next_bridge) {
+		ret = drm_bridge_attach(encoder, next_bridge, bridge,
+					DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+		if (ret)
+			return ret;
+
+		last_bridge = drm_bridge_chain_get_last_bridge(bridge->encoder);
+	}
+
 	connector = drm_bridge_connector_init(drm_dev, encoder);
 	if (IS_ERR(connector)) {
 		ret = PTR_ERR(connector);
@@ -1029,8 +1144,100 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
 		return ret;
 	}
 
+	if (last_bridge)
+		connector->fwnode = fwnode_handle_get(of_fwnode_handle(last_bridge->of_node));
+
 	drm_connector_attach_encoder(connector, encoder);
 
+	return 0;
+}
+
+static int cdn_dp_parse_next_bridge_dt(struct cdn_dp_device *dp)
+{
+	struct device_node *np = dp->dev->of_node;
+	struct device_node *port __free(device_node) = of_graph_get_port_by_id(np, 1);
+	struct drm_bridge *bridge;
+	int count = 0;
+	int ret = 0;
+	int i;
+
+	/* If device use extcon, do not use hpd bridge */
+	for (i = 0; i < dp->ports; i++) {
+		if (dp->port[i]->extcon) {
+			dp->bridge_count = 1;
+			return 0;
+		}
+	}
+
+	/* One endpoint may correspond to one next bridge. */
+	for_each_of_graph_port_endpoint(port, dp_ep) {
+		struct device_node *next_bridge_node __free(device_node) =
+			of_graph_get_remote_port_parent(dp_ep);
+
+		bridge = of_drm_find_bridge(next_bridge_node);
+		if (!bridge) {
+			ret = -EPROBE_DEFER;
+			goto out;
+		}
+
+		drm_bridge_get(bridge);
+		dp->next_bridge_valid = true;
+		dp->next_bridge_list[count] = bridge;
+		count++;
+	}
+
+out:
+	dp->bridge_count = count ? count : 1;
+	return ret;
+}
+
+static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
+{
+	struct cdn_dp_device *dp = dev_get_drvdata(dev);
+	struct drm_bridge *bridge, *next_bridge;
+	struct drm_encoder *encoder;
+	struct cdn_dp_port *port;
+	struct drm_device *drm_dev = data;
+	struct cdn_dp_bridge *dp_bridge;
+	int ret, i;
+
+	ret = cdn_dp_parse_dt(dp);
+	if (ret < 0)
+		return ret;
+
+	ret = cdn_dp_parse_next_bridge_dt(dp);
+	if (ret)
+		return ret;
+
+	dp->drm_dev = drm_dev;
+	dp->connected = false;
+	dp->active = false;
+	dp->active_port = -1;
+	dp->fw_loaded = false;
+
+	for (i = 0; i < dp->bridge_count; i++) {
+		dp_bridge = devm_drm_bridge_alloc(dev, struct cdn_dp_bridge, bridge,
+						    &cdn_dp_bridge_funcs);
+		if (IS_ERR(dp_bridge))
+			return PTR_ERR(dp_bridge);
+		dp_bridge->id = i;
+		dp_bridge->parent = dp;
+		if (!dp->next_bridge_valid)
+			dp_bridge->connected = true;
+		dp->bridge_list[i] = dp_bridge;
+	}
+
+	for (i = 0; i < dp->bridge_count; i++) {
+		encoder = &dp->bridge_list[i]->encoder.encoder;
+		bridge = &dp->bridge_list[i]->bridge;
+		next_bridge = dp->next_bridge_list[i];
+		ret = cdn_bridge_add(dev, bridge, next_bridge, encoder);
+		if (ret)
+			return ret;
+	}
+
+	INIT_WORK(&dp->event_work, cdn_dp_pd_event_work);
+
 	for (i = 0; i < dp->ports; i++) {
 		port = dp->port[i];
 
@@ -1058,10 +1265,18 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
 static void cdn_dp_unbind(struct device *dev, struct device *master, void *data)
 {
 	struct cdn_dp_device *dp = dev_get_drvdata(dev);
-	struct drm_encoder *encoder = &dp->encoder.encoder;
+	struct drm_encoder *encoder;
+	int i;
 
 	cancel_work_sync(&dp->event_work);
-	encoder->funcs->destroy(encoder);
+	for (i = 0; i < dp->bridge_count; i++) {
+		encoder = &dp->bridge_list[i]->encoder.encoder;
+		encoder->funcs->destroy(encoder);
+		drm_bridge_put(dp->next_bridge_list[i]);
+	}
+
+	for (i = 0; i < MAX_PHY; i++)
+		drm_edid_free(dp->edid_cache[i]);
 
 	pm_runtime_disable(dev);
 	if (dp->fw_loaded)
@@ -1112,10 +1327,10 @@ static int cdn_dp_probe(struct platform_device *pdev)
 	int ret;
 	int i;
 
-	dp = devm_drm_bridge_alloc(dev, struct cdn_dp_device, bridge,
-				   &cdn_dp_bridge_funcs);
-	if (IS_ERR(dp))
-		return PTR_ERR(dp);
+	dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
+	if (!dp)
+		return -ENOMEM;
+
 	dp->dev = dev;
 
 	match = of_match_node(cdn_dp_dt_ids, pdev->dev.of_node);
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.h b/drivers/gpu/drm/rockchip/cdn-dp-core.h
index e9c30b9fd543..c10e423bbf06 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.h
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h
@@ -38,6 +38,8 @@ enum vic_pxl_encoding_format {
 	Y_ONLY = 0x10,
 };
 
+struct cdn_dp_device;
+
 struct video_info {
 	bool h_sync_polarity;
 	bool v_sync_polarity;
@@ -63,16 +65,28 @@ struct cdn_dp_port {
 	u8 id;
 };
 
+struct cdn_dp_bridge {
+	struct cdn_dp_device *parent;
+	struct drm_bridge bridge;
+	struct rockchip_encoder encoder;
+	bool connected;
+	bool enabled;
+	int id;
+};
+
 struct cdn_dp_device {
 	struct device *dev;
 	struct drm_device *drm_dev;
-	struct drm_bridge bridge;
-	struct rockchip_encoder encoder;
+	int bridge_count;
+	struct cdn_dp_bridge *bridge_list[MAX_PHY];
+	struct drm_bridge *next_bridge_list[MAX_PHY];
+	const struct drm_edid *edid_cache[MAX_PHY];
 	struct drm_display_mode mode;
 	struct platform_device *audio_pdev;
 	struct work_struct event_work;
 
 	struct mutex lock;
+	bool next_bridge_valid;
 	bool connected;
 	bool active;
 	bool suspended;
-- 
2.51.1



From kernel at airkyi.com  Thu Nov 27 18:04:04 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Fri, 28 Nov 2025 10:04:04 +0800
Subject: [PATCH v11 10/11] arm64: dts: rockchip: Add missing dp_out port for RK3399 CDN-DP
In-Reply-To: <20251128020405.90-1-kernel@airkyi.com>
References: <20251128020405.90-1-kernel@airkyi.com>
Message-ID: <20251128020405.90-11-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

Let's make the ports nodes of cdn_dp in the same style as the other
display interface, and match the style of ports's yaml.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---

(no changes since v5)

Changes in v4:
- Remove unnecessary #address/#size-cells

(no changes since v1)

 arch/arm64/boot/dts/rockchip/rk3399-base.dtsi | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi
index 4dcceb9136b7..93b42820998f 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi
@@ -618,7 +618,11 @@ cdn_dp: dp at fec00000 {
 		status = "disabled";
 
 		ports {
-			dp_in: port {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			dp_in: port at 0 {
+				reg = <0>;
 				#address-cells = <1>;
 				#size-cells = <0>;
 
@@ -632,6 +636,10 @@ dp_in_vopl: endpoint at 1 {
 					remote-endpoint = <&vopl_out_dp>;
 				};
 			};
+
+			dp_out: port at 1 {
+				reg = <1>;
+			};
 		};
 	};
 
-- 
2.51.1



From kernel at airkyi.com  Thu Nov 27 18:04:05 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Fri, 28 Nov 2025 10:04:05 +0800
Subject: [PATCH v11 11/11] arm64: dts: rockchip: rk3399-evb-ind: Add support for DisplayPort
In-Reply-To: <20251128020405.90-1-kernel@airkyi.com>
References: <20251128020405.90-1-kernel@airkyi.com>
Message-ID: <20251128020405.90-12-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

The RK3399 EVB IND board has a Type-C interface DisplayPort.
It use fusb302 chip as Type-C controller.

fusb302 chip ---> USB/DP PHY0 <----> CDN-DP controller

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---

(no changes since v10)

Changes in v9:
- Add usb role switch for Type-C.
- Remove USB2 PHY in Type-C connection.

(no changes since v4)

Changes in v3:
- Fix wrong vdo value.
- Fix port node in usb-c-connector.

Changes in v2:
- Add endpoint to link DP PHY and DP controller.
- Fix devicetree coding style.

 .../boot/dts/rockchip/rk3399-evb-ind.dts      | 147 ++++++++++++++++++
 1 file changed, 147 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts
index 70aee1ab904c..be1e90f7a453 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts
@@ -4,6 +4,7 @@
  */
 
 /dts-v1/;
+#include <dt-bindings/usb/pd.h>
 #include "rk3399.dtsi"
 
 / {
@@ -19,6 +20,21 @@ chosen {
 		stdout-path = "serial2:1500000n8";
 	};
 
+	sound: sound {
+		compatible = "rockchip,rk3399-gru-sound";
+		rockchip,cpu = <&i2s0 &spdif>;
+	};
+
+	vbus_typec: regulator-vbus-typec {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc5v0_typec0_en>;
+		regulator-name = "vbus_typec";
+		vin-supply = <&vcc5v0_sys>;
+	};
+
 	vcc5v0_sys: regulator-vcc5v0-sys {
 		compatible = "regulator-fixed";
 		enable-active-high;
@@ -31,6 +47,11 @@ vcc5v0_sys: regulator-vcc5v0-sys {
 	};
 };
 
+&cdn_dp {
+	phys = <&tcphy0_dp>;
+	status = "okay";
+};
+
 &cpu_b0 {
 	cpu-supply = <&vdd_cpu_b>;
 };
@@ -55,6 +76,12 @@ &cpu_l3 {
 	cpu-supply = <&vdd_cpu_l>;
 };
 
+&dp_out {
+	dp_controller_output: endpoint {
+		remote-endpoint = <&dp_phy_in>;
+	};
+};
+
 &emmc_phy {
 	status = "okay";
 };
@@ -341,6 +368,71 @@ regulator-state-mem {
 	};
 };
 
+&i2c4 {
+	i2c-scl-rising-time-ns = <475>;
+	i2c-scl-falling-time-ns = <26>;
+	status = "okay";
+
+	usbc0: typec-portc at 22 {
+		compatible = "fcs,fusb302";
+		reg = <0x22>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <RK_PA2 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&usbc0_int>;
+		vbus-supply = <&vbus_typec>;
+
+		usb_con: connector {
+			compatible = "usb-c-connector";
+			label = "USB-C";
+			data-role = "dual";
+			power-role = "dual";
+			try-power-role = "sink";
+			op-sink-microwatt = <1000000>;
+			sink-pdos =
+				<PDO_FIXED(5000, 2500, PDO_FIXED_USB_COMM)>;
+			source-pdos =
+				<PDO_FIXED(5000, 1500, PDO_FIXED_USB_COMM)>;
+
+			altmodes {
+				displayport {
+					svid = /bits/ 16 <0xff01>;
+					vdo = <0x00001c46>;
+				};
+			};
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port at 0 {
+					reg = <0>;
+
+					usbc0_orien_sw: endpoint {
+						remote-endpoint = <&tcphy0_orientation_switch>;
+					};
+				};
+
+				port at 1 {
+					reg = <1>;
+
+					usbc0_role_sw: endpoint {
+						remote-endpoint = <&dwc3_0_role_switch>;
+					};
+				};
+
+				port at 2 {
+					reg = <2>;
+
+					dp_altmode_mux: endpoint {
+						remote-endpoint = <&tcphy0_typec_dp>;
+					};
+				};
+			};
+		};
+	};
+};
+
 &i2s2 {
 	status = "okay";
 };
@@ -354,6 +446,16 @@ &io_domains {
 };
 
 &pinctrl {
+	usb-typec {
+		usbc0_int: usbc0-int {
+			rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+
+		vcc5v0_typec0_en: vcc5v0-typec0-en {
+			rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
 	pmic {
 		pmic_int_l: pmic-int-l {
 			rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>;
@@ -400,10 +502,48 @@ &sdmmc {
 	status = "okay";
 };
 
+&sound {
+	rockchip,codec = <&cdn_dp>;
+	status = "okay";
+};
+
+&spdif {
+	status = "okay";
+};
+
 &tcphy0 {
 	status = "okay";
 };
 
+&tcphy0_dp {
+	mode-switch;
+
+	port {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		tcphy0_typec_dp: endpoint at 0 {
+			reg = <0>;
+			remote-endpoint = <&dp_altmode_mux>;
+		};
+
+		dp_phy_in: endpoint at 1 {
+			reg = <1>;
+			remote-endpoint = <&dp_controller_output>;
+		};
+	};
+};
+
+&tcphy0_usb3 {
+	orientation-switch;
+
+	port {
+		tcphy0_orientation_switch: endpoint {
+			remote-endpoint = <&usbc0_orien_sw>;
+		};
+	};
+};
+
 &tcphy1 {
 	status = "okay";
 };
@@ -461,7 +601,14 @@ &usb_host1_ohci {
 };
 
 &usbdrd_dwc3_0 {
+	usb-role-switch;
 	status = "okay";
+
+	port {
+		dwc3_0_role_switch: endpoint {
+			remote-endpoint = <&usbc0_role_sw>;
+		};
+	};
 };
 
 &usbdrd3_0 {
-- 
2.51.1



From robh at kernel.org  Thu Nov 27 19:17:25 2025
From: robh at kernel.org (Rob Herring (Arm))
Date: Thu, 27 Nov 2025 21:17:25 -0600
Subject: [PATCH v11 05/11] dt-bindings: phy: rockchip:
 rk3399-typec-phy: Support mode-switch
In-Reply-To: <20251128020405.90-6-kernel@airkyi.com>
References: <20251128020405.90-1-kernel@airkyi.com>
 <20251128020405.90-6-kernel@airkyi.com>
Message-ID: <176429984551.1030074.10716294618988682110.robh@kernel.org>


On Fri, 28 Nov 2025 10:03:59 +0800, Chaoyi Chen wrote:
> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> 
> The RK3399 SoC integrates two USB/DP combo PHYs, each of which
> supports software-configurable pin mapping and DisplayPort lane
> assignment. These capabilities enable the PHY itself to handle both
> mode switching and orientation switching, based on the Type-C plug
> orientation and USB PD negotiation results.
> 
> While an external Type-C controller is still required to detect cable
> attachment and report USB PD events, the actual mode and orientation
> switching is performed internally by the PHY through software
> configuration. This allows the PHY to act as a Type-C multiplexer for
> both data role and DP altmode configuration.
> 
> To reflect this hardware design, this patch introduces a new
> "mode-switch" property for the dp-port node in the device tree bindings.
> This property indicates that the connected PHY is capable of handling
> Type-C mode switching itself.
> 
> Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
> ---
> 
> (no changes since v5)
> 
> Changes in v4:
> - Remove "|" in description.
> 
> Changes in v3:
> - Add more descriptions to clarify the role of the PHY in switching.
> 
> Changes in v2:
> - Reuse dp-port/usb3-port in rk3399-typec-phy binding.
> 
>  .../devicetree/bindings/phy/rockchip,rk3399-typec-phy.yaml  | 6 ++++++
>  1 file changed, 6 insertions(+)
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/slimbus/slimbus.example.dtb: slim at 28080000 (qcom,slim-ngd-v1.5.0): 'audio-codec at 1,0' does not match any of the regexes: '^pinctrl-[0-9]+$', '^slim@[0-9a-f]+$'
	from schema $id: http://devicetree.org/schemas/slimbus/qcom,slim-ngd.yaml
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/slimbus/slimbus.example.dtb: slim at 28080000 (qcom,slim-ngd-v1.5.0): #address-cells: 1 was expected
	from schema $id: http://devicetree.org/schemas/slimbus/qcom,slim-ngd.yaml
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/slimbus/slimbus.example.dtb: slim at 28080000 (qcom,slim-ngd-v1.5.0): 'dmas' is a required property
	from schema $id: http://devicetree.org/schemas/slimbus/qcom,slim-ngd.yaml
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/slimbus/slimbus.example.dtb: slim at 28080000 (qcom,slim-ngd-v1.5.0): 'dma-names' is a required property
	from schema $id: http://devicetree.org/schemas/slimbus/qcom,slim-ngd.yaml
Documentation/devicetree/bindings/thermal/thermal-sensor.example.dtb: /example-0/soc/thermal-sensor at c263000: failed to match any schema with compatible: ['qcom,sdm845-tsens', 'qcom,tsens-v2']
Documentation/devicetree/bindings/thermal/thermal-sensor.example.dtb: /example-0/soc/thermal-sensor at c263000: failed to match any schema with compatible: ['qcom,sdm845-tsens', 'qcom,tsens-v2']
Documentation/devicetree/bindings/thermal/thermal-sensor.example.dtb: /example-0/soc/thermal-sensor at c265000: failed to match any schema with compatible: ['qcom,sdm845-tsens', 'qcom,tsens-v2']
Documentation/devicetree/bindings/thermal/thermal-sensor.example.dtb: /example-0/soc/thermal-sensor at c265000: failed to match any schema with compatible: ['qcom,sdm845-tsens', 'qcom,tsens-v2']

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20251128020405.90-6-kernel at airkyi.com

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.



From naoki at radxa.com  Thu Nov 27 21:15:28 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Fri, 28 Nov 2025 14:15:28 +0900
Subject: [PATCH 0/6] PCI: dwc: Revert Link Up IRQ support
In-Reply-To: <aSRli_Mb6qoQ9TZO@ryzen>
References: <20251111105100.869997-8-cassel@kernel.org>
 <mt7miqkipr4dvxemftq6octxqzauueln252ncrcwy6i2t7wfhi@jtwokeilhwsi>
 <aSRli_Mb6qoQ9TZO@ryzen>
Message-ID: <585D6D29DF1A6436+9b5db091-8d6e-42a5-ab8f-4b152f82ac54@radxa.com>

Hi Niklas,

On 11/24/25 23:02, Niklas Cassel wrote:
> On Mon, Nov 24, 2025 at 06:07:44PM +0530, Manivannan Sadhasivam wrote:
>> While I suggested to revert the link up IRQ patch for rockchip earlier, I didn't
>> expect to drop the support for Qcom. The reason is, on Qcom SoCs, we have not
>> seen a case where people connect a random PCIe switch and saw failures. Most of
>> the Qcom usecases were around the M.2 and other proprietary connectors. There is
>> only one in-house PCIe switch that is being actively used in our products, but
>> so far, none of the bootloaders have turned them ON before kernel booting. So
>> kernel relies on the newly merged pwrctrl driver to do the job. Even though it
>> also suffers from the same resource allocation issue, this series won't help in
>> any way as pwrctrl core performs rescan after the switch power ON, and by that
>> time, it will be very late anyway.
>>
>> So I'm happy to take the rockhip patches from this series as they fix the real
>> issue that people have reported. But once the pwrctrl rework series gets merged,
>> and the rockchip drivers support them, we can bring back the reverted changes.
> 
> FUKAUMI Naoki, just to confirm:

Should I try
  "PCI: dwc: Make Link Up IRQ logic handle already powered on PCIe switches"
  https://lore.kernel.org/r/20251127134318.3655052-2-cassel at kernel.org

instead of below approaches/patches?

> Neither my suggested approach:
> https://lore.kernel.org/linux-pci/aRHdeVCY3rRmxe80 at ryzen/
> 
> nor Shawn's suggested approach:
> https://lore.kernel.org/linux-pci/dc932773-af5b-4af7-a0d0-8cc72dfbd3c7 at rock-chips.com/
> 
> worked for you?
> 
> 
> If so, I don't see many alternative but for Mani to apply patch 1 and
> patch 2 from this series.

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> Kind regards,
> Niklas
> 




From cassel at kernel.org  Thu Nov 27 21:34:27 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Fri, 28 Nov 2025 06:34:27 +0100
Subject: [PATCH 0/6] PCI: dwc: Revert Link Up IRQ support
In-Reply-To: <585D6D29DF1A6436+9b5db091-8d6e-42a5-ab8f-4b152f82ac54@radxa.com>
References: <20251111105100.869997-8-cassel@kernel.org>
 <mt7miqkipr4dvxemftq6octxqzauueln252ncrcwy6i2t7wfhi@jtwokeilhwsi>
 <aSRli_Mb6qoQ9TZO@ryzen>
 <585D6D29DF1A6436+9b5db091-8d6e-42a5-ab8f-4b152f82ac54@radxa.com>
Message-ID: <aSk0Y74kPnsX0fGe@ryzen>

On Fri, Nov 28, 2025 at 02:15:28PM +0900, FUKAUMI Naoki wrote:
> Hi Niklas,
> 
> Should I try
>  "PCI: dwc: Make Link Up IRQ logic handle already powered on PCIe switches"
>  https://lore.kernel.org/r/20251127134318.3655052-2-cassel at kernel.org
> 
> instead of below approaches/patches?
> 
> > Neither my suggested approach:
> > https://lore.kernel.org/linux-pci/aRHdeVCY3rRmxe80 at ryzen/
> > 
> > nor Shawn's suggested approach:
> > https://lore.kernel.org/linux-pci/dc932773-af5b-4af7-a0d0-8cc72dfbd3c7 at rock-chips.com/

Yes please, your Tested-by would be very helpful.

It is basically the same as my patch above, I just sent it as a formal patch.

Since you said that it does indeed work for you, it does seem like a much
better solution. (Because if we would have reverted the patches, we would
have wanted to reapply them some time in the future.)


Kind regards,
Niklas


From gregkh at linuxfoundation.org  Thu Nov 27 21:51:56 2025
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Fri, 28 Nov 2025 06:51:56 +0100
Subject: [PATCH v11 01/11] usb: typec: Set the bus also for the port and
 plug altmodes
In-Reply-To: <20251128020405.90-2-kernel@airkyi.com>
References: <20251128020405.90-1-kernel@airkyi.com>
 <20251128020405.90-2-kernel@airkyi.com>
Message-ID: <2025112846-italicize-handled-84ff@gregkh>

On Fri, Nov 28, 2025 at 10:03:55AM +0800, Chaoyi Chen wrote:
> From: Heikki Krogerus <heikki.krogerus at linux.intel.com>
> 
> The port and plug altmodes can't be bound to the altmode
> drivers because the altmode drivers are meant for partner
> communication using the VDM (vendor defined messages), but
> they can still be part of the bus. The bus will make sure
> that the normal bus notifications are available also with
> the port altmodes.
> 
> The previously used common device type for all alternate
> modes is replaced with separate dedicated device types for
> port, plug, and partner alternate modes.
> 
> Signed-off-by: Heikki Krogerus <heikki.krogerus at linux.intel.com>
> ---

You forgot to sign off on this :(


From chaoyi.chen at rock-chips.com  Thu Nov 27 22:15:07 2025
From: chaoyi.chen at rock-chips.com (Chaoyi Chen)
Date: Fri, 28 Nov 2025 14:15:07 +0800
Subject: [PATCH v11 01/11] usb: typec: Set the bus also for the port and
 plug altmodes
In-Reply-To: <2025112846-italicize-handled-84ff@gregkh>
References: <20251128020405.90-1-kernel@airkyi.com>
 <20251128020405.90-2-kernel@airkyi.com>
 <2025112846-italicize-handled-84ff@gregkh>
Message-ID: <5520827b-bd13-4b32-8266-83a4eaa233c3@rock-chips.com>

On 11/28/2025 1:51 PM, Greg Kroah-Hartman wrote:
> On Fri, Nov 28, 2025 at 10:03:55AM +0800, Chaoyi Chen wrote:
>> From: Heikki Krogerus <heikki.krogerus at linux.intel.com>
>>
>> The port and plug altmodes can't be bound to the altmode
>> drivers because the altmode drivers are meant for partner
>> communication using the VDM (vendor defined messages), but
>> they can still be part of the bus. The bus will make sure
>> that the normal bus notifications are available also with
>> the port altmodes.
>>
>> The previously used common device type for all alternate
>> modes is replaced with separate dedicated device types for
>> port, plug, and partner alternate modes.
>>
>> Signed-off-by: Heikki Krogerus <heikki.krogerus at linux.intel.com>
>> ---
> 
> You forgot to sign off on this :(
> 

Sorry for that. If there are no further problem on this series,
I will resend it.

-- 
Best, 
Chaoyi


From oliver.sang at intel.com  Thu Nov 27 22:35:25 2025
From: oliver.sang at intel.com (kernel test robot)
Date: Fri, 28 Nov 2025 14:35:25 +0800
Subject: [linux-next:master] [syscore]  a97fbc3ee3:
 will-it-scale.per_process_ops 3.2% regression
Message-ID: <202511281432.47ac7e38-lkp@intel.com>



Hello,

kernel test robot noticed a 3.2% regression of will-it-scale.per_process_ops on:


commit: a97fbc3ee3e2a536fafaff04f21f45472db71769 ("syscore: Pass context data to callbacks")
https://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git master

[still regression on linux-next/master ef68bf704646690aba5e81c2f7be8d6ef13d7ad8]

testcase: will-it-scale
config: x86_64-rhel-9.4
compiler: gcc-14
test machine: 64 threads 2 sockets Intel(R) Xeon(R) Gold 6346 CPU @ 3.10GHz (Ice Lake) with 256G memory
parameters:

	nr_task: 100%
	mode: process
	test: signal1
	cpufreq_governor: performance




If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <oliver.sang at intel.com>
| Closes: https://lore.kernel.org/oe-lkp/202511281432.47ac7e38-lkp at intel.com


Details are as below:
-------------------------------------------------------------------------------------------------->


The kernel config and materials to reproduce are available at:
https://download.01.org/0day-ci/archive/20251128/202511281432.47ac7e38-lkp at intel.com

=========================================================================================
compiler/cpufreq_governor/kconfig/mode/nr_task/rootfs/tbox_group/test/testcase:
  gcc-14/performance/x86_64-rhel-9.4/process/100%/debian-13-x86_64-20250902.cgz/lkp-icl-2sp7/signal1/will-it-scale

commit: 
  v6.18-rc1
  a97fbc3ee3 ("syscore: Pass context data to callbacks")

       v6.18-rc1 a97fbc3ee3e2a536fafaff04f21 
---------------- --------------------------- 
         %stddev     %change         %stddev
             \          |                \  
     71066 ?105%    +119.1%     155709 ? 64%  numa-meminfo.node1.AnonHugePages
     34.80 ?105%    +118.6%      76.08 ? 64%  numa-vmstat.node1.nr_anon_transparent_hugepages
      0.34            +0.2        0.52 ? 25%  mpstat.cpu.all.idle%
      0.01            +0.0        0.01 ?  3%  mpstat.cpu.all.soft%
    142.02 ?  5%     +20.2%     170.65 ?  9%  sched_debug.cfs_rq:/.runnable_avg.stddev
      7.16 ?  5%     +52.9%      10.94 ?  8%  sched_debug.cpu.clock.stddev
      1233 ?  4%     -22.2%     960.17 ?  8%  perf-c2c.DRAM.remote
      2429 ?  3%     -18.0%       1993        perf-c2c.HITM.local
      1010 ?  5%     -29.8%     709.00 ?  2%  perf-c2c.HITM.remote
   8382642            -3.2%    8118230        will-it-scale.64.processes
    130978            -3.2%     126846        will-it-scale.per_process_ops
   8382642            -3.2%    8118230        will-it-scale.workload
    285565            -1.6%     280908        proc-vmstat.nr_active_anon
     28063            +4.4%      29306        proc-vmstat.nr_mapped
    117169            -3.9%     112656        proc-vmstat.nr_shmem
    285565            -1.6%     280908        proc-vmstat.nr_zone_active_anon
     38231 ? 33%     -48.6%      19647 ? 35%  proc-vmstat.numa_hint_faults
     19706 ? 75%     -65.5%       6790 ? 15%  proc-vmstat.numa_hint_faults_local
 9.391e+09            -3.1%  9.102e+09        perf-stat.i.branch-instructions
      0.48            -0.0        0.45        perf-stat.i.branch-miss-rate%
  45545162           -10.7%   40674481        perf-stat.i.branch-misses
     11.08 ?  8%      -2.3        8.81 ? 12%  perf-stat.i.cache-miss-rate%
      1811            +6.2%       1922        perf-stat.i.context-switches
      5.09            +3.2%       5.26        perf-stat.i.cpi
    117.53            -2.1%     115.06        perf-stat.i.cpu-migrations
    216404 ?  2%     +86.7%     404107 ?  4%  perf-stat.i.cycles-between-cache-misses
  3.87e+10            -3.1%  3.752e+10        perf-stat.i.instructions
      0.20            -3.1%       0.19        perf-stat.i.ipc
      0.49            -0.0        0.45        perf-stat.overall.branch-miss-rate%
      5.10            +3.2%       5.26        perf-stat.overall.cpi
      0.20            -3.1%       0.19        perf-stat.overall.ipc
 9.361e+09            -3.1%  9.068e+09        perf-stat.ps.branch-instructions
  45428240           -10.7%   40562730        perf-stat.ps.branch-misses
      1806            +6.2%       1917        perf-stat.ps.context-switches
    117.13            -2.1%     114.62        perf-stat.ps.cpu-migrations
 3.858e+10            -3.1%  3.738e+10        perf-stat.ps.instructions
 1.166e+13            -3.0%  1.131e+13        perf-stat.total.instructions
     32.30            -6.5       25.85        perf-profile.calltrace.cycles-pp.get_signal.arch_do_signal_or_restart.exit_to_user_mode_loop.do_syscall_64.entry_SYSCALL_64_after_hwframe
     31.42            -6.4       25.04        perf-profile.calltrace.cycles-pp.dequeue_signal.get_signal.arch_do_signal_or_restart.exit_to_user_mode_loop.do_syscall_64
     30.28            -6.3       23.98        perf-profile.calltrace.cycles-pp.dec_rlimit_put_ucounts.__sigqueue_free.dequeue_signal.get_signal.arch_do_signal_or_restart
     30.32            -6.3       24.02        perf-profile.calltrace.cycles-pp.__sigqueue_free.dequeue_signal.get_signal.arch_do_signal_or_restart.exit_to_user_mode_loop
     37.60            -6.0       31.57        perf-profile.calltrace.cycles-pp.arch_do_signal_or_restart.exit_to_user_mode_loop.do_syscall_64.entry_SYSCALL_64_after_hwframe
     37.68            -6.0       31.66        perf-profile.calltrace.cycles-pp.exit_to_user_mode_loop.do_syscall_64.entry_SYSCALL_64_after_hwframe
     90.92            -0.5       90.43        perf-profile.calltrace.cycles-pp.entry_SYSCALL_64_after_hwframe
     90.63            -0.5       90.14        perf-profile.calltrace.cycles-pp.do_syscall_64.entry_SYSCALL_64_after_hwframe
      0.62            +0.0        0.65        perf-profile.calltrace.cycles-pp.check_xstate_in_sigframe.__fpu_restore_sig.fpu__restore_sig.restore_sigcontext.__x64_sys_rt_sigreturn
      0.72 ?  2%      +0.0        0.75        perf-profile.calltrace.cycles-pp.kmem_cache_alloc_noprof.__send_signal_locked.do_send_sig_info.do_send_specific.__x64_sys_tgkill
      0.67            +0.0        0.70        perf-profile.calltrace.cycles-pp.__fpu_restore_sig.fpu__restore_sig.restore_sigcontext.__x64_sys_rt_sigreturn.do_syscall_64
      2.54            +0.0        2.58        perf-profile.calltrace.cycles-pp.fpu__restore_sig.restore_sigcontext.__x64_sys_rt_sigreturn.do_syscall_64.entry_SYSCALL_64_after_hwframe
      1.15            +0.0        1.19        perf-profile.calltrace.cycles-pp.fpu__clear_user_states.arch_do_signal_or_restart.exit_to_user_mode_loop.do_syscall_64.entry_SYSCALL_64_after_hwframe
      1.78            +0.0        1.83        perf-profile.calltrace.cycles-pp.clear_bhb_loop
      0.56            +0.1        0.61        perf-profile.calltrace.cycles-pp.rseq_ip_fixup.__rseq_handle_notify_resume.arch_do_signal_or_restart.exit_to_user_mode_loop.do_syscall_64
      1.46            +0.1        1.51        perf-profile.calltrace.cycles-pp.__restore_fpregs_from_user.restore_fpregs_from_user.fpu__restore_sig.restore_sigcontext.__x64_sys_rt_sigreturn
      1.62            +0.1        1.68        perf-profile.calltrace.cycles-pp.arch_do_signal_or_restart.exit_to_user_mode_loop.do_syscall_64.entry_SYSCALL_64_after_hwframe.handler
      3.06            +0.1        3.11        perf-profile.calltrace.cycles-pp.restore_sigcontext.__x64_sys_rt_sigreturn.do_syscall_64.entry_SYSCALL_64_after_hwframe
      1.69            +0.1        1.75        perf-profile.calltrace.cycles-pp.exit_to_user_mode_loop.do_syscall_64.entry_SYSCALL_64_after_hwframe.handler
      1.91            +0.1        1.98        perf-profile.calltrace.cycles-pp.entry_SYSCALL_64_after_hwframe.handler
      1.88            +0.1        1.96        perf-profile.calltrace.cycles-pp.do_syscall_64.entry_SYSCALL_64_after_hwframe.handler
      0.96            +0.1        1.04        perf-profile.calltrace.cycles-pp.save_xstate_epilog.get_sigframe.x64_setup_rt_frame.arch_do_signal_or_restart.exit_to_user_mode_loop
      0.93            +0.1        1.02        perf-profile.calltrace.cycles-pp.__rseq_handle_notify_resume.arch_do_signal_or_restart.exit_to_user_mode_loop.do_syscall_64.entry_SYSCALL_64_after_hwframe
      4.46            +0.1        4.57        perf-profile.calltrace.cycles-pp.__x64_sys_rt_sigreturn.do_syscall_64.entry_SYSCALL_64_after_hwframe
      2.18            +0.2        2.35        perf-profile.calltrace.cycles-pp.copy_fpstate_to_sigframe.get_sigframe.x64_setup_rt_frame.arch_do_signal_or_restart.exit_to_user_mode_loop
      4.88            +0.3        5.14        perf-profile.calltrace.cycles-pp.handler
      3.66            +0.3        3.95        perf-profile.calltrace.cycles-pp.get_sigframe.x64_setup_rt_frame.arch_do_signal_or_restart.exit_to_user_mode_loop.do_syscall_64
      4.16            +0.3        4.50        perf-profile.calltrace.cycles-pp.x64_setup_rt_frame.arch_do_signal_or_restart.exit_to_user_mode_loop.do_syscall_64.entry_SYSCALL_64_after_hwframe
      0.00            +0.5        0.51        perf-profile.calltrace.cycles-pp.restore_altstack.__x64_sys_rt_sigreturn.do_syscall_64.entry_SYSCALL_64_after_hwframe
      0.00            +0.5        0.52        perf-profile.calltrace.cycles-pp.__get_user_nocheck_8.__x64_sys_rt_sigreturn.do_syscall_64.entry_SYSCALL_64_after_hwframe
     45.91            +5.3       51.19        perf-profile.calltrace.cycles-pp.do_send_sig_info.do_send_specific.__x64_sys_tgkill.do_syscall_64.entry_SYSCALL_64_after_hwframe
     46.73            +5.3       52.02        perf-profile.calltrace.cycles-pp.do_send_specific.__x64_sys_tgkill.do_syscall_64.entry_SYSCALL_64_after_hwframe
     47.27            +5.3       52.57        perf-profile.calltrace.cycles-pp.__x64_sys_tgkill.do_syscall_64.entry_SYSCALL_64_after_hwframe
     45.10            +5.3       50.43        perf-profile.calltrace.cycles-pp.__send_signal_locked.do_send_sig_info.do_send_specific.__x64_sys_tgkill.do_syscall_64
     43.31            +5.3       48.65        perf-profile.calltrace.cycles-pp.inc_rlimit_get_ucounts.sig_get_ucounts.__send_signal_locked.do_send_sig_info.do_send_specific
     43.39            +5.3       48.73        perf-profile.calltrace.cycles-pp.sig_get_ucounts.__send_signal_locked.do_send_sig_info.do_send_specific.__x64_sys_tgkill
     32.36            -6.5       25.90        perf-profile.children.cycles-pp.get_signal
     31.44            -6.4       25.06        perf-profile.children.cycles-pp.dequeue_signal
     30.29            -6.3       23.99        perf-profile.children.cycles-pp.dec_rlimit_put_ucounts
     30.33            -6.3       24.03        perf-profile.children.cycles-pp.__sigqueue_free
     39.26            -6.0       33.30        perf-profile.children.cycles-pp.arch_do_signal_or_restart
     39.38            -5.9       33.43        perf-profile.children.cycles-pp.exit_to_user_mode_loop
     93.64            -0.3       93.30        perf-profile.children.cycles-pp.entry_SYSCALL_64_after_hwframe
     93.28            -0.3       92.95        perf-profile.children.cycles-pp.do_syscall_64
      0.36 ? 11%      -0.1        0.25        perf-profile.children.cycles-pp.recalc_sigpending
      0.61 ? 11%      -0.1        0.50 ?  6%  perf-profile.children.cycles-pp._raw_spin_lock_irq
      0.43            -0.1        0.38        perf-profile.children.cycles-pp.fpregs_mark_activate
      0.44            -0.0        0.40        perf-profile.children.cycles-pp.complete_signal
      0.27 ?  5%      -0.0        0.23 ?  3%  perf-profile.children.cycles-pp.sysvec_apic_timer_interrupt
      0.25 ?  6%      -0.0        0.22 ?  5%  perf-profile.children.cycles-pp.__sysvec_apic_timer_interrupt
      0.25 ?  6%      -0.0        0.22 ?  5%  perf-profile.children.cycles-pp.hrtimer_interrupt
      0.25            -0.0        0.22 ?  5%  perf-profile.children.cycles-pp._raw_spin_lock_irqsave
      0.29 ?  5%      -0.0        0.26 ?  3%  perf-profile.children.cycles-pp.asm_sysvec_apic_timer_interrupt
      0.31 ?  2%      -0.0        0.28        perf-profile.children.cycles-pp.set_current_blocked
      0.05            +0.0        0.06        perf-profile.children.cycles-pp.fpu__alloc_mathframe
      0.06            +0.0        0.07        perf-profile.children.cycles-pp.__cond_resched
      0.20            +0.0        0.21        perf-profile.children.cycles-pp.syscall_return_via_sysret
      0.24            +0.0        0.25        perf-profile.children.cycles-pp.__get_user_nocheck_4
      0.39            +0.0        0.40        perf-profile.children.cycles-pp.entry_SYSCALL_64_safe_stack
      0.72            +0.0        0.74        perf-profile.children.cycles-pp.entry_SYSRETQ_unsafe_stack
      0.20            +0.0        0.22        perf-profile.children.cycles-pp.__get_user_8
      0.22 ?  2%      +0.0        0.24        perf-profile.children.cycles-pp.__put_user_8
      0.46 ?  3%      +0.0        0.48        perf-profile.children.cycles-pp.__memcg_slab_post_alloc_hook
      0.69            +0.0        0.71        perf-profile.children.cycles-pp.__fpu_restore_sig
      0.27            +0.0        0.30        perf-profile.children.cycles-pp.rseq_get_rseq_cs
      0.63            +0.0        0.66        perf-profile.children.cycles-pp.check_xstate_in_sigframe
      0.74            +0.0        0.77        perf-profile.children.cycles-pp.kmem_cache_alloc_noprof
      0.50            +0.0        0.53        perf-profile.children.cycles-pp.restore_altstack
      0.32            +0.0        0.35        perf-profile.children.cycles-pp.rseq_update_cpu_node_id
      0.36            +0.0        0.39        perf-profile.children.cycles-pp.__put_user_nocheck_4
      0.69            +0.0        0.73        perf-profile.children.cycles-pp.arch_exit_to_user_mode_prepare
      0.37            +0.0        0.40        perf-profile.children.cycles-pp.__put_user_nocheck_8
      2.06            +0.0        2.10        perf-profile.children.cycles-pp.__getpid
      0.66            +0.0        0.70        perf-profile.children.cycles-pp._copy_from_user
      2.55            +0.0        2.59        perf-profile.children.cycles-pp.fpu__restore_sig
      0.87            +0.0        0.91        perf-profile.children.cycles-pp.its_return_thunk
      1.21            +0.0        1.25        perf-profile.children.cycles-pp.fpu__clear_user_states
      1.48            +0.0        1.52        perf-profile.children.cycles-pp.__restore_fpregs_from_user
      2.39            +0.1        2.44        perf-profile.children.cycles-pp.clear_bhb_loop
      0.09 ?  4%      +0.1        0.14 ?  4%  perf-profile.children.cycles-pp.shmem_file_write_iter
      0.08            +0.1        0.14 ?  5%  perf-profile.children.cycles-pp.generic_perform_write
      0.00            +0.1        0.06 ?  8%  perf-profile.children.cycles-pp.shmem_get_folio_gfp
      0.10 ?  3%      +0.1        0.16 ?  3%  perf-profile.children.cycles-pp.perf_mmap__push
      0.00            +0.1        0.06 ?  6%  perf-profile.children.cycles-pp.shmem_write_begin
      0.58            +0.1        0.64        perf-profile.children.cycles-pp.rseq_ip_fixup
      3.08            +0.1        3.13        perf-profile.children.cycles-pp.restore_sigcontext
      0.10 ?  3%      +0.1        0.16 ?  4%  perf-profile.children.cycles-pp.record__mmap_read_evlist
      0.09 ?  5%      +0.1        0.15 ?  4%  perf-profile.children.cycles-pp.record__pushfn
      0.12 ?  4%      +0.1        0.18 ?  4%  perf-profile.children.cycles-pp.handle_internal_command
      0.12 ?  4%      +0.1        0.18 ?  4%  perf-profile.children.cycles-pp.main
      0.12 ?  4%      +0.1        0.18 ?  4%  perf-profile.children.cycles-pp.run_builtin
      0.11 ?  6%      +0.1        0.17 ?  5%  perf-profile.children.cycles-pp.cmd_record
      0.98            +0.1        1.06        perf-profile.children.cycles-pp.__get_user_nocheck_8
      1.36            +0.1        1.45        perf-profile.children.cycles-pp.native_irq_return_iret
      1.00            +0.1        1.09        perf-profile.children.cycles-pp.save_xstate_epilog
      0.95            +0.1        1.04        perf-profile.children.cycles-pp.__rseq_handle_notify_resume
      4.52            +0.1        4.64        perf-profile.children.cycles-pp.__x64_sys_rt_sigreturn
      2.27            +0.2        2.45        perf-profile.children.cycles-pp.copy_fpstate_to_sigframe
      3.68            +0.2        3.86        perf-profile.children.cycles-pp.handler
      3.68            +0.3        3.98        perf-profile.children.cycles-pp.get_sigframe
      4.21            +0.3        4.55        perf-profile.children.cycles-pp.x64_setup_rt_frame
     45.96            +5.3       51.25        perf-profile.children.cycles-pp.do_send_sig_info
     46.77            +5.3       52.07        perf-profile.children.cycles-pp.do_send_specific
     47.30            +5.3       52.60        perf-profile.children.cycles-pp.__x64_sys_tgkill
     45.18            +5.3       50.51        perf-profile.children.cycles-pp.__send_signal_locked
     43.40            +5.3       48.74        perf-profile.children.cycles-pp.sig_get_ucounts
     43.32            +5.3       48.66        perf-profile.children.cycles-pp.inc_rlimit_get_ucounts
     30.28            -6.3       23.98        perf-profile.self.cycles-pp.dec_rlimit_put_ucounts
      0.34 ? 12%      -0.1        0.23 ?  2%  perf-profile.self.cycles-pp.recalc_sigpending
      0.58 ? 12%      -0.1        0.48 ?  6%  perf-profile.self.cycles-pp._raw_spin_lock_irq
      0.31            -0.1        0.25 ?  2%  perf-profile.self.cycles-pp.complete_signal
      0.36            -0.1        0.31        perf-profile.self.cycles-pp.fpregs_mark_activate
      0.23 ?  2%      -0.0        0.20 ?  3%  perf-profile.self.cycles-pp._raw_spin_lock_irqsave
      0.20            +0.0        0.21        perf-profile.self.cycles-pp.arch_do_signal_or_restart
      0.07            +0.0        0.08        perf-profile.self.cycles-pp.collect_signal
      0.40            +0.0        0.41        perf-profile.self.cycles-pp.__getpid
      0.20            +0.0        0.21        perf-profile.self.cycles-pp.syscall_return_via_sysret
      0.23            +0.0        0.24 ?  2%  perf-profile.self.cycles-pp.__get_user_nocheck_4
      0.15 ?  2%      +0.0        0.16 ?  2%  perf-profile.self.cycles-pp.__x64_sys_rt_sigreturn
      0.26            +0.0        0.28        perf-profile.self.cycles-pp.kmem_cache_free
      0.10            +0.0        0.11 ?  4%  perf-profile.self.cycles-pp.signal_setup_done
      0.70            +0.0        0.72        perf-profile.self.cycles-pp.entry_SYSRETQ_unsafe_stack
      0.18 ?  2%      +0.0        0.20        perf-profile.self.cycles-pp.__get_user_8
      0.21 ?  3%      +0.0        0.23        perf-profile.self.cycles-pp.__put_user_8
      0.25 ?  3%      +0.0        0.27 ?  2%  perf-profile.self.cycles-pp.__memcg_slab_post_alloc_hook
      0.47            +0.0        0.49        perf-profile.self.cycles-pp.get_signal
      0.52            +0.0        0.55        perf-profile.self.cycles-pp.its_return_thunk
      0.37            +0.0        0.40        perf-profile.self.cycles-pp.get_sigframe
      0.34            +0.0        0.37        perf-profile.self.cycles-pp.__put_user_nocheck_4
      0.31            +0.0        0.34        perf-profile.self.cycles-pp.rseq_update_cpu_node_id
      0.34            +0.0        0.38        perf-profile.self.cycles-pp.__put_user_nocheck_8
      0.37 ?  2%      +0.0        0.41        perf-profile.self.cycles-pp.save_xstate_epilog
      0.64            +0.0        0.68        perf-profile.self.cycles-pp.arch_exit_to_user_mode_prepare
      0.64            +0.0        0.68        perf-profile.self.cycles-pp._copy_from_user
      0.53            +0.0        0.57        perf-profile.self.cycles-pp.x64_setup_rt_frame
      1.46            +0.0        1.51        perf-profile.self.cycles-pp.__restore_fpregs_from_user
      2.36            +0.1        2.41        perf-profile.self.cycles-pp.clear_bhb_loop
      1.00            +0.1        1.06        perf-profile.self.cycles-pp.fpu__clear_user_states
      0.94            +0.1        1.01        perf-profile.self.cycles-pp.__get_user_nocheck_8
      1.36            +0.1        1.45        perf-profile.self.cycles-pp.native_irq_return_iret
      1.45            +0.1        1.55        perf-profile.self.cycles-pp.copy_fpstate_to_sigframe
     43.32            +5.3       48.66        perf-profile.self.cycles-pp.inc_rlimit_get_ucounts




Disclaimer:
Results have been estimated based on internal Intel analysis and are provided
for informational purposes only. Any difference in system hardware or software
design or configuration may affect actual performance.


-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki



From naoki at radxa.com  Thu Nov 27 22:55:30 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Fri, 28 Nov 2025 15:55:30 +0900
Subject: [PATCH] PCI: dwc: Make Link Up IRQ logic handle already powered
 on PCIe switches
In-Reply-To: <20251127134318.3655052-2-cassel@kernel.org>
References: <20251127134318.3655052-2-cassel@kernel.org>
Message-ID: <77CAEF73515D28BB+4b2d2237-7be7-4adb-b378-bc0a311272bc@radxa.com>

Hi Niklas,

On 11/27/25 22:43, Niklas Cassel wrote:
> The DWC glue drivers always call pci_host_probe() during probe(), which
> will allocate upstream bridge resources and enumerate the bus.
> 
> For controllers without Link Up IRQ support, pci_host_probe() is called
> after dw_pcie_wait_for_link(), which will also wait the time required by
> the PCIe specification before performing PCI Configuration Space reads.
> 
> For controllers with Link Up IRQ support, the pci_host_probe() call (which
> will perform PCI Configuration Space reads) is done without any of the
> delays mandated by the PCIe specification.
> 
> For controllers with Link Up IRQ support, since the pci_host_probe() call
> is done without any delay (link training might still be ongoing), it is
> very unlikely that this scan will find any devices. Once the Link Up IRQ
> triggers, the Link Up IRQ handler will call pci_rescan_bus().
> 
> This works fine for PCIe endpoints connected to the Root Port, since they
> don't extend the bus. However, if the pci_rescan_bus() call detects a PCIe
> switch, then there will be a problem when the downstream busses starts
> showing up, because the PCIe controller is not hotplug capable, so we are
> not allowed to extend the subordinate bus number after the initial scan,
> resulting in error messages such as:
> 
> pci_bus 0004:43: busn_res: can not insert [bus 43-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:43: busn_res: [bus 43-41] end is updated to 43
> pci_bus 0004:43: busn_res: can not insert [bus 43] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:00.0: devices behind bridge are unusable because [bus 43] cannot be assigned for them
> pci_bus 0004:44: busn_res: can not insert [bus 44-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:44: busn_res: [bus 44-41] end is updated to 44
> pci_bus 0004:44: busn_res: can not insert [bus 44] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:02.0: devices behind bridge are unusable because [bus 44] cannot be assigned for them
> pci_bus 0004:45: busn_res: can not insert [bus 45-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:45: busn_res: [bus 45-41] end is updated to 45
> pci_bus 0004:45: busn_res: can not insert [bus 45] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:06.0: devices behind bridge are unusable because [bus 45] cannot be assigned for them
> pci_bus 0004:46: busn_res: can not insert [bus 46-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:46: busn_res: [bus 46-41] end is updated to 46
> pci_bus 0004:46: busn_res: can not insert [bus 46] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:0e.0: devices behind bridge are unusable because [bus 46] cannot be assigned for them
> pci_bus 0004:42: busn_res: [bus 42-41] end is updated to 46
> pci_bus 0004:42: busn_res: can not insert [bus 42-46] under [bus 41] (conflicts with (null) [bus 41])
> pci 0004:41:00.0: devices behind bridge are unusable because [bus 42-46] cannot be assigned for them
> pcieport 0004:40:00.0: bridge has subordinate 41 but max busn 46
> 
> While we would like to set the is_hotplug_bridge flag
> (quirk_hotplug_bridge()), many embedded SoCs that use the DWC controller
> have synthesized the controller without hot-plug support.
> Thus, the Link Up IRQ logic is only mimicking hot-plug functionality, i.e.
> it is not compliant with the PCI Hot-Plug Specification, so we cannot make
> use of the is_hotplug_bridge flag.
> 
> In order to let the Link Up IRQ logic handle PCIe switches that are already
> powered on (PCIe switches that not powered on already need to implement a
> pwrctrl driver), don't perform a pci_host_probe() call during probe()
> (which disregards the delays required by the PCIe specification).
> 
> Instead let the first Link Up IRQ call pci_host_probe(). Any follow up
> Link Up IRQ will call pci_rescan_bus().

I'm pleased to inform you that your patch worked perfectly with devices 
behind the ASM2806 switch (Radxa Dual 2.5G Router HAT) connected to the 
PCIe 2.1 bus of the Radxa ROCK 5A, 5B, and 5C Lite.

So,
Tested-by: FUKAUMI Naoki <naoki at radxa.com>


Thank you very much for your work, and I apologize for any confusion 
caused by my test report.

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> Fixes: ec9fd499b9c6 ("PCI: dw-rockchip: Don't wait for link since we can detect Link Up")
> Fixes: 0e0b45ab5d77 ("PCI: dw-rockchip: Enumerate endpoints based on dll_link_up IRQ")
> Reported-by: FUKAUMI Naoki <naoki at radxa.com>
> Closes: https://lore.kernel.org/linux-pci/1E8E4DB773970CB5+5a52c9e1-01b8-4872-99b7-021099f04031 at radxa.com/
> Signed-off-by: Niklas Cassel <cassel at kernel.org>
> ---
>   .../pci/controller/dwc/pcie-designware-host.c | 70 ++++++++++++++++---
>   drivers/pci/controller/dwc/pcie-designware.h  |  5 ++
>   drivers/pci/controller/dwc/pcie-dw-rockchip.c |  5 +-
>   drivers/pci/controller/dwc/pcie-qcom.c        |  5 +-
>   4 files changed, 68 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> index e92513c5bda51..8654346729574 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -565,6 +565,59 @@ static int dw_pcie_host_get_resources(struct dw_pcie_rp *pp)
>   	return 0;
>   }
>   
> +static int dw_pcie_host_initial_scan(struct dw_pcie_rp *pp)
> +{
> +	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> +	struct pci_host_bridge *bridge = pp->bridge;
> +	int ret;
> +
> +	ret = pci_host_probe(bridge);
> +	if (ret)
> +		return ret;
> +
> +	if (pp->ops->post_init)
> +		pp->ops->post_init(pp);
> +
> +	dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
> +
> +	return 0;
> +}
> +
> +void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp)
> +{
> +	if (!pp->initial_linkup_irq_done) {
> +		int ret;
> +
> +		ret = dw_pcie_host_initial_scan(pp);
> +		if (ret) {
> +			struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> +			struct device *dev = pci->dev;
> +
> +			dev_err(dev, "Initial scan from IRQ failed: %d\n", ret);
> +
> +			dw_pcie_stop_link(pci);
> +
> +			dw_pcie_edma_remove(pci);
> +
> +			if (pp->has_msi_ctrl)
> +				dw_pcie_free_msi(pp);
> +
> +			if (pp->ops->deinit)
> +				pp->ops->deinit(pp);
> +
> +			if (pp->cfg)
> +				pci_ecam_free(pp->cfg);
> +		} else {
> +			pp->initial_linkup_irq_done = true;
> +		}
> +	} else {
> +		/* Rescan the bus to enumerate endpoint devices */
> +		pci_lock_rescan_remove();
> +		pci_rescan_bus(pp->bridge->bus);
> +		pci_unlock_rescan_remove();
> +	}
> +}
> +
>   int dw_pcie_host_init(struct dw_pcie_rp *pp)
>   {
>   	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> @@ -669,18 +722,17 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
>   	 * If there is no Link Up IRQ, we should not bypass the delay
>   	 * because that would require users to manually rescan for devices.
>   	 */
> -	if (!pp->use_linkup_irq)
> +	if (!pp->use_linkup_irq) {
>   		/* Ignore errors, the link may come up later */
>   		dw_pcie_wait_for_link(pci);
>   
> -	ret = pci_host_probe(bridge);
> -	if (ret)
> -		goto err_stop_link;
> -
> -	if (pp->ops->post_init)
> -		pp->ops->post_init(pp);
> -
> -	dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
> +		/*
> +		 * For platforms with Link Up IRQ, initial scan will be done
> +		 * on first Link Up IRQ.
> +		 */
> +		if (dw_pcie_host_initial_scan(pp))
> +			goto err_stop_link;
> +	}
>   
>   	return 0;
>   
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> index e995f692a1ecd..a31bd93490dcd 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -427,6 +427,7 @@ struct dw_pcie_rp {
>   	int			msg_atu_index;
>   	struct resource		*msg_res;
>   	bool			use_linkup_irq;
> +	bool			initial_linkup_irq_done;
>   	struct pci_eq_presets	presets;
>   	struct pci_config_window *cfg;
>   	bool			ecam_enabled;
> @@ -807,6 +808,7 @@ void dw_pcie_msi_init(struct dw_pcie_rp *pp);
>   int dw_pcie_msi_host_init(struct dw_pcie_rp *pp);
>   void dw_pcie_free_msi(struct dw_pcie_rp *pp);
>   int dw_pcie_setup_rc(struct dw_pcie_rp *pp);
> +void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp);
>   int dw_pcie_host_init(struct dw_pcie_rp *pp);
>   void dw_pcie_host_deinit(struct dw_pcie_rp *pp);
>   int dw_pcie_allocate_domains(struct dw_pcie_rp *pp);
> @@ -844,6 +846,9 @@ static inline int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
>   	return 0;
>   }
>   
> +static inline void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp)
> +{ }
> +
>   static inline int dw_pcie_host_init(struct dw_pcie_rp *pp)
>   {
>   	return 0;
> diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> index 3e2752c7dd096..8f2cc1ef25e3d 100644
> --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
> @@ -466,10 +466,7 @@ static irqreturn_t rockchip_pcie_rc_sys_irq_thread(int irq, void *arg)
>   		if (rockchip_pcie_link_up(pci)) {
>   			msleep(PCIE_RESET_CONFIG_WAIT_MS);
>   			dev_dbg(dev, "Received Link up event. Starting enumeration!\n");
> -			/* Rescan the bus to enumerate endpoint devices */
> -			pci_lock_rescan_remove();
> -			pci_rescan_bus(pp->bridge->bus);
> -			pci_unlock_rescan_remove();
> +			dw_pcie_handle_link_up_irq(pp);
>   		}
>   	}
>   
> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
> index c48a20602d7fa..2d8aca6630949 100644
> --- a/drivers/pci/controller/dwc/pcie-qcom.c
> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> @@ -1617,10 +1617,7 @@ static irqreturn_t qcom_pcie_global_irq_thread(int irq, void *data)
>   	if (FIELD_GET(PARF_INT_ALL_LINK_UP, status)) {
>   		msleep(PCIE_RESET_CONFIG_WAIT_MS);
>   		dev_dbg(dev, "Received Link up event. Starting enumeration!\n");
> -		/* Rescan the bus to enumerate endpoint devices */
> -		pci_lock_rescan_remove();
> -		pci_rescan_bus(pp->bridge->bus);
> -		pci_unlock_rescan_remove();
> +		dw_pcie_handle_link_up_irq(pp);
>   
>   		qcom_pcie_icc_opp_update(pcie);
>   	} else {




From shawn.lin at rock-chips.com  Thu Nov 27 23:09:22 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Fri, 28 Nov 2025 15:09:22 +0800
Subject: [PATCH] arm64: dts: rockchip: add dma-coherent for pcie and gmac of RK3576
Message-ID: <1764313762-78063-1-git-send-email-shawn.lin@rock-chips.com>

The RK3576 SoC employs ARM CCI for maintaining cache coherency
between the CPU cluster and high-speed peripherals including USB3,
SATA, GMAC, and PCIe controllers. While the USB3 and SATA controllers
were correctly marked as dma-coherent, the GMAC and PCIe nodes were
overlooked.

Without dma-coherent, the kernel falls back to software cache maintenance
for DMA operations, requiring explicit cache flushing and invalidating.
This adds significant overhead that degrades performance in high-throughput
workloads.

Add the missing dma-coherent properties to enable hardware coherency and
avoid unnecessary software cache management overhead.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
---
Hi Heiko,

This patch needs U-boot support which was added on Apr 15 2025 at least.
https://elixir.bootlin.com/u-boot/v2025.10/source/arch/arm/mach-rockchip/rk3576/rk3576.c#L156

Given that when the time USB3 and SATA were added, they set dma-coherent but without a
CCI enabled U-boot, they were in fact broken due to no CCI support and no software cache
maintenace when seeing dma-coherent. But there is no anyone complained about thes, so
it should be ok that we don't need to bother ourselves.

 arch/arm64/boot/dts/rockchip/rk3576.dtsi | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3576.dtsi b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
index a86fc6b4..33d2e521 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
@@ -709,6 +709,7 @@
 			reset-names = "pwr", "pipe";
 			#address-cells = <3>;
 			#size-cells = <2>;
+			dma-coherent;
 			status = "disabled";
 
 			pcie0_intc: legacy-interrupt-controller {
@@ -763,6 +764,7 @@
 			reset-names = "pwr", "pipe";
 			#address-cells = <3>;
 			#size-cells = <2>;
+			dma-coherent;
 			status = "disabled";
 
 			pcie1_intc: legacy-interrupt-controller {
@@ -1709,6 +1711,7 @@
 			snps,mtl-rx-config = <&gmac0_mtl_rx_setup>;
 			snps,mtl-tx-config = <&gmac0_mtl_tx_setup>;
 			snps,tso;
+			dma-coherent;
 			status = "disabled";
 
 			mdio0: mdio {
@@ -1756,6 +1759,7 @@
 			snps,mtl-rx-config = <&gmac1_mtl_rx_setup>;
 			snps,mtl-tx-config = <&gmac1_mtl_tx_setup>;
 			snps,tso;
+			dma-coherent;
 			status = "disabled";
 
 			mdio1: mdio {
-- 
2.7.4



From kernel at airkyi.com  Thu Nov 27 23:13:21 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Fri, 28 Nov 2025 15:13:21 +0800
Subject: [PATCH v2 1/2] dt-bindings: iommu: rockchip: Add support for multiple interface clocks
In-Reply-To: <20251128071322.92-1-kernel@airkyi.com>
References: <20251128071322.92-1-kernel@airkyi.com>
Message-ID: <20251128071322.92-2-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

The iommu found on RK3576 NPU and RK3576 RKVDEC have 4 clock instead of
2 clock. Their clock names might differ, but I don't think that matters
much.

Add support for them.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---

Changes in v2:
- Rewrite dt binding.

 .../bindings/iommu/rockchip,iommu.yaml        | 52 ++++++++++++++++---
 1 file changed, 46 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/iommu/rockchip,iommu.yaml b/Documentation/devicetree/bindings/iommu/rockchip,iommu.yaml
index 6ce41d11ff5e..dfa5e25476d9 100644
--- a/Documentation/devicetree/bindings/iommu/rockchip,iommu.yaml
+++ b/Documentation/devicetree/bindings/iommu/rockchip,iommu.yaml
@@ -27,6 +27,8 @@ properties:
           - enum:
               - rockchip,rk3576-iommu
               - rockchip,rk3588-iommu
+              - rockchip,rk3576-npu-iommu
+              - rockchip,rk3576-rkvdec-iommu
           - const: rockchip,rk3568-iommu
 
   reg:
@@ -42,14 +44,12 @@ properties:
     minItems: 1
 
   clocks:
-    items:
-      - description: Core clock
-      - description: Interface clock
+    minItems: 2
+    maxItems: 4
 
   clock-names:
-    items:
-      - const: aclk
-      - const: iface
+    minItems: 2
+    maxItems: 4
 
   "#iommu-cells":
     const: 0
@@ -64,6 +64,46 @@ properties:
       Some mmu instances may produce unexpected results
       when the reset operation is used.
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - rockchip,rk3576-npu-iommu
+              - rockchip,rk3576-rkvdec-iommu
+    then:
+      properties:
+        clocks:
+          minItems: 4
+        clock-names:
+          minItems: 4
+  - if:
+      properties:
+        compatible:
+          items:
+            - const: rockchip,iommu
+            - const: rockchip,rk3568-iommu
+    then:
+      properties:
+        clocks:
+          maxItems: 2
+        clock-names:
+          maxItems: 2
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - rockchip,rk3576-iommu
+              - rockchip,rk3588-iommu
+    then:
+      properties:
+        clocks:
+          maxItems: 2
+        clock-names:
+          maxItems: 2
+
 required:
   - compatible
   - reg
-- 
2.51.1



From kernel at airkyi.com  Thu Nov 27 23:13:22 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Fri, 28 Nov 2025 15:13:22 +0800
Subject: [PATCH v2 2/2] iommu/rockchip: Use devm_clk_bulk_get_all() to get multiple iface clock
In-Reply-To: <20251128071322.92-1-kernel@airkyi.com>
References: <20251128071322.92-1-kernel@airkyi.com>
Message-ID: <20251128071322.92-3-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

The iommu found on RK3576 NPU and RK3576 RKVDEC contain 4 clock.

Just use devm_clk_bulk_get_all() to get all the clocks and use them.

Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
---

Changes in v2:
- Change comment.

 drivers/iommu/rockchip-iommu.c | 20 ++++----------------
 1 file changed, 4 insertions(+), 16 deletions(-)

diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 0861dd469bd8..76f71fb679f8 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -93,11 +93,6 @@ struct rk_iommu_domain {
 	struct iommu_domain domain;
 };
 
-/* list of clocks required by IOMMU */
-static const char * const rk_iommu_clocks[] = {
-	"aclk", "iface",
-};
-
 struct rk_iommu_ops {
 	phys_addr_t (*pt_address)(u32 dte);
 	u32 (*mk_dtentries)(dma_addr_t pt_dma);
@@ -1236,25 +1231,18 @@ static int rk_iommu_probe(struct platform_device *pdev)
 	iommu->reset_disabled = device_property_read_bool(dev,
 					"rockchip,disable-mmu-reset");
 
-	iommu->num_clocks = ARRAY_SIZE(rk_iommu_clocks);
-	iommu->clocks = devm_kcalloc(iommu->dev, iommu->num_clocks,
-				     sizeof(*iommu->clocks), GFP_KERNEL);
-	if (!iommu->clocks)
-		return -ENOMEM;
-
-	for (i = 0; i < iommu->num_clocks; ++i)
-		iommu->clocks[i].id = rk_iommu_clocks[i];
-
 	/*
 	 * iommu clocks should be present for all new devices and devicetrees
 	 * but there are older devicetrees without clocks out in the wild.
 	 * So clocks as optional for the time being.
 	 */
-	err = devm_clk_bulk_get(iommu->dev, iommu->num_clocks, iommu->clocks);
+	err = devm_clk_bulk_get_all(dev, &iommu->clocks);
 	if (err == -ENOENT)
 		iommu->num_clocks = 0;
-	else if (err)
+	else if (err < 0)
 		return err;
+	else
+		iommu->num_clocks = err;
 
 	err = clk_bulk_prepare(iommu->num_clocks, iommu->clocks);
 	if (err)
-- 
2.51.1



From kernel at airkyi.com  Thu Nov 27 23:13:20 2025
From: kernel at airkyi.com (Chaoyi Chen)
Date: Fri, 28 Nov 2025 15:13:20 +0800
Subject: [PATCH v2 0/2] iommu/rockchip: Add support for multiple interface clocks
Message-ID: <20251128071322.92-1-kernel@airkyi.com>

From: Chaoyi Chen <chaoyi.chen at rock-chips.com>

Hi,

Some rockchip iommus require extra clocks besides aclk and interface
clock, such as the iommus for NPU and RKVENC in RK3576.

Changes in v2:
- Link to v1: https://lore.kernel.org/all/20251126083345.88-1-kernel at airkyi.com/
- Rewrite dt binding.

Chaoyi Chen (2):
  dt-bindings: iommu: rockchip: Add support for multiple interface
    clocks
  iommu/rockchip: Use devm_clk_bulk_get_all() to get multiple iface
    clock

 .../bindings/iommu/rockchip,iommu.yaml        | 52 ++++++++++++++++---
 drivers/iommu/rockchip-iommu.c                | 20 ++-----
 2 files changed, 50 insertions(+), 22 deletions(-)

-- 
2.51.1



From s.pueschel at pengutronix.de  Thu Nov 27 23:26:55 2025
From: s.pueschel at pengutronix.de (=?UTF-8?Q?Sven_P=C3=BCschel?=)
Date: Fri, 28 Nov 2025 08:26:55 +0100
Subject: [PATCH] iommu/rockchip: disable fetch dte time limit
In-Reply-To: <075100c0-b4af-4077-bd3c-dd9407524671@rock-chips.com>
References: <20251126-spu-iommudtefix-v1-1-f90003dbfcc4@pengutronix.de>
 <075100c0-b4af-4077-bd3c-dd9407524671@rock-chips.com>
Message-ID: <cea54dcb-6236-4363-8b46-e2213a190894@pengutronix.de>


On 11/27/25 5:32 AM, Shawn Lin wrote:
> ? 2025/11/26 ??? 19:45, Sven P?schel ??:
>> From: Simon Xue <xxm at rock-chips.com>
>>
>> Disable the Bit 31 of the AUTO_GATING iommu register, as it causes
>> hangups with the RGA3 (Raster Graphics Acceleration 3) peripheral.
>> The RGA3 register description of the TRM already states that the bit
>> must be set to 1. The vendor kernel sets the bit unconditionally to
>> 1 to fix VOP (Video Output Processor) screen black issues. This patch
>> squashes the 2 vendor kernel commits with the following commit messages:
>>
>> Master fetch data and cpu update page table may work in parallel, may
>> have the following procedure:
>>
>> ????master????????????????? cpu
>> ????fetch dte?????????????? update page tabl
>> ??????????? |?????????????????????? |
>> ????(make dte invalid)? <-? zap iotlb entry
>> ??????????? |?????????????????????? |
>> ????fetch dte again
>> ????(make dte invalid)? <-? zap iotlb entry
>> ??????????? |?????????????????????? |
>> ????fetch dte again
>> ????(make dte invalid)? <-? zap iotlb entry
>> ??????????? |?????????????????????? |
>> ????fetch dte again
>> ????(make iommu block)? <-? zap iotlb entry
>>
>> New iommu version has the above bug, if fetch dte consecutively four
>> times, then it will be blocked. Fortunately, we can set bit 31 of
>> register MMU_AUTO_GATING to 1 to make it work as old version which does
>> not have this issue.
>>
>> This issue only appears on RV1126 so far, so make a workaround dedicated
>> to "rockchip,rv1126" machine type.
>>
>> iommu/rockchip: fix vop blocked and screen black on RK356X and RK3588
>>
>> RK3568 and RK3588 has the same issue as RV1126/RV1109 that caused by
>> dte fetch time limit, So we can set BIT(31) of register 0x24 default
>> to 1 as a workaround.
>>
>> Signed-off-by: Simon Xue <xxm at rock-chips.com>
>> Signed-off-by: Sven P?schel <s.pueschel at pengutronix.de>
>> ---
>> During testing of a newly developed driver for the RGA3 peripheral [1]
>> (Raster Graphic Acceleration 3) of the RK3588 some sporadic hangs
>> have been observed. The upstream rockchip-iommu driver is used to handle
>> the RGA3 IOMMU register space.
>>
>> After a closer look at the TRM for the RK3588, the RGA3 iommu register
>> description of the RGA3_MMU_AUTO_GATING register (offset 0x24) mentions
>
> It's 0xF24 per RGA3 chapter.

yeah, sorry. I was already thinking relative to the rga3 iommu address 
space in my head, but didn't really mention that the chapter says 0xF24 
with the iommu related registers starting at 0xF00.

Sincerely
 ? ? Sven

>
>> a mmu_bug_fixed_disable bit, which must be set to 1 but defaults to 0.
>>
>> Looking at the commits in the vendor kernel, the bit is unconditionally
>> set to 1 and mentions that it fixes a blocked VOP (Video Output
>> Processor) [3]. Therefore squash the relevant vendor commits
>> [2] and [3] into a single patch, combine the commit messages and keep
>> the Signed-off-by line from the original author.
>>
>> [1] 
>> https://lore.kernel.org/all/20251007-spu-rga3-v1-0-36ad85570402 at pengutronix.de/
>> [2] 
>> https://github.com/rockchip-linux/kernel/commit/7f8158fb41b5cc8e738aaeebc3637c50ebd74cae
>> [3] 
>> https://github.com/rockchip-linux/kernel/commit/6a355e5f9a2069a2309e240791bc3aad63b7324e
>> ---
>> ? drivers/iommu/rockchip-iommu.c | 8 ++++++++
>> ? 1 file changed, 8 insertions(+)
>>
>> diff --git a/drivers/iommu/rockchip-iommu.c 
>> b/drivers/iommu/rockchip-iommu.c
>> index 0861dd469bd86..2d0dabb0d101a 100644
>> --- a/drivers/iommu/rockchip-iommu.c
>> +++ b/drivers/iommu/rockchip-iommu.c
>> @@ -76,6 +76,8 @@
>> ? #define SPAGE_ORDER 12
>> ? #define SPAGE_SIZE (1 << SPAGE_ORDER)
>> ? +#define DISABLE_FETCH_DTE_TIME_LIMIT BIT(31)
>> +
>> ?? /*
>> ??? * Support mapping any size that fits in one page table:
>> ??? *?? 4 KiB to 4 MiB
>> @@ -930,6 +932,7 @@ static int rk_iommu_enable(struct rk_iommu *iommu)
>> ????? struct iommu_domain *domain = iommu->domain;
>> ????? struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
>> ????? int ret, i;
>> +??? u32 auto_gate;
>> ? ????? ret = clk_bulk_enable(iommu->num_clocks, iommu->clocks);
>> ????? if (ret)
>> @@ -948,6 +951,11 @@ static int rk_iommu_enable(struct rk_iommu *iommu)
>> rk_ops->mk_dtentries(rk_domain->dt_dma));
>> ????????? rk_iommu_base_command(iommu->bases[i], RK_MMU_CMD_ZAP_CACHE);
>> ????????? rk_iommu_write(iommu->bases[i], RK_MMU_INT_MASK, 
>> RK_MMU_IRQ_MASK);
>> +
>> +??????? /* Workaround for iommu blocked, BIT(31) default to 1 */
>> +??????? auto_gate = rk_iommu_read(iommu->bases[i], RK_MMU_AUTO_GATING);
>> +??????? auto_gate |= DISABLE_FETCH_DTE_TIME_LIMIT;
>> +??????? rk_iommu_write(iommu->bases[i], RK_MMU_AUTO_GATING, auto_gate);
>> ????? }
>> ? ????? ret = rk_iommu_enable_paging(iommu);
>>
>> ---
>> base-commit: 30f09200cc4aefbd8385b01e41bde2e4565a6f0e
>> change-id: 20251126-spu-iommudtefix-cd0c5244c74a
>>
>> Best regards,
>
>


From shawn.lin at rock-chips.com  Thu Nov 27 23:31:04 2025
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Fri, 28 Nov 2025 15:31:04 +0800
Subject: [PATCH v2 2/2] iommu/rockchip: Use devm_clk_bulk_get_all() to get
 multiple iface clock
In-Reply-To: <20251128071322.92-3-kernel@airkyi.com>
References: <20251128071322.92-1-kernel@airkyi.com>
 <20251128071322.92-3-kernel@airkyi.com>
Message-ID: <7797ac67-6f57-409a-83c8-0ca21a2d2475@rock-chips.com>

? 2025/11/28 ??? 15:13, Chaoyi Chen ??:
> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> 
> The iommu found on RK3576 NPU and RK3576 RKVDEC contain 4 clock.
> 
> Just use devm_clk_bulk_get_all() to get all the clocks and use them.
> 

Reviewed-by: Shawn Lin <shawn.lin at rock-chips.com>

> Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> ---
> 
> Changes in v2:
> - Change comment.
> 
>   drivers/iommu/rockchip-iommu.c | 20 ++++----------------
>   1 file changed, 4 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
> index 0861dd469bd8..76f71fb679f8 100644
> --- a/drivers/iommu/rockchip-iommu.c
> +++ b/drivers/iommu/rockchip-iommu.c
> @@ -93,11 +93,6 @@ struct rk_iommu_domain {
>   	struct iommu_domain domain;
>   };
>   
> -/* list of clocks required by IOMMU */
> -static const char * const rk_iommu_clocks[] = {
> -	"aclk", "iface",
> -};
> -
>   struct rk_iommu_ops {
>   	phys_addr_t (*pt_address)(u32 dte);
>   	u32 (*mk_dtentries)(dma_addr_t pt_dma);
> @@ -1236,25 +1231,18 @@ static int rk_iommu_probe(struct platform_device *pdev)
>   	iommu->reset_disabled = device_property_read_bool(dev,
>   					"rockchip,disable-mmu-reset");
>   
> -	iommu->num_clocks = ARRAY_SIZE(rk_iommu_clocks);
> -	iommu->clocks = devm_kcalloc(iommu->dev, iommu->num_clocks,
> -				     sizeof(*iommu->clocks), GFP_KERNEL);
> -	if (!iommu->clocks)
> -		return -ENOMEM;
> -
> -	for (i = 0; i < iommu->num_clocks; ++i)
> -		iommu->clocks[i].id = rk_iommu_clocks[i];
> -
>   	/*
>   	 * iommu clocks should be present for all new devices and devicetrees
>   	 * but there are older devicetrees without clocks out in the wild.
>   	 * So clocks as optional for the time being.
>   	 */
> -	err = devm_clk_bulk_get(iommu->dev, iommu->num_clocks, iommu->clocks);
> +	err = devm_clk_bulk_get_all(dev, &iommu->clocks);
>   	if (err == -ENOENT)
>   		iommu->num_clocks = 0;
> -	else if (err)
> +	else if (err < 0)
>   		return err;
> +	else
> +		iommu->num_clocks = err;
>   
>   	err = clk_bulk_prepare(iommu->num_clocks, iommu->clocks);
>   	if (err)



From alchark at gmail.com  Thu Nov 27 23:49:31 2025
From: alchark at gmail.com (Alexey Charkov)
Date: Fri, 28 Nov 2025 11:49:31 +0400
Subject: [PATCH] arm64: dts: rockchip: enable UFS controller on
 FriendlyElec NanoPi M5
In-Reply-To: <20251127-nanopi-m5-ufs-v1-1-0d28d157712c@gmail.com>
References: <20251127-nanopi-m5-ufs-v1-1-0d28d157712c@gmail.com>
Message-ID: <CABjd4Yx0wJG-RjbGo1EZXK=bDp0sBJvcwA8tJ5jNOZRmGq3r3g@mail.gmail.com>

On Thu, Nov 27, 2025 at 3:46?PM Alexey Charkov <alchark at gmail.com> wrote:
>
> The NanoPi M5 board supports pluggable UFS modules using the UFSHC
> inside its Rockchip RK3576 SoC.
>
> Enable the respective devicetree node.
>
> Board specific supply regulators are not added, because they are all
> non-gateable descendants of other regulators marked always-on.

On a second thought, I'll add those regulators in v2, and also include
a link to the relevant schematic [1]. Explicitly listing the
regulators has a slight benefit of fewer complaints from the driver at
boot time, and maybe at some point we'll want to try and remove some
of the "always-on" markings (which would require a reasonably complete
description of the power graph inside the device tree). They are also
actual devices on board and not pure aliases of other existing power
lines, which IMO qualifies them for inclusion in the DT.

FTR:
VCC_UFS is directly fed by VCC_3V3_S3, no fancy circuitry in between
VCC1V2_UFS_VCCQ is fed by VCC5V0_SYS_S5 via a DCDC buck converter,
whose EN pin is driven by VCC_3V3_S3
VCC1V8_UFS_VCCQ2 is fed by VCC_1V8_S3 via a MOSFET gated by voltage on
VDDA_1V2_S0
UFS host controller itself is part of the VCCIO7 domain, whose logic
is driven by VDD_0V75_S3 and whose VCC is fed by VDDA_1V2_S0

Will wait for 24h to elapse since v1 submission and send a v2 later today.

Best regards,
Alexey

[1] https://wiki.friendlyelec.com/wiki/images/9/97/NanoPi_M5_LP5_2411_SCH.pdf


From robh at kernel.org  Fri Nov 28 00:18:07 2025
From: robh at kernel.org (Rob Herring (Arm))
Date: Fri, 28 Nov 2025 02:18:07 -0600
Subject: [PATCH v2 1/2] dt-bindings: iommu: rockchip: Add support for
 multiple interface clocks
In-Reply-To: <20251128071322.92-2-kernel@airkyi.com>
References: <20251128071322.92-1-kernel@airkyi.com>
 <20251128071322.92-2-kernel@airkyi.com>
Message-ID: <176431788757.1500601.18210148365739838676.robh@kernel.org>


On Fri, 28 Nov 2025 15:13:21 +0800, Chaoyi Chen wrote:
> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> 
> The iommu found on RK3576 NPU and RK3576 RKVDEC have 4 clock instead of
> 2 clock. Their clock names might differ, but I don't think that matters
> much.
> 
> Add support for them.
> 
> Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> ---
> 
> Changes in v2:
> - Rewrite dt binding.
> 
>  .../bindings/iommu/rockchip,iommu.yaml        | 52 ++++++++++++++++---
>  1 file changed, 46 insertions(+), 6 deletions(-)
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/thermal/thermal-sensor.example.dtb: /example-0/soc/thermal-sensor at c263000: failed to match any schema with compatible: ['qcom,sdm845-tsens', 'qcom,tsens-v2']
Documentation/devicetree/bindings/thermal/thermal-sensor.example.dtb: /example-0/soc/thermal-sensor at c263000: failed to match any schema with compatible: ['qcom,sdm845-tsens', 'qcom,tsens-v2']
Documentation/devicetree/bindings/thermal/thermal-sensor.example.dtb: /example-0/soc/thermal-sensor at c265000: failed to match any schema with compatible: ['qcom,sdm845-tsens', 'qcom,tsens-v2']
Documentation/devicetree/bindings/thermal/thermal-sensor.example.dtb: /example-0/soc/thermal-sensor at c265000: failed to match any schema with compatible: ['qcom,sdm845-tsens', 'qcom,tsens-v2']

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20251128071322.92-2-kernel at airkyi.com

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.



From chaoyi.chen at rock-chips.com  Fri Nov 28 00:46:46 2025
From: chaoyi.chen at rock-chips.com (Chaoyi Chen)
Date: Fri, 28 Nov 2025 16:46:46 +0800
Subject: [PATCH v3 4/4] drm/rockchip: vop2: Support setting custom
 background color
In-Reply-To: <20251118-rk3588-bgcolor-v3-4-a2cc909428ea@collabora.com>
References: <20251118-rk3588-bgcolor-v3-0-a2cc909428ea@collabora.com>
 <20251118-rk3588-bgcolor-v3-4-a2cc909428ea@collabora.com>
Message-ID: <0ed71b8d-5a2e-4213-bd2f-7ba317d1e4cb@rock-chips.com>

Hello Cristian,

On 11/18/2025 7:52 AM, Cristian Ciocaltea wrote:
> The Rockchip VOP2 display controller allows configuring the background
> color of each video output port.
> 
> Since a previous patch introduced the BACKGROUND_COLOR CRTC property,
> which defaults to solid black, make use of it when programming the
> hardware.
> 
> Note the maximum precision allowed by the display controller is 10bpc,
> while the alpha component is not supported, hence ignored.
> 
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
> ---
>  drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 13 ++++++++++++-
>  drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  4 ++++
>  2 files changed, 16 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> index 498df0ce4680..87110beba366 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
> @@ -1554,6 +1554,7 @@ static void vop2_post_config(struct drm_crtc *crtc)
>  	struct vop2_video_port *vp = to_vop2_video_port(crtc);
>  	struct vop2 *vop2 = vp->vop2;
>  	struct drm_display_mode *mode = &crtc->state->adjusted_mode;
> +	u64 bgcolor = crtc->state->background_color;
>  	u16 vtotal = mode->crtc_vtotal;
>  	u16 hdisplay = mode->crtc_hdisplay;
>  	u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
> @@ -1599,7 +1600,11 @@ static void vop2_post_config(struct drm_crtc *crtc)
>  		vop2_vp_write(vp, RK3568_VP_POST_DSP_VACT_INFO_F1, val);
>  	}
>  
> -	vop2_vp_write(vp, RK3568_VP_DSP_BG, 0);
> +	/* Background color is programmed with 10 bits of precision */
> +	val = FIELD_PREP(RK3568_VP_DSP_BG__DSP_BG_RED, DRM_ARGB64_GETR_BPC(bgcolor, 10));
> +	val |= FIELD_PREP(RK3568_VP_DSP_BG__DSP_BG_GREEN, DRM_ARGB64_GETG_BPC(bgcolor, 10));
> +	val |= FIELD_PREP(RK3568_VP_DSP_BG__DSP_BG_BLUE, DRM_ARGB64_GETB_BPC(bgcolor, 10));

Division is expensive. If we convert a 16 bpc value to 10 bpc using
direct bit-shifts, that is "DRM_ARGB64_GETX(bgcolor) >> 6" will
keep the relative error within 1 compared to DIV_ROUND_CLOSEST().

Should we be concerned about the precision problem here?

> +	vop2_vp_write(vp, RK3568_VP_DSP_BG, val);
>  }
>  
>  static int us_to_vertical_line(struct drm_display_mode *mode, int us)
> @@ -1984,6 +1989,10 @@ static int vop2_crtc_state_dump(struct drm_crtc *crtc, struct seq_file *s)
>  		   drm_get_bus_format_name(vcstate->bus_format));
>  	seq_printf(s, "\toutput_mode[%x]", vcstate->output_mode);
>  	seq_printf(s, " color_space[%d]\n", vcstate->color_space);
> +	seq_printf(s, "\tbackground color (10bpc): r=0x%x g=0x%x b=0x%x\n",
> +		   DRM_ARGB64_GETR_BPC(cstate->background_color, 10),
> +		   DRM_ARGB64_GETG_BPC(cstate->background_color, 10),
> +		   DRM_ARGB64_GETB_BPC(cstate->background_color, 10));
>  	seq_printf(s, "    Display mode: %dx%d%s%d\n",
>  		   mode->hdisplay, mode->vdisplay, interlaced ? "i" : "p",
>  		   drm_mode_vrefresh(mode));
> @@ -2473,6 +2482,8 @@ static int vop2_create_crtcs(struct vop2 *vop2)
>  			return dev_err_probe(drm->dev, ret,
>  					     "crtc init for video_port%d failed\n", i);
>  
> +		drm_crtc_attach_background_color_property(&vp->crtc);
> +
>  		drm_crtc_helper_add(&vp->crtc, &vop2_crtc_helper_funcs);
>  		if (vop2->lut_regs) {
>  			const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
> index 9124191899ba..37722652844a 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
> @@ -658,6 +658,10 @@ enum dst_factor_mode {
>  #define RK3588_VP_CLK_CTRL__DCLK_OUT_DIV		GENMASK(3, 2)
>  #define RK3588_VP_CLK_CTRL__DCLK_CORE_DIV		GENMASK(1, 0)
>  
> +#define RK3568_VP_DSP_BG__DSP_BG_RED			GENMASK(29, 20)
> +#define RK3568_VP_DSP_BG__DSP_BG_GREEN			GENMASK(19, 10)
> +#define RK3568_VP_DSP_BG__DSP_BG_BLUE			GENMASK(9, 0)
> +
>  #define RK3568_VP_POST_SCL_CTRL__VSCALEDOWN		BIT(1)
>  #define RK3568_VP_POST_SCL_CTRL__HSCALEDOWN		BIT(0)
>  

-- 
Best, 
Chaoyi


From cristian.ciocaltea at collabora.com  Fri Nov 28 01:44:55 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Fri, 28 Nov 2025 11:44:55 +0200
Subject: [PATCH v3 4/4] drm/rockchip: vop2: Support setting custom
 background color
In-Reply-To: <0ed71b8d-5a2e-4213-bd2f-7ba317d1e4cb@rock-chips.com>
References: <20251118-rk3588-bgcolor-v3-0-a2cc909428ea@collabora.com>
 <20251118-rk3588-bgcolor-v3-4-a2cc909428ea@collabora.com>
 <0ed71b8d-5a2e-4213-bd2f-7ba317d1e4cb@rock-chips.com>
Message-ID: <4a6443b8-d440-4921-8a43-7c20e4e265e7@collabora.com>

Hi Chaoyi,

On 11/28/25 10:46 AM, Chaoyi Chen wrote:
> Hello Cristian,
> 
> On 11/18/2025 7:52 AM, Cristian Ciocaltea wrote:
>> The Rockchip VOP2 display controller allows configuring the background
>> color of each video output port.
>>
>> Since a previous patch introduced the BACKGROUND_COLOR CRTC property,
>> which defaults to solid black, make use of it when programming the
>> hardware.
>>
>> Note the maximum precision allowed by the display controller is 10bpc,
>> while the alpha component is not supported, hence ignored.
>>
>> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea at collabora.com>
>> ---
>>  drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 13 ++++++++++++-
>>  drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |  4 ++++
>>  2 files changed, 16 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>> index 498df0ce4680..87110beba366 100644
>> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>> @@ -1554,6 +1554,7 @@ static void vop2_post_config(struct drm_crtc *crtc)
>>  	struct vop2_video_port *vp = to_vop2_video_port(crtc);
>>  	struct vop2 *vop2 = vp->vop2;
>>  	struct drm_display_mode *mode = &crtc->state->adjusted_mode;
>> +	u64 bgcolor = crtc->state->background_color;
>>  	u16 vtotal = mode->crtc_vtotal;
>>  	u16 hdisplay = mode->crtc_hdisplay;
>>  	u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
>> @@ -1599,7 +1600,11 @@ static void vop2_post_config(struct drm_crtc *crtc)
>>  		vop2_vp_write(vp, RK3568_VP_POST_DSP_VACT_INFO_F1, val);
>>  	}
>>  
>> -	vop2_vp_write(vp, RK3568_VP_DSP_BG, 0);
>> +	/* Background color is programmed with 10 bits of precision */
>> +	val = FIELD_PREP(RK3568_VP_DSP_BG__DSP_BG_RED, DRM_ARGB64_GETR_BPC(bgcolor, 10));
>> +	val |= FIELD_PREP(RK3568_VP_DSP_BG__DSP_BG_GREEN, DRM_ARGB64_GETG_BPC(bgcolor, 10));
>> +	val |= FIELD_PREP(RK3568_VP_DSP_BG__DSP_BG_BLUE, DRM_ARGB64_GETB_BPC(bgcolor, 10));
> 
> Division is expensive. If we convert a 16 bpc value to 10 bpc using
> direct bit-shifts, that is "DRM_ARGB64_GETX(bgcolor) >> 6" will
> keep the relative error within 1 compared to DIV_ROUND_CLOSEST().
> 
> Should we be concerned about the precision problem here?

The precision was something I initially looked into for CRC verification, in the
context of the related IGT test.  But since I've added the VKMS support, I think
we should not worry about that anymore. 

Moreover, as already pointed out in [1], only RK3576 supports CRC generation at
display controller level, and that is not particularly useful because it doesn't
take the background color into account.  Therefore I had to capture the frame
CRCs at DisplayPort AUX channel level, by using the USB-C DP AltMode capable
port of my RK3588-based board.  However, that solution is not yet available
upstream, as it requires further work for cleanup and improving the overall
USB-C reliability. 

Hence I'll move on with your suggestion and switch to the simple bit-shifting
approach for the next revision.

Thanks,
Cristian

[1] https://lore.kernel.org/all/20251118-crtc-bgcolor-v2-1-dce4063f85a9 at collabora.com/


From quentin.schulz at cherry.de  Fri Nov 28 02:24:49 2025
From: quentin.schulz at cherry.de (Quentin Schulz)
Date: Fri, 28 Nov 2025 11:24:49 +0100
Subject: [PATCH] arm64: dts: rockchip: Fix audio-supply for ROCK Pi 4
In-Reply-To: <acfc2185-0cb9-4620-abdb-ee25028e8374@cherry.de>
References: <20251027005220.22298-1-naoki@radxa.com>
 <acfc2185-0cb9-4620-abdb-ee25028e8374@cherry.de>
Message-ID: <a93ace02-a952-4727-957b-0ed790b47676@cherry.de>

Hi Naoki,

On 11/27/25 4:20 PM, Quentin Schulz wrote:
> Hi Naoki,
> 
> On 10/27/25 1:52 AM, FUKAUMI Naoki wrote:
>> This reverts commit 8240e87f16d17 ("arm64: dts: rockchip: fix
>> audio-supply for Rock Pi 4").
>>
>> Fix the APIO5_VDD power supply to vcc_3v0 as per the schematics[1][2]
>> [3][4][5].
>>
>> This fixes the SPI-NOR flash probe failure when the blue LED is on[6],
>> and the garbled serial console output on Linux.
>>
>> The ES8316 headphone and microphone are confirmed to work correctly
>> after this fix.
>>

Please test the ES8316 works when booting Linux from a U-Boot where 
ROCKCHIP_IODOMAIN and SPL_ROCKCHIP_IODOMAIN is *disabled*.

Having the IO domain properly configured from U-Boot may make you think 
that the ES8316 always work in the Linux kernel but that may not be the 
case depending on probe order e.g. between the IO domain driver in Linux 
and the ES8316 (if the original issue is indeed related to IO domain).

Cheers,
Quentin


From quentin.schulz at cherry.de  Fri Nov 28 02:24:49 2025
From: quentin.schulz at cherry.de (Quentin Schulz)
Date: Fri, 28 Nov 2025 11:24:49 +0100
Subject: [PATCH] arm64: dts: rockchip: Fix audio-supply for ROCK Pi 4
In-Reply-To: <acfc2185-0cb9-4620-abdb-ee25028e8374@cherry.de>
References: <20251027005220.22298-1-naoki@radxa.com>
 <acfc2185-0cb9-4620-abdb-ee25028e8374@cherry.de>
Message-ID: <a93ace02-a952-4727-957b-0ed790b47676@cherry.de>

Hi Naoki,

On 11/27/25 4:20 PM, Quentin Schulz wrote:
> Hi Naoki,
> 
> On 10/27/25 1:52 AM, FUKAUMI Naoki wrote:
>> This reverts commit 8240e87f16d17 ("arm64: dts: rockchip: fix
>> audio-supply for Rock Pi 4").
>>
>> Fix the APIO5_VDD power supply to vcc_3v0 as per the schematics[1][2]
>> [3][4][5].
>>
>> This fixes the SPI-NOR flash probe failure when the blue LED is on[6],
>> and the garbled serial console output on Linux.
>>
>> The ES8316 headphone and microphone are confirmed to work correctly
>> after this fix.
>>

Please test the ES8316 works when booting Linux from a U-Boot where 
ROCKCHIP_IODOMAIN and SPL_ROCKCHIP_IODOMAIN is *disabled*.

Having the IO domain properly configured from U-Boot may make you think 
that the ES8316 always work in the Linux kernel but that may not be the 
case depending on probe order e.g. between the IO domain driver in Linux 
and the ES8316 (if the original issue is indeed related to IO domain).

Cheers,
Quentin


From quentin.schulz at cherry.de  Fri Nov 28 02:32:17 2025
From: quentin.schulz at cherry.de (Quentin Schulz)
Date: Fri, 28 Nov 2025 11:32:17 +0100
Subject: [PATCH 1/2] arm64: dts: rockchip: enable NPU on rk3588-tiger
In-Reply-To: <20250812085213.1071106-1-heiko@sntech.de>
References: <20250812085213.1071106-1-heiko@sntech.de>
Message-ID: <de401340-be1c-4354-b6c8-c86d6f724c73@cherry.de>

Hi Heiko,

On 8/12/25 10:52 AM, Heiko Stuebner wrote:
> From: Heiko Stuebner <heiko.stuebner at cherry.de>
> 
> Enable the NPU cores and their mmus and wire up the supply-regulator.
> The regulator itself was already defined, but it does not need to be
> always on - the npu can control it.
> 
> Signed-off-by: Heiko Stuebner <heiko.stuebner at cherry.de>

Reviewed-by: Quentin Schulz <quentin.schulz at cherry.de>
Tested-by: Quentin Schulz <quentin.schulz at cherry.de>

I still have the same remark about regulator-boot-on but this isn't a 
blocker per-se.

The Oops I alluded to in my answer to the Jaguar patch is triggered by 
making DRM_ACCEL_ROCKET driver built-in instead of as a module. I'm not 
sure how much I will debug this on my side, I'll prolly just report this 
on the ML in a few hours.

Thanks!
Quentin


From naoki at radxa.com  Fri Nov 28 04:09:55 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Fri, 28 Nov 2025 21:09:55 +0900
Subject: [PATCH] arm64: dts: rockchip: Fix audio-supply for ROCK Pi 4
In-Reply-To: <a93ace02-a952-4727-957b-0ed790b47676@cherry.de>
References: <20251027005220.22298-1-naoki@radxa.com>
 <acfc2185-0cb9-4620-abdb-ee25028e8374@cherry.de>
 <a93ace02-a952-4727-957b-0ed790b47676@cherry.de>
Message-ID: <20486653DCCA80ED+7f87a03c-519e-4d6a-a47c-7670e5ae502c@radxa.com>

Hi Quentin,

On 11/28/25 19:24, Quentin Schulz wrote:
> Hi Naoki,
> 
> On 11/27/25 4:20 PM, Quentin Schulz wrote:
>> Hi Naoki,
>>
>> On 10/27/25 1:52 AM, FUKAUMI Naoki wrote:
>>> This reverts commit 8240e87f16d17 ("arm64: dts: rockchip: fix
>>> audio-supply for Rock Pi 4").
>>>
>>> Fix the APIO5_VDD power supply to vcc_3v0 as per the schematics[1][2]
>>> [3][4][5].
>>>
>>> This fixes the SPI-NOR flash probe failure when the blue LED is on[6],
>>> and the garbled serial console output on Linux.
>>>
>>> The ES8316 headphone and microphone are confirmed to work correctly
>>> after this fix.
>>>
> 
> Please test the ES8316 works when booting Linux from a U-Boot where 
> ROCKCHIP_IODOMAIN and SPL_ROCKCHIP_IODOMAIN is *disabled*.

I tried below, and confirmed that ES8316 is still working.

diff --git a/configs/rock-pi-4-rk3399_defconfig 
b/configs/rock-pi-4-rk3399_defconfig
index 219f42bc7d4..276ca961c10 100644
--- a/configs/rock-pi-4-rk3399_defconfig
+++ b/configs/rock-pi-4-rk3399_defconfig
@@ -53,6 +53,7 @@ CONFIG_ROCKCHIP_GPIO=y
  CONFIG_SYS_I2C_ROCKCHIP=y
  CONFIG_LED=y
  CONFIG_LED_GPIO=y
+# CONFIG_ROCKCHIP_IODOMAIN is not set
  CONFIG_MMC_DW=y
  CONFIG_MMC_DW_ROCKCHIP=y
  CONFIG_MMC_SDHCI=y
diff --git a/dts/upstream/src/arm64/rockchip/rk3399-rock-pi-4.dtsi 
b/dts/upstream/src/arm64/rockchip/rk3399-rock-pi-4.dtsi
index 046dbe32901..c734f7824c0 100644
--- a/dts/upstream/src/arm64/rockchip/rk3399-rock-pi-4.dtsi
+++ b/dts/upstream/src/arm64/rockchip/rk3399-rock-pi-4.dtsi
@@ -51,7 +51,7 @@

         sound: sound {
                 compatible = "audio-graph-card";
-               label = "Analog";
+               label = "rk3588-es8316";
                 dais = <&i2s0_p0>;
         };

@@ -516,7 +516,7 @@
  };

  &io_domains {
-       audio-supply = <&vcca1v8_codec>;
+       audio-supply = <&vcc_3v0>;
         bt656-supply = <&vcc_3v0>;
         gpio1830-supply = <&vcc_3v0>;
         sdmmc-supply = <&vcc_sdio>;

Notes:
- SPL_ROCKCHIP_IODOMAIN is not set by default
- I don't understand alsa ucm2 ;) so I modified /sound/label

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> Having the IO domain properly configured from U-Boot may make you think 
> that the ES8316 always work in the Linux kernel but that may not be the 
> case depending on probe order e.g. between the IO domain driver in Linux 
> and the ES8316 (if the original issue is indeed related to IO domain).
> 
> Cheers,
> Quentin
> 



From quentin.schulz at cherry.de  Fri Nov 28 04:33:55 2025
From: quentin.schulz at cherry.de (Quentin Schulz)
Date: Fri, 28 Nov 2025 13:33:55 +0100
Subject: [PATCH] arm64: dts: rockchip: Fix audio-supply for ROCK Pi 4
In-Reply-To: <20486653DCCA80ED+7f87a03c-519e-4d6a-a47c-7670e5ae502c@radxa.com>
References: <20251027005220.22298-1-naoki@radxa.com>
 <acfc2185-0cb9-4620-abdb-ee25028e8374@cherry.de>
 <a93ace02-a952-4727-957b-0ed790b47676@cherry.de>
 <20486653DCCA80ED+7f87a03c-519e-4d6a-a47c-7670e5ae502c@radxa.com>
Message-ID: <ffe5e4d1-49d8-4075-a5c4-6f27dda7f35a@cherry.de>

Hi Naoki,

On 11/28/25 1:09 PM, FUKAUMI Naoki wrote:
> Hi Quentin,
> 
> On 11/28/25 19:24, Quentin Schulz wrote:
>> Hi Naoki,
>>
>> On 11/27/25 4:20 PM, Quentin Schulz wrote:
>>> Hi Naoki,
>>>
>>> On 10/27/25 1:52 AM, FUKAUMI Naoki wrote:
>>>> This reverts commit 8240e87f16d17 ("arm64: dts: rockchip: fix
>>>> audio-supply for Rock Pi 4").
>>>>
>>>> Fix the APIO5_VDD power supply to vcc_3v0 as per the schematics[1][2]
>>>> [3][4][5].
>>>>
>>>> This fixes the SPI-NOR flash probe failure when the blue LED is on[6],
>>>> and the garbled serial console output on Linux.
>>>>
>>>> The ES8316 headphone and microphone are confirmed to work correctly
>>>> after this fix.
>>>>
>>
>> Please test the ES8316 works when booting Linux from a U-Boot where 
>> ROCKCHIP_IODOMAIN and SPL_ROCKCHIP_IODOMAIN is *disabled*.
> 
> I tried below, and confirmed that ES8316 is still working.
> 
> diff --git a/configs/rock-pi-4-rk3399_defconfig b/configs/rock-pi-4- 
> rk3399_defconfig
> index 219f42bc7d4..276ca961c10 100644
> --- a/configs/rock-pi-4-rk3399_defconfig
> +++ b/configs/rock-pi-4-rk3399_defconfig
> @@ -53,6 +53,7 @@ CONFIG_ROCKCHIP_GPIO=y
>  ?CONFIG_SYS_I2C_ROCKCHIP=y
>  ?CONFIG_LED=y
>  ?CONFIG_LED_GPIO=y
> +# CONFIG_ROCKCHIP_IODOMAIN is not set
>  ?CONFIG_MMC_DW=y
>  ?CONFIG_MMC_DW_ROCKCHIP=y
>  ?CONFIG_MMC_SDHCI=y
> diff --git a/dts/upstream/src/arm64/rockchip/rk3399-rock-pi-4.dtsi b/ 
> dts/upstream/src/arm64/rockchip/rk3399-rock-pi-4.dtsi
> index 046dbe32901..c734f7824c0 100644
> --- a/dts/upstream/src/arm64/rockchip/rk3399-rock-pi-4.dtsi
> +++ b/dts/upstream/src/arm64/rockchip/rk3399-rock-pi-4.dtsi
> @@ -51,7 +51,7 @@
> 
>  ??????? sound: sound {
>  ??????????????? compatible = "audio-graph-card";
> -?????????????? label = "Analog";
> +?????????????? label = "rk3588-es8316";
>  ??????????????? dais = <&i2s0_p0>;
>  ??????? };
> 
> @@ -516,7 +516,7 @@
>  ?};
> 
>  ?&io_domains {
> -?????? audio-supply = <&vcca1v8_codec>;
> +?????? audio-supply = <&vcc_3v0>;
>  ??????? bt656-supply = <&vcc_3v0>;
>  ??????? gpio1830-supply = <&vcc_3v0>;
>  ??????? sdmmc-supply = <&vcc_sdio>;
> 
> Notes:
> - SPL_ROCKCHIP_IODOMAIN is not set by default
> - I don't understand alsa ucm2 ;) so I modified /sound/label
> 

Thanks for testing. Let's hope the original issue doesn't appear for 
*some* boots (depending on probe order or some timing for example). For 
now I guess this will do. Adding Alex in Cc maybe they are able to 
reproduce the issue they had 4 years ago with their board?

Cheers,
Quentin


From quentin.schulz at cherry.de  Fri Nov 28 10:41:34 2025
From: quentin.schulz at cherry.de (Quentin Schulz)
Date: Fri, 28 Nov 2025 19:41:34 +0100
Subject: Issues with DRM_ACCEL_ROCKET (Oops, power-domain, probe-ordering)
Message-ID: <0b20d760-ad4f-41c0-b733-39db10d6cc41@cherry.de>

Hi all,

I've finally found the time to test the RK3588 NPU (aka Rocket, 
upstream) on our products and I've been hit with Oopses when loosely 
following the instructions from https://docs.mesa3d.org/teflon.html. 
After debugging for a while this is often (not always!) reproducible 
when DRM_ACCEL_ROCKET=y (but not when built as a module!). The fact it's 
"not always" is a dead giveaway timing or probe order is involved, more 
later on that.

I don't think the Oops is important as I believe it's a symptom of other 
issues, so I won't post it.

I'll list the issue I've identified so far, some seem easier to fix than 
others (the biggest issue of course being the hardest to fix).

1. 
https://elixir.bootlin.com/linux/v6.18-rc7/source/drivers/accel/rocket/rocket_core.c#L79

The error path after a failed pm_runtime_resume_and_get() probably 
should be calling rocket_core_fini(core) and not rocket_job_fini() (the 
former calls the latter) as to unwind everything that's been done in 
rocket_core_init() before this failed.

The PM core complains about unbalanced something when the core fails to 
init and is retried later.

I suggest the following:

"""
diff --git a/drivers/accel/rocket/rocket_core.c 
b/drivers/accel/rocket/rocket_core.c
index abe7719c1db46..95a732ab418c3 100644
--- a/drivers/accel/rocket/rocket_core.c
+++ b/drivers/accel/rocket/rocket_core.c
@@ -76,7 +76,7 @@ int rocket_core_init(struct rocket_core *core)

  	err = pm_runtime_resume_and_get(dev);
  	if (err) {
-		rocket_job_fini(core);
+		rocket_core_fini(core);
  		return err;
  	}

"""

I can send a patch for that.

2. rocket_probe() 
(https://elixir.bootlin.com/linux/v6.18-rc7/source/drivers/accel/rocket/rocket_drv.c#L159) 
can result in out-of-bounds access when rocket_core_init() fails as rdev 
is a global variable (so rdev->num_cores persists between tries). 
Considering rdev->cores is allocated based on the number of available 
nodes in the DTB with the rknn compatible, if rocket_probe() is called 
more than the number of available nodes, rdev->cores[core] will result 
in out-of-bounds access.

I believe we could do:

"""
diff --git a/drivers/accel/rocket/rocket_drv.c 
b/drivers/accel/rocket/rocket_drv.c
index 5c0b63f0a8f00..ad602ebd17c44 100644
--- a/drivers/accel/rocket/rocket_drv.c
+++ b/drivers/accel/rocket/rocket_drv.c
@@ -158,6 +158,8 @@ static const struct drm_driver rocket_drm_driver = {

  static int rocket_probe(struct platform_device *pdev)
  {
+	int ret;
+
  	if (rdev == NULL) {
  		/* First core probing, initialize DRM device. */
  		rdev = rocket_device_init(drm_dev, &rocket_drm_driver);
@@ -177,7 +179,15 @@ static int rocket_probe(struct platform_device *pdev)

  	rdev->num_cores++;

-	return rocket_core_init(&rdev->cores[core]);
+	ret = rocket_core_init(&rdev->cores[core]);
+	if (ret) {
+		rdev->num_cores--;
+		if (rdev->num_cores == 0) {
+			rocket_device_fini(rdev);
+		}
+	}
+
+	return ret;
  }

  static void rocket_remove(struct platform_device *pdev)

"""

I can send a patch for that.

3. I believe (but I may be wrong) that core 0 is special (do we need to 
schedule through core 0 maybe?). There's a hardcoded fetch of the device 
associated with core 0 via 
rocket_iommu_domain_create(rdev->cores[0].dev); 
(https://elixir.bootlin.com/linux/v6.18-rc7/source/drivers/accel/rocket/rocket_drv.c#L88). 
The issue is that this assumes that core 0 is always rdev->cores[0], 
which may not be true as it depends on the probe order (which is not 
guaranteed), which can be exacerbated by core 0 (HW index) probe being 
deferred for some reason. Is it necessary for core 0 to be the one 
initializing the DRM device or could we simply use any core for that 
(just the first to probe, whichever it actually is HW-wise)?

If there's a need to know which of the three cores is core 0, we can 
have a vendor property for it or maybe aliases for the cores? We can 
also do a check on the base register address of the core in DT and then 
do a mapping in the driver. Any other suggestion?

4. The actual issue I'm unable to suggest something for comes now. The 
following is all happening in the context of DRM_ACCEL_ROCKET being 
built-in (that is DRM_ACCEL_ROCKET=y). You can use aarch64's default 
defconfig, then DRM=y, DRM_ACCEL=y and DRM_ACCEL_ROCKET=y via 
menuconfig. Remember that this is not 100% reproducible (more often 
happening than not).

Points 1, 2 and 3 only are an issue if you hit some error-path during 
the probe of one of the cores, which is triggered by this point 4 here.

rknn_core_0 depends on rknn_mmu_0 as highlighted by the iommus phandle 
property. rknn_mmu_0 depends on RK3588_PD_NPUTOP power-domain. The 
parent domain (RK3588_PD_NPU) of RK3588_PD_NPUTOP power-domain has a 
domain-supply on a regulator on i2c (i2c0 at 42 for Jaguar, patches on the 
ML at 
https://lore.kernel.org/linux-rockchip/20250812085213.1071106-2-heiko at sntech.de/). 
When the rocket driver calls platform_driver_register() in its 
module_init() function, the kernel core will try to probe the associated 
device, via driver_probe_device(), then __driver_probe_device() and more 
specifically pm_runtime_get_suppliers(dev) in there 
(https://elixir.bootlin.com/linux/v6.18-rc7/source/drivers/base/dd.c#L793). 
Then this calls pm_runtime_get_sync() on all links, c.f. 
https://elixir.bootlin.com/linux/v6.18-rc7/source/drivers/base/power/runtime.c#L1914. 
Note that pm_runtime_get_suppliers() returns void. One of the links is 
the rknn_mmu_0.

Follow the next series of function calls, pm_runtime_get_sync() on 
rknn_mmu_0, rpm_resume(), rpm_callback(), __rpm_callback(). This then 
calls cb(). cb() is set via RPM_GET_CALLBACK(dev, runtime_resume). Due 
to rknn_mmu_0 device being probed with dev_pm_domain_attach() attaching 
the power-domain device to iommu via the pm_domain member, 
genpd_runtime_resume() (which goes to rockchip_pd_power_on()) is 
actually called. This then calls rockchip_pd_regulator_enable() which 
returns -EPROBE_DEFER. Going up in the call stack up to rpm_callback() 
you can see that retval = __rpm_callback(cb, dev); now is EPROBE_DEFER 
and thus, dev->power.runtime_error = EPROBE_DEFER at the end of the 
function.

Then once pm_runtime_resume_and_get(dev); is called in 
rocket_core_init() during probe of the rocket device, it'll call into 
rpm_get_suppliers() in __rpm_callback() which in turn will call 
pm_runtime_get_sync() on rknn_mmu_0 which will go up to rpm_resume() 
where dev->power.runtime_error will be checked and if non-zero will 
return -EINVAL, effectively eating -EPROBE_DEFER and failing the probe 
of the rocket device instead of deferring the probe.

Applying the below patch:

"""
diff --git a/drivers/accel/rocket/rocket_core.c 
b/drivers/accel/rocket/rocket_core.c
index abe7719c1db46..c4692189bbfc6 100644
--- a/drivers/accel/rocket/rocket_core.c
+++ b/drivers/accel/rocket/rocket_core.c
@@ -72,22 +72,9 @@ int rocket_core_init(struct rocket_core *core)
  	 */
  	pm_runtime_set_autosuspend_delay(dev, 50);

+	pm_runtime_set_suspended(dev);
  	pm_runtime_enable(dev);

-	err = pm_runtime_resume_and_get(dev);
-	if (err) {
-		rocket_job_fini(core);
-		return err;
-	}
-
-	version = rocket_pc_readl(core, VERSION);
-	version += rocket_pc_readl(core, VERSION_NUM) & 0xffff;
-
-	pm_runtime_mark_last_busy(dev);
-	pm_runtime_put_autosuspend(dev);
-
-	dev_info(dev, "Rockchip NPU core %d version: %d\n", core->index, version);
-
  	return 0;
  }

"""

seems to make it possible to run mesa's example. If 
pm_runtime_set_suspended(dev); isn't added, we'll only ever get job 
timeouts.

Note that I'm pretty sure this isn't the proper way to do it but wanted 
to give some of my debugging attempts at that.

I'm not sure how much further I can go and specifically I have no clue 
how to handle that properly. Please also verify all the claims I'm 
making, I'm not entirely sure I got every call stack right, it is quite 
convoluted and I don't have experience with those frameworks.

Does anyone have a clue how we can deal with that?

The driver built as a module doesn't have this issue because the 
regulator has enough time to probe so that PD doesn't return 
EPROBE_DEFER when the rocket device gets probed once reaching userspace 
(where the module is). I'm not entirely sure if this could be reproduced 
by having the regulator driver as a module too for example?

Cheers,
Quentin


From nicolas.frattaroli at collabora.com  Fri Nov 28 13:05:37 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Fri, 28 Nov 2025 22:05:37 +0100
Subject: [PATCH v5 01/17] drm/amd/display: Remove unnecessary
 SIGNAL_TYPE_HDMI_TYPE_A check
In-Reply-To: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
References: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
Message-ID: <20251128-color-format-v5-1-63e82f1db1e1@collabora.com>

From: Werner Sembach <wse at tuxedocomputers.com>

Remove unnecessary SIGNAL_TYPE_HDMI_TYPE_A check that was performed in the
drm_mode_is_420_only() case, but not in the drm_mode_is_420_also() &&
force_yuv420_output case.

Without further knowledge if YCbCr 4:2:0 is supported outside of HDMI,
there is no reason to use RGB when the display
reports drm_mode_is_420_only() even on a non HDMI connection.

This patch also moves both checks in the same if-case. This  eliminates an
extra else-if-case.

Signed-off-by: Werner Sembach <wse at tuxedocomputers.com>
Signed-off-by: Andri Yngvason <andri at yngvason.is>
Tested-by: Andri Yngvason <andri at yngvason.is>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index f02bcd108685..0b44bfe9e7e5 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -6668,12 +6668,8 @@ static void fill_stream_properties_from_drm_display_mode(
 	timing_out->v_border_top = 0;
 	timing_out->v_border_bottom = 0;
 	/* TODO: un-hardcode */
-	if (drm_mode_is_420_only(info, mode_in)
-			&& stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
-		timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
-	else if (drm_mode_is_420_also(info, mode_in)
-			&& aconnector
-			&& aconnector->force_yuv420_output)
+	if (drm_mode_is_420_only(info, mode_in) || (drm_mode_is_420_also(info, mode_in) &&
+	    aconnector && aconnector->force_yuv420_output))
 		timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
 	else if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCBCR422)
 			&& aconnector

-- 
2.52.0



From nicolas.frattaroli at collabora.com  Fri Nov 28 13:05:36 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Fri, 28 Nov 2025 22:05:36 +0100
Subject: [PATCH v5 00/17] Add new general DRM property "color format"
Message-ID: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>

Hello,

this is a follow-up to
https://lore.kernel.org/all/20250911130739.4936-1-marius.vlad at collabora.com/
which in of itself is a follow-up to
https://lore.kernel.org/dri-devel/20240115160554.720247-1-andri at yngvason.is/ where
a new DRM connector property has been added allowing users to
force a particular color format.

That in turn was actually also a follow-up from Werner Sembach's posted at
https://lore.kernel.org/dri-devel/20210630151018.330354-1-wse at tuxedocomputers.com/

As the number of cooks have reached critical mass, I'm hoping I'll be
the last person to touch this particular series.

We have an implementation in Weston at
https://gitlab.freedesktop.org/wayland/weston/-/merge_requests/1825 that
adds support for this property. This patch series has been tested
against that MR on i915 (HDMI, DP), amdgpu (HDMI, DP) and on rockchip
(HDMI).

You can also manually test this with modetest like so, but beware that
this is a non-atomic invocation, so testing YUV420 like this will result
in weird outcomes if only some of the modes support YUV420:

  $ modetest -s 115:1920x1080-60 at NV12 -w 115:'color format':4

where 115 is the connector ID and '4' is the enum value for a particular
color format.

General notes on the approach taken by me: instead of silently switching
to a different format than was explicitly requested, or even worse,
outputting something to the sink the sink doesn't support, bubble up an
error to userspace instead. "color format" is a "I want this" type
property, not a "force this" type property, i.e. the kernel will respect
the limits imposed by the hardware.

I'm not sure if my drm_bridge change actually achieves what I want in a
more complex bridge setup. I'd need to either come up with a virtual
bridge to test these scenarios, or spend some time making a flat flex
cable adapter for the DSI-HDMI bridge board I have here. Before I invest
too much time into either of those, I'd like to get some feedback on
this approach however.

Things I've tested:
- HDMI (YCbCr 4:4:4 + YCbCr 4:2:2 (8-bit) + RGB + Auto) on RK3588
- HDMI (YCbCr 4:4:4 + YCbCr 4:2:2 (8-bit) + RGB + Auto) on RK3576
- HDMI + DP (YCbCr 4:4:4, YCbCr 4:2:0, RGB, Auto) on Intel N97 (i915)
  DP-MST is untested, but I expect it to work the same.
- HDMI (YCbCr 4:4:4, YCbCr 4:2:2, YCbCr 4:2:0, RGB, Auto) + DP (YCbCr
  4:4:4, RGB, Auto) on an AMD Radeon RX 550 (amdgpu). DP-MST is
  untested.

Changes in v5:
- Rebase onto drm-tip
- Drop DRM_MODE_COLOR_FORMAT_* as an enum
- Unify DRM_COLOR_FORMAT_NONE and DRM_COLOR_FORMAT_AUTO, with AUTO being
  0. This makes conversion and general logic much easier.
  - Note: this means the weston side of this work has a small change as
    well.
- Adjust the drm_color_format enum to not needlessly renumber the
  existing defines, as it doesn't need to correspond to how HDMI numbers
  them.
- Make the DRM-to-HDMI conversion function static inline __pure, because
  the assembly it generates is tiny, and the function is pure.
- Don't accept nothing as the list of supported color formats for
  registration of the property.
- Drop the per-connector variants of the color format registration
  function, as it's not needed.
- drm_hdmi_state_helper: Fix mode_valid rejecting 420-only modes.
- drm_hdmi_state_helper: Only fall back to YUV420 with
  DRM_COLOR_FORMAT_AUTO.
- drm_hdmi_state_helper: Remove redundant AUTO->RGB condition, as the
  conversion already does this.
- Add KUnit tests for hdmi_compute_config.
- drm/bridge: Refactor bus_format_is_color_fmt and add a few more YUV422
  formats.
- Register the color format property in drmm_connector_hdmi_init based
  on the supported HDMI formats passed to it. This means rockchip
  dw_hdmi_qp no longer needs to register it.
- amdgpu: Simplify YUV420 logic
- amdgpu: Don't try to pick YUV444 on YUV420-only modes
- i915: Try to make behaviour more or less the same as that of the drm
  hdmi state helper.
- rockchip dw_hdmi_qp: Set supported HDMI formats
- rockchip dw_hdmi_qp: Set the right VO GRF values depending on color
  format.
- rockchip dw_hdmi_qp: Act on the color format property in this driver,
  rather than in VOP2, by setting the bus_format appropriately.
- rockchip VOP2: Can the BCSH-based implementation. BCSH isn't available
  on all video ports of the hardware, and the code was extremely
  suspect. Instead, plug into the existing YUV-to-RGB/RGB-to-YUV code,
  which can be done now that the HDMI driver sets the bus format.
- A whole bunch of Rockchip VOP2 fixes.
- Link to v4: https://lore.kernel.org/r/20251117-color-format-v4-0-0ded72bd1b00 at collabora.com

Changes in v4:
- Rebase onto next-20251117
- Get rid of HDMI_COLORSPACE_AUTO
- Split hdmi_compute_config change into separate patch
- Add missing symbol export for color_format_to_hdmi_colorspace to fix
  builds in certain configurations
- Drop "drm: Pass supported color formats straight onto drm_bridge"
- Make dw-hdmi-qp set the platform data's supported color formats as
  the bridge's supported HDMI color formats
- drm_hdmi_state_helper: pass requested color format to
  hdmi_compute_format_bpc if set.
- drm_bridge: limit the bus formats to those explicitly requested with
  the color format property during the atomic bridge check call,
  specifically in drm_atomic_bridge_chain_select_bus_fmts.
- i915: Remove INTEL_OUTPUT_FORMAT_AUTO, as automatic format selection
  does not need to involve the hardware state
- i915: Deduplicate ntel_output_format_to_drm_color_format code by
  moving it as a static inline __pure function into a shared header
- i915: rework logic in HDMI, DP and DP-MST output config functions to
  remove redundant locals, simplify execution flow, and return an error
  to userspace if an explicit color_format request can't be satisfied.
- i915: assign myself as the author and make the others Co-developers,
  so that they don't get the blame for any of my bugs.
- amdgpu: refactor fill_stream_properties_from_drm_display_mode to
  improve readability and ensure that impossible color format requests
  get bubbled up to userspace as errors
- amdgpu: don't pick YUV444 over RGB.
- amdgpu: assign authorship to myself, with others as Co-developers, as
  logic was modified and the blame should fall on me
- dw_hdmi_qp-rockchip: set the supported color formats platform data
  member
- rockchip: remove drm property registration for rk3066_hdmi and
  inno_hdmi. None of the platforms that use these use vop2 as the
  video output processor.
- Link to v3: https://lore.kernel.org/all/20250911130739.4936-1-marius.vlad at collabora.com/

Changes in v3 by mvlad compared to Andri's v2 series:
- renamed the property to just 'color format'
- the property is added dynamically similar to the Colorspace property
- a key point from previous comments was that drivers should advertise
  the color formats they support and userspace would query EDID and
  perform an intersection from those color formats which users can
  further use. With this patch set each driver that adds this property
  has such list of hard-coded color formats, but fundamentally the idea
  is that driver can query the HW and do that on its own. The
  infrastructure is now in place to allow to do that
- by default the 'AUTO' color format is set. With this patch series that
  has been introduced as a fallback to RGB. Drivers could further
  customize this behavour and could perform additional checks on the sink
  to pick another suitable color format they'd like for AUTO
- drm_bridge bridge code has been improved to allow initialization with
  the same color formats list as the DRM connector property. Similarly, bpc
  pick-up now takes the color format into consideration when deciding
  which bpc to choose from
- The new DRM color format re-uses HDMI_COLORPSACE enum and provides an
  enum translations between the two to avoid touching all other drivers that
  use HDMI_COLORPSACE enum. I believe at this point that this allows the
  least amount of disruption and avoids a massive bike shedding around
  that part
- a rockchip implementation has been by my colleague Derek Foreman
- YUV444 color format has been added in i915
- address comment about "Remove unnecessary SIGNAL_TYPE_HDMI_TYPE_A
  check" where aconnector might be invalid
- Link to v2: https://lore.kernel.org/dri-devel/20240115160554.720247-1-andri at yngvason.is/

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
Andri Yngvason (1):
      drm: Add new general DRM property "color format"

Marius Vlad (1):
      drm: Add enum conversion from DRM_COLOR_FORMAT to HDMI_COLORSPACE

Nicolas Frattaroli (14):
      drm/bridge: Act on the DRM color format property
      drm/display: hdmi-state-helper: Act on color format DRM property
      drm/display: hdmi-state-helper: Try subsampling in mode_valid
      drm/i915: Implement the "color format" DRM property
      drm/amdgpu: Implement "color format" DRM property
      drm/rockchip: Add YUV422 output mode constants for VOP2
      drm/rockchip: vop2: Fix YUV444 output
      drm/rockchip: vop2: Add RK3576 to the RG swap special case
      drm/rockchip: vop2: Recognise 10/12-bit YUV422 as YUV formats
      drm/rockchip: vop2: Set correct output format for RK3576 YUV422
      drm/rockchip: dw_hdmi_qp: Implement "color format" DRM property
      drm/rockchip: dw_hdmi_qp: Set supported_formats platdata
      drm/connector: Register color format property on HDMI connectors
      drm/tests: hdmi: Add tests for the color_format property

Werner Sembach (1):
      drm/amd/display: Remove unnecessary SIGNAL_TYPE_HDMI_TYPE_A check

 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  |  87 ++++++++++--
 .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c    |  13 ++
 drivers/gpu/drm/display/drm_hdmi_state_helper.c    |  27 +++-
 drivers/gpu/drm/drm_atomic_helper.c                |   5 +
 drivers/gpu/drm/drm_atomic_uapi.c                  |  11 ++
 drivers/gpu/drm/drm_bridge.c                       |  45 ++++++
 drivers/gpu/drm/drm_connector.c                    | 156 +++++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_connector.c     |  11 ++
 drivers/gpu/drm/i915/display/intel_connector.h     |   1 +
 drivers/gpu/drm/i915/display/intel_display_types.h |  15 ++
 drivers/gpu/drm/i915/display/intel_dp.c            |  55 ++++++--
 drivers/gpu/drm/i915/display/intel_dp.h            |   4 +
 drivers/gpu/drm/i915/display/intel_dp_mst.c        |  36 ++++-
 drivers/gpu/drm/i915/display/intel_hdmi.c          |  53 +++++--
 drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c     |  65 ++++++++-
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h        |   5 +
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c       |  40 +++++-
 drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c | 109 ++++++++++++++
 include/drm/display/drm_hdmi_state_helper.h        |   4 +
 include/drm/drm_connector.h                        |  62 +++++++-
 20 files changed, 752 insertions(+), 52 deletions(-)
---
base-commit: 7fe1b006b65af67bc0ef5df53aedcd265be7fb19
change-id: 20251028-color-format-49fd202b7183

Best regards,
-- 
Nicolas Frattaroli <nicolas.frattaroli at collabora.com>



From nicolas.frattaroli at collabora.com  Fri Nov 28 13:05:38 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Fri, 28 Nov 2025 22:05:38 +0100
Subject: [PATCH v5 02/17] drm: Add new general DRM property "color format"
In-Reply-To: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
References: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
Message-ID: <20251128-color-format-v5-2-63e82f1db1e1@collabora.com>

From: Andri Yngvason <andri at yngvason.is>

Add a new general DRM property named "color format" which can be used by
userspace to request the display driver to output a particular color
format.

Possible options are:
    - auto (setup by default, driver internally picks the color format)
    - rgb
    - ycbcr444
    - ycbcr422
    - ycbcr420

Drivers should advertise from this list which formats they support.
Together with this list and EDID data from the sink we should be able
to relay a list of usable color formats to users to pick from.

Signed-off-by: Werner Sembach <wse at tuxedocomputers.com>
Signed-off-by: Andri Yngvason <andri at yngvason.is>
Signed-off-by: Marius Vlad <marius.vlad at collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/gpu/drm/drm_atomic_helper.c |   5 ++
 drivers/gpu/drm/drm_atomic_uapi.c   |  11 +++
 drivers/gpu/drm/drm_connector.c     | 143 ++++++++++++++++++++++++++++++++++++
 include/drm/drm_connector.h         |  35 +++++++--
 4 files changed, 189 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 10adac9397cf..ca2daa4c84de 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -736,6 +736,11 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
 			if (old_connector_state->max_requested_bpc !=
 			    new_connector_state->max_requested_bpc)
 				new_crtc_state->connectors_changed = true;
+
+			if (old_connector_state->color_format !=
+			    new_connector_state->color_format)
+				new_crtc_state->connectors_changed = true;
+
 		}
 
 		if (funcs->atomic_check)
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index 7320db4b8489..ecf30e23a736 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -915,6 +915,15 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
 		state->privacy_screen_sw_state = val;
 	} else if (property == connector->broadcast_rgb_property) {
 		state->hdmi.broadcast_rgb = val;
+	} else if (property == connector->color_format_property) {
+		if (val >= DRM_COLOR_FORMAT_COUNT) {
+			drm_dbg_atomic(connector->dev,
+				       "[CONNECTOR:%d:%s] unknown color format %llu\n",
+				       connector->base.id, connector->name, val);
+			return -EINVAL;
+		}
+
+		state->color_format = val ? BIT(val - 1) : DRM_COLOR_FORMAT_AUTO;
 	} else if (connector->funcs->atomic_set_property) {
 		return connector->funcs->atomic_set_property(connector,
 				state, property, val);
@@ -1000,6 +1009,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
 		*val = state->privacy_screen_sw_state;
 	} else if (property == connector->broadcast_rgb_property) {
 		*val = state->hdmi.broadcast_rgb;
+	} else if (property == connector->color_format_property) {
+		*val = ffs(state->color_format);
 	} else if (connector->funcs->atomic_get_property) {
 		return connector->funcs->atomic_get_property(connector,
 				state, property, val);
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 4d6dc9ebfdb5..13151d9bfb82 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1348,6 +1348,32 @@ static const char * const colorspace_names[] = {
 	[DRM_MODE_COLORIMETRY_BT601_YCC] = "BT601_YCC",
 };
 
+/**
+ * drm_get_color_format_name - return a string for color format
+ * @color_fmt: color format to return the name of
+ *
+ * Returns a string constant matching the format's name, or NULL if no match
+ * is found.
+ */
+const char *drm_get_color_format_name(enum drm_color_format color_fmt)
+{
+	switch (color_fmt) {
+	case DRM_COLOR_FORMAT_AUTO:
+		return "AUTO";
+	case DRM_COLOR_FORMAT_RGB444:
+		return "RGB";
+	case DRM_COLOR_FORMAT_YCBCR444:
+		return "YUV 4:4:4";
+	case DRM_COLOR_FORMAT_YCBCR422:
+		return "YUV 4:2:2";
+	case DRM_COLOR_FORMAT_YCBCR420:
+		return "YUV 4:2:0";
+	default:
+		return NULL;
+	}
+}
+EXPORT_SYMBOL(drm_get_color_format_name);
+
 /**
  * drm_get_colorspace_name - return a string for color encoding
  * @colorspace: color space to compute name of
@@ -1377,6 +1403,20 @@ static const u32 hdmi_colorspaces =
 	BIT(DRM_MODE_COLORIMETRY_DCI_P3_RGB_D65) |
 	BIT(DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER);
 
+/* already bit-shifted */
+static const u32 hdmi_colorformats =
+	DRM_COLOR_FORMAT_RGB444 |
+	DRM_COLOR_FORMAT_YCBCR444 |
+	DRM_COLOR_FORMAT_YCBCR422 |
+	DRM_COLOR_FORMAT_YCBCR420;
+
+/* already bit-shifted */
+static const u32 dp_colorformats =
+	DRM_COLOR_FORMAT_RGB444 |
+	DRM_COLOR_FORMAT_YCBCR444 |
+	DRM_COLOR_FORMAT_YCBCR422 |
+	DRM_COLOR_FORMAT_YCBCR420;
+
 /*
  * As per DP 1.4a spec, 2.2.5.7.5 VSC SDP Payload for Pixel Encoding/Colorimetry
  * Format Table 2-120
@@ -2628,6 +2668,89 @@ int drm_mode_create_hdmi_colorspace_property(struct drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_mode_create_hdmi_colorspace_property);
 
+/**
+ * drm_mode_create_color_format_property - create color format property
+ * @connector: connector to create the color format property on
+ * @supported_color_formats: bitmask of &enum drm_color_format values the
+ *                           connector supports
+ *
+ * Called by a driver to create a color format property. Must be attached to
+ * the desired connector afterwards.
+ *
+ * @supported_color_formats should only include color formats the connector
+ * type can actually support.
+ *
+ * Returns:
+ * 0 on success, negative errno on error
+ */
+int drm_mode_create_color_format_property(struct drm_connector *connector,
+					  u32 supported_color_formats)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_prop_enum_list enum_list[DRM_COLOR_FORMAT_COUNT];
+	unsigned int len = 1;
+	unsigned int i = 1;
+	u32 fmt;
+
+	if (connector->color_format_property)
+		return 0;
+
+	if (!supported_color_formats) {
+		drm_err(dev, "No supported color formats provided on [CONNECTOR:%d:%s]\n",
+			connector->base.id, connector->name);
+		return -EINVAL;
+	}
+
+	if (supported_color_formats & ~GENMASK_U32(DRM_COLOR_FORMAT_COUNT - 1, 0)) {
+		drm_err(dev, "Unknown color formats provided on [CONNECTOR:%d:%s]\n",
+			connector->base.id, connector->name);
+		return -EINVAL;
+	}
+
+	switch (connector->connector_type) {
+	case DRM_MODE_CONNECTOR_HDMIA:
+	case DRM_MODE_CONNECTOR_HDMIB:
+		if (supported_color_formats & ~hdmi_colorformats) {
+			drm_err(dev, "Color formats not allowed for HDMI on [CONNECTOR:%d:%s]\n",
+				connector->base.id, connector->name);
+			return -EINVAL;
+		}
+		break;
+	case DRM_MODE_CONNECTOR_DisplayPort:
+	case DRM_MODE_CONNECTOR_eDP:
+		if (supported_color_formats & ~dp_colorformats) {
+			drm_err(dev, "Color formats not allowed for DP on [CONNECTOR:%d:%s]\n",
+				connector->base.id, connector->name);
+			return -EINVAL;
+		}
+		break;
+	}
+
+	enum_list[0].name = drm_get_color_format_name(DRM_COLOR_FORMAT_AUTO);
+	enum_list[0].type = 0;
+
+	while (supported_color_formats) {
+		fmt = BIT(i - 1);
+		if (supported_color_formats & fmt) {
+			supported_color_formats ^= fmt;
+			enum_list[len].name = drm_get_color_format_name(fmt);
+			enum_list[len].type = i;
+			len++;
+		}
+		i++;
+	}
+
+	connector->color_format_property =
+		drm_property_create_enum(dev, DRM_MODE_PROP_ENUM, "color format",
+					enum_list, len);
+
+	if (!connector->color_format_property)
+		return -ENOMEM;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_mode_create_color_format_property);
+
 /**
  * drm_mode_create_dp_colorspace_property - create dp colorspace property
  * @connector: connector to create the Colorspace property on.
@@ -2845,6 +2968,26 @@ int drm_connector_attach_max_bpc_property(struct drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_connector_attach_max_bpc_property);
 
+/**
+ * drm_connector_attach_color_format_property - attach "force color format" property
+ * @connector: connector to attach force color format property on.
+ *
+ * This is used to add support for selecting a color format on a connector.
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_connector_attach_color_format_property(struct drm_connector *connector)
+{
+	struct drm_property *prop = connector->color_format_property;
+
+	drm_object_attach_property(&connector->base, prop, DRM_COLOR_FORMAT_AUTO);
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_connector_attach_color_format_property);
+
+
 /**
  * drm_connector_attach_hdr_output_metadata_property - attach "HDR_OUTPUT_METADA" property
  * @connector: connector to attach the property on.
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 8f34f4b8183d..38968a557b82 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -556,6 +556,16 @@ enum drm_colorspace {
 	DRM_MODE_COLORIMETRY_COUNT
 };
 
+enum drm_color_format {
+	DRM_COLOR_FORMAT_AUTO			= 0,
+	DRM_COLOR_FORMAT_RGB444			= BIT(0),
+	DRM_COLOR_FORMAT_YCBCR444		= BIT(1),
+	DRM_COLOR_FORMAT_YCBCR422		= BIT(2),
+	DRM_COLOR_FORMAT_YCBCR420		= BIT(3),
+};
+
+#define DRM_COLOR_FORMAT_COUNT 5
+
 /**
  * enum drm_bus_flags - bus_flags info for &drm_display_info
  *
@@ -699,11 +709,6 @@ struct drm_display_info {
 	 */
 	enum subpixel_order subpixel_order;
 
-#define DRM_COLOR_FORMAT_RGB444		(1<<0)
-#define DRM_COLOR_FORMAT_YCBCR444	(1<<1)
-#define DRM_COLOR_FORMAT_YCBCR422	(1<<2)
-#define DRM_COLOR_FORMAT_YCBCR420	(1<<3)
-
 	/**
 	 * @panel_orientation: Read only connector property for built-in panels,
 	 * indicating the orientation of the panel vs the device's casing.
@@ -1107,6 +1112,13 @@ struct drm_connector_state {
 	 */
 	enum drm_colorspace colorspace;
 
+	/**
+	 * @color_format: State variable for Connector property to request
+	 * color format change on Sink. This is most commonly used to switch
+	 * between RGB to YUV and vice-versa.
+	 */
+	enum drm_color_format color_format;
+
 	/**
 	 * @writeback_job: Writeback job for writeback connectors
 	 *
@@ -2060,6 +2072,12 @@ struct drm_connector {
 	 */
 	struct drm_property *colorspace_property;
 
+	/**
+	 * @color_format_property: Connector property to set the suitable
+	 * color format supported by the sink.
+	 */
+	struct drm_property *color_format_property;
+
 	/**
 	 * @path_blob_ptr:
 	 *
@@ -2461,6 +2479,9 @@ int drm_mode_create_dp_colorspace_property(struct drm_connector *connector,
 int drm_mode_create_content_type_property(struct drm_device *dev);
 int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
 
+int drm_mode_create_color_format_property(struct drm_connector *connector,
+					  u32 supported_color_formats);
+
 int drm_connector_set_path_property(struct drm_connector *connector,
 				    const char *path);
 int drm_connector_set_tile_property(struct drm_connector *connector);
@@ -2542,6 +2563,10 @@ bool drm_connector_has_possible_encoder(struct drm_connector *connector,
 					struct drm_encoder *encoder);
 const char *drm_get_colorspace_name(enum drm_colorspace colorspace);
 
+int drm_connector_attach_color_format_property(struct drm_connector *connector);
+
+const char *drm_get_color_format_name(enum drm_color_format color_fmt);
+
 /**
  * drm_for_each_connector_iter - connector_list iterator macro
  * @connector: &struct drm_connector pointer used as cursor

-- 
2.52.0



From nicolas.frattaroli at collabora.com  Fri Nov 28 13:05:39 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Fri, 28 Nov 2025 22:05:39 +0100
Subject: [PATCH v5 03/17] drm: Add enum conversion from DRM_COLOR_FORMAT to
 HDMI_COLORSPACE
In-Reply-To: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
References: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
Message-ID: <20251128-color-format-v5-3-63e82f1db1e1@collabora.com>

From: Marius Vlad <marius.vlad at collabora.com>

While the two enums have similar values, they're not identical, and
HDMI's enum is defined as per the HDMI standard.

Add a simple conversion function. Unexpected inputs aren't handled in
any clever way, DRM_COLOR_FORMAT_AUTO and any other value that doesn't
cleanly map to HDMI just gets returned as HDMI_COLORSPACE_RGB.

Signed-off-by: Marius Vlad <marius.vlad at collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 include/drm/drm_connector.h | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 38968a557b82..cf556f0e5731 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -2567,6 +2567,33 @@ int drm_connector_attach_color_format_property(struct drm_connector *connector);
 
 const char *drm_get_color_format_name(enum drm_color_format color_fmt);
 
+/**
+ * drm_color_format_to_hdmi_colorspace - convert DRM color format to HDMI
+ * @fmt: the &enum drm_color_format to convert
+ *
+ * Convert a given &enum drm_color_format to an equivalent
+ * &enum hdmi_colorspace. For non-representable values and
+ * %DRM_COLOR_FORMAT_AUTO, the value %HDMI_COLORSPACE_RGB is returned.
+ *
+ * Returns: the corresponding &enum hdmi_colorspace value
+ */
+static inline enum hdmi_colorspace __pure
+drm_color_format_to_hdmi_colorspace(enum drm_color_format fmt)
+{
+	switch (fmt) {
+	default:
+	case DRM_COLOR_FORMAT_AUTO:
+	case DRM_COLOR_FORMAT_RGB444:
+		return HDMI_COLORSPACE_RGB;
+	case DRM_COLOR_FORMAT_YCBCR444:
+		return HDMI_COLORSPACE_YUV444;
+	case DRM_COLOR_FORMAT_YCBCR422:
+		return HDMI_COLORSPACE_YUV422;
+	case DRM_COLOR_FORMAT_YCBCR420:
+		return HDMI_COLORSPACE_YUV420;
+	}
+}
+
 /**
  * drm_for_each_connector_iter - connector_list iterator macro
  * @connector: &struct drm_connector pointer used as cursor

-- 
2.52.0



From nicolas.frattaroli at collabora.com  Fri Nov 28 13:05:40 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Fri, 28 Nov 2025 22:05:40 +0100
Subject: [PATCH v5 04/17] drm/bridge: Act on the DRM color format property
In-Reply-To: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
References: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
Message-ID: <20251128-color-format-v5-4-63e82f1db1e1@collabora.com>

The new DRM color format property allows userspace to request a specific
color format on a connector. In turn, this fills the connector state's
color_format member to switch color formats.

Make drm_bridges consider the color_format set in the connector state
during the atomic bridge check. Specifically, reject any output bus
formats that do not correspond to the requested color format.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/gpu/drm/drm_bridge.c | 45 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index 8f355df883d8..8aac9747f35e 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -1052,6 +1052,47 @@ static int select_bus_fmt_recursive(struct drm_bridge *first_bridge,
 	return ret;
 }
 
+static bool __pure bus_format_is_color_fmt(u32 bus_fmt, enum drm_color_format fmt)
+{
+	if (fmt == DRM_COLOR_FORMAT_AUTO)
+		return true;
+
+	switch (bus_fmt) {
+	case MEDIA_BUS_FMT_FIXED:
+		return true;
+	case MEDIA_BUS_FMT_RGB888_1X24:
+	case MEDIA_BUS_FMT_RGB101010_1X30:
+	case MEDIA_BUS_FMT_RGB121212_1X36:
+	case MEDIA_BUS_FMT_RGB161616_1X48:
+		return fmt == DRM_COLOR_FORMAT_RGB444;
+	case MEDIA_BUS_FMT_YUV8_1X24:
+	case MEDIA_BUS_FMT_YUV10_1X30:
+	case MEDIA_BUS_FMT_YUV12_1X36:
+	case MEDIA_BUS_FMT_YUV16_1X48:
+		return fmt == DRM_COLOR_FORMAT_YCBCR444;
+	case MEDIA_BUS_FMT_UYVY8_1X16:
+	case MEDIA_BUS_FMT_VYUY8_1X16:
+	case MEDIA_BUS_FMT_YUYV8_1X16:
+	case MEDIA_BUS_FMT_YVYU8_1X16:
+	case MEDIA_BUS_FMT_UYVY10_1X20:
+	case MEDIA_BUS_FMT_YUYV10_1X20:
+	case MEDIA_BUS_FMT_VYUY10_1X20:
+	case MEDIA_BUS_FMT_YVYU10_1X20:
+	case MEDIA_BUS_FMT_UYVY12_1X24:
+	case MEDIA_BUS_FMT_VYUY12_1X24:
+	case MEDIA_BUS_FMT_YUYV12_1X24:
+	case MEDIA_BUS_FMT_YVYU12_1X24:
+		return fmt == DRM_COLOR_FORMAT_YCBCR422;
+	case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
+	case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
+	case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
+	case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
+		return fmt == DRM_COLOR_FORMAT_YCBCR420;
+	default:
+		return false;
+	}
+}
+
 /*
  * This function is called by &drm_atomic_bridge_chain_check() just before
  * calling &drm_bridge_funcs.atomic_check() on all elements of the chain.
@@ -1137,6 +1178,10 @@ drm_atomic_bridge_chain_select_bus_fmts(struct drm_bridge *bridge,
 	}
 
 	for (i = 0; i < num_out_bus_fmts; i++) {
+		if (!bus_format_is_color_fmt(out_bus_fmts[i], conn_state->color_format)) {
+			ret = -ENOTSUPP;
+			continue;
+		}
 		ret = select_bus_fmt_recursive(bridge, last_bridge, crtc_state,
 					       conn_state, out_bus_fmts[i]);
 		if (ret != -ENOTSUPP)

-- 
2.52.0



From nicolas.frattaroli at collabora.com  Fri Nov 28 13:05:41 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Fri, 28 Nov 2025 22:05:41 +0100
Subject: [PATCH v5 05/17] drm/display: hdmi-state-helper: Act on color
 format DRM property
In-Reply-To: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
References: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
Message-ID: <20251128-color-format-v5-5-63e82f1db1e1@collabora.com>

With the introduction of the "color format" DRM property, which allows
userspace to request a specific color format, the HDMI state helper
should implement this.

Implement it by checking whether the property is set and set to
something other than auto. If so, pass the requested color format, and
otherwise set RGB.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/gpu/drm/display/drm_hdmi_state_helper.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
index a561f124be99..5da956bdd68c 100644
--- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c
+++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
@@ -649,11 +649,21 @@ hdmi_compute_config(const struct drm_connector *connector,
 	unsigned int max_bpc = clamp_t(unsigned int,
 				       conn_state->max_bpc,
 				       8, connector->max_bpc);
+	enum hdmi_colorspace hdmi_colorspace =
+		drm_color_format_to_hdmi_colorspace(conn_state->color_format);
 	int ret;
 
 	ret = hdmi_compute_format_bpc(connector, conn_state, mode, max_bpc,
-				      HDMI_COLORSPACE_RGB);
+				      hdmi_colorspace);
 	if (ret) {
+		/* If a color format was explicitly requested, don't fall back */
+		if (conn_state->color_format) {
+			drm_dbg_kms(connector->dev,
+				    "Explicitly set color format '%s' doesn't work.\n",
+				    drm_get_color_format_name(conn_state->color_format));
+			return ret;
+		}
+
 		if (connector->ycbcr_420_allowed) {
 			ret = hdmi_compute_format_bpc(connector, conn_state,
 						      mode, max_bpc,

-- 
2.52.0



From nicolas.frattaroli at collabora.com  Fri Nov 28 13:05:42 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Fri, 28 Nov 2025 22:05:42 +0100
Subject: [PATCH v5 06/17] drm/display: hdmi-state-helper: Try subsampling
 in mode_valid
In-Reply-To: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
References: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
Message-ID: <20251128-color-format-v5-6-63e82f1db1e1@collabora.com>

drm_hdmi_connector_mode_valid assumes modes are only valid if they work
with RGB. The reality is more complex however: YCbCr 4:2:0
chroma-subsampled modes only require half the pixel clock that the same
mode would require in RGB.

This leads to drm_hdmi_connector_mode_valid rejecting perfectly valid
420-only modes.

Fix this by checking whether the mode is 420-only first. If so, then
proceed by checking it with HDMI_COLORSPACE_YUV420 so long as the
connector has legalized 420, otherwise error out. If the mode is not
420-only, check with RGB as was previously always the case.

Fixes: 47368ab437fd ("drm/display: hdmi: add generic mode_valid helper")
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/gpu/drm/display/drm_hdmi_state_helper.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
index 5da956bdd68c..1800e00b30c5 100644
--- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c
+++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
@@ -892,8 +892,18 @@ drm_hdmi_connector_mode_valid(struct drm_connector *connector,
 			      const struct drm_display_mode *mode)
 {
 	unsigned long long clock;
+	enum hdmi_colorspace fmt;
+
+	if (drm_mode_is_420_only(&connector->display_info, mode)) {
+		if (connector->ycbcr_420_allowed)
+			fmt = HDMI_COLORSPACE_YUV420;
+		else
+			return MODE_NO_420;
+	} else {
+		fmt = HDMI_COLORSPACE_RGB;
+	}
 
-	clock = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
+	clock = drm_hdmi_compute_mode_clock(mode, 8, fmt);
 	if (!clock)
 		return MODE_ERROR;
 

-- 
2.52.0



From nicolas.frattaroli at collabora.com  Fri Nov 28 13:05:43 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Fri, 28 Nov 2025 22:05:43 +0100
Subject: [PATCH v5 07/17] drm/i915: Implement the "color format" DRM
 property
In-Reply-To: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
References: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
Message-ID: <20251128-color-format-v5-7-63e82f1db1e1@collabora.com>

This includes RGB, YUV420, YUV444 and Auto. Auto will pick RGB, unless
the mode being asked for is YUV420-only, in which case it picks YUV420.

Should the explicitly requested color format not be supported by the
sink, then an error is returned to userspace, so that it can make a
better choice.

Co-developed-by: Werner Sembach <wse at tuxedocomputers.com>
Signed-off-by: Werner Sembach <wse at tuxedocomputers.com>
Co-developed-by: Andri Yngvason <andri at yngvason.is>
Signed-off-by: Andri Yngvason <andri at yngvason.is>
Co-developed-by: Marius Vlad <marius.vlad at collabora.com>
Signed-off-by: Marius Vlad <marius.vlad at collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/gpu/drm/i915/display/intel_connector.c     | 11 +++++
 drivers/gpu/drm/i915/display/intel_connector.h     |  1 +
 drivers/gpu/drm/i915/display/intel_display_types.h | 15 ++++++
 drivers/gpu/drm/i915/display/intel_dp.c            | 55 +++++++++++++++++-----
 drivers/gpu/drm/i915/display/intel_dp.h            |  4 ++
 drivers/gpu/drm/i915/display/intel_dp_mst.c        | 36 +++++++++++++-
 drivers/gpu/drm/i915/display/intel_hdmi.c          | 53 +++++++++++++++------
 7 files changed, 147 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_connector.c b/drivers/gpu/drm/i915/display/intel_connector.c
index 913d90a7a508..5ee74280b9d3 100644
--- a/drivers/gpu/drm/i915/display/intel_connector.c
+++ b/drivers/gpu/drm/i915/display/intel_connector.c
@@ -40,6 +40,10 @@
 #include "intel_hdcp.h"
 #include "intel_panel.h"
 
+static const u32 supported_colorformats = DRM_COLOR_FORMAT_RGB444 |
+					  DRM_COLOR_FORMAT_YCBCR444 |
+					  DRM_COLOR_FORMAT_YCBCR420;
+
 static void intel_connector_modeset_retry_work_fn(struct work_struct *work)
 {
 	struct intel_connector *connector = container_of(work, typeof(*connector),
@@ -333,6 +337,13 @@ intel_attach_dp_colorspace_property(struct drm_connector *connector)
 		drm_connector_attach_colorspace_property(connector);
 }
 
+void
+intel_attach_colorformat_property(struct drm_connector *connector)
+{
+	if (!drm_mode_create_color_format_property(connector, supported_colorformats))
+		drm_connector_attach_color_format_property(connector);
+}
+
 void
 intel_attach_scaling_mode_property(struct drm_connector *connector)
 {
diff --git a/drivers/gpu/drm/i915/display/intel_connector.h b/drivers/gpu/drm/i915/display/intel_connector.h
index 0aa86626e646..fe6149d1d559 100644
--- a/drivers/gpu/drm/i915/display/intel_connector.h
+++ b/drivers/gpu/drm/i915/display/intel_connector.h
@@ -31,6 +31,7 @@ void intel_attach_broadcast_rgb_property(struct drm_connector *connector);
 void intel_attach_aspect_ratio_property(struct drm_connector *connector);
 void intel_attach_hdmi_colorspace_property(struct drm_connector *connector);
 void intel_attach_dp_colorspace_property(struct drm_connector *connector);
+void intel_attach_colorformat_property(struct drm_connector *connector);
 void intel_attach_scaling_mode_property(struct drm_connector *connector);
 void intel_connector_queue_modeset_retry_work(struct intel_connector *connector);
 void intel_connector_cancel_modeset_retry_work(struct intel_connector *connector);
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 38702a9e0f50..c82bff8a44f1 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -2206,6 +2206,21 @@ to_intel_frontbuffer(struct drm_framebuffer *fb)
 	return fb ? to_intel_framebuffer(fb)->frontbuffer : NULL;
 }
 
+static inline __pure enum drm_color_format
+intel_output_format_to_drm_color_format(enum intel_output_format input)
+{
+	switch (input) {
+	case INTEL_OUTPUT_FORMAT_RGB:
+		return DRM_COLOR_FORMAT_RGB444;
+	case INTEL_OUTPUT_FORMAT_YCBCR444:
+		return DRM_COLOR_FORMAT_YCBCR444;
+	case INTEL_OUTPUT_FORMAT_YCBCR420:
+		return DRM_COLOR_FORMAT_YCBCR420;
+	}
+
+	return DRM_COLOR_FORMAT_AUTO;
+}
+
 /*
  * Conversion functions/macros from various pointer types to struct
  * intel_display pointer.
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 0ec82fcbcf48..bd1687e3a53f 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1183,7 +1183,7 @@ dfp_can_convert(struct intel_dp *intel_dp,
 	return false;
 }
 
-static enum intel_output_format
+enum intel_output_format
 intel_dp_output_format(struct intel_connector *connector,
 		       enum intel_output_format sink_format)
 {
@@ -3141,17 +3141,24 @@ intel_dp_compute_output_format(struct intel_encoder *encoder,
 	struct intel_connector *connector = intel_dp->attached_connector;
 	const struct drm_display_info *info = &connector->base.display_info;
 	const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
-	bool ycbcr_420_only;
+	enum drm_color_format sink_format_drm;
 	int ret;
 
-	ycbcr_420_only = drm_mode_is_420_only(info, adjusted_mode);
+	if ((conn_state->color_format == DRM_COLOR_FORMAT_YCBCR420 &&
+	     drm_mode_is_420(info, adjusted_mode)) ||
+	    (conn_state->color_format == DRM_COLOR_FORMAT_AUTO &&
+	     drm_mode_is_420_only(info, adjusted_mode)))
+		crtc_state->sink_format = INTEL_OUTPUT_FORMAT_YCBCR420;
+	else if (conn_state->color_format == DRM_COLOR_FORMAT_YCBCR444)
+		crtc_state->sink_format = INTEL_OUTPUT_FORMAT_YCBCR444;
+	else
+		crtc_state->sink_format = INTEL_OUTPUT_FORMAT_RGB;
 
-	if (ycbcr_420_only && !connector->base.ycbcr_420_allowed) {
+	if (crtc_state->sink_format == INTEL_OUTPUT_FORMAT_YCBCR420 &&
+	    !connector->base.ycbcr_420_allowed) {
 		drm_dbg_kms(display->drm,
-			    "YCbCr 4:2:0 mode but YCbCr 4:2:0 output not possible. Falling back to RGB.\n");
-		crtc_state->sink_format = INTEL_OUTPUT_FORMAT_RGB;
-	} else {
-		crtc_state->sink_format = intel_dp_sink_format(connector, adjusted_mode);
+			"YCbCr 4:2:0 mode requested but unsupported by connector.\n");
+		return -EINVAL;
 	}
 
 	crtc_state->output_format = intel_dp_output_format(connector, crtc_state->sink_format);
@@ -3159,9 +3166,20 @@ intel_dp_compute_output_format(struct intel_encoder *encoder,
 	ret = intel_dp_compute_link_config(encoder, crtc_state, conn_state,
 					   respect_downstream_limits);
 	if (ret) {
-		if (crtc_state->sink_format == INTEL_OUTPUT_FORMAT_YCBCR420 ||
-		    !connector->base.ycbcr_420_allowed ||
-		    !drm_mode_is_420_also(info, adjusted_mode))
+		/*
+		 * If no valid link config can be found due to bandwidth constraints,
+		 * degrade from RGB/YCbCr 4:4:4 to YCbCr 4:2:0 if permitted by
+		 * the source and sink.
+		 */
+		if (!connector->base.ycbcr_420_allowed)
+			return ret;
+		/* No point in trying YCbCr420 a second time. */
+		if (crtc_state->sink_format == INTEL_OUTPUT_FORMAT_YCBCR420)
+			return ret;
+		if (!drm_mode_is_420(info, adjusted_mode))
+			return ret;
+		/* If a non-AUTO color format is chosen, don't fall back. */
+		if (conn_state->color_format)
 			return ret;
 
 		crtc_state->sink_format = INTEL_OUTPUT_FORMAT_YCBCR420;
@@ -3169,9 +3187,20 @@ intel_dp_compute_output_format(struct intel_encoder *encoder,
 								   crtc_state->sink_format);
 		ret = intel_dp_compute_link_config(encoder, crtc_state, conn_state,
 						   respect_downstream_limits);
+		if (ret)
+			return ret;
 	}
 
-	return ret;
+	sink_format_drm = intel_output_format_to_drm_color_format(crtc_state->sink_format);
+	if (conn_state->color_format && conn_state->color_format != sink_format_drm) {
+		drm_dbg_kms(display->drm,
+			    "Explicitly asked for color format %s, got sink format %s\n",
+			    drm_get_color_format_name(conn_state->color_format),
+			    drm_get_color_format_name(sink_format_drm));
+		return -EINVAL;
+	}
+
+	return 0;
 }
 
 void
@@ -6630,6 +6659,8 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *_connec
 		intel_attach_dp_colorspace_property(&connector->base);
 	}
 
+	intel_attach_colorformat_property(&connector->base);
+
 	if (intel_dp_has_gamut_metadata_dip(&dp_to_dig_port(intel_dp)->base))
 		drm_connector_attach_hdr_output_metadata_property(&connector->base);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index 200a8b267f64..a7492c97ac97 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -205,6 +205,10 @@ bool intel_dp_compute_config_limits(struct intel_dp *intel_dp,
 void intel_dp_get_dsc_sink_cap(u8 dpcd_rev,
 			       const struct drm_dp_desc *desc, bool is_branch,
 			       struct intel_connector *connector);
+enum intel_output_format
+intel_dp_output_format(struct intel_connector *connector,
+		       enum intel_output_format sink_format);
+
 bool intel_dp_has_gamut_metadata_dip(struct intel_encoder *encoder);
 
 bool intel_dp_link_params_valid(struct intel_dp *intel_dp, int link_rate,
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 4c0b943fe86f..e059306cea40 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -653,6 +653,8 @@ static int mst_stream_compute_config(struct intel_encoder *encoder,
 		to_intel_connector(conn_state->connector);
 	const struct drm_display_mode *adjusted_mode =
 		&pipe_config->hw.adjusted_mode;
+	const struct drm_display_info *info = &connector->base.display_info;
+	enum drm_color_format sink_format_drm;
 	struct link_config_limits limits;
 	bool dsc_needed, joiner_needs_dsc;
 	int num_joined_pipes;
@@ -671,10 +673,35 @@ static int mst_stream_compute_config(struct intel_encoder *encoder,
 	if (num_joined_pipes > 1)
 		pipe_config->joiner_pipes = GENMASK(crtc->pipe + num_joined_pipes - 1, crtc->pipe);
 
-	pipe_config->sink_format = INTEL_OUTPUT_FORMAT_RGB;
-	pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
+	if ((conn_state->color_format == DRM_COLOR_FORMAT_YCBCR420 &&
+	     drm_mode_is_420(info, adjusted_mode)) ||
+	    (conn_state->color_format == DRM_COLOR_FORMAT_AUTO &&
+	     drm_mode_is_420_only(info, adjusted_mode)))
+		pipe_config->sink_format = INTEL_OUTPUT_FORMAT_YCBCR420;
+	else if (conn_state->color_format == DRM_COLOR_FORMAT_YCBCR444)
+		pipe_config->sink_format = INTEL_OUTPUT_FORMAT_YCBCR444;
+	else
+		pipe_config->sink_format = INTEL_OUTPUT_FORMAT_RGB;
+
+	if (pipe_config->sink_format == INTEL_OUTPUT_FORMAT_YCBCR420 &&
+	    !connector->base.ycbcr_420_allowed) {
+		drm_dbg_kms(display->drm,
+			"YCbCr 4:2:0 mode requested but unsupported by connector.\n");
+		return -EINVAL;
+	}
+
+	pipe_config->output_format = intel_dp_output_format(connector, pipe_config->sink_format);
 	pipe_config->has_pch_encoder = false;
 
+	sink_format_drm = intel_output_format_to_drm_color_format(pipe_config->sink_format);
+	if (conn_state->color_format && conn_state->color_format != sink_format_drm) {
+		drm_dbg_kms(display->drm,
+			    "Unsupported color format %s (0x%x), sink has 0x%x\n",
+			    drm_get_color_format_name(conn_state->color_format),
+			    conn_state->color_format, sink_format_drm);
+		return -EINVAL;
+	}
+
 	joiner_needs_dsc = intel_dp_joiner_needs_dsc(display, num_joined_pipes);
 
 	dsc_needed = joiner_needs_dsc || intel_dp->force_dsc_en ||
@@ -1660,6 +1687,11 @@ static int mst_topology_add_connector_properties(struct intel_dp *intel_dp,
 	if (connector->base.max_bpc_property)
 		drm_connector_attach_max_bpc_property(&connector->base, 6, 12);
 
+	connector->base.color_format_property =
+		intel_dp->attached_connector->base.color_format_property;
+	if (connector->base.color_format_property)
+		intel_attach_colorformat_property(&connector->base);
+
 	return drm_connector_set_path_property(&connector->base, pathprop);
 }
 
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 908faf17f93d..d3e77781a0a6 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2271,30 +2271,53 @@ static int intel_hdmi_compute_output_format(struct intel_encoder *encoder,
 	struct intel_connector *connector = to_intel_connector(conn_state->connector);
 	const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
 	const struct drm_display_info *info = &connector->base.display_info;
-	bool ycbcr_420_only = drm_mode_is_420_only(info, adjusted_mode);
+	enum drm_color_format req_fmt = conn_state->color_format;
+	enum drm_color_format sink_format_drm;
 	int ret;
 
-	crtc_state->sink_format =
-		intel_hdmi_sink_format(crtc_state, connector, ycbcr_420_only);
-
-	if (ycbcr_420_only && crtc_state->sink_format != INTEL_OUTPUT_FORMAT_YCBCR420) {
-		drm_dbg_kms(display->drm,
-			    "YCbCr 4:2:0 mode but YCbCr 4:2:0 output not possible. Falling back to RGB.\n");
-		crtc_state->sink_format = INTEL_OUTPUT_FORMAT_RGB;
-	}
+	if (!req_fmt)
+		crtc_state->sink_format =
+			intel_hdmi_sink_format(crtc_state, connector,
+					       drm_mode_is_420_only(info, adjusted_mode));
+	else if (req_fmt == DRM_COLOR_FORMAT_YCBCR444)
+		crtc_state->sink_format = INTEL_OUTPUT_FORMAT_YCBCR444;
+	else
+		crtc_state->sink_format = intel_hdmi_sink_format(crtc_state, connector,
+			req_fmt == DRM_COLOR_FORMAT_YCBCR420);
 
 	crtc_state->output_format = intel_hdmi_output_format(crtc_state);
 	ret = intel_hdmi_compute_clock(encoder, crtc_state, respect_downstream_limits);
 	if (ret) {
-		if (crtc_state->sink_format == INTEL_OUTPUT_FORMAT_YCBCR420 ||
-		    !crtc_state->has_hdmi_sink ||
-		    !connector->base.ycbcr_420_allowed ||
-		    !drm_mode_is_420_also(info, adjusted_mode))
+		/*
+		 * If no valid link config can be found due to bandwidth constraints,
+		 * degrade from RGB/YCbCr 4:4:4 to YCbCr 4:2:0 if permitted by
+		 * the source and sink.
+		 */
+		if (!connector->base.ycbcr_420_allowed)
+			return ret;
+		/* No point in trying YCbCr420 a second time. */
+		if (crtc_state->sink_format == INTEL_OUTPUT_FORMAT_YCBCR420)
+			return ret;
+		if (!drm_mode_is_420(info, adjusted_mode))
+			return ret;
+		/* If a non-AUTO color format is chosen, don't fall back. */
+		if (req_fmt)
 			return ret;
 
 		crtc_state->sink_format = INTEL_OUTPUT_FORMAT_YCBCR420;
 		crtc_state->output_format = intel_hdmi_output_format(crtc_state);
 		ret = intel_hdmi_compute_clock(encoder, crtc_state, respect_downstream_limits);
+		if (ret)
+			return ret;
+	}
+
+	sink_format_drm = intel_output_format_to_drm_color_format(crtc_state->sink_format);
+	if (req_fmt && req_fmt != sink_format_drm) {
+		drm_dbg_kms(display->drm,
+			    "Explicitly asked for color format %s, got sink format %s\n",
+			    drm_get_color_format_name(req_fmt),
+			    drm_get_color_format_name(sink_format_drm));
+		ret = -EINVAL;
 	}
 
 	return ret;
@@ -2690,8 +2713,10 @@ intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *_
 	if (DISPLAY_VER(display) >= 10)
 		drm_connector_attach_hdr_output_metadata_property(&connector->base);
 
-	if (!HAS_GMCH(display))
+	if (!HAS_GMCH(display)) {
 		drm_connector_attach_max_bpc_property(&connector->base, 8, 12);
+		intel_attach_colorformat_property(&connector->base);
+	}
 }
 
 /*

-- 
2.52.0



From nicolas.frattaroli at collabora.com  Fri Nov 28 13:05:44 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Fri, 28 Nov 2025 22:05:44 +0100
Subject: [PATCH v5 08/17] drm/amdgpu: Implement "color format" DRM property
In-Reply-To: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
References: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
Message-ID: <20251128-color-format-v5-8-63e82f1db1e1@collabora.com>

The "color format" DRM property allows userspace to explicitly pick a
color format to use. If an unsupported color format is requested,
userspace will be given an error instead of silently having its request
disobeyed.

The default case, which is AUTO, picks YCbCr 4:2:0 if it's a 4:2:0-only
mode, and RGB in all other cases.

Co-developed-by: Werner Sembach <wse at tuxedocomputers.com>
Signed-off-by: Werner Sembach <wse at tuxedocomputers.com>
Co-developed-by: Andri Yngvason <andri at yngvason.is>
Signed-off-by: Andri Yngvason <andri at yngvason.is>
Co-developed-by: Marius Vlad <marius.vlad at collabora.com>
Signed-off-by: Marius Vlad <marius.vlad at collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  | 85 +++++++++++++++++++---
 .../amd/display/amdgpu_dm/amdgpu_dm_mst_types.c    | 13 ++++
 2 files changed, 89 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 0b44bfe9e7e5..60de0a748172 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -6650,11 +6650,14 @@ static void fill_stream_properties_from_drm_display_mode(
 	const struct dc_stream_state *old_stream,
 	int requested_bpc)
 {
+	bool is_dp_or_hdmi = dc_is_hdmi_signal(stream->signal) || dc_is_dp_signal(stream->signal);
 	struct dc_crtc_timing *timing_out = &stream->timing;
 	const struct drm_display_info *info = &connector->display_info;
 	struct amdgpu_dm_connector *aconnector = NULL;
 	struct hdmi_vendor_infoframe hv_frame;
 	struct hdmi_avi_infoframe avi_frame;
+	bool want_420;
+	bool want_422;
 	ssize_t err;
 
 	if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK)
@@ -6667,19 +6670,38 @@ static void fill_stream_properties_from_drm_display_mode(
 	timing_out->h_border_right = 0;
 	timing_out->v_border_top = 0;
 	timing_out->v_border_bottom = 0;
-	/* TODO: un-hardcode */
-	if (drm_mode_is_420_only(info, mode_in) || (drm_mode_is_420_also(info, mode_in) &&
-	    aconnector && aconnector->force_yuv420_output))
+
+	want_420 = (aconnector && aconnector->force_yuv420_output) ||
+		   (connector_state->color_format == DRM_COLOR_FORMAT_YCBCR420);
+	want_422 = (aconnector && aconnector->force_yuv422_output) ||
+		   (connector_state->color_format == DRM_COLOR_FORMAT_YCBCR422);
+
+	if (drm_mode_is_420_only(info, mode_in) && (want_420 || !connector_state->color_format))
 		timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
-	else if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCBCR422)
-			&& aconnector
-			&& aconnector->force_yuv422_output)
+	else if (drm_mode_is_420_also(info, mode_in) && want_420)
+		timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
+	else if ((info->color_formats & DRM_COLOR_FORMAT_YCBCR422) && want_422 && is_dp_or_hdmi)
 		timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR422;
-	else if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCBCR444)
-			&& stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
+	else if (connector_state->color_format == DRM_COLOR_FORMAT_YCBCR444 &&
+		 (info->color_formats & DRM_COLOR_FORMAT_YCBCR444) && is_dp_or_hdmi)
 		timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR444;
-	else
+	else if ((connector_state->color_format == DRM_COLOR_FORMAT_RGB444 ||
+		  !connector_state->color_format))
 		timing_out->pixel_encoding = PIXEL_ENCODING_RGB;
+	else {
+		/*
+		 * If a format was explicitly requested but the requested format
+		 * can't be satisfied, set it to an invalid value so that an
+		 * error bubbles up to userspace. This way, userspace knows it
+		 * needs to make a better choice.
+		 */
+		if (connector_state->color_format)
+			timing_out->pixel_encoding = PIXEL_ENCODING_UNDEFINED;
+		else if (drm_mode_is_420_only(info, mode_in))
+			timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
+		else
+			timing_out->pixel_encoding = PIXEL_ENCODING_RGB;
+	}
 
 	timing_out->timing_3d_format = TIMING_3D_FORMAT_NONE;
 	timing_out->display_color_depth = convert_color_depth_from_display_info(
@@ -8027,6 +8049,38 @@ static enum dc_status dm_validate_stream_and_context(struct dc *dc,
 	return dc_result;
 }
 
+static enum dc_status
+dm_validate_stream_color_format(const struct drm_connector_state *drm_state,
+				const struct dc_stream_state *stream)
+{
+	enum dc_pixel_encoding encoding;
+
+	if (!drm_state->color_format)
+		return DC_OK;
+
+	switch (drm_state->color_format) {
+	case DRM_COLOR_FORMAT_AUTO:
+	case DRM_COLOR_FORMAT_RGB444:
+		encoding = PIXEL_ENCODING_RGB;
+		break;
+	case DRM_COLOR_FORMAT_YCBCR444:
+		encoding = PIXEL_ENCODING_YCBCR444;
+		break;
+	case DRM_COLOR_FORMAT_YCBCR422:
+		encoding = PIXEL_ENCODING_YCBCR422;
+		break;
+	case DRM_COLOR_FORMAT_YCBCR420:
+		encoding = PIXEL_ENCODING_YCBCR420;
+		break;
+	default:
+		encoding = PIXEL_ENCODING_UNDEFINED;
+		break;
+	}
+
+	return encoding == stream->timing.pixel_encoding ?
+		DC_OK : DC_UNSUPPORTED_VALUE;
+}
+
 struct dc_stream_state *
 create_validate_stream_for_sink(struct drm_connector *connector,
 				const struct drm_display_mode *drm_mode,
@@ -8073,6 +8127,9 @@ create_validate_stream_for_sink(struct drm_connector *connector,
 		if (dc_result == DC_OK)
 			dc_result = dm_validate_stream_and_context(adev->dm.dc, stream);
 
+		if (dc_result == DC_OK)
+			dc_result = dm_validate_stream_color_format(drm_state, stream);
+
 		if (dc_result != DC_OK) {
 			DRM_DEBUG_KMS("Pruned mode %d x %d (clk %d) %s %s -- %s\n",
 				      drm_mode->hdisplay,
@@ -8888,6 +8945,12 @@ static const u32 supported_colorspaces =
 	BIT(DRM_MODE_COLORIMETRY_BT2020_RGB) |
 	BIT(DRM_MODE_COLORIMETRY_BT2020_YCC);
 
+static const u32 supported_colorformats =
+	DRM_COLOR_FORMAT_RGB444 |
+	DRM_COLOR_FORMAT_YCBCR444 |
+	DRM_COLOR_FORMAT_YCBCR422 |
+	DRM_COLOR_FORMAT_YCBCR420;
+
 void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
 				     struct amdgpu_dm_connector *aconnector,
 				     int connector_type,
@@ -9000,6 +9063,10 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
 
 		if (adev->dm.hdcp_workqueue)
 			drm_connector_attach_content_protection_property(&aconnector->base, true);
+
+		if (!drm_mode_create_color_format_property(&aconnector->base,
+							   supported_colorformats))
+			drm_connector_attach_color_format_property(&aconnector->base);
 	}
 
 	if (connector_type == DRM_MODE_CONNECTOR_eDP) {
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index dbd1da4d85d3..3ae610e11806 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -52,6 +52,12 @@
 
 #define PEAK_FACTOR_X1000 1006
 
+static const u32 supported_colorformats =
+	DRM_COLOR_FORMAT_RGB444 |
+	DRM_COLOR_FORMAT_YCBCR444 |
+	DRM_COLOR_FORMAT_YCBCR422 |
+	DRM_COLOR_FORMAT_YCBCR420;
+
 /*
  * This function handles both native AUX and I2C-Over-AUX transactions.
  */
@@ -679,6 +685,13 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
 	if (connector->max_bpc_property)
 		drm_connector_attach_max_bpc_property(connector, 8, 16);
 
+	connector->color_format_property = master->base.color_format_property;
+	if (connector->color_format_property) {
+		if (!drm_mode_create_color_format_property(&aconnector->base,
+							   supported_colorformats))
+			drm_connector_attach_color_format_property(&aconnector->base);
+	}
+
 	connector->vrr_capable_property = master->base.vrr_capable_property;
 	if (connector->vrr_capable_property)
 		drm_connector_attach_vrr_capable_property(connector);

-- 
2.52.0



From nicolas.frattaroli at collabora.com  Fri Nov 28 13:05:45 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Fri, 28 Nov 2025 22:05:45 +0100
Subject: [PATCH v5 09/17] drm/rockchip: Add YUV422 output mode constants
 for VOP2
In-Reply-To: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
References: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
Message-ID: <20251128-color-format-v5-9-63e82f1db1e1@collabora.com>

The Rockchip display controller has a general YUV422 output mode, and
some SoC-specific connector-specific output modes for RK3576.

Add them, based on the values in downstream and the TRM (dsp_out_mode in
RK3576 TRM Part 2, register POST*_CTRL_POST_DSP_CTRL).

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index 2e86ad00979c..4705dc6b8bd7 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -30,10 +30,14 @@
 #define ROCKCHIP_OUT_MODE_P565		2
 #define ROCKCHIP_OUT_MODE_BT656		5
 #define ROCKCHIP_OUT_MODE_S888		8
+#define ROCKCHIP_OUT_MODE_YUV422	9
 #define ROCKCHIP_OUT_MODE_S888_DUMMY	12
 #define ROCKCHIP_OUT_MODE_YUV420	14
 /* for use special outface */
 #define ROCKCHIP_OUT_MODE_AAAA		15
+/* SoC specific output modes */
+#define ROCKCHIP_OUT_MODE_YUV422_RK3576_DP	12
+#define ROCKCHIP_OUT_MODE_YUV422_RK3576_HDMI	13
 
 /* output flags */
 #define ROCKCHIP_OUTPUT_DSI_DUAL	BIT(0)

-- 
2.52.0



From nicolas.frattaroli at collabora.com  Fri Nov 28 13:05:46 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Fri, 28 Nov 2025 22:05:46 +0100
Subject: [PATCH v5 10/17] drm/rockchip: vop2: Fix YUV444 output
In-Reply-To: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
References: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
Message-ID: <20251128-color-format-v5-10-63e82f1db1e1@collabora.com>

YUV444 (aka YCbCr444) output isn't working quite right on RK3588. The
resulting image on the display, while identifying itself as YUV444, has
some components swapped, even after adding the necessary DRM formats to
the conversion functions.

Judging by downstream, this is because YUV444 also needs an rb swap
performed in the AFBC case.

Add the DRM formats to the appropriate switch statements, and add a
function for checking whether an rb swap needs to be performed in the
AFBC case.

Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver")
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 498df0ce4680..f1252d1f06e9 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -176,6 +176,7 @@ static enum vop2_data_format vop2_convert_format(u32 format)
 	case DRM_FORMAT_ARGB2101010:
 	case DRM_FORMAT_XBGR2101010:
 	case DRM_FORMAT_ABGR2101010:
+	case DRM_FORMAT_VUY101010:
 		return VOP2_FMT_XRGB101010;
 	case DRM_FORMAT_XRGB8888:
 	case DRM_FORMAT_ARGB8888:
@@ -184,6 +185,7 @@ static enum vop2_data_format vop2_convert_format(u32 format)
 		return VOP2_FMT_ARGB8888;
 	case DRM_FORMAT_RGB888:
 	case DRM_FORMAT_BGR888:
+	case DRM_FORMAT_VUY888:
 		return VOP2_FMT_RGB888;
 	case DRM_FORMAT_RGB565:
 	case DRM_FORMAT_BGR565:
@@ -225,6 +227,7 @@ static enum vop2_afbc_format vop2_convert_afbc_format(u32 format)
 	case DRM_FORMAT_ARGB2101010:
 	case DRM_FORMAT_XBGR2101010:
 	case DRM_FORMAT_ABGR2101010:
+	case DRM_FORMAT_VUY101010:
 		return VOP2_AFBC_FMT_ARGB2101010;
 	case DRM_FORMAT_XRGB8888:
 	case DRM_FORMAT_ARGB8888:
@@ -233,6 +236,7 @@ static enum vop2_afbc_format vop2_convert_afbc_format(u32 format)
 		return VOP2_AFBC_FMT_ARGB8888;
 	case DRM_FORMAT_RGB888:
 	case DRM_FORMAT_BGR888:
+	case DRM_FORMAT_VUY888:
 		return VOP2_AFBC_FMT_RGB888;
 	case DRM_FORMAT_RGB565:
 	case DRM_FORMAT_BGR565:
@@ -270,6 +274,19 @@ static bool vop2_win_rb_swap(u32 format)
 	}
 }
 
+static bool vop2_afbc_rb_swap(u32 format)
+{
+	switch (format) {
+	case DRM_FORMAT_NV24:
+	case DRM_FORMAT_NV30:
+	case DRM_FORMAT_VUY888:
+	case DRM_FORMAT_VUY101010:
+		return true;
+	default:
+		return false;
+	}
+}
+
 static bool vop2_afbc_uv_swap(u32 format)
 {
 	switch (format) {
@@ -1304,6 +1321,7 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 		 /* It's for head stride, each head size is 16 byte */
 		stride = ALIGN(stride, block_w) / block_w * 16;
 
+		rb_swap = vop2_afbc_rb_swap(fb->format->format);
 		uv_swap = vop2_afbc_uv_swap(fb->format->format);
 		/*
 		 * This is a workaround for crazy IC design, Cluster
@@ -1321,6 +1339,7 @@ static void vop2_plane_atomic_update(struct drm_plane *plane,
 			vop2_win_write(win, VOP2_WIN_AFBC_ENABLE, 1);
 		vop2_win_write(win, VOP2_WIN_AFBC_FORMAT, afbc_format);
 		vop2_win_write(win, VOP2_WIN_AFBC_UV_SWAP, uv_swap);
+		vop2_win_write(win, VOP2_WIN_AFBC_RB_SWAP, rb_swap);
 		/*
 		 * On rk3566/8, this bit is auto gating enable,
 		 * but this function is not work well so we need

-- 
2.52.0



From nicolas.frattaroli at collabora.com  Fri Nov 28 13:05:47 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Fri, 28 Nov 2025 22:05:47 +0100
Subject: [PATCH v5 11/17] drm/rockchip: vop2: Add RK3576 to the RG swap
 special case
In-Reply-To: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
References: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
Message-ID: <20251128-color-format-v5-11-63e82f1db1e1@collabora.com>

Much like RK3588, RK3576 requires an RG swap to be performed for YUV444
8-bit and YUV444 10-bit bus formats.

Add its version to the already existing check for RK3588, so that YUV444
output is correct on this platform.

Fixes: 944757a4cba6 ("drm/rockchip: vop2: Add support for rk3576")
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index f1252d1f06e9..0a1adf36a24f 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -354,7 +354,8 @@ static bool vop2_output_uv_swap(u32 bus_format, u32 output_mode)
 
 static bool vop2_output_rg_swap(struct vop2 *vop2, u32 bus_format)
 {
-	if (vop2->version == VOP_VERSION_RK3588) {
+	if (vop2->version == VOP_VERSION_RK3588 ||
+	    vop2->version == VOP_VERSION_RK3576) {
 		if (bus_format == MEDIA_BUS_FMT_YUV8_1X24 ||
 		    bus_format == MEDIA_BUS_FMT_YUV10_1X30)
 			return true;

-- 
2.52.0



From nicolas.frattaroli at collabora.com  Fri Nov 28 13:05:49 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Fri, 28 Nov 2025 22:05:49 +0100
Subject: [PATCH v5 13/17] drm/rockchip: vop2: Set correct output format for
 RK3576 YUV422
In-Reply-To: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
References: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
Message-ID: <20251128-color-format-v5-13-63e82f1db1e1@collabora.com>

For RK3576 to be able to output YUV422 signals, it first needs to be
able to pick the right output mode in the display controller to do so.

The RK3576 hardware specifies different output formats depending on the
used display protocol.

Adjust the written register value based on the SoC and connector, so
other users of vcstate->output_mode don't have to care about this.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 21afcca1218c..cd18876955e4 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1707,6 +1707,22 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
 	if (vcstate->output_mode == ROCKCHIP_OUT_MODE_AAAA &&
 	    !(vp_data->feature & VOP2_VP_FEATURE_OUTPUT_10BIT))
 		out_mode = ROCKCHIP_OUT_MODE_P888;
+	else if (vcstate->output_mode == ROCKCHIP_OUT_MODE_YUV422 &&
+		 vop2->version == VOP_VERSION_RK3576)
+		switch (vcstate->output_type) {
+		case DRM_MODE_CONNECTOR_DisplayPort:
+		case DRM_MODE_CONNECTOR_eDP:
+			out_mode = ROCKCHIP_OUT_MODE_YUV422_RK3576_DP;
+			break;
+		case DRM_MODE_CONNECTOR_HDMIA:
+			out_mode = ROCKCHIP_OUT_MODE_YUV422_RK3576_HDMI;
+			break;
+		default:
+			drm_err(vop2->drm, "Unknown DRM_MODE_CONNECTOR %d\n",
+				vcstate->output_type);
+			vop2_unlock(vop2);
+			return;
+		}
 	else
 		out_mode = vcstate->output_mode;
 

-- 
2.52.0



From nicolas.frattaroli at collabora.com  Fri Nov 28 13:05:48 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Fri, 28 Nov 2025 22:05:48 +0100
Subject: [PATCH v5 12/17] drm/rockchip: vop2: Recognise 10/12-bit YUV422 as
 YUV formats
In-Reply-To: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
References: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
Message-ID: <20251128-color-format-v5-12-63e82f1db1e1@collabora.com>

The Rockchip VOP2 video output driver has a "is_yuv_output" function,
which returns true when a given bus format is a YUV format, and false
otherwise.

This switch statement is lacking the bus format used for YUV422 10-bit,
as well as the bus format used for YUV422 12-bit.

Add MEDIA_BUS_FMT_YUYV10_1X20 and MEDIA_BUS_FMT_YUYV12_1X24 to
is_yuv_output's switch cases to resolve this.

Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver")
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 0a1adf36a24f..21afcca1218c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -369,6 +369,8 @@ static bool is_yuv_output(u32 bus_format)
 	switch (bus_format) {
 	case MEDIA_BUS_FMT_YUV8_1X24:
 	case MEDIA_BUS_FMT_YUV10_1X30:
+	case MEDIA_BUS_FMT_YUYV10_1X20:
+	case MEDIA_BUS_FMT_YUYV12_1X24:
 	case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
 	case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
 	case MEDIA_BUS_FMT_YUYV8_2X8:

-- 
2.52.0



From nicolas.frattaroli at collabora.com  Fri Nov 28 13:05:50 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Fri, 28 Nov 2025 22:05:50 +0100
Subject: [PATCH v5 14/17] drm/rockchip: dw_hdmi_qp: Implement "color
 format" DRM property
In-Reply-To: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
References: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
Message-ID: <20251128-color-format-v5-14-63e82f1db1e1@collabora.com>

Switch between requested color formats by setting the right bus formats,
configuring the VO GRF registers, and setting the right output mode.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 61 ++++++++++++++++++++++++--
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h    |  1 +
 2 files changed, 59 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
index c9fe6aa3e3e3..c79ebd9e866c 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
@@ -11,6 +11,7 @@
 #include <linux/gpio/consumer.h>
 #include <linux/hw_bitfield.h>
 #include <linux/mfd/syscon.h>
+#include <linux/media-bus-format.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/phy/phy.h>
@@ -135,24 +136,70 @@ dw_hdmi_qp_rockchip_encoder_atomic_check(struct drm_encoder *encoder,
 					 struct drm_crtc_state *crtc_state,
 					 struct drm_connector_state *conn_state)
 {
-	struct rockchip_hdmi_qp *hdmi = to_rockchip_hdmi_qp(encoder);
+	struct drm_display_info *info = &conn_state->connector->display_info;
 	struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
+	struct rockchip_hdmi_qp *hdmi = to_rockchip_hdmi_qp(encoder);
 	union phy_configure_opts phy_cfg = {};
 	int ret;
 
 	if (hdmi->tmds_char_rate == conn_state->hdmi.tmds_char_rate &&
-	    s->output_bpc == conn_state->hdmi.output_bpc)
+	    s->output_bpc == conn_state->hdmi.output_bpc &&
+	    s->color_format == conn_state->color_format)
 		return 0;
 
+	if (conn_state->color_format &&
+	    !(info->color_formats & conn_state->color_format))
+		return -EINVAL;
+
+	switch (conn_state->color_format) {
+	case DRM_COLOR_FORMAT_AUTO:
+	case DRM_COLOR_FORMAT_RGB444:
+		if (conn_state->hdmi.output_bpc == 8)
+			s->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
+		else if (conn_state->hdmi.output_bpc == 10)
+			s->bus_format = MEDIA_BUS_FMT_RGB101010_1X30;
+		else
+			return -EINVAL;
+		s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
+		break;
+	case DRM_COLOR_FORMAT_YCBCR444:
+		if (conn_state->hdmi.output_bpc == 8)
+			s->bus_format = MEDIA_BUS_FMT_YUV8_1X24;
+		else if (conn_state->hdmi.output_bpc == 10)
+			s->bus_format = MEDIA_BUS_FMT_YUV10_1X30;
+		else
+			return -EINVAL;
+		s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
+		break;
+	case DRM_COLOR_FORMAT_YCBCR422:
+		if (conn_state->hdmi.output_bpc == 8)
+			s->bus_format = MEDIA_BUS_FMT_YUYV8_1X16;
+		else /* 10 bpc possible, but currently busted */
+			return -EINVAL;
+		s->output_mode = ROCKCHIP_OUT_MODE_YUV422;
+		break;
+	case DRM_COLOR_FORMAT_YCBCR420:
+		if (conn_state->hdmi.output_bpc == 8)
+			s->bus_format = MEDIA_BUS_FMT_UYYVYY8_0_5X24;
+		else if (conn_state->hdmi.output_bpc == 10)
+			s->bus_format = MEDIA_BUS_FMT_UYYVYY10_0_5X30;
+		else
+			return -EINVAL;
+		s->output_mode = ROCKCHIP_OUT_MODE_YUV420;
+		break;
+	default:
+		return -EINVAL;
+	}
+
 	phy_cfg.hdmi.tmds_char_rate = conn_state->hdmi.tmds_char_rate;
 	phy_cfg.hdmi.bpc = conn_state->hdmi.output_bpc;
 
 	ret = phy_configure(hdmi->phy, &phy_cfg);
 	if (!ret) {
 		hdmi->tmds_char_rate = conn_state->hdmi.tmds_char_rate;
-		s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
 		s->output_type = DRM_MODE_CONNECTOR_HDMIA;
 		s->output_bpc = conn_state->hdmi.output_bpc;
+		s->color_format = conn_state->color_format;
 	} else {
 		dev_err(hdmi->dev, "Failed to configure phy: %d\n", ret);
 	}
@@ -391,6 +438,8 @@ static void dw_hdmi_qp_rk3588_io_init(struct rockchip_hdmi_qp *hdmi)
 static void dw_hdmi_qp_rk3576_enc_init(struct rockchip_hdmi_qp *hdmi,
 				       struct rockchip_crtc_state *state)
 {
+	enum hdmi_colorspace color =
+		drm_color_format_to_hdmi_colorspace(state->color_format);
 	u32 val;
 
 	if (state->output_bpc == 10)
@@ -398,12 +447,16 @@ static void dw_hdmi_qp_rk3576_enc_init(struct rockchip_hdmi_qp *hdmi,
 	else
 		val = FIELD_PREP_WM16(RK3576_COLOR_DEPTH_MASK, RK3576_8BPC);
 
+	val |= FIELD_PREP_WM16(RK3576_COLOR_FORMAT_MASK, color);
+
 	regmap_write(hdmi->vo_regmap, RK3576_VO0_GRF_SOC_CON8, val);
 }
 
 static void dw_hdmi_qp_rk3588_enc_init(struct rockchip_hdmi_qp *hdmi,
 				       struct rockchip_crtc_state *state)
 {
+	enum hdmi_colorspace color =
+		drm_color_format_to_hdmi_colorspace(state->color_format);
 	u32 val;
 
 	if (state->output_bpc == 10)
@@ -411,6 +464,8 @@ static void dw_hdmi_qp_rk3588_enc_init(struct rockchip_hdmi_qp *hdmi,
 	else
 		val = FIELD_PREP_WM16(RK3588_COLOR_DEPTH_MASK, RK3588_8BPC);
 
+	val |= FIELD_PREP_WM16(RK3588_COLOR_FORMAT_MASK, color);
+
 	regmap_write(hdmi->vo_regmap,
 		     hdmi->port_id ? RK3588_GRF_VO1_CON6 : RK3588_GRF_VO1_CON3,
 		     val);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index 4705dc6b8bd7..2549e58f3497 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -57,6 +57,7 @@ struct rockchip_crtc_state {
 	u32 bus_format;
 	u32 bus_flags;
 	int color_space;
+	enum drm_color_format color_format;
 };
 #define to_rockchip_crtc_state(s) \
 		container_of(s, struct rockchip_crtc_state, base)

-- 
2.52.0



From nicolas.frattaroli at collabora.com  Fri Nov 28 13:05:51 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Fri, 28 Nov 2025 22:05:51 +0100
Subject: [PATCH v5 15/17] drm/rockchip: dw_hdmi_qp: Set supported_formats
 platdata
In-Reply-To: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
References: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
Message-ID: <20251128-color-format-v5-15-63e82f1db1e1@collabora.com>

With the introduction of the supported_formats member in the
dw-hdmi-qp platform data struct, drivers that have access to this
information should now set it.

Set it in the rockchip dw_hdmi_qp glue driver.

This allows this information to be passed down to the dw-hdmi-qp core,
which sets it in the bridge it creates, and consequently will allow the
common HDMI bridge code to act on it.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
index c79ebd9e866c..5827ca2de0bd 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
@@ -576,6 +576,10 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
 	plat_data.phy_data = hdmi;
 	plat_data.max_bpc = 10;
 
+	plat_data.supported_formats = BIT(HDMI_COLORSPACE_RGB) |
+				      BIT(HDMI_COLORSPACE_YUV444) |
+				      BIT(HDMI_COLORSPACE_YUV422);
+
 	encoder = &hdmi->encoder.encoder;
 	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
 

-- 
2.52.0



From nicolas.frattaroli at collabora.com  Fri Nov 28 13:05:52 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Fri, 28 Nov 2025 22:05:52 +0100
Subject: [PATCH v5 16/17] drm/connector: Register color format property on
 HDMI connectors
In-Reply-To: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
References: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
Message-ID: <20251128-color-format-v5-16-63e82f1db1e1@collabora.com>

The drmm_connector_hdmi_init function can figure out what DRM color
formats are supported by a particular connector based on the supported
HDMI format bitmask that's passed in.

Use it to register the drm color format property.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/gpu/drm/drm_connector.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 13151d9bfb82..7c38123f99cd 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -578,6 +578,7 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
 			     unsigned long supported_formats,
 			     unsigned int max_bpc)
 {
+	u32 supported_drm_formats = 0;
 	int ret;
 
 	if (!vendor || !product)
@@ -621,6 +622,18 @@ int drmm_connector_hdmi_init(struct drm_device *dev,
 	if (max_bpc > 8)
 		drm_connector_attach_hdr_output_metadata_property(connector);
 
+	if (supported_formats & BIT(HDMI_COLORSPACE_RGB))
+		supported_drm_formats |= DRM_COLOR_FORMAT_RGB444;
+	if (supported_formats & BIT(HDMI_COLORSPACE_YUV444))
+		supported_drm_formats |= DRM_COLOR_FORMAT_YCBCR444;
+	if (supported_formats & BIT(HDMI_COLORSPACE_YUV422))
+		supported_drm_formats |= DRM_COLOR_FORMAT_YCBCR422;
+	if (supported_formats & BIT(HDMI_COLORSPACE_YUV420))
+		supported_drm_formats |= DRM_COLOR_FORMAT_YCBCR420;
+
+	if (!drm_mode_create_color_format_property(connector, supported_drm_formats))
+		drm_connector_attach_color_format_property(connector);
+
 	connector->hdmi.funcs = hdmi_funcs;
 
 	return 0;

-- 
2.52.0



From nicolas.frattaroli at collabora.com  Fri Nov 28 13:05:53 2025
From: nicolas.frattaroli at collabora.com (Nicolas Frattaroli)
Date: Fri, 28 Nov 2025 22:05:53 +0100
Subject: [PATCH v5 17/17] drm/tests: hdmi: Add tests for the color_format
 property
In-Reply-To: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
References: <20251128-color-format-v5-0-63e82f1db1e1@collabora.com>
Message-ID: <20251128-color-format-v5-17-63e82f1db1e1@collabora.com>

Add some KUnit tests to check the color_format property is working as
expected with the HDMI state helper.

The added tests check that AUTO results in RGB, and the YCBCR modes
result in the corresponding YUV modes. An additional test ensures that
only DRM_COLOR_FORMAT_AUTO falls back to YUV420 with a YUV420-only mode,
and RGB errors out instead, while explicitly asking for YUV420 still
works.

This requires exporting hdmi_compute_config, so that it is accessible
from the tests.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli at collabora.com>
---
 drivers/gpu/drm/display/drm_hdmi_state_helper.c    |   3 +-
 drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c | 109 +++++++++++++++++++++
 include/drm/display/drm_hdmi_state_helper.h        |   4 +
 3 files changed, 115 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
index 1800e00b30c5..e86fb837ceaf 100644
--- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c
+++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c
@@ -641,7 +641,7 @@ hdmi_compute_format_bpc(const struct drm_connector *connector,
 	return -EINVAL;
 }
 
-static int
+int
 hdmi_compute_config(const struct drm_connector *connector,
 		    struct drm_connector_state *conn_state,
 		    const struct drm_display_mode *mode)
@@ -680,6 +680,7 @@ hdmi_compute_config(const struct drm_connector *connector,
 
 	return ret;
 }
+EXPORT_SYMBOL(hdmi_compute_config);
 
 static int hdmi_generate_avi_infoframe(const struct drm_connector *connector,
 				       struct drm_connector_state *conn_state)
diff --git a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c
index 8bd412735000..e7050cd9cb12 100644
--- a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c
@@ -55,6 +55,23 @@ static struct drm_display_mode *find_preferred_mode(struct drm_connector *connec
 	return preferred;
 }
 
+static struct drm_display_mode *find_420_only_mode(struct drm_connector *connector)
+{
+	struct drm_device *drm = connector->dev;
+	struct drm_display_mode *mode;
+
+	mutex_lock(&drm->mode_config.mutex);
+	list_for_each_entry(mode, &connector->modes, head) {
+		if (drm_mode_is_420_only(&connector->display_info, mode)) {
+			mutex_unlock(&drm->mode_config.mutex);
+			return mode;
+		}
+	}
+	mutex_unlock(&drm->mode_config.mutex);
+
+	return NULL;
+}
+
 static int set_connector_edid(struct kunit *test, struct drm_connector *connector,
 			      const void *edid, size_t edid_len)
 {
@@ -1999,6 +2016,95 @@ static void drm_test_check_disable_connector(struct kunit *test)
 	drm_modeset_acquire_fini(&ctx);
 }
 
+struct color_format_test_param {
+	enum drm_color_format fmt;
+	enum hdmi_colorspace expected;
+	const char *desc;
+};
+
+/* Test that AUTO results in RGB, and explicit choices result in those */
+static void drm_test_check_hdmi_color_format(struct kunit *test)
+{
+	const struct color_format_test_param *param = test->param_value;
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_connector_state *conn_state;
+	struct drm_display_info *info;
+	struct drm_display_mode *preferred;
+	int ret;
+
+	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
+				BIT(HDMI_COLORSPACE_RGB) |
+				BIT(HDMI_COLORSPACE_YUV422) |
+				BIT(HDMI_COLORSPACE_YUV420) |
+				BIT(HDMI_COLORSPACE_YUV444),
+				12,
+				&dummy_connector_hdmi_funcs,
+				test_edid_hdmi_4k_rgb_yuv420_dc_max_340mhz);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn_state = priv->connector.state;
+	info = &priv->connector.display_info;
+	conn_state->color_format = param->fmt;
+	KUNIT_ASSERT_TRUE(test, priv->connector.ycbcr_420_allowed);
+
+	preferred = find_preferred_mode(&priv->connector);
+	KUNIT_ASSERT_TRUE(test, drm_mode_is_420(info, preferred));
+
+	ret = hdmi_compute_config(&priv->connector, conn_state, preferred);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, param->expected);
+}
+
+static const struct color_format_test_param hdmi_color_format_params[] = {
+	{ DRM_COLOR_FORMAT_AUTO, HDMI_COLORSPACE_RGB, "AUTO -> RGB" },
+	{ DRM_COLOR_FORMAT_YCBCR422, HDMI_COLORSPACE_YUV422, "YCBCR422 -> YUV422" },
+	{ DRM_COLOR_FORMAT_YCBCR420, HDMI_COLORSPACE_YUV420, "YCBCR420 -> YUV420" },
+	{ DRM_COLOR_FORMAT_YCBCR444, HDMI_COLORSPACE_YUV444, "YCBCR444 -> YUV444" },
+	{ DRM_COLOR_FORMAT_RGB444, HDMI_COLORSPACE_RGB, "RGB -> RGB" },
+};
+
+KUNIT_ARRAY_PARAM_DESC(check_hdmi_color_format,
+		  hdmi_color_format_params, desc);
+
+
+/* Test that AUTO falls back to YUV420, and that RGB does not, but YUV420 works */
+static void drm_test_check_hdmi_color_format_420_only(struct kunit *test)
+{
+	struct drm_atomic_helper_connector_hdmi_priv *priv;
+	struct drm_connector_state *conn_state;
+	struct drm_display_mode *dank;
+	int ret;
+
+	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
+				BIT(HDMI_COLORSPACE_RGB) |
+				BIT(HDMI_COLORSPACE_YUV422) |
+				BIT(HDMI_COLORSPACE_YUV420) |
+				BIT(HDMI_COLORSPACE_YUV444),
+				12,
+				&dummy_connector_hdmi_funcs,
+				test_edid_hdmi_1080p_rgb_yuv_4k_yuv420_dc_max_200mhz);
+	KUNIT_ASSERT_NOT_NULL(test, priv);
+
+	conn_state = priv->connector.state;
+
+	dank = find_420_only_mode(&priv->connector);
+	KUNIT_ASSERT_NOT_NULL(test, dank);
+
+	conn_state->color_format = DRM_COLOR_FORMAT_AUTO;
+	ret = hdmi_compute_config(&priv->connector, conn_state, dank);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_YUV420);
+
+	conn_state->color_format = DRM_COLOR_FORMAT_RGB444;
+	ret = hdmi_compute_config(&priv->connector, conn_state, dank);
+	KUNIT_EXPECT_LT(test, ret, 0);
+
+	conn_state->color_format = DRM_COLOR_FORMAT_YCBCR420;
+	ret = hdmi_compute_config(&priv->connector, conn_state, dank);
+	KUNIT_EXPECT_EQ(test, ret, 0);
+	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_YUV420);
+};
+
 static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = {
 	KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode),
 	KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode_vic_1),
@@ -2028,6 +2134,9 @@ static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = {
 	KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_8bpc),
 	KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_10bpc),
 	KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_12bpc),
+	KUNIT_CASE_PARAM(drm_test_check_hdmi_color_format,
+			 check_hdmi_color_format_gen_params),
+	KUNIT_CASE(drm_test_check_hdmi_color_format_420_only),
 	/*
 	 * TODO: We should have tests to check that a change in the
 	 * format triggers a CRTC mode change just like we do for the
diff --git a/include/drm/display/drm_hdmi_state_helper.h b/include/drm/display/drm_hdmi_state_helper.h
index 2349c0d0f00f..01ae31209820 100644
--- a/include/drm/display/drm_hdmi_state_helper.h
+++ b/include/drm/display/drm_hdmi_state_helper.h
@@ -30,4 +30,8 @@ enum drm_mode_status
 drm_hdmi_connector_mode_valid(struct drm_connector *connector,
 			      const struct drm_display_mode *mode);
 
+int hdmi_compute_config(const struct drm_connector *connector,
+			struct drm_connector_state *conn_state,
+			const struct drm_display_mode *mode);
+
 #endif // DRM_HDMI_STATE_HELPER_H_

-- 
2.52.0



From knaerzche at gmail.com  Fri Nov 28 17:36:24 2025
From: knaerzche at gmail.com (Alex Bee)
Date: Sat, 29 Nov 2025 02:36:24 +0100
Subject: [PATCH] arm64: dts: rockchip: Fix audio-supply for ROCK Pi 4
In-Reply-To: <ffe5e4d1-49d8-4075-a5c4-6f27dda7f35a@cherry.de>
References: <20251027005220.22298-1-naoki@radxa.com>
 <acfc2185-0cb9-4620-abdb-ee25028e8374@cherry.de>
 <a93ace02-a952-4727-957b-0ed790b47676@cherry.de>
 <20486653DCCA80ED+7f87a03c-519e-4d6a-a47c-7670e5ae502c@radxa.com>
 <ffe5e4d1-49d8-4075-a5c4-6f27dda7f35a@cherry.de>
Message-ID: <acbbef49-02ad-47e9-9874-68d058b95f21@gmail.com>

Hi,

Am 28.11.25 um 13:33 schrieb Quentin Schulz:
> Hi Naoki,
>
> On 11/28/25 1:09 PM, FUKAUMI Naoki wrote:
>> Hi Quentin,
>>
>> On 11/28/25 19:24, Quentin Schulz wrote:
>>> Hi Naoki,
>>>
>>> On 11/27/25 4:20 PM, Quentin Schulz wrote:
>>>> Hi Naoki,
>>>>
>>>> On 10/27/25 1:52 AM, FUKAUMI Naoki wrote:
>>>>> This reverts commit 8240e87f16d17 ("arm64: dts: rockchip: fix
>>>>> audio-supply for Rock Pi 4").
>>>>>
>>>>> Fix the APIO5_VDD power supply to vcc_3v0 as per the schematics[1][2]
>>>>> [3][4][5].
>>>>>
>>>>> This fixes the SPI-NOR flash probe failure when the blue LED is 
>>>>> on[6],
>>>>> and the garbled serial console output on Linux.
>>>>>
>>>>> The ES8316 headphone and microphone are confirmed to work correctly
>>>>> after this fix.
>>>>>
>>>
>>> Please test the ES8316 works when booting Linux from a U-Boot where 
>>> ROCKCHIP_IODOMAIN and SPL_ROCKCHIP_IODOMAIN is *disabled*.
>>
>> I tried below, and confirmed that ES8316 is still working.
>>
>> diff --git a/configs/rock-pi-4-rk3399_defconfig b/configs/rock-pi-4- 
>> rk3399_defconfig
>> index 219f42bc7d4..276ca961c10 100644
>> --- a/configs/rock-pi-4-rk3399_defconfig
>> +++ b/configs/rock-pi-4-rk3399_defconfig
>> @@ -53,6 +53,7 @@ CONFIG_ROCKCHIP_GPIO=y
>> ??CONFIG_SYS_I2C_ROCKCHIP=y
>> ??CONFIG_LED=y
>> ??CONFIG_LED_GPIO=y
>> +# CONFIG_ROCKCHIP_IODOMAIN is not set
>> ??CONFIG_MMC_DW=y
>> ??CONFIG_MMC_DW_ROCKCHIP=y
>> ??CONFIG_MMC_SDHCI=y
>> diff --git a/dts/upstream/src/arm64/rockchip/rk3399-rock-pi-4.dtsi b/ 
>> dts/upstream/src/arm64/rockchip/rk3399-rock-pi-4.dtsi
>> index 046dbe32901..c734f7824c0 100644
>> --- a/dts/upstream/src/arm64/rockchip/rk3399-rock-pi-4.dtsi
>> +++ b/dts/upstream/src/arm64/rockchip/rk3399-rock-pi-4.dtsi
>> @@ -51,7 +51,7 @@
>>
>> ???????? sound: sound {
>> ???????????????? compatible = "audio-graph-card";
>> -?????????????? label = "Analog";
>> +?????????????? label = "rk3588-es8316";
>> ???????????????? dais = <&i2s0_p0>;
>> ???????? };
>>
>> @@ -516,7 +516,7 @@
>> ??};
>>
>> ??&io_domains {
>> -?????? audio-supply = <&vcca1v8_codec>;
>> +?????? audio-supply = <&vcc_3v0>;
>> ???????? bt656-supply = <&vcc_3v0>;
>> ???????? gpio1830-supply = <&vcc_3v0>;
>> ???????? sdmmc-supply = <&vcc_sdio>;
>>
>> Notes:
>> - SPL_ROCKCHIP_IODOMAIN is not set by default
>> - I don't understand alsa ucm2 ;) so I modified /sound/label
>>
>
> Thanks for testing. Let's hope the original issue doesn't appear for 
> *some* boots (depending on probe order or some timing for example). 
> For now I guess this will do. Adding Alex in Cc maybe they are able to 
> reproduce the issue they had 4 years ago with their board?
>
> Cheers,
> Quentin


I can confirm that with this change analog audio is _broken_ for me again.

I never had any issues with uart2 or spi - neither in kernel nor in u-boot
(also not after io-domain driver has been added to u-boot for RK3399).
Given this commit is now ~4 years in tree? I'd guess that someone else
would have reported that issue earlier. It's correct that this information
came from a "Power Domain Map"? which you call "non schematic" and the
"schematic part"? says something else -? it would have been indeed be
better to have clearer information.

Anyway: I can't neither see how this change should relate to uart2 or spi
which are both in different io-domain, nor why it would happen only in
u-boot. My strongest guess is, that radxa changed something along the way.
Or maybe it would be worth to double-check the io-domain driver in u-boot.


Regards,
Alex




From mani at kernel.org  Fri Nov 28 18:46:12 2025
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Sat, 29 Nov 2025 08:16:12 +0530
Subject: [PATCH] PCI: dwc: Make Link Up IRQ logic handle already powered
 on PCIe switches
In-Reply-To: <20251127134318.3655052-2-cassel@kernel.org>
References: <20251127134318.3655052-2-cassel@kernel.org>
Message-ID: <x6nhj6maseucclrhvpyiknxqqxaobgvfuaaljohbl3hnkiwayi@elgihi5dqc5y>

On Thu, Nov 27, 2025 at 02:43:18PM +0100, Niklas Cassel wrote:
> The DWC glue drivers always call pci_host_probe() during probe(), which
> will allocate upstream bridge resources and enumerate the bus.
> 
> For controllers without Link Up IRQ support, pci_host_probe() is called
> after dw_pcie_wait_for_link(), which will also wait the time required by
> the PCIe specification before performing PCI Configuration Space reads.
> 
> For controllers with Link Up IRQ support, the pci_host_probe() call (which
> will perform PCI Configuration Space reads) is done without any of the
> delays mandated by the PCIe specification.
> 
> For controllers with Link Up IRQ support, since the pci_host_probe() call
> is done without any delay (link training might still be ongoing), it is
> very unlikely that this scan will find any devices. Once the Link Up IRQ
> triggers, the Link Up IRQ handler will call pci_rescan_bus().
> 
> This works fine for PCIe endpoints connected to the Root Port, since they
> don't extend the bus. However, if the pci_rescan_bus() call detects a PCIe
> switch, then there will be a problem when the downstream busses starts
> showing up, because the PCIe controller is not hotplug capable, so we are
> not allowed to extend the subordinate bus number after the initial scan,
> resulting in error messages such as:
> 
> pci_bus 0004:43: busn_res: can not insert [bus 43-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:43: busn_res: [bus 43-41] end is updated to 43
> pci_bus 0004:43: busn_res: can not insert [bus 43] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:00.0: devices behind bridge are unusable because [bus 43] cannot be assigned for them
> pci_bus 0004:44: busn_res: can not insert [bus 44-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:44: busn_res: [bus 44-41] end is updated to 44
> pci_bus 0004:44: busn_res: can not insert [bus 44] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:02.0: devices behind bridge are unusable because [bus 44] cannot be assigned for them
> pci_bus 0004:45: busn_res: can not insert [bus 45-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:45: busn_res: [bus 45-41] end is updated to 45
> pci_bus 0004:45: busn_res: can not insert [bus 45] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:06.0: devices behind bridge are unusable because [bus 45] cannot be assigned for them
> pci_bus 0004:46: busn_res: can not insert [bus 46-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci_bus 0004:46: busn_res: [bus 46-41] end is updated to 46
> pci_bus 0004:46: busn_res: can not insert [bus 46] under [bus 42-41] (conflicts with (null) [bus 42-41])
> pci 0004:42:0e.0: devices behind bridge are unusable because [bus 46] cannot be assigned for them
> pci_bus 0004:42: busn_res: [bus 42-41] end is updated to 46
> pci_bus 0004:42: busn_res: can not insert [bus 42-46] under [bus 41] (conflicts with (null) [bus 41])
> pci 0004:41:00.0: devices behind bridge are unusable because [bus 42-46] cannot be assigned for them
> pcieport 0004:40:00.0: bridge has subordinate 41 but max busn 46
> 
> While we would like to set the is_hotplug_bridge flag
> (quirk_hotplug_bridge()), many embedded SoCs that use the DWC controller
> have synthesized the controller without hot-plug support.
> Thus, the Link Up IRQ logic is only mimicking hot-plug functionality, i.e.
> it is not compliant with the PCI Hot-Plug Specification, so we cannot make
> use of the is_hotplug_bridge flag.
> 
> In order to let the Link Up IRQ logic handle PCIe switches that are already
> powered on (PCIe switches that not powered on already need to implement a
> pwrctrl driver), don't perform a pci_host_probe() call during probe()
> (which disregards the delays required by the PCIe specification).
> 
> Instead let the first Link Up IRQ call pci_host_probe(). Any follow up
> Link Up IRQ will call pci_rescan_bus().
> 
> Fixes: ec9fd499b9c6 ("PCI: dw-rockchip: Don't wait for link since we can detect Link Up")
> Fixes: 0e0b45ab5d77 ("PCI: dw-rockchip: Enumerate endpoints based on dll_link_up IRQ")
> Reported-by: FUKAUMI Naoki <naoki at radxa.com>
> Closes: https://lore.kernel.org/linux-pci/1E8E4DB773970CB5+5a52c9e1-01b8-4872-99b7-021099f04031 at radxa.com/
> Signed-off-by: Niklas Cassel <cassel at kernel.org>
> ---
>  .../pci/controller/dwc/pcie-designware-host.c | 70 ++++++++++++++++---
>  drivers/pci/controller/dwc/pcie-designware.h  |  5 ++
>  drivers/pci/controller/dwc/pcie-dw-rockchip.c |  5 +-
>  drivers/pci/controller/dwc/pcie-qcom.c        |  5 +-
>  4 files changed, 68 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> index e92513c5bda51..8654346729574 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> @@ -565,6 +565,59 @@ static int dw_pcie_host_get_resources(struct dw_pcie_rp *pp)
>  	return 0;
>  }
>  
> +static int dw_pcie_host_initial_scan(struct dw_pcie_rp *pp)
> +{
> +	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> +	struct pci_host_bridge *bridge = pp->bridge;
> +	int ret;
> +
> +	ret = pci_host_probe(bridge);
> +	if (ret)
> +		return ret;
> +
> +	if (pp->ops->post_init)
> +		pp->ops->post_init(pp);
> +
> +	dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
> +
> +	return 0;
> +}
> +
> +void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp)
> +{
> +	if (!pp->initial_linkup_irq_done) {
> +		int ret;
> +
> +		ret = dw_pcie_host_initial_scan(pp);
> +		if (ret) {
> +			struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> +			struct device *dev = pci->dev;
> +
> +			dev_err(dev, "Initial scan from IRQ failed: %d\n", ret);
> +
> +			dw_pcie_stop_link(pci);
> +
> +			dw_pcie_edma_remove(pci);
> +
> +			if (pp->has_msi_ctrl)
> +				dw_pcie_free_msi(pp);
> +
> +			if (pp->ops->deinit)
> +				pp->ops->deinit(pp);
> +
> +			if (pp->cfg)
> +				pci_ecam_free(pp->cfg);
> +		} else {
> +			pp->initial_linkup_irq_done = true;
> +		}
> +	} else {
> +		/* Rescan the bus to enumerate endpoint devices */
> +		pci_lock_rescan_remove();
> +		pci_rescan_bus(pp->bridge->bus);
> +		pci_unlock_rescan_remove();
> +	}
> +}
> +
>  int dw_pcie_host_init(struct dw_pcie_rp *pp)
>  {
>  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> @@ -669,18 +722,17 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
>  	 * If there is no Link Up IRQ, we should not bypass the delay
>  	 * because that would require users to manually rescan for devices.
>  	 */
> -	if (!pp->use_linkup_irq)
> +	if (!pp->use_linkup_irq) {
>  		/* Ignore errors, the link may come up later */
>  		dw_pcie_wait_for_link(pci);
>  
> -	ret = pci_host_probe(bridge);
> -	if (ret)
> -		goto err_stop_link;
> -
> -	if (pp->ops->post_init)
> -		pp->ops->post_init(pp);
> -
> -	dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
> +		/*
> +		 * For platforms with Link Up IRQ, initial scan will be done
> +		 * on first Link Up IRQ.
> +		 */
> +		if (dw_pcie_host_initial_scan(pp))
> +			goto err_stop_link;

This is causing NULL ptr dereference on Qcom platforms as 'pp->bridge->bus' is
dereferenced after dw_pcie_host_init() for registering the IRQ.

I still feel that a revert would be the safest option.

- Mani

-- 
????????? ????????


From martin.petersen at oracle.com  Fri Nov 28 19:30:05 2025
From: martin.petersen at oracle.com (Martin K. Petersen)
Date: Fri, 28 Nov 2025 22:30:05 -0500
Subject: [PATCH] scsi: ufs: rockchip: Reset controller on PRE_CHANGE of hce enable notify
In-Reply-To: <1763009575-237552-1-git-send-email-shawn.lin@rock-chips.com>
References: <1763009575-237552-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <176438479585.3682470.6069803802402545335.b4-ty@oracle.com>

On Thu, 13 Nov 2025 12:52:55 +0800, Shawn Lin wrote:

> This fixes the dme-reset failed when doing recoverying, because device
> reset is not enough, we could occasionally see the error below:
> 
> ufshcd-rockchip 2a2d0000.ufs: uic cmd 0x14 with arg3 0x0 completion timeout
> ufshcd-rockchip 2a2d0000.ufs: dme-reset: error code -110
> ufshcd-rockchip 2a2d0000.ufs: DME_RESET failed
> ufshcd-rockchip 2a2d0000.ufs: ufshcd_host_reset_and_restore: Host init failed -110
> 
> [...]

Applied to 6.19/scsi-queue, thanks!

[1/1] scsi: ufs: rockchip: Reset controller on PRE_CHANGE of hce enable notify
      https://git.kernel.org/mkp/scsi/c/b0ee72db9132

-- 
Martin K. Petersen


From martin.petersen at oracle.com  Fri Nov 28 19:30:04 2025
From: martin.petersen at oracle.com (Martin K. Petersen)
Date: Fri, 28 Nov 2025 22:30:04 -0500
Subject: [PATCH] scsi: ufs: rockchip: Fix compile error without CONFIG_GPIOLIB
In-Reply-To: <1763011091-243727-1-git-send-email-shawn.lin@rock-chips.com>
References: <1763011091-243727-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <176438479587.3682470.2060847017391787355.b4-ty@oracle.com>

On Thu, 13 Nov 2025 13:18:11 +0800, Shawn Lin wrote:

> drivers/ufs/host/ufs-rockchip.c:168:19: error: implicit declaration of function
> 'devm_gpiod_get'; did you mean 'em_pd_get'? [-Werror=implicit-function-declaration]
> 
> drivers/ufs/host/ufs-rockchip.c:214:2: error: implicit declaration of function
> 'gpiod_set_value_cansleep'; did you mean 'gpio_set_value_cansleep'?
> [-Werror=implicit-function-declaration]
> 
> [...]

Applied to 6.19/scsi-queue, thanks!

[1/1] scsi: ufs: rockchip: Fix compile error without CONFIG_GPIOLIB
      https://git.kernel.org/mkp/scsi/c/cda5f23eed84

-- 
Martin K. Petersen


From naoki at radxa.com  Fri Nov 28 19:40:10 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Sat, 29 Nov 2025 12:40:10 +0900
Subject: [PATCH] arm64: dts: rockchip: Fix audio-supply for ROCK Pi 4
In-Reply-To: <acbbef49-02ad-47e9-9874-68d058b95f21@gmail.com>
References: <20251027005220.22298-1-naoki@radxa.com>
 <acfc2185-0cb9-4620-abdb-ee25028e8374@cherry.de>
 <a93ace02-a952-4727-957b-0ed790b47676@cherry.de>
 <20486653DCCA80ED+7f87a03c-519e-4d6a-a47c-7670e5ae502c@radxa.com>
 <ffe5e4d1-49d8-4075-a5c4-6f27dda7f35a@cherry.de>
 <acbbef49-02ad-47e9-9874-68d058b95f21@gmail.com>
Message-ID: <60D749559660CD94+62b923bb-f852-4e83-b9fb-a2a25030ef73@radxa.com>

Hi Alex,

On 11/29/25 10:36, Alex Bee wrote:
> Hi,
> 
> Am 28.11.25 um 13:33 schrieb Quentin Schulz:
>> Hi Naoki,
>>
>> On 11/28/25 1:09 PM, FUKAUMI Naoki wrote:
>>> Hi Quentin,
>>>
>>> On 11/28/25 19:24, Quentin Schulz wrote:
>>>> Hi Naoki,
>>>>
>>>> On 11/27/25 4:20 PM, Quentin Schulz wrote:
>>>>> Hi Naoki,
>>>>>
>>>>> On 10/27/25 1:52 AM, FUKAUMI Naoki wrote:
>>>>>> This reverts commit 8240e87f16d17 ("arm64: dts: rockchip: fix
>>>>>> audio-supply for Rock Pi 4").
>>>>>>
>>>>>> Fix the APIO5_VDD power supply to vcc_3v0 as per the schematics[1][2]
>>>>>> [3][4][5].
>>>>>>
>>>>>> This fixes the SPI-NOR flash probe failure when the blue LED is 
>>>>>> on[6],
>>>>>> and the garbled serial console output on Linux.
>>>>>>
>>>>>> The ES8316 headphone and microphone are confirmed to work correctly
>>>>>> after this fix.
>>>>>>
>>>>
>>>> Please test the ES8316 works when booting Linux from a U-Boot where 
>>>> ROCKCHIP_IODOMAIN and SPL_ROCKCHIP_IODOMAIN is *disabled*.
>>>
>>> I tried below, and confirmed that ES8316 is still working.
>>>
>>> diff --git a/configs/rock-pi-4-rk3399_defconfig b/configs/rock-pi-4- 
>>> rk3399_defconfig
>>> index 219f42bc7d4..276ca961c10 100644
>>> --- a/configs/rock-pi-4-rk3399_defconfig
>>> +++ b/configs/rock-pi-4-rk3399_defconfig
>>> @@ -53,6 +53,7 @@ CONFIG_ROCKCHIP_GPIO=y
>>> ??CONFIG_SYS_I2C_ROCKCHIP=y
>>> ??CONFIG_LED=y
>>> ??CONFIG_LED_GPIO=y
>>> +# CONFIG_ROCKCHIP_IODOMAIN is not set
>>> ??CONFIG_MMC_DW=y
>>> ??CONFIG_MMC_DW_ROCKCHIP=y
>>> ??CONFIG_MMC_SDHCI=y
>>> diff --git a/dts/upstream/src/arm64/rockchip/rk3399-rock-pi-4.dtsi b/ 
>>> dts/upstream/src/arm64/rockchip/rk3399-rock-pi-4.dtsi
>>> index 046dbe32901..c734f7824c0 100644
>>> --- a/dts/upstream/src/arm64/rockchip/rk3399-rock-pi-4.dtsi
>>> +++ b/dts/upstream/src/arm64/rockchip/rk3399-rock-pi-4.dtsi
>>> @@ -51,7 +51,7 @@
>>>
>>> ???????? sound: sound {
>>> ???????????????? compatible = "audio-graph-card";
>>> -?????????????? label = "Analog";
>>> +?????????????? label = "rk3588-es8316";
>>> ???????????????? dais = <&i2s0_p0>;
>>> ???????? };
>>>
>>> @@ -516,7 +516,7 @@
>>> ??};
>>>
>>> ??&io_domains {
>>> -?????? audio-supply = <&vcca1v8_codec>;
>>> +?????? audio-supply = <&vcc_3v0>;
>>> ???????? bt656-supply = <&vcc_3v0>;
>>> ???????? gpio1830-supply = <&vcc_3v0>;
>>> ???????? sdmmc-supply = <&vcc_sdio>;
>>>
>>> Notes:
>>> - SPL_ROCKCHIP_IODOMAIN is not set by default
>>> - I don't understand alsa ucm2 ;) so I modified /sound/label
>>>
>>
>> Thanks for testing. Let's hope the original issue doesn't appear for 
>> *some* boots (depending on probe order or some timing for example). 
>> For now I guess this will do. Adding Alex in Cc maybe they are able to 
>> reproduce the issue they had 4 years ago with their board?
>>
>> Cheers,
>> Quentin
> 
> 
> I can confirm that with this change analog audio is _broken_ for me again.
> 
> I never had any issues with uart2 or spi - neither in kernel nor in u-boot
> (also not after io-domain driver has been added to u-boot for RK3399).
> Given this commit is now ~4 years in tree? I'd guess that someone else
> would have reported that issue earlier. It's correct that this information
> came from a "Power Domain Map"? which you call "non schematic" and the
> "schematic part"? says something else -? it would have been indeed be
> better to have clearer information.

We can confirm that "schematic part" is correct.

> Anyway: I can't neither see how this change should relate to uart2 or spi
> which are both in different io-domain, nor why it would happen only in
> u-boot. My strongest guess is, that radxa changed something along the way.

I'm sorry, I can't explain the relationship between UART2/SPI and APIO5.

However, I had been seeing "the garbled serial console output on Linux" 
for a long time, and couldn't figure out how to fix it.

What version of your ROCK Pi 4 board do you have?

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

> Or maybe it would be worth to double-check the io-domain driver in u-boot.
> 
> 
> Regards,
> Alex
> 
> 
> 




From chaoyi.chen at rock-chips.com  Fri Nov 28 19:49:02 2025
From: chaoyi.chen at rock-chips.com (Chaoyi Chen)
Date: Sat, 29 Nov 2025 11:49:02 +0800
Subject: [PATCH v3 4/4] drm/rockchip: vop2: Support setting custom
 background color
In-Reply-To: <4a6443b8-d440-4921-8a43-7c20e4e265e7@collabora.com>
References: <20251118-rk3588-bgcolor-v3-0-a2cc909428ea@collabora.com>
 <20251118-rk3588-bgcolor-v3-4-a2cc909428ea@collabora.com>
 <0ed71b8d-5a2e-4213-bd2f-7ba317d1e4cb@rock-chips.com>
 <4a6443b8-d440-4921-8a43-7c20e4e265e7@collabora.com>
Message-ID: <b8819463-cc61-432f-b451-db90e3b43884@rock-chips.com>

Hello Cristian, 

On 11/28/2025 5:44 PM, Cristian Ciocaltea wrote:
> The precision was something I initially looked into for CRC verification, in the
> context of the related IGT test.  But since I've added the VKMS support, I think
> we should not worry about that anymore. 
> 
> Moreover, as already pointed out in [1], only RK3576 supports CRC generation at
> display controller level, and that is not particularly useful because it doesn't

I believe you can get the CRTC CRC on the RK3576, even when only the 
background is visible and all plane is disabled. Feel free to let me
know if you run into any issues :)

> take the background color into account.  Therefore I had to capture the frame
> CRCs at DisplayPort AUX channel level, by using the USB-C DP AltMode capable

Oh that sounds interesting! I'm not sure how complex it would be to
implement.

> port of my RK3588-based board.  However, that solution is not yet available
> upstream, as it requires further work for cleanup and improving the overall
> USB-C reliability. 
> 
> Hence I'll move on with your suggestion and switch to the simple bit-shifting
> approach for the next revision.

-- 
Best, 
Chaoyi


From naoki at radxa.com  Fri Nov 28 20:02:33 2025
From: naoki at radxa.com (FUKAUMI Naoki)
Date: Sat, 29 Nov 2025 13:02:33 +0900
Subject: [PATCH] arm64: dts: rockchip: Fix audio-supply for ROCK Pi 4
In-Reply-To: <60D749559660CD94+62b923bb-f852-4e83-b9fb-a2a25030ef73@radxa.com>
References: <20251027005220.22298-1-naoki@radxa.com>
 <acfc2185-0cb9-4620-abdb-ee25028e8374@cherry.de>
 <a93ace02-a952-4727-957b-0ed790b47676@cherry.de>
 <20486653DCCA80ED+7f87a03c-519e-4d6a-a47c-7670e5ae502c@radxa.com>
 <ffe5e4d1-49d8-4075-a5c4-6f27dda7f35a@cherry.de>
 <acbbef49-02ad-47e9-9874-68d058b95f21@gmail.com>
 <60D749559660CD94+62b923bb-f852-4e83-b9fb-a2a25030ef73@radxa.com>
Message-ID: <980092DD85519275+a4dd9cbd-12ad-4aec-b1a1-1b15f9932b8d@radxa.com>

I forgot to mention this:
  https://forum.radxa.com/t/problem-using-i2s-and-spi-on-the-gpio-header-of-the-rock-pi-4b/25390/14

Best regards,

--
FUKAUMI Naoki
Radxa Computer (Shenzhen) Co., Ltd.

On 11/29/25 12:40, FUKAUMI Naoki wrote:
> Hi Alex,
> 
> On 11/29/25 10:36, Alex Bee wrote:
>> Hi,
>>
>> Am 28.11.25 um 13:33 schrieb Quentin Schulz:
>>> Hi Naoki,
>>>
>>> On 11/28/25 1:09 PM, FUKAUMI Naoki wrote:
>>>> Hi Quentin,
>>>>
>>>> On 11/28/25 19:24, Quentin Schulz wrote:
>>>>> Hi Naoki,
>>>>>
>>>>> On 11/27/25 4:20 PM, Quentin Schulz wrote:
>>>>>> Hi Naoki,
>>>>>>
>>>>>> On 10/27/25 1:52 AM, FUKAUMI Naoki wrote:
>>>>>>> This reverts commit 8240e87f16d17 ("arm64: dts: rockchip: fix
>>>>>>> audio-supply for Rock Pi 4").
>>>>>>>
>>>>>>> Fix the APIO5_VDD power supply to vcc_3v0 as per the 
>>>>>>> schematics[1][2]
>>>>>>> [3][4][5].
>>>>>>>
>>>>>>> This fixes the SPI-NOR flash probe failure when the blue LED is 
>>>>>>> on[6],
>>>>>>> and the garbled serial console output on Linux.
>>>>>>>
>>>>>>> The ES8316 headphone and microphone are confirmed to work correctly
>>>>>>> after this fix.
>>>>>>>
>>>>>
>>>>> Please test the ES8316 works when booting Linux from a U-Boot where 
>>>>> ROCKCHIP_IODOMAIN and SPL_ROCKCHIP_IODOMAIN is *disabled*.
>>>>
>>>> I tried below, and confirmed that ES8316 is still working.
>>>>
>>>> diff --git a/configs/rock-pi-4-rk3399_defconfig b/configs/rock-pi-4- 
>>>> rk3399_defconfig
>>>> index 219f42bc7d4..276ca961c10 100644
>>>> --- a/configs/rock-pi-4-rk3399_defconfig
>>>> +++ b/configs/rock-pi-4-rk3399_defconfig
>>>> @@ -53,6 +53,7 @@ CONFIG_ROCKCHIP_GPIO=y
>>>> ??CONFIG_SYS_I2C_ROCKCHIP=y
>>>> ??CONFIG_LED=y
>>>> ??CONFIG_LED_GPIO=y
>>>> +# CONFIG_ROCKCHIP_IODOMAIN is not set
>>>> ??CONFIG_MMC_DW=y
>>>> ??CONFIG_MMC_DW_ROCKCHIP=y
>>>> ??CONFIG_MMC_SDHCI=y
>>>> diff --git a/dts/upstream/src/arm64/rockchip/rk3399-rock-pi-4.dtsi 
>>>> b/ dts/upstream/src/arm64/rockchip/rk3399-rock-pi-4.dtsi
>>>> index 046dbe32901..c734f7824c0 100644
>>>> --- a/dts/upstream/src/arm64/rockchip/rk3399-rock-pi-4.dtsi
>>>> +++ b/dts/upstream/src/arm64/rockchip/rk3399-rock-pi-4.dtsi
>>>> @@ -51,7 +51,7 @@
>>>>
>>>> ???????? sound: sound {
>>>> ???????????????? compatible = "audio-graph-card";
>>>> -?????????????? label = "Analog";
>>>> +?????????????? label = "rk3588-es8316";
>>>> ???????????????? dais = <&i2s0_p0>;
>>>> ???????? };
>>>>
>>>> @@ -516,7 +516,7 @@
>>>> ??};
>>>>
>>>> ??&io_domains {
>>>> -?????? audio-supply = <&vcca1v8_codec>;
>>>> +?????? audio-supply = <&vcc_3v0>;
>>>> ???????? bt656-supply = <&vcc_3v0>;
>>>> ???????? gpio1830-supply = <&vcc_3v0>;
>>>> ???????? sdmmc-supply = <&vcc_sdio>;
>>>>
>>>> Notes:
>>>> - SPL_ROCKCHIP_IODOMAIN is not set by default
>>>> - I don't understand alsa ucm2 ;) so I modified /sound/label
>>>>
>>>
>>> Thanks for testing. Let's hope the original issue doesn't appear for 
>>> *some* boots (depending on probe order or some timing for example). 
>>> For now I guess this will do. Adding Alex in Cc maybe they are able 
>>> to reproduce the issue they had 4 years ago with their board?
>>>
>>> Cheers,
>>> Quentin
>>
>>
>> I can confirm that with this change analog audio is _broken_ for me 
>> again.
>>
>> I never had any issues with uart2 or spi - neither in kernel nor in u- 
>> boot
>> (also not after io-domain driver has been added to u-boot for RK3399).
>> Given this commit is now ~4 years in tree? I'd guess that someone else
>> would have reported that issue earlier. It's correct that this 
>> information
>> came from a "Power Domain Map"? which you call "non schematic" and the
>> "schematic part"? says something else -? it would have been indeed be
>> better to have clearer information.
> 
> We can confirm that "schematic part" is correct.
> 
>> Anyway: I can't neither see how this change should relate to uart2 or spi
>> which are both in different io-domain, nor why it would happen only in
>> u-boot. My strongest guess is, that radxa changed something along the 
>> way.
> 
> I'm sorry, I can't explain the relationship between UART2/SPI and APIO5.
> 
> However, I had been seeing "the garbled serial console output on Linux" 
> for a long time, and couldn't figure out how to fix it.
> 
> What version of your ROCK Pi 4 board do you have?
> 
> Best regards,
> 
> -- 
> FUKAUMI Naoki
> Radxa Computer (Shenzhen) Co., Ltd.
> 
>> Or maybe it would be worth to double-check the io-domain driver in u- 
>> boot.
>>
>>
>> Regards,
>> Alex
>>
>>
>>
> 
> 



From linux.amoon at gmail.com  Fri Nov 28 22:51:58 2025
From: linux.amoon at gmail.com (Anand Moon)
Date: Sat, 29 Nov 2025 12:21:58 +0530
Subject: [PATCH] arm64: dts: rockchip: Fix audio-supply for ROCK Pi 4
In-Reply-To: <20251027005220.22298-1-naoki@radxa.com>
References: <20251027005220.22298-1-naoki@radxa.com>
Message-ID: <CANAwSgS-OxBoRy4jwb+XkuxYwws3P97eAFaOJAPBvK5gtgHuLg@mail.gmail.com>

Hi FUKAUMI,

On Mon, 27 Oct 2025 at 06:24, FUKAUMI Naoki <naoki at radxa.com> wrote:
>
> This reverts commit 8240e87f16d17 ("arm64: dts: rockchip: fix
> audio-supply for Rock Pi 4").
>
> Fix the APIO5_VDD power supply to vcc_3v0 as per the schematics[1][2]
> [3][4][5].
>
> This fixes the SPI-NOR flash probe failure when the blue LED is on[6],
> and the garbled serial console output on Linux.
>
> The ES8316 headphone and microphone are confirmed to work correctly
> after this fix.
>
> [1] https://dl.radxa.com/rockpi4/docs/hw/rockpi4/4a/ROCK_4A_V1.52_SCH.pdf p.14
> [2] https://dl.radxa.com/rockpi4/docs/hw/rockpi4/4ap/radxa_rock_4ap_v1730_schematic.pdf p.14
> [3] https://dl.radxa.com/rockpi4/docs/hw/rockpi4/4b/ROCK_4B_v1.52_SCH.pdf p.14
> [4] https://dl.radxa.com/rockpi4/docs/hw/rockpi4/4bp/radxa_rock_4bp_v1730_schematic.pdf p.14
> [5] https://dl.radxa.com/rockpi4/docs/hw/rockpi4/ROCK-4-SE-V1.53-SCH.pdf p.14
>
> [6]
> => led blue:status off
> => sf probe
> SF: Detected w25q128 with page size 256 Bytes, erase size 4 KiB, total 16 MiB
> => led blue:status on
> => sf probe
> jedec_spi_nor flash at 0: unrecognized JEDEC id bytes: ff, ff, ff
> Failed to initialize SPI flash at 1:0 (error -2)
>
> Fixes: 7ebfd4f6b52a6 ("arm64: dts: rockchip: add LED for ROCK Pi 4A/B/C/A+/B+")
> Fixes: 8240e87f16d17 ("arm64: dts: rockchip: fix audio-supply for Rock Pi 4")
> Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>

Tested-by: Anand Moon <linux.amoon at gmail.com>

With this patch applied,  I can get my console working.

Thanks
-Anand


From cristian.ciocaltea at collabora.com  Sat Nov 29 01:50:16 2025
From: cristian.ciocaltea at collabora.com (Cristian Ciocaltea)
Date: Sat, 29 Nov 2025 11:50:16 +0200
Subject: [PATCH v3 4/4] drm/rockchip: vop2: Support setting custom
 background color
In-Reply-To: <b8819463-cc61-432f-b451-db90e3b43884@rock-chips.com>
References: <20251118-rk3588-bgcolor-v3-0-a2cc909428ea@collabora.com>
 <20251118-rk3588-bgcolor-v3-4-a2cc909428ea@collabora.com>
 <0ed71b8d-5a2e-4213-bd2f-7ba317d1e4cb@rock-chips.com>
 <4a6443b8-d440-4921-8a43-7c20e4e265e7@collabora.com>
 <b8819463-cc61-432f-b451-db90e3b43884@rock-chips.com>
Message-ID: <058027df-1b1b-4c46-b8e1-ec53fc809e82@collabora.com>

Hi Chaoyi,

On 11/29/25 5:49 AM, Chaoyi Chen wrote:
> Hello Cristian, 
> 
> On 11/28/2025 5:44 PM, Cristian Ciocaltea wrote:
>> The precision was something I initially looked into for CRC verification, in the
>> context of the related IGT test.  But since I've added the VKMS support, I think
>> we should not worry about that anymore. 
>>
>> Moreover, as already pointed out in [1], only RK3576 supports CRC generation at
>> display controller level, and that is not particularly useful because it doesn't
> 
> I believe you can get the CRTC CRC on the RK3576, even when only the 
> background is visible and all plane is disabled. Feel free to let me
> know if you run into any issues :)

Yes, CRTC CRC works on RK3576 for the planes, but not for the background, i.e.
the CRC is not updated when setting a different background color.  Unless
there's a way to change this default behavior, which I'm not aware of. 

My current understanding is that the background color is applied at a later
stage in the display pipeline, *after* blending the planes and computing CRC.

>> take the background color into account.  Therefore I had to capture the frame
>> CRCs at DisplayPort AUX channel level, by using the USB-C DP AltMode capable
> 
> Oh that sounds interesting! I'm not sure how complex it would be to
> implement.

That's already implemented, I plan to submit the patches soon.

> 
>> port of my RK3588-based board.  However, that solution is not yet available
>> upstream, as it requires further work for cleanup and improving the overall
>> USB-C reliability. 
>>
>> Hence I'll move on with your suggestion and switch to the simple bit-shifting
>> approach for the next revision.
> 


From dan.carpenter at linaro.org  Sat Nov 29 08:50:22 2025
From: dan.carpenter at linaro.org (Dan Carpenter)
Date: Sat, 29 Nov 2025 19:50:22 +0300
Subject: [PATCH] PCI: dwc: Make Link Up IRQ logic handle already powered
 on PCIe switches
In-Reply-To: <20251127134318.3655052-2-cassel@kernel.org>
Message-ID: <202511290255.uBLXDIG5-lkp@intel.com>

Hi Niklas,

kernel test robot noticed the following build warnings:

https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Niklas-Cassel/PCI-dwc-Make-Link-Up-IRQ-logic-handle-already-powered-on-PCIe-switches/20251127-214649
base:   https://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git next
patch link:    https://lore.kernel.org/r/20251127134318.3655052-2-cassel%40kernel.org
patch subject: [PATCH] PCI: dwc: Make Link Up IRQ logic handle already powered on PCIe switches
config: x86_64-randconfig-r071-20251128 (https://download.01.org/0day-ci/archive/20251129/202511290255.uBLXDIG5-lkp at intel.com/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp at intel.com>
| Reported-by: Dan Carpenter <dan.carpenter at linaro.org>
| Closes: https://lore.kernel.org/r/202511290255.uBLXDIG5-lkp at intel.com/

smatch warnings:
drivers/pci/controller/dwc/pcie-designware-host.c:737 dw_pcie_host_init() warn: missing error code 'ret'

vim +/ret +737 drivers/pci/controller/dwc/pcie-designware-host.c

59fbab1ae40eb0 drivers/pci/controller/dwc/pcie-designware-host.c Rob Herring               2020-11-05  712  
939fbcd568fd29 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin               2023-01-13  713  	ret = dw_pcie_setup_rc(pp);
939fbcd568fd29 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin               2023-01-13  714  	if (ret)
939fbcd568fd29 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin               2023-01-13  715  		goto err_remove_edma;
939fbcd568fd29 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin               2023-01-13  716  
c5097b9869a136 drivers/pci/controller/dwc/pcie-designware-host.c Johan Hovold              2023-07-06  717  	if (!dw_pcie_link_up(pci)) {
a37beefbde8802 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin               2022-06-24  718  		ret = dw_pcie_start_link(pci);
886a9c1347558f drivers/pci/controller/dwc/pcie-designware-host.c Rob Herring               2020-11-05  719  		if (ret)
939fbcd568fd29 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin               2023-01-13  720  			goto err_remove_edma;
da56a1bfbab551 drivers/pci/controller/dwc/pcie-designware-host.c Ajay Agarwal              2023-04-12  721  	}
886a9c1347558f drivers/pci/controller/dwc/pcie-designware-host.c Rob Herring               2020-11-05  722  
8d3bf19f1b585a drivers/pci/controller/dwc/pcie-designware-host.c Krishna chaitanya chundru 2024-11-23  723  	/*
8d3bf19f1b585a drivers/pci/controller/dwc/pcie-designware-host.c Krishna chaitanya chundru 2024-11-23  724  	 * Note: Skip the link up delay only when a Link Up IRQ is present.
8d3bf19f1b585a drivers/pci/controller/dwc/pcie-designware-host.c Krishna chaitanya chundru 2024-11-23  725  	 * If there is no Link Up IRQ, we should not bypass the delay
8d3bf19f1b585a drivers/pci/controller/dwc/pcie-designware-host.c Krishna chaitanya chundru 2024-11-23  726  	 * because that would require users to manually rescan for devices.
8d3bf19f1b585a drivers/pci/controller/dwc/pcie-designware-host.c Krishna chaitanya chundru 2024-11-23  727  	 */
cd723d3dce14ac drivers/pci/controller/dwc/pcie-designware-host.c Niklas Cassel             2025-11-27  728  	if (!pp->use_linkup_irq) {
c5097b9869a136 drivers/pci/controller/dwc/pcie-designware-host.c Johan Hovold              2023-07-06  729  		/* Ignore errors, the link may come up later */
c5097b9869a136 drivers/pci/controller/dwc/pcie-designware-host.c Johan Hovold              2023-07-06  730  		dw_pcie_wait_for_link(pci);
c5097b9869a136 drivers/pci/controller/dwc/pcie-designware-host.c Johan Hovold              2023-07-06  731  
cd723d3dce14ac drivers/pci/controller/dwc/pcie-designware-host.c Niklas Cassel             2025-11-27  732  		/*
cd723d3dce14ac drivers/pci/controller/dwc/pcie-designware-host.c Niklas Cassel             2025-11-27  733  		 * For platforms with Link Up IRQ, initial scan will be done
cd723d3dce14ac drivers/pci/controller/dwc/pcie-designware-host.c Niklas Cassel             2025-11-27  734  		 * on first Link Up IRQ.
cd723d3dce14ac drivers/pci/controller/dwc/pcie-designware-host.c Niklas Cassel             2025-11-27  735  		 */
cd723d3dce14ac drivers/pci/controller/dwc/pcie-designware-host.c Niklas Cassel             2025-11-27  736  		if (dw_pcie_host_initial_scan(pp))
113fa857b74c94 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin               2022-06-24 @737  			goto err_stop_link;


	ret = dw_pcie_host_initial_scan(pp);
	if (ret)
		goto err_stop_link;

cd723d3dce14ac drivers/pci/controller/dwc/pcie-designware-host.c Niklas Cassel             2025-11-27  738  	}
4fbfa17f9a0755 drivers/pci/controller/dwc/pcie-designware-host.c Shradha Todi              2025-02-21  739  
feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c            Kishon Vijay Abraham I    2017-02-15  740  	return 0;
feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c            Kishon Vijay Abraham I    2017-02-15  741  
113fa857b74c94 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin               2022-06-24  742  err_stop_link:
a37beefbde8802 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin               2022-06-24  743  	dw_pcie_stop_link(pci);
113fa857b74c94 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin               2022-06-24  744  
939fbcd568fd29 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin               2023-01-13  745  err_remove_edma:
939fbcd568fd29 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin               2023-01-13  746  	dw_pcie_edma_remove(pci);
939fbcd568fd29 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin               2023-01-13  747  
9e2b5de5604a6f drivers/pci/controller/dwc/pcie-designware-host.c Jisheng Zhang             2019-03-29  748  err_free_msi:
f78f02638af594 drivers/pci/controller/dwc/pcie-designware-host.c Rob Herring               2020-11-05  749  	if (pp->has_msi_ctrl)
9e2b5de5604a6f drivers/pci/controller/dwc/pcie-designware-host.c Jisheng Zhang             2019-03-29  750  		dw_pcie_free_msi(pp);
c6481d51dc65f2 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin               2022-06-24  751  
c6481d51dc65f2 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin               2022-06-24  752  err_deinit_host:
aea370b2aec9d3 drivers/pci/controller/dwc/pcie-designware-host.c Yoshihiro Shimoda         2023-12-20  753  	if (pp->ops->deinit)
aea370b2aec9d3 drivers/pci/controller/dwc/pcie-designware-host.c Yoshihiro Shimoda         2023-12-20  754  		pp->ops->deinit(pp);
c6481d51dc65f2 drivers/pci/controller/dwc/pcie-designware-host.c Serge Semin               2022-06-24  755  
f6fd357f7afbeb drivers/pci/controller/dwc/pcie-designware-host.c Krishna Chaitanya Chundru 2025-09-23  756  err_free_ecam:
f6fd357f7afbeb drivers/pci/controller/dwc/pcie-designware-host.c Krishna Chaitanya Chundru 2025-09-23  757  	if (pp->cfg)
f6fd357f7afbeb drivers/pci/controller/dwc/pcie-designware-host.c Krishna Chaitanya Chundru 2025-09-23  758  		pci_ecam_free(pp->cfg);
f6fd357f7afbeb drivers/pci/controller/dwc/pcie-designware-host.c Krishna Chaitanya Chundru 2025-09-23  759  
feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c            Kishon Vijay Abraham I    2017-02-15  760  	return ret;
feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c            Kishon Vijay Abraham I    2017-02-15  761  }

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki



From chaoyi.chen at rock-chips.com  Sat Nov 29 19:01:42 2025
From: chaoyi.chen at rock-chips.com (Chaoyi Chen)
Date: Sun, 30 Nov 2025 11:01:42 +0800
Subject: [PATCH v3 4/4] drm/rockchip: vop2: Support setting custom
 background color
In-Reply-To: <058027df-1b1b-4c46-b8e1-ec53fc809e82@collabora.com>
References: <20251118-rk3588-bgcolor-v3-0-a2cc909428ea@collabora.com>
 <20251118-rk3588-bgcolor-v3-4-a2cc909428ea@collabora.com>
 <0ed71b8d-5a2e-4213-bd2f-7ba317d1e4cb@rock-chips.com>
 <4a6443b8-d440-4921-8a43-7c20e4e265e7@collabora.com>
 <b8819463-cc61-432f-b451-db90e3b43884@rock-chips.com>
 <058027df-1b1b-4c46-b8e1-ec53fc809e82@collabora.com>
Message-ID: <292ed476-2b5a-4b61-97e5-3b8d8a24c324@rock-chips.com>

On 11/29/2025 5:50 PM, Cristian Ciocaltea wrote:
> Hi Chaoyi,
> 
> On 11/29/25 5:49 AM, Chaoyi Chen wrote:
>> Hello Cristian, 
>>
>> On 11/28/2025 5:44 PM, Cristian Ciocaltea wrote:
>>> The precision was something I initially looked into for CRC verification, in the
>>> context of the related IGT test.  But since I've added the VKMS support, I think
>>> we should not worry about that anymore. 
>>>
>>> Moreover, as already pointed out in [1], only RK3576 supports CRC generation at
>>> display controller level, and that is not particularly useful because it doesn't
>>
>> I believe you can get the CRTC CRC on the RK3576, even when only the 
>> background is visible and all plane is disabled. Feel free to let me
>> know if you run into any issues :)
> 
> Yes, CRTC CRC works on RK3576 for the planes, but not for the background, i.e.
> the CRC is not updated when setting a different background color.  Unless
> there's a way to change this default behavior, which I'm not aware of. 
> 
> My current understanding is that the background color is applied at a later
> stage in the display pipeline, *after* blending the planes and computing CRC.
> 

Which CRTC are you using? If you're using VP0, you might run into this
problem. Please try VP1 instead.

>>> take the background color into account.  Therefore I had to capture the frame
>>> CRCs at DisplayPort AUX channel level, by using the USB-C DP AltMode capable
>>
>> Oh that sounds interesting! I'm not sure how complex it would be to
>> implement.
> 
> That's already implemented, I plan to submit the patches soon.
> 
>>
>>> port of my RK3588-based board.  However, that solution is not yet available
>>> upstream, as it requires further work for cleanup and improving the overall
>>> USB-C reliability. 
>>>
>>> Hence I'll move on with your suggestion and switch to the simple bit-shifting
>>> approach for the next revision.
>>
> 
> 

-- 
Best, 
Chaoyi


From raphael.kernel at jakse.fr  Sun Nov 30 08:12:59 2025
From: raphael.kernel at jakse.fr (=?UTF-8?q?Rapha=C3=ABl=20Jakse?=)
Date: Sun, 30 Nov 2025 17:12:59 +0100
Subject: [PATCH] arm64: dts: rockchip: Fix Bluetooth on the RockPro64 board
Message-ID: <20251130161259.9828-1-raphael.kernel@jakse.fr>

The RockPro64 board has an optional BCM4345C5 Bluetooth device on UART0.

This patch fixes audio stutters by setting its correct max-speed and
compatible properties.

Signed-off-by: Rapha?l Jakse <raphael.kernel at jakse.fr>
---
 arch/arm64/boot/dts/rockchip/rk3399-rockpro64-v2.dts | 7 +++++++
 arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts    | 7 +++++++
 2 files changed, 14 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64-v2.dts b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64-v2.dts
index 304e3c51391c..883d9bcfe792 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64-v2.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64-v2.dts
@@ -28,3 +28,10 @@ es8316_p0_0: endpoint {
 		};
 	};
 };
+
+&uart0 {
+	bluetooth {
+		compatible = "brcm,bcm4345c5";
+		max-speed = <1500000>;
+	};
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts
index 4b42717800f7..ae3ee91dba2f 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts
@@ -28,3 +28,10 @@ es8316_p0_0: endpoint {
 		};
 	};
 };
+
+&uart0 {
+	bluetooth {
+		compatible = "brcm,bcm4345c5";
+		max-speed = <1500000>;
+	};
+};
-- 
2.52.0



From sboyd at kernel.org  Sun Nov 30 11:41:59 2025
From: sboyd at kernel.org (Stephen Boyd)
Date: Sun, 30 Nov 2025 11:41:59 -0800
Subject: [GIT PULL] Rockchip clock changes for 6.19 #1
In-Reply-To: <3018362.e9J7NaK4W3@diego>
References: <3018362.e9J7NaK4W3@diego>
Message-ID: <176453171913.11952.17955530818254096640@lazor>

Quoting Heiko Stuebner (2025-11-24 13:57:09)
> Hi Mike, Stephen,
> 
> please find below a pull-request with Rockchip clock change for 6.19
> 
> Please pull.
> 
> Thanks
> Heiko
> 
> 
> The following changes since commit 3a8660878839faadb4f1a6dd72c3179c1df56787:
> 
>   Linux 6.18-rc1 (2025-10-12 13:42:36 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git tags/v6.19-rockchip-clk1
> 
> for you to fetch changes up to 18191dd750e6c9e17fabefd09ff418dd587bcdb9:
> 
>   clk: rockchip: Add clock and reset driver for RK3506 (2025-11-23 22:56:49 +0100)
> 
> ----------------------------------------------------------------

Thanks. Pulled into clk-next


From laurent.pinchart at ideasonboard.com  Sun Nov 30 19:37:00 2025
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Mon, 1 Dec 2025 12:37:00 +0900
Subject: [PATCH v2 2/3] media: rockchip: add driver for the rockchip mipi
 csi-2 receiver
In-Reply-To: <87049b4c-df7d-454b-a7f4-073975a7ee94@collabora.com>
References: <20251114-rockchip-mipi-receiver-v2-0-eb9b43377fc4@collabora.com>
 <20251114-rockchip-mipi-receiver-v2-2-eb9b43377fc4@collabora.com>
 <aRyplYZOrGsSxSlp@lizhi-Precision-Tower-5810>
 <554971e1-6fde-4b2c-a2de-fe178358a4e3@collabora.com>
 <aRzub5Ak6DZpO5f/@lizhi-Precision-Tower-5810>
 <87049b4c-df7d-454b-a7f4-073975a7ee94@collabora.com>
Message-ID: <20251201033700.GB21943@pendragon.ideasonboard.com>

Hello,

On Wed, Nov 26, 2025 at 09:57:31PM +0100, Michael Riesch wrote:
> On 11/18/25 23:08, Frank Li wrote:
> > On Tue, Nov 18, 2025 at 07:59:14PM +0100, Michael Riesch wrote:
> >> On 11/18/25 18:15, Frank Li wrote:
> >>> On Tue, Nov 18, 2025 at 12:12:26PM +0100, Michael Riesch via B4 Relay wrote:
> >>>> From: Michael Riesch <michael.riesch at collabora.com>
> >>>>
> >>>> [...]
> >>>> +#define CSI2HOST_N_LANES     0x04
> >>>> +#define CSI2HOST_CSI2_RESETN 0x10
> >>>> +#define CSI2HOST_PHY_STATE   0x14
> >>>> +#define CSI2HOST_ERR1	     0x20
> >>>> +#define CSI2HOST_ERR2	     0x24
> >>>> +#define CSI2HOST_MSK1	     0x28
> >>>> +#define CSI2HOST_MSK2	     0x2c
> >>>> +#define CSI2HOST_CONTROL     0x40
> >>>
> >>> Look like that is designware CSI2 controller, can we build common library
> >>> for all dwc csi2 controller, instead of every vendor create individual one.
> >>>
> >>> First try at
> >>> https://lore.kernel.org/linux-media/20250821-95_cam-v3-21-c9286fbb34b9 at nxp.com/
> >>>
> >>> Toshiba have similar patch
> >>> https://lore.kernel.org/linux-media/aPZd39riAxqfw3mT at lizhi-Precision-Tower-5810/
> >>>
> >>> Frank
> >>
> >> This has been discussed already a while ago:
> >> https://lore.kernel.org/all/20250507083837.GA11152 at pendragon.ideasonboard.com/
> > 
> > https://lore.kernel.org/all/20250702093806.GF16835 at pendragon.ideasonboard.com/
> > 
> > Laurent Pinchart prevent imx93 DWC CSI2 driver at Jul, your discussion at
> > May, I think Laurent Pinchart change the mind.
> > 
> > We can choose not base on imx6, but we should create a standard dwc2 under
> > drivers/media/platform/synopsys/
> 
> In principle, I agree with refactoring out common code. However, I am
> not sure how similar these IP cores really are. Again, the answer I
> received from Rockchip states that this is *not* a Synopsys IP core.

That's what I based my opinion on. If we're dealing with different IP
cores from different vendors, we can have separate drivers. Even within
the family of CSI-2 receivers from Synopsys, I'm fine having different
drivers if the version differ significantly enough that using a single
driver would cause more pain than gain.

To explain this differently, for Synopsys CSI-2 receivers, I would like
to try and support multiple IP cores integrated in different SoCs in a
single driver. If, during that development, we find good reasons to use
separate drivers, then we can do so.

> Can you maybe test whether the Rockchip MIPI CSI-2 Receiver driver in
> this series works on your hardware? Then we will know if (and what)
> parts can be shared.
> 
> > Laurent Pinchart:
> > 
> > 	Can you provide direction?
> > 
> >> Bottom line from Laurent:
> >>
> >> "Let's keep this driver Rockchip-specific then. Thanks for checking."
> >>
> >>>  [...]

-- 
Regards,

Laurent Pinchart


From chaoyi.chen at rock-chips.com  Sun Nov 30 22:24:59 2025
From: chaoyi.chen at rock-chips.com (Chaoyi Chen)
Date: Mon, 1 Dec 2025 14:24:59 +0800
Subject: Issues with DRM_ACCEL_ROCKET (Oops, power-domain, probe-ordering)
In-Reply-To: <0b20d760-ad4f-41c0-b733-39db10d6cc41@cherry.de>
References: <0b20d760-ad4f-41c0-b733-39db10d6cc41@cherry.de>
Message-ID: <77685900-2c34-49b8-8c7e-14718841ef17@rock-chips.com>

Hi Quentin,

On 11/29/2025 2:41 AM, Quentin Schulz wrote:
> Hi all,
> 
> I've finally found the time to test the RK3588 NPU (aka Rocket, upstream) on our products and I've been hit with Oopses when loosely following the instructions from https://docs.mesa3d.org/teflon.html. After debugging for a while this is often (not always!) reproducible when DRM_ACCEL_ROCKET=y (but not when built as a module!). The fact it's "not always" is a dead giveaway timing or probe order is involved, more later on that.
> 

This looks like a power domain problem. What would happen if you tried
enabling the regulator for the NPU power domain in U-Boot?

Or did you properly configure the corresponding regulator supply in
the power domain?


> I don't think the Oops is important as I believe it's a symptom of other issues, so I won't post it.
> 
> I'll list the issue I've identified so far, some seem easier to fix than others (the biggest issue of course being the hardest to fix).
> 
> 1. https://elixir.bootlin.com/linux/v6.18-rc7/source/drivers/accel/rocket/rocket_core.c#L79
> 
> The error path after a failed pm_runtime_resume_and_get() probably should be calling rocket_core_fini(core) and not rocket_job_fini() (the former calls the latter) as to unwind everything that's been done in rocket_core_init() before this failed.
> 
> The PM core complains about unbalanced something when the core fails to init and is retried later.
> 
> I suggest the following:
> 
> """
> diff --git a/drivers/accel/rocket/rocket_core.c b/drivers/accel/rocket/rocket_core.c
> index abe7719c1db46..95a732ab418c3 100644
> --- a/drivers/accel/rocket/rocket_core.c
> +++ b/drivers/accel/rocket/rocket_core.c
> @@ -76,7 +76,7 @@ int rocket_core_init(struct rocket_core *core)
> 
>      err = pm_runtime_resume_and_get(dev);
>      if (err) {
> -        rocket_job_fini(core);
> +        rocket_core_fini(core);
>          return err;
>      }
> 
> """
> 
> I can send a patch for that.
> 
> 2. rocket_probe() (https://elixir.bootlin.com/linux/v6.18-rc7/source/drivers/accel/rocket/rocket_drv.c#L159) can result in out-of-bounds access when rocket_core_init() fails as rdev is a global variable (so rdev->num_cores persists between tries). Considering rdev->cores is allocated based on the number of available nodes in the DTB with the rknn compatible, if rocket_probe() is called more than the number of available nodes, rdev->cores[core] will result in out-of-bounds access.
> 
> I believe we could do:
> 
> """
> diff --git a/drivers/accel/rocket/rocket_drv.c b/drivers/accel/rocket/rocket_drv.c
> index 5c0b63f0a8f00..ad602ebd17c44 100644
> --- a/drivers/accel/rocket/rocket_drv.c
> +++ b/drivers/accel/rocket/rocket_drv.c
> @@ -158,6 +158,8 @@ static const struct drm_driver rocket_drm_driver = {
> 
>  static int rocket_probe(struct platform_device *pdev)
>  {
> +    int ret;
> +
>      if (rdev == NULL) {
>          /* First core probing, initialize DRM device. */
>          rdev = rocket_device_init(drm_dev, &rocket_drm_driver);
> @@ -177,7 +179,15 @@ static int rocket_probe(struct platform_device *pdev)
> 
>      rdev->num_cores++;
> 
> -    return rocket_core_init(&rdev->cores[core]);
> +    ret = rocket_core_init(&rdev->cores[core]);
> +    if (ret) {
> +        rdev->num_cores--;
> +        if (rdev->num_cores == 0) {
> +            rocket_device_fini(rdev);
> +        }
> +    }
> +
> +    return ret;
>  }
> 
>  static void rocket_remove(struct platform_device *pdev)
> 
> """
> 

It seems hacky. I'm not sure whether this would be better
implemented as a component driver.

> I can send a patch for that.
> 
> 3. I believe (but I may be wrong) that core 0 is special (do we need to schedule through core 0 maybe?). There's a hardcoded fetch of the device associated with core 0 via rocket_iommu_domain_create(rdev->cores[0].dev); (https://elixir.bootlin.com/linux/v6.18-rc7/source/drivers/accel/rocket/rocket_drv.c#L88). The issue is that this assumes that core 0 is always rdev->cores[0], which may not be true as it depends on the probe order (which is not guaranteed), which can be exacerbated by core 0 (HW index) probe being deferred for some reason. Is it necessary for core 0 to be the one initializing the DRM device or could we simply use any core for that (just the first to probe, whichever it actually is HW-wise)?

I think this is because multiple cores share the same IOMMU device.

> 
> If there's a need to know which of the three cores is core 0, we can have a vendor property for it or maybe aliases for the cores? We can also do a check on the base register address of the core in DT and then do a mapping in the driver. Any other suggestion?
> 
> 4. The actual issue I'm unable to suggest something for comes now. The following is all happening in the context of DRM_ACCEL_ROCKET being built-in (that is DRM_ACCEL_ROCKET=y). You can use aarch64's default defconfig, then DRM=y, DRM_ACCEL=y and DRM_ACCEL_ROCKET=y via menuconfig. Remember that this is not 100% reproducible (more often happening than not).
> 
> Points 1, 2 and 3 only are an issue if you hit some error-path during the probe of one of the cores, which is triggered by this point 4 here.
> 
> rknn_core_0 depends on rknn_mmu_0 as highlighted by the iommus phandle property. rknn_mmu_0 depends on RK3588_PD_NPUTOP power-domain. The parent domain (RK3588_PD_NPU) of RK3588_PD_NPUTOP power-domain has a domain-supply on a regulator on i2c (i2c0 at 42 for Jaguar, patches on the ML at https://lore.kernel.org/linux-rockchip/20250812085213.1071106-2-heiko at sntech.de/). When the rocket driver calls platform_driver_register() in its module_init() function, the kernel core will try to probe the associated device, via driver_probe_device(), then __driver_probe_device() and more specifically pm_runtime_get_suppliers(dev) in there (https://elixir.bootlin.com/linux/v6.18-rc7/source/drivers/base/dd.c#L793). Then this calls pm_runtime_get_sync() on all links, c.f. https://elixir.bootlin.com/linux/v6.18-rc7/source/drivers/base/power/runtime.c#L1914. Note that pm_runtime_get_suppliers() returns void. One of the links is the rknn_mmu_0.
> 
> Follow the next series of function calls, pm_runtime_get_sync() on rknn_mmu_0, rpm_resume(), rpm_callback(), __rpm_callback(). This then calls cb(). cb() is set via RPM_GET_CALLBACK(dev, runtime_resume). Due to rknn_mmu_0 device being probed with dev_pm_domain_attach() attaching the power-domain device to iommu via the pm_domain member, genpd_runtime_resume() (which goes to rockchip_pd_power_on()) is actually called. This then calls rockchip_pd_regulator_enable() which returns -EPROBE_DEFER. Going up in the call stack up to rpm_callback() you can see that retval = __rpm_callback(cb, dev); now is EPROBE_DEFER and thus, dev->power.runtime_error = EPROBE_DEFER at the end of the function.
> 
> Then once pm_runtime_resume_and_get(dev); is called in rocket_core_init() during probe of the rocket device, it'll call into rpm_get_suppliers() in __rpm_callback() which in turn will call pm_runtime_get_sync() on rknn_mmu_0 which will go up to rpm_resume() where dev->power.runtime_error will be checked and if non-zero will return -EINVAL, effectively eating -EPROBE_DEFER and failing the probe of the rocket device instead of deferring the probe.
> 
> Applying the below patch:
> 
> """
> diff --git a/drivers/accel/rocket/rocket_core.c b/drivers/accel/rocket/rocket_core.c
> index abe7719c1db46..c4692189bbfc6 100644
> --- a/drivers/accel/rocket/rocket_core.c
> +++ b/drivers/accel/rocket/rocket_core.c
> @@ -72,22 +72,9 @@ int rocket_core_init(struct rocket_core *core)
>       */
>      pm_runtime_set_autosuspend_delay(dev, 50);
> 
> +    pm_runtime_set_suspended(dev);
>      pm_runtime_enable(dev);
> 
> -    err = pm_runtime_resume_and_get(dev);
> -    if (err) {
> -        rocket_job_fini(core);
> -        return err;
> -    }
> -
> -    version = rocket_pc_readl(core, VERSION);
> -    version += rocket_pc_readl(core, VERSION_NUM) & 0xffff;
> -
> -    pm_runtime_mark_last_busy(dev);
> -    pm_runtime_put_autosuspend(dev);
> -
> -    dev_info(dev, "Rockchip NPU core %d version: %d\n", core->index, version);
> -
>      return 0;
>  }
> 
> """
> 
> seems to make it possible to run mesa's example. If pm_runtime_set_suspended(dev); isn't added, we'll only ever get job timeouts.
> 
> Note that I'm pretty sure this isn't the proper way to do it but wanted to give some of my debugging attempts at that.
> 
> I'm not sure how much further I can go and specifically I have no clue how to handle that properly. Please also verify all the claims I'm making, I'm not entirely sure I got every call stack right, it is quite convoluted and I don't have experience with those frameworks.
> 
> Does anyone have a clue how we can deal with that?
> 
> The driver built as a module doesn't have this issue because the regulator has enough time to probe so that PD doesn't return EPROBE_DEFER when the rocket device gets probed once reaching userspace (where the module is). I'm not entirely sure if this could be reproduced by having the regulator driver as a module too for example?
> 
> Cheers,
> Quentin
> 
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip

-- 
Best, 
Chaoyi


From cassel at kernel.org  Sun Nov 30 22:36:35 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Mon,  1 Dec 2025 07:36:35 +0100
Subject: [PATCH v2] PCI: dwc: Make Link Up IRQ logic handle already powered on PCIe switches
Message-ID: <20251201063634.4115762-2-cassel@kernel.org>

The DWC glue drivers always call pci_host_probe() during probe(), which
will allocate upstream bridge resources and enumerate the bus.

For controllers without Link Up IRQ support, pci_host_probe() is called
after dw_pcie_wait_for_link(), which will also wait the time required by
the PCIe specification before performing PCI Configuration Space reads.

For controllers with Link Up IRQ support, the pci_host_probe() call (which
will perform PCI Configuration Space reads) is done without any of the
delays mandated by the PCIe specification.

For controllers with Link Up IRQ support, since the pci_host_probe() call
is done without any delay (link training might still be ongoing), it is
very unlikely that this scan will find any devices. Once the Link Up IRQ
triggers, the Link Up IRQ handler will call pci_rescan_bus().

This works fine for PCIe endpoints connected to the Root Port, since they
don't extend the bus. However, if the pci_rescan_bus() call detects a PCIe
switch, then there will be a problem when the downstream busses starts
showing up, because the PCIe controller is not hotplug capable, so we are
not allowed to extend the subordinate bus number after the initial scan,
resulting in error messages such as:

pci_bus 0004:43: busn_res: can not insert [bus 43-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci_bus 0004:43: busn_res: [bus 43-41] end is updated to 43
pci_bus 0004:43: busn_res: can not insert [bus 43] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci 0004:42:00.0: devices behind bridge are unusable because [bus 43] cannot be assigned for them
pci_bus 0004:44: busn_res: can not insert [bus 44-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci_bus 0004:44: busn_res: [bus 44-41] end is updated to 44
pci_bus 0004:44: busn_res: can not insert [bus 44] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci 0004:42:02.0: devices behind bridge are unusable because [bus 44] cannot be assigned for them
pci_bus 0004:45: busn_res: can not insert [bus 45-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci_bus 0004:45: busn_res: [bus 45-41] end is updated to 45
pci_bus 0004:45: busn_res: can not insert [bus 45] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci 0004:42:06.0: devices behind bridge are unusable because [bus 45] cannot be assigned for them
pci_bus 0004:46: busn_res: can not insert [bus 46-41] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci_bus 0004:46: busn_res: [bus 46-41] end is updated to 46
pci_bus 0004:46: busn_res: can not insert [bus 46] under [bus 42-41] (conflicts with (null) [bus 42-41])
pci 0004:42:0e.0: devices behind bridge are unusable because [bus 46] cannot be assigned for them
pci_bus 0004:42: busn_res: [bus 42-41] end is updated to 46
pci_bus 0004:42: busn_res: can not insert [bus 42-46] under [bus 41] (conflicts with (null) [bus 41])
pci 0004:41:00.0: devices behind bridge are unusable because [bus 42-46] cannot be assigned for them
pcieport 0004:40:00.0: bridge has subordinate 41 but max busn 46

While we would like to set the is_hotplug_bridge flag
(quirk_hotplug_bridge()), many embedded SoCs that use the DWC controller
have synthesized the controller without hot-plug support.
Thus, the Link Up IRQ logic is only mimicking hot-plug functionality, i.e.
it is not compliant with the PCI Hot-Plug Specification, so we cannot make
use of the is_hotplug_bridge flag.

In order to let the Link Up IRQ logic handle PCIe switches that are already
powered on (PCIe switches that not powered on already need to implement a
pwrctrl driver), don't perform a pci_host_probe() call during probe()
(which disregards the delays required by the PCIe specification).

Instead let the first Link Up IRQ call pci_host_probe(). Any follow up
Link Up IRQ will call pci_rescan_bus().

The IRQ name in /proc/interrupts for the pcie-qcom driver is renamed in
order to not dereference pp->bridge->bus before it has been assigned.

Fixes: ec9fd499b9c6 ("PCI: dw-rockchip: Don't wait for link since we can detect Link Up")
Fixes: 0e0b45ab5d77 ("PCI: dw-rockchip: Enumerate endpoints based on dll_link_up IRQ")
Reported-by: FUKAUMI Naoki <naoki at radxa.com>
Closes: https://lore.kernel.org/linux-pci/1E8E4DB773970CB5+5a52c9e1-01b8-4872-99b7-021099f04031 at radxa.com/
Signed-off-by: Niklas Cassel <cassel at kernel.org>
---
Changes since v1:
-Rename the IRQ on pcie-qcom to not depend on pp->bridge->bus (Mani)
-Make sure that ret is initialized in dw_pcie_host_init() error path (Dan)

 .../pci/controller/dwc/pcie-designware-host.c | 71 ++++++++++++++++---
 drivers/pci/controller/dwc/pcie-designware.h  |  5 ++
 drivers/pci/controller/dwc/pcie-dw-rockchip.c |  5 +-
 drivers/pci/controller/dwc/pcie-qcom.c        |  9 +--
 4 files changed, 71 insertions(+), 19 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index e92513c5bda51..bed7b309f6d9e 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -565,6 +565,59 @@ static int dw_pcie_host_get_resources(struct dw_pcie_rp *pp)
 	return 0;
 }
 
+static int dw_pcie_host_initial_scan(struct dw_pcie_rp *pp)
+{
+	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+	struct pci_host_bridge *bridge = pp->bridge;
+	int ret;
+
+	ret = pci_host_probe(bridge);
+	if (ret)
+		return ret;
+
+	if (pp->ops->post_init)
+		pp->ops->post_init(pp);
+
+	dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
+
+	return 0;
+}
+
+void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp)
+{
+	if (!pp->initial_linkup_irq_done) {
+		int ret;
+
+		ret = dw_pcie_host_initial_scan(pp);
+		if (ret) {
+			struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+			struct device *dev = pci->dev;
+
+			dev_err(dev, "Initial scan from IRQ failed: %d\n", ret);
+
+			dw_pcie_stop_link(pci);
+
+			dw_pcie_edma_remove(pci);
+
+			if (pp->has_msi_ctrl)
+				dw_pcie_free_msi(pp);
+
+			if (pp->ops->deinit)
+				pp->ops->deinit(pp);
+
+			if (pp->cfg)
+				pci_ecam_free(pp->cfg);
+		} else {
+			pp->initial_linkup_irq_done = true;
+		}
+	} else {
+		/* Rescan the bus to enumerate endpoint devices */
+		pci_lock_rescan_remove();
+		pci_rescan_bus(pp->bridge->bus);
+		pci_unlock_rescan_remove();
+	}
+}
+
 int dw_pcie_host_init(struct dw_pcie_rp *pp)
 {
 	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
@@ -669,18 +722,18 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
 	 * If there is no Link Up IRQ, we should not bypass the delay
 	 * because that would require users to manually rescan for devices.
 	 */
-	if (!pp->use_linkup_irq)
+	if (!pp->use_linkup_irq) {
 		/* Ignore errors, the link may come up later */
 		dw_pcie_wait_for_link(pci);
 
-	ret = pci_host_probe(bridge);
-	if (ret)
-		goto err_stop_link;
-
-	if (pp->ops->post_init)
-		pp->ops->post_init(pp);
-
-	dwc_pcie_debugfs_init(pci, DW_PCIE_RC_TYPE);
+		/*
+		 * For platforms with Link Up IRQ, initial scan will be done
+		 * on first Link Up IRQ.
+		 */
+		ret = dw_pcie_host_initial_scan(pp);
+		if (ret)
+			goto err_stop_link;
+	}
 
 	return 0;
 
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index e995f692a1ecd..a31bd93490dcd 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -427,6 +427,7 @@ struct dw_pcie_rp {
 	int			msg_atu_index;
 	struct resource		*msg_res;
 	bool			use_linkup_irq;
+	bool			initial_linkup_irq_done;
 	struct pci_eq_presets	presets;
 	struct pci_config_window *cfg;
 	bool			ecam_enabled;
@@ -807,6 +808,7 @@ void dw_pcie_msi_init(struct dw_pcie_rp *pp);
 int dw_pcie_msi_host_init(struct dw_pcie_rp *pp);
 void dw_pcie_free_msi(struct dw_pcie_rp *pp);
 int dw_pcie_setup_rc(struct dw_pcie_rp *pp);
+void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp);
 int dw_pcie_host_init(struct dw_pcie_rp *pp);
 void dw_pcie_host_deinit(struct dw_pcie_rp *pp);
 int dw_pcie_allocate_domains(struct dw_pcie_rp *pp);
@@ -844,6 +846,9 @@ static inline int dw_pcie_setup_rc(struct dw_pcie_rp *pp)
 	return 0;
 }
 
+static inline void dw_pcie_handle_link_up_irq(struct dw_pcie_rp *pp)
+{ }
+
 static inline int dw_pcie_host_init(struct dw_pcie_rp *pp)
 {
 	return 0;
diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
index 3e2752c7dd096..8f2cc1ef25e3d 100644
--- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c
+++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c
@@ -466,10 +466,7 @@ static irqreturn_t rockchip_pcie_rc_sys_irq_thread(int irq, void *arg)
 		if (rockchip_pcie_link_up(pci)) {
 			msleep(PCIE_RESET_CONFIG_WAIT_MS);
 			dev_dbg(dev, "Received Link up event. Starting enumeration!\n");
-			/* Rescan the bus to enumerate endpoint devices */
-			pci_lock_rescan_remove();
-			pci_rescan_bus(pp->bridge->bus);
-			pci_unlock_rescan_remove();
+			dw_pcie_handle_link_up_irq(pp);
 		}
 	}
 
diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index c48a20602d7fa..04f29cd8d8881 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -1617,10 +1617,7 @@ static irqreturn_t qcom_pcie_global_irq_thread(int irq, void *data)
 	if (FIELD_GET(PARF_INT_ALL_LINK_UP, status)) {
 		msleep(PCIE_RESET_CONFIG_WAIT_MS);
 		dev_dbg(dev, "Received Link up event. Starting enumeration!\n");
-		/* Rescan the bus to enumerate endpoint devices */
-		pci_lock_rescan_remove();
-		pci_rescan_bus(pp->bridge->bus);
-		pci_unlock_rescan_remove();
+		dw_pcie_handle_link_up_irq(pp);
 
 		qcom_pcie_icc_opp_update(pcie);
 	} else {
@@ -1937,8 +1934,8 @@ static int qcom_pcie_probe(struct platform_device *pdev)
 		goto err_phy_exit;
 	}
 
-	name = devm_kasprintf(dev, GFP_KERNEL, "qcom_pcie_global_irq%d",
-			      pci_domain_nr(pp->bridge->bus));
+	name = devm_kasprintf(dev, GFP_KERNEL, "qcom_pcie_global_irq_%pOFP",
+			      dev->of_node);
 	if (!name) {
 		ret = -ENOMEM;
 		goto err_host_deinit;
-- 
2.52.0



From cassel at kernel.org  Sun Nov 30 22:40:11 2025
From: cassel at kernel.org (Niklas Cassel)
Date: Mon, 1 Dec 2025 07:40:11 +0100
Subject: [PATCH v2] PCI: dwc: Make Link Up IRQ logic handle already
 powered on PCIe switches
In-Reply-To: <20251201063634.4115762-2-cassel@kernel.org>
References: <20251201063634.4115762-2-cassel@kernel.org>
Message-ID: <aS04Sx9YRPwPjPzc@ryzen>

Forgot to pick up tags from v1, adding them here so that e.g. b4 will pick
them up:

Tested-by: Shawn Lin <shawn.lin at rock-chips.com>
Tested-by: FUKAUMI Naoki <naoki at radxa.com>


From krzk at kernel.org  Sun Nov 30 23:55:11 2025
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 1 Dec 2025 08:55:11 +0100
Subject: [PATCH v2 1/2] dt-bindings: iommu: rockchip: Add support for
 multiple interface clocks
In-Reply-To: <20251128071322.92-2-kernel@airkyi.com>
References: <20251128071322.92-1-kernel@airkyi.com>
 <20251128071322.92-2-kernel@airkyi.com>
Message-ID: <96958186-0e46-4606-ae36-239112eb31ea@kernel.org>

On 28/11/2025 08:13, Chaoyi Chen wrote:
> From: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> 
> The iommu found on RK3576 NPU and RK3576 RKVDEC have 4 clock instead of
> 2 clock. Their clock names might differ, but I don't think that matters
> much.
> 
> Add support for them.
> 
> Signed-off-by: Chaoyi Chen <chaoyi.chen at rock-chips.com>
> ---
> 
> Changes in v2:
> - Rewrite dt binding.
> 
>  .../bindings/iommu/rockchip,iommu.yaml        | 52 ++++++++++++++++---
>  1 file changed, 46 insertions(+), 6 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/iommu/rockchip,iommu.yaml b/Documentation/devicetree/bindings/iommu/rockchip,iommu.yaml
> index 6ce41d11ff5e..dfa5e25476d9 100644
> --- a/Documentation/devicetree/bindings/iommu/rockchip,iommu.yaml
> +++ b/Documentation/devicetree/bindings/iommu/rockchip,iommu.yaml
> @@ -27,6 +27,8 @@ properties:
>            - enum:
>                - rockchip,rk3576-iommu
>                - rockchip,rk3588-iommu
> +              - rockchip,rk3576-npu-iommu
> +              - rockchip,rk3576-rkvdec-iommu
>            - const: rockchip,rk3568-iommu
>  
>    reg:
> @@ -42,14 +44,12 @@ properties:
>      minItems: 1
>  
>    clocks:
> -    items:
> -      - description: Core clock
> -      - description: Interface clock

These go to specific variant if:then.

> +    minItems: 2
> +    maxItems: 4
>  
>    clock-names:
> -    items:
> -      - const: aclk
> -      - const: iface
> +    minItems: 2
> +    maxItems: 4

So you just allow any names, like pink-pony.

No, define common list here. Actually same for clocks.

>  
>    "#iommu-cells":
>      const: 0
> @@ -64,6 +64,46 @@ properties:
>        Some mmu instances may produce unexpected results
>        when the reset operation is used.
>  
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - rockchip,rk3576-npu-iommu
> +              - rockchip,rk3576-rkvdec-iommu
> +    then:
> +      properties:
> +        clocks:
> +          minItems: 4
> +        clock-names:
> +          minItems: 4
> +  - if:
> +      properties:
> +        compatible:
> +          items:
> +            - const: rockchip,iommu
> +            - const: rockchip,rk3568-iommu
> +    then:
> +      properties:
> +        clocks:
> +          maxItems: 2

Why this is unspecific now? Please look at other examples how it is
done, e.g. Samsung clocks.


Best regards,
Krzysztof


