* Re: [PATCH v5 8/8] futex: Use runtime constants for __futex_hash() hot path
From: Peter Zijlstra @ 2026-07-01 7:57 UTC (permalink / raw)
To: K Prateek Nayak
Cc: Arnd Bergmann, Thomas Gleixner, Ingo Molnar,
Sebastian Andrzej Siewior, Borislav Petkov, Dave Hansen, x86,
Catalin Marinas, Will Deacon, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
Darren Hart, Davidlohr Bueso, André Almeida, linux-arch,
linux-kernel, Samuel Holland, Charlie Jenkins, linux-arm-kernel,
linux-riscv, linux-s390, H. Peter Anvin, Thomas Huth,
Sean Christopherson, Jisheng Zhang, Alexandre Ghiti,
Christian Borntraeger, Sven Schnelle
In-Reply-To: <20260630045531.3939-9-kprateek.nayak@amd.com>
On Tue, Jun 30, 2026 at 04:55:31AM +0000, K Prateek Nayak wrote:
> From: Peter Zijlstra <peterz@infradead.org>
>
> Runtime constify the read-only after init data __futex_shift(shift_32),
> __futex_mask(mask_32), and __futex_queues(ptr) used in __futex_hash()
> hot path to avoid referencing global variable.
>
> This also allows __futex_queues to be allocated dynamically to
> "nr_node_ids" slots instead of reserving config dependent MAX_NUMNODES
> (1 << CONFIG_NODES_SHIFT) worth of slots upfront.
>
> Runtime constants are initialized before their first access and
> runtime_const_init() provides necessary barrier to ensure subsequent
> accesses are not reordered against their initialization.
>
> No functional changes intended.
>
> [ prateek: Dynamically allocate __futex_queues, mark the global data
> __ro_after_init since they are constified after futex_init(). ]
>
> Link: https://patch.msgid.link/20260227161841.GH606826@noisy.programming.kicks-ass.net
> Reported-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> # MAX_NUMNODES bloat
> Not-yet-signed-off-by: Peter Zijlstra <peterz@infradead.org>
> Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
The big $1M question: does it actually make it go faster? The whole
point here was performance, right? But I'm not seeing numbers showing
how awesome these patches are.
^ permalink raw reply
* Re: [PATCH v2 2/2] arm64: dts: rockchip: Fix devices suspend freeze on RK3568/RK3566
From: Michael Riesch @ 2026-07-01 8:02 UTC (permalink / raw)
To: Jonas Karlman, Heiko Stuebner, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Peter Geis
Cc: Diederik de Haas, Greg Kroah-Hartman, devicetree, linux-rockchip,
linux-usb, linux-arm-kernel, linux-kernel
In-Reply-To: <20260624192726.781864-3-jonas@kwiboo.se>
Hi Jonas,
On 6/24/26 21:27, Jonas Karlman wrote:
> The EHCI/OHCI controller depends on clk_usbphy1_480m being enabled, or
> the system may freeze when registers are accessed, i.e. during suspend
> in ohci_suspend().
>
> Add the missing clk_usbphy1_480m clocks reference to EHCI/OHCI
> controllers to ensure the clock is enabled when ECHI/OHCI registers are
> accessed to prevent a system freeze.
>
> Fixes suspend pm_test issue with EHCI/OHCI devices due to the missing
> clk_usbphy1_480m reference and makes following pm_test modes work:
>
> echo N > /sys/module/printk/parameters/console_suspend
>
> echo devices > /sys/power/pm_test
> echo platform > /sys/power/pm_test
> echo processors > /sys/power/pm_test
> echo core > /sys/power/pm_test
>
> echo mem > /sys/power/state
>
> Fixes: 91c4c3e06a25 ("arm64: dts: rockchip: add usb2 nodes to rk3568 device tree")
> Fixes: 78f7186095db ("arm64: dts: rockchip: rename and sort the rk356x usb2 phy handles")
> Tested-by: Diederik de Haas <diederik@cknow-tech.com>
> Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
Acked-by: Michael Riesch <michael.riesch@collabora.com>
Thanks and best regards,
Michael
> ---
> v2: Collect t-b tag
> ---
> arch/arm64/boot/dts/rockchip/rk356x-base.dtsi | 16 ++++++++--------
> 1 file changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
> index a5832895bd39..c930a6fd6ea0 100644
> --- a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
> @@ -321,44 +321,44 @@ its: msi-controller@fd440000 {
> };
>
> usb_host0_ehci: usb@fd800000 {
> - compatible = "generic-ehci";
> + compatible = "rockchip,rk3568-ehci", "generic-ehci";
> reg = <0x0 0xfd800000 0x0 0x40000>;
> interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
> clocks = <&cru HCLK_USB2HOST0>, <&cru HCLK_USB2HOST0_ARB>,
> - <&cru PCLK_USB>;
> + <&cru PCLK_USB>, <&usb2phy1>;
> phys = <&usb2phy1_otg>;
> phy-names = "usb";
> status = "disabled";
> };
>
> usb_host0_ohci: usb@fd840000 {
> - compatible = "generic-ohci";
> + compatible = "rockchip,rk3568-ohci", "generic-ohci";
> reg = <0x0 0xfd840000 0x0 0x40000>;
> interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
> clocks = <&cru HCLK_USB2HOST0>, <&cru HCLK_USB2HOST0_ARB>,
> - <&cru PCLK_USB>;
> + <&cru PCLK_USB>, <&usb2phy1>;
> phys = <&usb2phy1_otg>;
> phy-names = "usb";
> status = "disabled";
> };
>
> usb_host1_ehci: usb@fd880000 {
> - compatible = "generic-ehci";
> + compatible = "rockchip,rk3568-ehci", "generic-ehci";
> reg = <0x0 0xfd880000 0x0 0x40000>;
> interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
> clocks = <&cru HCLK_USB2HOST1>, <&cru HCLK_USB2HOST1_ARB>,
> - <&cru PCLK_USB>;
> + <&cru PCLK_USB>, <&usb2phy1>;
> phys = <&usb2phy1_host>;
> phy-names = "usb";
> status = "disabled";
> };
>
> usb_host1_ohci: usb@fd8c0000 {
> - compatible = "generic-ohci";
> + compatible = "rockchip,rk3568-ohci", "generic-ohci";
> reg = <0x0 0xfd8c0000 0x0 0x40000>;
> interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>;
> clocks = <&cru HCLK_USB2HOST1>, <&cru HCLK_USB2HOST1_ARB>,
> - <&cru PCLK_USB>;
> + <&cru PCLK_USB>, <&usb2phy1>;
> phys = <&usb2phy1_host>;
> phy-names = "usb";
> status = "disabled";
^ permalink raw reply
* [PATCH net-next v7 0/3] airoha: add the capability to configure GDM3/GDM4 as WAN/LAN on demand
From: Lorenzo Bianconi @ 2026-07-01 8:09 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Lorenzo Bianconi
Cc: Simon Horman, Alexander Lobakin, linux-arm-kernel, linux-mediatek,
netdev, Madhur Agrawal
Add the capability to configure GDM3/GDM4 as WAN/LAN on demand when QoS
offload is created or destroyed.
Make dev->qdma an RCU pointer so the TX path can safely dereference it
without holding RTNL.
Introduce airoha_qdma_start() and airoha_qdma_stop() helpers.
---
Changes in v7:
- Fix ETS stats accounting in patch 2/3
- Reset ETS stats accounting in airoha_dev_set_qdma().
- Link to v6: https://lore.kernel.org/r/20260629-airoha-ethtool-priv_flags-v6-0-86bc600d31bc@kernel.org
Changes in v6:
- Rebase on top of next-next
- Add patch 1/3: "rename airoha_priv_flags to airoha_dev_flags"
- Drop patch 2/3: "refactor QDMA start/stop into reusable helpers"
- Link to v5: https://lore.kernel.org/r/20260611-airoha-ethtool-priv_flags-v5-0-c11de08486d1@kernel.org
Changes in v5:
- Add patch 1/3: use int instead of atomic_t for qdma users counter
- Protect dev->flags with flow_offload_mutex mutex.
- Introduce AIROHA_PRIV_F_QOS in order to handle better WAN/LAN
switching.
- Link to v4: https://lore.kernel.org/r/20260610-airoha-ethtool-priv_flags-v4-0-60e89cf28fea@kernel.org
Changes in v4:
- Move back QDMA TX/RX DMA enable to airoha_dev_open()/airoha_dev_stop().
- Configure GDM3/4 as WAN if GDM2 is not available in ndo_init()
callback.
- Protect qdma pointer in airoha_gdm_dev struct using RCU.
- Rely on rtnl_dereference() to access qdma pointer in the control path.
- Add airoha_qdma_start() and airoha_qdma_stop() utility routines in
patch 1/2
- Link to v3: https://lore.kernel.org/r/20260608-airoha-ethtool-priv_flags-v3-1-3e8e3dc3f715@kernel.org
Changes in v3:
- Do not introduce ethtool private flags support to configure LAN/WAN
for GDM3/4 and rely on tc qdisc offload for it instead.
- Set GDM3/4 ports as LAN by default.
- Move QDMA TX/RX DMA enable from airoha_dev_open() to airoha_probe()
and the corresponding disable from airoha_dev_stop() to airoha_qdma_cleanup().
- Link to v2: https://lore.kernel.org/r/20260607-airoha-ethtool-priv_flags-v2-1-742c7aa1e182@kernel.org
Changes in v2:
- Rework airoha_dev_set_wan_flag routine
- Enable GDM_STRIP_CRC_MASK in airoha_disable_gdm2_loopback()
- Do not always reset REG_SRC_PORT_FC_MAP6 in
airoha_disable_gdm2_loopback() but use the same condition used in
airoha_enable_gdm2_loopback().
- Link to v1: https://lore.kernel.org/r/20260606-airoha-ethtool-priv_flags-v1-1-401b2c9fe9f1@kernel.org
---
Lorenzo Bianconi (3):
net: airoha: rename airoha_priv_flags to airoha_dev_flags
net: airoha: fix ETS QoS stats counter underflow and cross-channel corruption
net: airoha: defer GDM3/GDM4 WAN mode and GDM2 loopback to QoS offload
drivers/net/ethernet/airoha/airoha_eth.c | 239 ++++++++++++++++++++++++++----
drivers/net/ethernet/airoha/airoha_eth.h | 26 +++-
drivers/net/ethernet/airoha/airoha_ppe.c | 9 +-
drivers/net/ethernet/airoha/airoha_regs.h | 1 +
4 files changed, 233 insertions(+), 42 deletions(-)
---
base-commit: 1c664ec4b9ea827b609d296921ed5bad8a40a158
change-id: 20260606-airoha-ethtool-priv_flags-b6aa70caa780
Best regards,
--
Lorenzo Bianconi <lorenzo@kernel.org>
^ permalink raw reply
* [PATCH net-next v7 1/3] net: airoha: rename airoha_priv_flags to airoha_dev_flags
From: Lorenzo Bianconi @ 2026-07-01 8:09 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Lorenzo Bianconi
Cc: Simon Horman, Alexander Lobakin, linux-arm-kernel, linux-mediatek,
netdev
In-Reply-To: <20260701-airoha-ethtool-priv_flags-v7-0-b4153bd44428@kernel.org>
Rename the airoha_priv_flags enum to airoha_dev_flags and the
AIROHA_PRIV_F_WAN flag to AIROHA_DEV_F_WAN. The "priv_flags" naming
dates back to an earlier design that used ethtool private flags; since
this series switched to tc qdisc offload for LAN/WAN configuration,
align the naming to reflect that these are per-device flags rather than
ethtool private flags. No functional change.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 2 +-
drivers/net/ethernet/airoha/airoha_eth.h | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 932b3a3df2e5..8bba54ebcf07 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -2048,7 +2048,7 @@ static int airoha_dev_init(struct net_device *netdev)
fallthrough;
case AIROHA_GDM2_IDX:
/* GDM2 is always used as wan */
- dev->flags |= AIROHA_PRIV_F_WAN;
+ dev->flags |= AIROHA_DEV_F_WAN;
break;
default:
break;
diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
index d7ff8c5200e2..87ab3ea10664 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -535,8 +535,8 @@ struct airoha_qdma {
DECLARE_BITMAP(qos_channel_map, AIROHA_NUM_QOS_CHANNELS);
};
-enum airoha_priv_flags {
- AIROHA_PRIV_F_WAN = BIT(0),
+enum airoha_dev_flags {
+ AIROHA_DEV_F_WAN = BIT(0),
};
struct airoha_gdm_dev {
@@ -659,7 +659,7 @@ static inline u16 airoha_qdma_get_txq(struct airoha_qdma *qdma, u16 qid)
static inline bool airoha_is_lan_gdm_dev(struct airoha_gdm_dev *dev)
{
- return !(dev->flags & AIROHA_PRIV_F_WAN);
+ return !(dev->flags & AIROHA_DEV_F_WAN);
}
static inline bool airoha_is_7581(struct airoha_eth *eth)
--
2.54.0
^ permalink raw reply related
* [PATCH net-next v7 2/3] net: airoha: fix ETS QoS stats counter underflow and cross-channel corruption
From: Lorenzo Bianconi @ 2026-07-01 8:09 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Lorenzo Bianconi
Cc: Simon Horman, Alexander Lobakin, linux-arm-kernel, linux-mediatek,
netdev
In-Reply-To: <20260701-airoha-ethtool-priv_flags-v7-0-b4153bd44428@kernel.org>
airoha_qdma_get_tx_ets_stats() has two bugs:
- The hardware counters read via airoha_qdma_rr() are 32-bit values
but are stored in u64 locals and subtracted from u64 baselines. When
a 32-bit hardware counter wraps around, the subtraction produces a
large underflow value passed to _bstats_update().
- The baseline counters (cpu_tx_packets, fwd_tx_packets) are stored as
single per-device fields, but airoha_qdma_get_tx_ets_stats() is
called with different channel values (0-3). Each call reads a
different channel's hardware counter but overwrites the same
baseline, corrupting the delta computation for other channels.
Fix both by:
- Narrowing the counter locals and baselines to u32 so that 32-bit
unsigned subtraction handles wrap-around naturally.
- Grouping the baselines into a per-channel qos_stats array so each
channel tracks its own previous counter value independently.
Fixes: 20bf7d07c956 ("net: airoha: Add sched ETS offload support")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 18 +++++++++++-------
drivers/net/ethernet/airoha/airoha_eth.h | 7 ++++---
2 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 8bba54ebcf07..2c9ceb9f16f8 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -2491,16 +2491,20 @@ static int airoha_qdma_get_tx_ets_stats(struct net_device *netdev, int channel,
{
struct airoha_gdm_dev *dev = netdev_priv(netdev);
struct airoha_qdma *qdma = dev->qdma;
+ u32 cpu_tx_packets, fwd_tx_packets;
+ u64 tx_packets;
- u64 cpu_tx_packets = airoha_qdma_rr(qdma, REG_CNTR_VAL(channel << 1));
- u64 fwd_tx_packets = airoha_qdma_rr(qdma,
- REG_CNTR_VAL((channel << 1) + 1));
- u64 tx_packets = (cpu_tx_packets - dev->cpu_tx_packets) +
- (fwd_tx_packets - dev->fwd_tx_packets);
+ cpu_tx_packets = airoha_qdma_rr(qdma, REG_CNTR_VAL(channel << 1));
+ fwd_tx_packets = airoha_qdma_rr(qdma,
+ REG_CNTR_VAL((channel << 1) + 1));
+ tx_packets = (u32)(cpu_tx_packets -
+ dev->qos_stats[channel].cpu_tx_packets) +
+ (u32)(fwd_tx_packets -
+ dev->qos_stats[channel].fwd_tx_packets);
_bstats_update(opt->stats.bstats, 0, tx_packets);
- dev->cpu_tx_packets = cpu_tx_packets;
- dev->fwd_tx_packets = fwd_tx_packets;
+ dev->qos_stats[channel].cpu_tx_packets = cpu_tx_packets;
+ dev->qos_stats[channel].fwd_tx_packets = fwd_tx_packets;
return 0;
}
diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
index 87ab3ea10664..ac5f571f3e53 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -545,9 +545,10 @@ struct airoha_gdm_dev {
struct airoha_eth *eth;
DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS);
- /* qos stats counters */
- u64 cpu_tx_packets;
- u64 fwd_tx_packets;
+ struct {
+ u32 cpu_tx_packets;
+ u32 fwd_tx_packets;
+ } qos_stats[AIROHA_NUM_QOS_CHANNELS];
u32 flags;
int nbq;
--
2.54.0
^ permalink raw reply related
* [PATCH net-next v7 3/3] net: airoha: defer GDM3/GDM4 WAN mode and GDM2 loopback to QoS offload
From: Lorenzo Bianconi @ 2026-07-01 8:09 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Lorenzo Bianconi
Cc: Simon Horman, Alexander Lobakin, linux-arm-kernel, linux-mediatek,
netdev, Madhur Agrawal
In-Reply-To: <20260701-airoha-ethtool-priv_flags-v7-0-b4153bd44428@kernel.org>
GDM3 and GDM4 ports require GDM2 loopback to be enabled for hardware
QoS offload to function. Without it, HTB and ETS offload on these ports
do not work.
Previously, GDM3/GDM4 ports were automatically configured as WAN with
GDM2 loopback enabled during ndo_init(). Add the capability to configure
GDM3/GDM4 as WAN/LAN on demand when QoS offload is created or destroyed.
Hook airoha_enable_qos_for_gdm34() into TC_HTB_CREATE so that requesting
HTB offload on a GDM3/GDM4 LAN port switches it to WAN mode and enables
GDM2 loopback, with proper rollback on failure. Introduce the
AIROHA_DEV_F_QOS flag to track whether a device has an active HTB
qdisc; clear it on TC_HTB_DESTROY. The device keeps its WAN role after
qdisc teardown so that its configuration is preserved until another
device explicitly needs the WAN role for QoS offload.
If another GDM3/GDM4 device already holds the WAN role without an active
QoS qdisc, demote it to LAN before promoting the requesting device. Skip
the demotion when the requesting device is itself already the WAN device.
Since airoha_dev_set_qdma() can now be called on a running device to
migrate between QDMA blocks, make dev->qdma an RCU pointer so the TX
path can safely dereference it without holding RTNL.
Hold flow_offload_mutex in airoha_enable_qos_for_gdm34() and
airoha_disable_qos_for_gdm34() around the dev->flags update,
airoha_dev_set_qdma() and GDM2 loopback configuration, serializing
against concurrent airoha_ppe_hw_init() in the TC_SETUP_CLSFLOWER
offload path.
Introduce airoha_qdma_deref() helper that wraps rcu_dereference_protected()
with a lockdep condition accepting either rtnl_lock or flow_offload_mutex,
and use it across all control-path dereferences of the RCU-protected
dev->qdma pointer.
Add airoha_disable_gdm2_loopback() to disable GDM2 hw loopback.
Tested-by: Madhur Agrawal <madhur.agrawal@airoha.com>
Reviewed-by: Alexander Lobakin <aleksander.lobakin@intel.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 219 ++++++++++++++++++++++++++----
drivers/net/ethernet/airoha/airoha_eth.h | 13 +-
drivers/net/ethernet/airoha/airoha_ppe.c | 9 +-
drivers/net/ethernet/airoha/airoha_regs.h | 1 +
4 files changed, 214 insertions(+), 28 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 2c9ceb9f16f8..609a5ea67fb7 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -929,7 +929,7 @@ static void airoha_qdma_wake_netdev_txqs(struct airoha_queue *q)
if (!dev)
continue;
- if (dev->qdma != qdma)
+ if (rcu_access_pointer(dev->qdma) != qdma)
continue;
netdev = netdev_from_priv(dev);
@@ -1837,13 +1837,14 @@ static int airoha_dev_open(struct net_device *netdev)
struct airoha_gdm_dev *dev = netdev_priv(netdev);
struct airoha_gdm_port *port = dev->port;
u32 cur_len, pse_port = FE_PSE_PORT_PPE1;
- struct airoha_qdma *qdma = dev->qdma;
+ struct airoha_qdma *qdma;
netif_tx_start_all_queues(netdev);
err = airoha_set_vip_for_gdm_port(dev, true);
if (err)
return err;
+ qdma = airoha_qdma_deref(dev);
if (netdev_uses_dsa(netdev))
airoha_fe_set(qdma->eth, REG_GDM_INGRESS_CFG(port->id),
GDM_STAG_EN_MASK);
@@ -1903,7 +1904,6 @@ static int airoha_dev_stop(struct net_device *netdev)
{
struct airoha_gdm_dev *dev = netdev_priv(netdev);
struct airoha_gdm_port *port = dev->port;
- struct airoha_qdma *qdma = dev->qdma;
netif_tx_disable(netdev);
airoha_set_vip_for_gdm_port(dev, false);
@@ -1911,7 +1911,7 @@ static int airoha_dev_stop(struct net_device *netdev)
if (--port->users)
airoha_set_port_mtu(dev->eth, port);
else
- airoha_set_gdm_port_fwd_cfg(qdma->eth,
+ airoha_set_gdm_port_fwd_cfg(dev->eth,
REG_GDM_FWD_CFG(port->id),
FE_PSE_PORT_DROP);
return 0;
@@ -1998,6 +1998,53 @@ static int airoha_enable_gdm2_loopback(struct airoha_gdm_dev *dev)
return 0;
}
+static int airoha_disable_gdm2_loopback(struct airoha_gdm_dev *dev)
+{
+ struct airoha_gdm_port *port = dev->port;
+ struct airoha_eth *eth = dev->eth;
+ int i, src_port;
+ u32 pse_port;
+
+ src_port = eth->soc->ops.get_sport(dev->port, dev->nbq);
+ if (src_port < 0)
+ return src_port;
+
+ airoha_fe_clear(eth,
+ REG_SP_DFT_CPORT(src_port >> fls(SP_CPORT_DFT_MASK)),
+ SP_CPORT_MASK(src_port & SP_CPORT_DFT_MASK));
+
+ airoha_fe_set(eth, REG_GDM_FWD_CFG(AIROHA_GDM2_IDX),
+ GDM_STRIP_CRC_MASK);
+ airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(AIROHA_GDM2_IDX),
+ FE_PSE_PORT_DROP);
+ airoha_fe_clear(eth, REG_GDM_LPBK_CFG(AIROHA_GDM2_IDX),
+ LPBK_CHAN_MASK | LPBK_MODE_MASK | LPBK_EN_MASK);
+ pse_port = airoha_ppe_is_enabled(eth, 1) ? FE_PSE_PORT_PPE2
+ : FE_PSE_PORT_PPE1;
+ airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(AIROHA_GDM2_IDX),
+ pse_port);
+
+ airoha_fe_rmw(eth, REG_FE_WAN_PORT, WAN0_MASK,
+ FIELD_PREP(WAN0_MASK, AIROHA_GDM2_IDX));
+
+ for (i = 0; i < eth->soc->num_ppe; i++)
+ airoha_fe_clear(eth, REG_PPE_DFT_CPORT(i, AIROHA_GDM2_IDX),
+ DFT_CPORT_MASK(AIROHA_GDM2_IDX));
+
+ /* Enable VIP and IFC for GDM2 */
+ airoha_fe_set(eth, REG_FE_VIP_PORT_EN, BIT(AIROHA_GDM2_IDX));
+ airoha_fe_set(eth, REG_FE_IFC_PORT_EN, BIT(AIROHA_GDM2_IDX));
+
+ if (port->id == AIROHA_GDM4_IDX && airoha_is_7581(eth)) {
+ u32 mask = FC_ID_OF_SRC_PORT_MASK(dev->nbq);
+
+ airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6, mask,
+ FC_MAP6_DEF_VALUE & mask);
+ }
+
+ return 0;
+}
+
static struct airoha_gdm_dev *
airoha_get_wan_gdm_dev(struct airoha_eth *eth)
{
@@ -2024,15 +2071,26 @@ airoha_get_wan_gdm_dev(struct airoha_eth *eth)
static void airoha_dev_set_qdma(struct airoha_gdm_dev *dev)
{
struct net_device *netdev = netdev_from_priv(dev);
+ struct airoha_qdma *cur_qdma, *qdma;
struct airoha_eth *eth = dev->eth;
int ppe_id;
/* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */
- dev->qdma = ð->qdma[!airoha_is_lan_gdm_dev(dev)];
- netdev->irq = dev->qdma->irq_banks[0].irq;
+ qdma = ð->qdma[!airoha_is_lan_gdm_dev(dev)];
+ cur_qdma = airoha_qdma_deref(dev);
+
+ rcu_assign_pointer(dev->qdma, qdma);
+ netdev->irq = qdma->irq_banks[0].irq;
ppe_id = !airoha_is_lan_gdm_dev(dev) && airoha_ppe_is_enabled(eth, 1);
airoha_ppe_set_cpu_port(dev, ppe_id, airoha_get_fe_port(dev));
+
+ if (!cur_qdma)
+ return;
+
+ memset(dev->qos_stats, 0, sizeof(dev->qos_stats));
+ synchronize_rcu();
+ netif_tx_wake_all_queues(netdev);
}
static int airoha_dev_init(struct net_device *netdev)
@@ -2187,9 +2245,9 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
struct net_device *netdev)
{
struct airoha_gdm_dev *dev = netdev_priv(netdev);
- struct airoha_qdma *qdma = dev->qdma;
u32 nr_frags, tag, msg0, msg1, len;
struct airoha_queue_entry *e;
+ struct airoha_qdma *qdma;
struct netdev_queue *txq;
struct airoha_queue *q;
LIST_HEAD(tx_list);
@@ -2198,6 +2256,8 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
u16 index;
u8 fport;
+ rcu_read_lock();
+ qdma = rcu_dereference(dev->qdma);
qid = airoha_qdma_get_txq(qdma, skb_get_queue_mapping(skb));
tag = airoha_get_dsa_tag(skb, netdev);
@@ -2247,6 +2307,8 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
netif_tx_stop_queue(txq);
q->txq_stopped = true;
spin_unlock_bh(&q->lock);
+ rcu_read_unlock();
+
return NETDEV_TX_BUSY;
}
@@ -2309,6 +2371,7 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
FIELD_PREP(TX_RING_CPU_IDX_MASK, index));
spin_unlock_bh(&q->lock);
+ rcu_read_unlock();
return NETDEV_TX_OK;
@@ -2324,6 +2387,7 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
error:
dev_kfree_skb_any(skb);
netdev->stats.tx_dropped++;
+ rcu_read_unlock();
return NETDEV_TX_OK;
}
@@ -2403,17 +2467,19 @@ static int airoha_qdma_set_chan_tx_sched(struct net_device *netdev,
const u16 *weights, u8 n_weights)
{
struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_qdma *qdma;
int i;
+ qdma = airoha_qdma_deref(dev);
for (i = 0; i < AIROHA_NUM_QOS_QUEUES; i++)
- airoha_qdma_clear(dev->qdma, REG_QUEUE_CLOSE_CFG(channel),
+ airoha_qdma_clear(qdma, REG_QUEUE_CLOSE_CFG(channel),
TXQ_DISABLE_CHAN_QUEUE_MASK(channel, i));
for (i = 0; i < n_weights; i++) {
u32 status;
int err;
- airoha_qdma_wr(dev->qdma, REG_TXWRR_WEIGHT_CFG,
+ airoha_qdma_wr(qdma, REG_TXWRR_WEIGHT_CFG,
TWRR_RW_CMD_MASK |
FIELD_PREP(TWRR_CHAN_IDX_MASK, channel) |
FIELD_PREP(TWRR_QUEUE_IDX_MASK, i) |
@@ -2421,12 +2487,12 @@ static int airoha_qdma_set_chan_tx_sched(struct net_device *netdev,
err = read_poll_timeout(airoha_qdma_rr, status,
status & TWRR_RW_CMD_DONE,
USEC_PER_MSEC, 10 * USEC_PER_MSEC,
- true, dev->qdma, REG_TXWRR_WEIGHT_CFG);
+ true, qdma, REG_TXWRR_WEIGHT_CFG);
if (err)
return err;
}
- airoha_qdma_rmw(dev->qdma, REG_CHAN_QOS_MODE(channel >> 3),
+ airoha_qdma_rmw(qdma, REG_CHAN_QOS_MODE(channel >> 3),
CHAN_QOS_MODE_MASK(channel),
__field_prep(CHAN_QOS_MODE_MASK(channel), mode));
@@ -2490,10 +2556,11 @@ static int airoha_qdma_get_tx_ets_stats(struct net_device *netdev, int channel,
struct tc_ets_qopt_offload *opt)
{
struct airoha_gdm_dev *dev = netdev_priv(netdev);
- struct airoha_qdma *qdma = dev->qdma;
u32 cpu_tx_packets, fwd_tx_packets;
+ struct airoha_qdma *qdma;
u64 tx_packets;
+ qdma = airoha_qdma_deref(dev);
cpu_tx_packets = airoha_qdma_rr(qdma, REG_CNTR_VAL(channel << 1));
fwd_tx_packets = airoha_qdma_rr(qdma,
REG_CNTR_VAL((channel << 1) + 1));
@@ -2760,16 +2827,18 @@ static int airoha_qdma_set_tx_rate_limit(struct net_device *netdev,
u32 bucket_size)
{
struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_qdma *qdma;
int i, err;
+ qdma = airoha_qdma_deref(dev);
for (i = 0; i <= TRTCM_PEAK_MODE; i++) {
- err = airoha_qdma_set_trtcm_config(dev->qdma, channel,
+ err = airoha_qdma_set_trtcm_config(qdma, channel,
REG_EGRESS_TRTCM_CFG, i,
!!rate, TRTCM_METER_MODE);
if (err)
return err;
- err = airoha_qdma_set_trtcm_token_bucket(dev->qdma, channel,
+ err = airoha_qdma_set_trtcm_token_bucket(qdma, channel,
REG_EGRESS_TRTCM_CFG,
i, rate, bucket_size);
if (err)
@@ -2805,11 +2874,12 @@ static int airoha_tc_htb_alloc_leaf_queue(struct net_device *netdev,
u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
int err, num_tx_queues = AIROHA_NUM_TX_RING + channel + 1;
struct airoha_gdm_dev *dev = netdev_priv(netdev);
- struct airoha_qdma *qdma = dev->qdma;
+ struct airoha_qdma *qdma;
/* Here we need to check the requested QDMA channel is not already
* in use by another net_device running on the same QDMA block.
*/
+ qdma = airoha_qdma_deref(dev);
if (test_and_set_bit(channel, qdma->qos_channel_map)) {
NL_SET_ERR_MSG_MOD(opt->extack,
"qdma qos channel already in use");
@@ -2845,7 +2915,7 @@ static int airoha_qdma_set_rx_meter(struct airoha_gdm_dev *dev,
u32 rate, u32 bucket_size,
enum trtcm_unit_type unit_type)
{
- struct airoha_qdma *qdma = dev->qdma;
+ struct airoha_qdma *qdma = airoha_qdma_deref(dev);
int i;
for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
@@ -3020,10 +3090,11 @@ static void airoha_tc_remove_htb_queue(struct net_device *netdev, int queue)
{
struct airoha_gdm_dev *dev = netdev_priv(netdev);
int num_tx_queues = AIROHA_NUM_TX_RING;
- struct airoha_qdma *qdma = dev->qdma;
+ struct airoha_qdma *qdma;
airoha_qdma_set_tx_rate_limit(netdev, queue, 0, 0);
+ qdma = airoha_qdma_deref(dev);
clear_bit(queue, qdma->qos_channel_map);
clear_bit(queue, dev->qos_sq_bmap);
@@ -3049,6 +3120,95 @@ static int airoha_tc_htb_delete_leaf_queue(struct net_device *netdev,
return 0;
}
+static void airoha_disable_qos_for_gdm34(struct net_device *netdev)
+{
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
+ int err;
+
+ if (port->id != AIROHA_GDM3_IDX &&
+ port->id != AIROHA_GDM4_IDX)
+ return;
+
+ err = airoha_disable_gdm2_loopback(dev);
+ if (err)
+ netdev_warn(netdev,
+ "failed disabling GDM2 loopback: %d\n", err);
+
+ dev->flags &= ~AIROHA_DEV_F_WAN;
+ airoha_dev_set_qdma(dev);
+
+ airoha_set_macaddr(dev, netdev->dev_addr);
+ if (netif_running(netdev))
+ airoha_set_gdm_port_fwd_cfg(dev->eth,
+ REG_GDM_FWD_CFG(port->id),
+ FE_PSE_PORT_PPE1);
+}
+
+static int airoha_enable_qos_for_gdm34(struct net_device *netdev,
+ struct netlink_ext_ack *extack)
+{
+ struct airoha_gdm_dev *wan_dev, *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
+ struct airoha_eth *eth = dev->eth;
+ int err = -EBUSY;
+
+ if (port->id != AIROHA_GDM3_IDX &&
+ port->id != AIROHA_GDM4_IDX) {
+ /* HW QoS is always supported by GDM1 and GDM2 */
+ return 0;
+ }
+
+ if (!airoha_is_lan_gdm_dev(dev)) /* Already enabled */
+ return 0;
+
+ mutex_lock(&flow_offload_mutex);
+
+ wan_dev = airoha_get_wan_gdm_dev(eth);
+ if (wan_dev) {
+ if ((wan_dev->flags & AIROHA_DEV_F_QOS) ||
+ wan_dev->port->id == AIROHA_GDM2_IDX) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "QoS configured for WAN device");
+ goto error_unlock;
+ }
+ airoha_disable_qos_for_gdm34(netdev_from_priv(wan_dev));
+ }
+
+ dev->flags |= AIROHA_DEV_F_WAN;
+ airoha_dev_set_qdma(dev);
+ err = airoha_enable_gdm2_loopback(dev);
+ if (err)
+ goto error_disable_wan;
+
+ err = airoha_set_macaddr(dev, netdev->dev_addr);
+ if (err)
+ goto error_disable_loopback;
+
+ if (netif_running(netdev)) {
+ u32 pse_port;
+
+ pse_port = airoha_ppe_is_enabled(eth, 1) ? FE_PSE_PORT_PPE2
+ : FE_PSE_PORT_PPE1;
+ airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(port->id),
+ pse_port);
+ }
+
+ mutex_unlock(&flow_offload_mutex);
+
+ return 0;
+
+error_disable_loopback:
+ airoha_disable_gdm2_loopback(dev);
+error_disable_wan:
+ dev->flags &= ~AIROHA_DEV_F_WAN;
+ airoha_dev_set_qdma(dev);
+error_unlock:
+ mutex_unlock(&flow_offload_mutex);
+
+ return err;
+}
+
static int airoha_tc_htb_destroy(struct net_device *netdev)
{
struct airoha_gdm_dev *dev = netdev_priv(netdev);
@@ -3057,6 +3217,8 @@ static int airoha_tc_htb_destroy(struct net_device *netdev)
for_each_set_bit(q, dev->qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS)
airoha_tc_remove_htb_queue(netdev, q);
+ dev->flags &= ~AIROHA_DEV_F_QOS;
+
return 0;
}
@@ -3076,24 +3238,33 @@ static int airoha_tc_get_htb_get_leaf_queue(struct net_device *netdev,
return 0;
}
-static int airoha_tc_setup_qdisc_htb(struct net_device *dev,
+static int airoha_tc_setup_qdisc_htb(struct net_device *netdev,
struct tc_htb_qopt_offload *opt)
{
switch (opt->command) {
- case TC_HTB_CREATE:
+ case TC_HTB_CREATE: {
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ int err;
+
+ err = airoha_enable_qos_for_gdm34(netdev, opt->extack);
+ if (err)
+ return err;
+
+ dev->flags |= AIROHA_DEV_F_QOS;
break;
+ }
case TC_HTB_DESTROY:
- return airoha_tc_htb_destroy(dev);
+ return airoha_tc_htb_destroy(netdev);
case TC_HTB_NODE_MODIFY:
- return airoha_tc_htb_modify_queue(dev, opt);
+ return airoha_tc_htb_modify_queue(netdev, opt);
case TC_HTB_LEAF_ALLOC_QUEUE:
- return airoha_tc_htb_alloc_leaf_queue(dev, opt);
+ return airoha_tc_htb_alloc_leaf_queue(netdev, opt);
case TC_HTB_LEAF_DEL:
case TC_HTB_LEAF_DEL_LAST:
case TC_HTB_LEAF_DEL_LAST_FORCE:
- return airoha_tc_htb_delete_leaf_queue(dev, opt);
+ return airoha_tc_htb_delete_leaf_queue(netdev, opt);
case TC_HTB_LEAF_QUERY_QUEUE:
- return airoha_tc_get_htb_get_leaf_queue(dev, opt);
+ return airoha_tc_get_htb_get_leaf_queue(netdev, opt);
default:
return -EOPNOTSUPP;
}
diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
index ac5f571f3e53..a314330fcd48 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -537,11 +537,12 @@ struct airoha_qdma {
enum airoha_dev_flags {
AIROHA_DEV_F_WAN = BIT(0),
+ AIROHA_DEV_F_QOS = BIT(1),
};
struct airoha_gdm_dev {
+ struct airoha_qdma __rcu *qdma;
struct airoha_gdm_port *port;
- struct airoha_qdma *qdma;
struct airoha_eth *eth;
DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS);
@@ -677,6 +678,16 @@ int airoha_get_fe_port(struct airoha_gdm_dev *dev);
bool airoha_is_valid_gdm_dev(struct airoha_eth *eth,
struct airoha_gdm_dev *dev);
+extern struct mutex flow_offload_mutex;
+
+static inline struct airoha_qdma *
+airoha_qdma_deref(struct airoha_gdm_dev *dev)
+{
+ return rcu_dereference_protected(dev->qdma,
+ lockdep_rtnl_is_held() ||
+ lockdep_is_held(&flow_offload_mutex));
+}
+
void airoha_ppe_set_cpu_port(struct airoha_gdm_dev *dev, u8 ppe_id, u8 fport);
bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index);
void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb,
diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
index 42f4b0f21d17..0f260c50ac3c 100644
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
@@ -15,7 +15,10 @@
#include "airoha_regs.h"
#include "airoha_eth.h"
-static DEFINE_MUTEX(flow_offload_mutex);
+/* Serialize airoha_gdm_dev flags, QDMA pointer and PPE CPU port
+ * configuration.
+ */
+DEFINE_MUTEX(flow_offload_mutex);
static DEFINE_SPINLOCK(ppe_lock);
static const struct rhashtable_params airoha_flow_table_params = {
@@ -86,8 +89,8 @@ static u32 airoha_ppe_get_timestamp(struct airoha_ppe *ppe)
void airoha_ppe_set_cpu_port(struct airoha_gdm_dev *dev, u8 ppe_id, u8 fport)
{
- struct airoha_qdma *qdma = dev->qdma;
- struct airoha_eth *eth = qdma->eth;
+ struct airoha_qdma *qdma = airoha_qdma_deref(dev);
+ struct airoha_eth *eth = dev->eth;
u8 qdma_id = qdma - ð->qdma[0];
u32 fe_cpu_port;
diff --git a/drivers/net/ethernet/airoha/airoha_regs.h b/drivers/net/ethernet/airoha/airoha_regs.h
index 436f3c8779c1..4e17dfbcf2b8 100644
--- a/drivers/net/ethernet/airoha/airoha_regs.h
+++ b/drivers/net/ethernet/airoha/airoha_regs.h
@@ -376,6 +376,7 @@
#define REG_SRC_PORT_FC_MAP6 0x2298
#define FC_ID_OF_SRC_PORT_MASK(_n) GENMASK(4 + ((_n) << 3), ((_n) << 3))
+#define FC_MAP6_DEF_VALUE 0x1b1a1918
#define REG_CDM5_RX_OQ1_DROP_CNT 0x29d4
--
2.54.0
^ permalink raw reply related
* Re: [PATCH v5] dmaengine: sun6i-dma: Fix reclaim descriptors while terminating DMA
From: Vinod Koul @ 2026-07-01 8:17 UTC (permalink / raw)
To: Hongling Zeng
Cc: Frank.Li, wens, jernej.skrabec, samuel, mripard, arnd, dmaengine,
linux-arm-kernel, linux-sunxi, linux-kernel, zhongling0719,
Frank Li, Frank Li
In-Reply-To: <20260701045733.33654-1-zenghongling@kylinos.cn>
On 01-07-26, 12:57, Hongling Zeng wrote:
> When terminating DMA transfers, active descriptors are not properly
> reclaimed. Only cyclic descriptors were handled, leaving non-cyclic
> descriptors and their LLI chains to be permanently leaked.
>
> Fix by using vchan_terminate_vdesc() which handles both cyclic and
> non-cyclic descriptors by adding them to desc_terminated queue for
> proper cleanup.
>
> Add pchan->desc != pchan->done check to prevent double-adding completed
> descriptors, which would corrupt the list.
You should run checkpatch to fix the formatting issues.
ERROR: trailing whitespace
#65: FILE: drivers/dma/sun6i-dma.c:95
For now, I have fixed and applied
--
~Vinod
^ permalink raw reply
* [PATCH v6 1/1] arm64: dts: add tqma9596la-mba95xxca
From: Alexander Stein @ 2026-07-01 8:26 UTC (permalink / raw)
To: Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm
Cc: Markus Niebel, imx, linux-arm-kernel, devicetree, linux-kernel,
linux, linux-renesas-soc, Alexander Stein
From: Markus Niebel <Markus.Niebel@ew.tq-group.com>
This adds support for TQMa95xxLA modules, designed to be soldered
on a carrier board. MBa95xxCA is a carrier reference board / starter kit
design.
There is a common device tree for all variants with e.g. reduced
CPU core / feature count.
Enable the external accessible PCIe controllers as host,
add clocking and reset GPIO. While at it, add hogs for GPIO
lines from the M.2 slots until M.2 connector driver is available.
Signed-off-by: Markus Niebel <Markus.Niebel@ew.tq-group.com>
Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
---
Changes in v6:
* Remove spi-max-frequency from SPI controller (only device property)
* Add comment about maximum speed instead
* Sort I2C devices per address
* Fix clock-names for enetc_port2
* Fix vcc-supply for GPIO expander
* Fix typo for M2_KEYB_WDISABLE2#
* Fix typo in pinxtrl groups
* Add comment about vendor-specific pins for GPIO hogs on PCIe M.2 E-Key
Changes in v5:
* Limit LPSPI4 max frequency
* Replace PCIe M2 Key-E GPIO hogs with dedicated connector node
* Fix PCIe clock configuration
Changes in v4:
* Fix LPSPI4 pad muxing and control
Changes in v3:
* Moved reserved-memory to board-lebel
* Remove VPU reserved memory (unused for now)
* Fix typo in connector comment
Changes in v2:
* removed useless regulator
* added USB PD source configuration
* Removed unused uart-has-rtscts properties (unused by LPUART)
* Fixed RTS/CTS pullups in pinctrl
* Added thermalzone on module
arch/arm64/boot/dts/freescale/Makefile | 1 +
.../freescale/imx95-tqma9596la-mba95xxca.dts | 963 ++++++++++++++++++
.../boot/dts/freescale/imx95-tqma9596la.dtsi | 278 +++++
3 files changed, 1242 insertions(+)
create mode 100644 arch/arm64/boot/dts/freescale/imx95-tqma9596la-mba95xxca.dts
create mode 100644 arch/arm64/boot/dts/freescale/imx95-tqma9596la.dtsi
diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 8ddaab127ab9c..43e1dc51b11d7 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -649,6 +649,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx95-19x19-frdm-pro.dtb
dtb-$(CONFIG_ARCH_MXC) += imx95-aquila-clover.dtb
dtb-$(CONFIG_ARCH_MXC) += imx95-aquila-dev.dtb
dtb-$(CONFIG_ARCH_MXC) += imx95-toradex-smarc-dev.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx95-tqma9596la-mba95xxca.dtb
dtb-$(CONFIG_ARCH_MXC) += imx95-tqma9596sa-mb-smarc-2.dtb
dtb-$(CONFIG_ARCH_MXC) += imx95-var-dart-sonata.dtb
dtb-$(CONFIG_ARCH_MXC) += imx95-verdin-nonwifi-dahlia.dtb
diff --git a/arch/arm64/boot/dts/freescale/imx95-tqma9596la-mba95xxca.dts b/arch/arm64/boot/dts/freescale/imx95-tqma9596la-mba95xxca.dts
new file mode 100644
index 0000000000000..e90f37bbdcd80
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx95-tqma9596la-mba95xxca.dts
@@ -0,0 +1,963 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+/*
+ * Copyright (c) 2024-2026 TQ-Systems GmbH <linux@ew.tq-group.com>,
+ * D-82229 Seefeld, Germany.
+ * Author: Alexander Stein
+ * Author: Markus Niebel
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/net/ti-dp83867.h>
+#include <dt-bindings/pwm/pwm.h>
+#include <dt-bindings/usb/pd.h>
+#include "imx95-tqma9596la.dtsi"
+
+/ {
+ model = "TQ-Systems i.MX95 TQMa95xxLA on MBa95xxCA";
+ compatible = "tq,imx95-tqma9596la-mba95xxca", "tq,imx95-tqma9596la", "fsl,imx95";
+ chassis-type = "embedded";
+
+ aliases {
+ ethernet0 = &enetc_port0;
+ ethernet1 = &enetc_port1;
+ ethernet2 = &enetc_port2;
+ gpio0 = &gpio1;
+ gpio1 = &gpio2;
+ gpio2 = &gpio3;
+ gpio3 = &gpio4;
+ i2c0 = &lpi2c1;
+ i2c1 = &lpi2c2;
+ i2c2 = &lpi2c3;
+ i2c3 = &lpi2c4;
+ i2c4 = &lpi2c5;
+ i2c5 = &lpi2c6;
+ i2c6 = &lpi2c7;
+ i2c7 = &lpi2c8;
+ mmc0 = &usdhc1;
+ mmc1 = &usdhc2;
+ rtc0 = &pcf85063;
+ rtc1 = &scmi_bbm;
+ serial0 = &lpuart1;
+ serial1 = &lpuart2;
+ serial2 = &lpuart3;
+ serial3 = &lpuart4;
+ serial4 = &lpuart5;
+ serial5 = &lpuart6;
+ serial6 = &lpuart7;
+ serial7 = &lpuart8;
+ spi0 = &flexspi1;
+ };
+
+ chosen {
+ stdout-path = &lpuart1;
+ };
+
+ backlight_lvds: backlight-lvds {
+ compatible = "pwm-backlight";
+ pwms = <&tpm5 2 100000 0>;
+ brightness-levels = <0 4 8 16 32 64 128 255>;
+ default-brightness-level = <7>;
+ enable-gpios = <&expander2 6 GPIO_ACTIVE_HIGH>;
+ power-supply = <®_12v0>;
+ status = "disabled";
+ };
+
+ clk_eth: clk-eth {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <156250000>;
+ };
+
+ /*
+ * TODO: gate is disabled for now and GPIO are hogged
+ * ENETC driver switches the clock far too late for ENETC2 + SFP
+ */
+ clk_eth_gate: clk-eth-gate {
+ compatible = "gpio-gate-clock";
+ enable-gpios = <&expander2 0 GPIO_ACTIVE_HIGH>;
+ clocks = <&clk_eth>;
+ #clock-cells = <0>;
+ status = "disabled";
+ };
+
+ clk_xtal25: clk-xtal25 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ autorepeat;
+
+ button-b {
+ label = "BUTTON_B#";
+ linux,code = <BTN_1>;
+ gpios = <&expander1 0 GPIO_ACTIVE_LOW>;
+ wakeup-source;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ led-1 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_STATUS;
+ gpios = <&expander2 13 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "default-on";
+ };
+
+ led-2 {
+ color = <LED_COLOR_ID_AMBER>;
+ function = LED_FUNCTION_HEARTBEAT;
+ gpios = <&expander2 14 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ iio-hwmon {
+ compatible = "iio-hwmon";
+ io-channels = <&adc1 0>, <&adc1 1>, <&adc1 2>, <&adc1 3>,
+ <&adc1 4>, <&adc1 5>, <&adc1 6>, <&adc1 7>;
+ };
+
+ reg_v1v8_mb: regulator-v1v8-mb {
+ compatible = "regulator-fixed";
+ regulator-name = "V_1V8_MB";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ reg_v3v3_mb: regulator-v3v3-mb {
+ compatible = "regulator-fixed";
+ regulator-name = "V_3V3_MB";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_3v3a_10g: regulator-3v3a-10g {
+ compatible = "regulator-fixed";
+ regulator-name = "3V3A_10G";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&expander2 15 GPIO_ACTIVE_HIGH>;
+ startup-delay-us = <2000>;
+ enable-active-high;
+ };
+
+ reg_12v0: regulator-12v0 {
+ compatible = "regulator-fixed";
+ regulator-name = "12V0";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ gpio = <&expander1 15 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reg_pwm_fan: regulator-pwm-fan {
+ compatible = "regulator-fixed";
+ regulator-name = "FAN_PWR";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ gpio = <&expander3 15 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <®_12v0>;
+ };
+
+ reg_lvds: regulator-lvds {
+ compatible = "regulator-fixed";
+ regulator-name = "LCD_PWR_EN";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&expander2 7 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ /* USB NC limitations, RM 162.1.2 VBUS limitations */
+ reg_vbus_usb3: regulator-vbus-usb3 {
+ compatible = "regulator-fixed";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-name = "USB3_VBUS";
+ gpio = <&gpio4 1 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ linux_cma: linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0 0x28000000>;
+ alloc-ranges = <0 0x80000000 0 0x80000000>;
+ linux,cma-default;
+ };
+ };
+
+ sfp_xfi: sfp-xfi {
+ compatible = "sff,sfp";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sfp>;
+ i2c-bus = <&lpi2c7>;
+ maximum-power-milliwatt = <2000>;
+ mod-def0-gpios = <&expander1 3 GPIO_ACTIVE_LOW>;
+ tx-fault-gpios = <&gpio2 30 GPIO_ACTIVE_HIGH>;
+ los-gpios = <&gpio2 31 GPIO_ACTIVE_HIGH>;
+ tx-disable-gpios = <&expander2 2 GPIO_ACTIVE_HIGH>;
+ };
+
+ sound {
+ compatible = "fsl,imx-audio-tlv320aic32x4";
+ model = "tqm-tlv320aic32";
+ audio-codec = <&tlv320aic3x04>;
+ audio-cpu = <&sai3>;
+ audio-routing =
+ "IN3_L", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "Headphone Jack", "HPL",
+ "Headphone Jack", "HPR",
+ "IN1_L", "Line In Jack",
+ "IN1_R", "Line In Jack",
+ "Line Out Jack", "LOL",
+ "Line Out Jack", "LOR";
+ };
+
+ wifi-connector {
+ compatible = "pcie-m2-e-connector";
+ vpcie3v3-supply = <®_v3v3_mb>;
+ vpcie1v8-supply = <®_v1v8_mb>;
+ i2c-parent = <&lpi2c2>;
+ w-disable1-gpios = <&expander2 9 GPIO_ACTIVE_LOW>;
+ w-disable2-gpios = <&expander2 10 GPIO_ACTIVE_LOW>;
+ /* UART_WAKE is connected to SM */
+ /* SDIO_WAKE is connected to SM */
+ sdio-reset-gpios = <&expander3 2 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&adc1 {
+ status = "okay";
+};
+
+&enetc_port0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enetc0>;
+ phy-handle = <ðphy0>;
+ phy-mode = "rgmii-id";
+ status = "okay";
+};
+
+&enetc_port1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enetc1>;
+ phy-handle = <ðphy1>;
+ phy-mode = "rgmii-id";
+ status = "okay";
+};
+
+/* No support for XFI yet */
+&enetc_port2 {
+ sfp = <&sfp_xfi>;
+ phy-mode = "10gbase-r";
+ clocks = <&clk_eth>;
+ managed = "in-band-status";
+ status = "disabled";
+};
+
+&flexcan1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ status = "okay";
+};
+
+&flexcan2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ status = "okay";
+};
+
+&lpi2c2 {
+ tlv320aic3x04: audio-codec@18 {
+ compatible = "ti,tlv320aic32x4";
+ reg = <0x18>;
+ clocks = <&scmi_clk IMX95_CLK_SAI3>;
+ clock-names = "mclk";
+ reset-gpios = <&expander1 14 GPIO_ACTIVE_LOW>;
+ iov-supply = <®_v3v3_mb>;
+ ldoin-supply = <®_v3v3_mb>;
+ };
+
+ sensor_mb: temperature-sensor@1e {
+ compatible = "nxp,se97b", "jedec,jc-42.4-temp";
+ reg = <0x1e>;
+ };
+
+ fan_controller: fan-controller@2f {
+ compatible = "microchip,emc2301", "microchip,emc2305";
+ reg = <0x2f>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #pwm-cells = <3>;
+ status = "okay";
+
+ fan: fan@0 {
+ reg = <0x0>;
+ pwms = <&fan_controller 40000 PWM_POLARITY_INVERTED 1>;
+ #cooling-cells = <2>;
+ fan-supply = <®_pwm_fan>;
+ };
+ };
+
+ ptn5110: usb-typec@50 {
+ compatible = "nxp,ptn5110", "tcpci";
+ reg = <0x50>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_typec>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <28 IRQ_TYPE_LEVEL_LOW>;
+
+ typec_con: connector {
+ compatible = "usb-c-connector";
+ label = "X9";
+ power-role = "source";
+ data-role = "dual";
+ source-pdos = <PDO_FIXED(5000, 500, PDO_FIXED_USB_COMM)>;
+ self-powered;
+
+ port {
+ typec_con_hs: endpoint {
+ remote-endpoint = <&typec_hs>;
+ };
+ };
+ };
+ };
+
+ eeprom_mb: eeprom@56 {
+ compatible = "nxp,se97b", "atmel,24c02";
+ reg = <0x56>;
+ pagesize = <16>;
+ vcc-supply = <®_v3v3_mb>;
+ };
+
+ pcieclk: clock-generator@68 {
+ compatible = "renesas,9fgv0441";
+ reg = <0x68>;
+ clocks = <&clk_xtal25>;
+ #clock-cells = <1>;
+ };
+
+ /* D39 IN/OUT 3V3 */
+ expander1: gpio@74 {
+ compatible = "ti,tca9539";
+ reg = <0x74>;
+ vcc-supply = <®_v3v3_mb>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_expander1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&gpio2>;
+ interrupts = <14 IRQ_TYPE_EDGE_FALLING>;
+
+ gpio-line-names =
+ /* 00 */ "BUTTON_B#", "CAM0_SYNC_3V3",
+ /* 02 */ "CAM1_SYNC_3V3", "SFP_MOD_ABS",
+ /* 04 */ "DIG_IN1", "DIG_IN2",
+ /* 06 */ "DIG_IN3", "DIG_IN4",
+ /* 08 */ "DIG_OUT_1_2_STATE", "DIG_OUT_3_4_STATE",
+ /* 10 */ "DIG_OUT_1_EN", "DIG_OUT_2_EN",
+ /* 12 */ "DIG_OUT_3_EN", "DIG_OUT_4_EN",
+ /* 14 */ "AUDIO_RST#", "12V_EN";
+ };
+
+ /* D40 OUT 3V3 */
+ expander2: gpio@75 {
+ compatible = "ti,tca9539";
+ reg = <0x75>;
+ vcc-supply = <®_v3v3_mb>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ gpio-line-names =
+ /* 00 */ "ETH10G_REFCLK_EN", "ETH10G_REFCLK_RST#",
+ /* 02 */ "SFP_TX_DIS", "USB3_RESET#",
+ /* 04 */ "USB2_RESET#", "LCD_RESET#",
+ /* 06 */ "LCD_BLT_EN", "LCD_PWR_EN",
+ /* 08 */ "M2_KEYE_PERST#", "M2_KEYE_WDISABLE1#",
+ /* 10 */ "M2_KEYE_WDISABLE2#", "M2_KEYB_PERST#",
+ /* 12 */ "M2_KEYB_WDISABLE1#", "USER_LED1",
+ /* 14 */ "USER_LED2", "3V3A_10G_EN";
+
+ eth10g-refclk-en-hog {
+ gpio-hog;
+ gpios = <0 GPIO_ACTIVE_HIGH>;
+ output-high;
+ line-name = "ETH10G_REFCLK_EN";
+ };
+
+ eth10g-refclk-rst-hog {
+ gpio-hog;
+ gpios = <1 GPIO_ACTIVE_LOW>;
+ output-low;
+ line-name = "ETH10G_REFCLK_RST#";
+ };
+
+ m2-keyb-wdisable1-hog {
+ gpio-hog;
+ gpios = <12 GPIO_ACTIVE_LOW>;
+ output-low;
+ line-name = "M2_KEYB_WDISABLE1#";
+ };
+ };
+
+ /* D41 OUT 1V8 */
+ expander3: gpio@76 {
+ compatible = "ti,tca9539";
+ reg = <0x76>;
+ vcc-supply = <®_v1v8_mb>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ gpio-line-names =
+ /* 00 */ "ENET1_RESET#", "ENET2_RESET#",
+ /* 02 */ "M2_KEYE_SDIO_RST#", "M2_KEYE_DEV_WLAN_WAKE#",
+ /* 04 */ "M2_KEYE_DEV_BT_WAKE", "M2_KEYB_W_DISABLE2#",
+ /* 06 */ "M2_KEYB_RST#", "M2_KEYB_FULL_CARD_PWR_OFF#",
+ /* 08 */ "M2_KEYB_DPR", "CAM0_PWR#",
+ /* 10 */ "CAM1_PWR#", "CAM0_RST#",
+ /* 12 */ "CAM1_RST#", "CAM0_TRIGGER",
+ /* 14 */ "CAM1_TRIGGER", "FAN_PWR_EN";
+
+ m2-keye-sdio-rst-hog {
+ gpio-hog;
+ gpios = <2 GPIO_ACTIVE_LOW>;
+ output-low;
+ line-name = "M2_KEYE_SDIO_RST#";
+ };
+
+ /* vendor defined pin 42 */
+ m2-keye-dev_wlan-wake-hog {
+ gpio-hog;
+ gpios = <3 GPIO_ACTIVE_LOW>;
+ input;
+ line-name = "M2_KEYE_DEV_WLAN_WAKE#";
+ };
+
+ /* vendor defined pin 40 */
+ m2-keye-dev_bt-wake-hog {
+ gpio-hog;
+ gpios = <4 GPIO_ACTIVE_LOW>;
+ input;
+ line-name = "M2_KEYE_DEV_BT_WAKE#";
+ };
+
+ m2-keyb-wdisable2-hog {
+ gpio-hog;
+ gpios = <5 GPIO_ACTIVE_LOW>;
+ output-low;
+ line-name = "M2_KEYB_WDISABLE2#";
+ };
+
+ m2-keyb-rst-hog {
+ gpio-hog;
+ gpios = <6 GPIO_ACTIVE_LOW>;
+ output-low;
+ line-name = "M2_KEYB_RST#";
+ };
+
+ m2-keyb-full-card-pwr-off-hog {
+ gpio-hog;
+ gpios = <7 GPIO_ACTIVE_LOW>;
+ output-low;
+ line-name = "M2_KEYB_FULL_CARD_PWR_OFF#";
+ };
+ };
+};
+
+/* X4 + SFP */
+&lpi2c7 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_lpi2c7>;
+ pinctrl-1 = <&pinctrl_lpi2c7_recovery>;
+ scl-gpios = <&gpio2 7 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio2 6 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "okay";
+
+ /* TODO: 0x19: retimer */
+
+ /* 0x50 / 0x51: SFP EEPROM */
+};
+
+/* X4 */
+&lpspi4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpspi4>;
+ cs-gpios = <&gpio5 14 GPIO_ACTIVE_LOW>, <&gpio5 13 GPIO_ACTIVE_LOW>;
+ /* max 30 MHz as per datasheet, without SCK loopback via pad (LPSPI_CFGR1[SAMPLE]) */
+ status = "okay";
+};
+
+&lpuart1 {
+ /* console */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart1>;
+ status = "okay";
+};
+
+&lpuart2 {
+ /* SM */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart2>;
+ status = "reserved";
+};
+
+&lpuart5 {
+ /* X16 M.2 KEY E */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart5>;
+ status = "okay";
+};
+
+&lpuart7 {
+ /* X5 */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart7>;
+ status = "okay";
+};
+
+&lpuart8 {
+ /* X15 */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart8>;
+ linux,rs485-enabled-at-boot-time;
+ status = "okay";
+};
+
+&netc_blk_ctrl {
+ status = "okay";
+};
+
+&netc_emdio {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_emdio>;
+ status = "okay";
+
+ /* IRQ pin is AON GPIO, not usable */
+ ethphy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ reset-gpios = <&expander3 0 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <500000>;
+ reset-deassert-us = <50000>;
+ ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_50_NS>;
+ ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_50_NS>;
+ ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+ ti,dp83867-rxctrl-strap-quirk;
+ ti,clk-output-sel = <DP83867_CLK_O_SEL_OFF>;
+ };
+
+ ethphy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ethphy1>;
+ reset-gpios = <&expander3 1 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <500000>;
+ reset-deassert-us = <50000>;
+ interrupt-parent = <&gpio4>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_50_NS>;
+ ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_50_NS>;
+ ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+ ti,dp83867-rxctrl-strap-quirk;
+ ti,clk-output-sel = <DP83867_CLK_O_SEL_OFF>;
+ };
+};
+
+&netc_timer {
+ status = "okay";
+};
+
+&netcmix_blk_ctrl {
+ status = "okay";
+};
+
+/* X16 M2 / E-Key mPCIe */
+&pcie0 {
+ pinctrl-0 = <&pinctrl_pcie0>;
+ pinctrl-names = "default";
+ clocks = <&scmi_clk IMX95_CLK_HSIO>,
+ <&scmi_clk IMX95_CLK_HSIOPLL>,
+ <&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
+ <&scmi_clk IMX95_CLK_HSIOPCIEAUX>,
+ <&hsio_blk_ctl 0>,
+ <&pcieclk 1>;
+ clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux", "ref", "extref";
+ reset-gpios = <&expander2 8 GPIO_ACTIVE_LOW>;
+ /* Not supported on REV.0100 */
+ /* supports-clkreq; */
+ status = "okay";
+};
+
+/* X17 M2 / B-Key PCIe */
+&pcie1 {
+ pinctrl-0 = <&pinctrl_pcie1>;
+ pinctrl-names = "default";
+ clocks = <&scmi_clk IMX95_CLK_HSIO>,
+ <&scmi_clk IMX95_CLK_HSIOPLL>,
+ <&scmi_clk IMX95_CLK_HSIOPLL_VCO>,
+ <&scmi_clk IMX95_CLK_HSIOPCIEAUX>,
+ <&hsio_blk_ctl 0>,
+ <&pcieclk 0>;
+ clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux", "ref", "extref";
+ reset-gpios = <&expander2 11 GPIO_ACTIVE_LOW>;
+ /* Not supported on REV.0100 */
+ /* supports-clkreq; */
+ status = "okay";
+};
+
+®_sdvmmc {
+ status = "okay";
+};
+
+&sai3 {
+ #sound-dai-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai3>;
+ assigned-clocks = <&scmi_clk IMX95_CLK_AUDIOPLL1_VCO>,
+ <&scmi_clk IMX95_CLK_AUDIOPLL2_VCO>,
+ <&scmi_clk IMX95_CLK_AUDIOPLL1>,
+ <&scmi_clk IMX95_CLK_AUDIOPLL2>,
+ <&scmi_clk IMX95_CLK_SAI3>;
+ assigned-clock-parents = <0>, <0>, <0>, <0>,
+ <&scmi_clk IMX95_CLK_AUDIOPLL1>;
+ assigned-clock-rates = <3932160000>,
+ <3612672000>, <393216000>,
+ <361267200>, <12288000>;
+ fsl,sai-mclk-direction-output;
+ status = "okay";
+};
+
+&scmi_bbm {
+ linux,code = <KEY_POWER>;
+};
+
+&thermal_zones {
+ a55-thermal {
+ trips {
+ cpu_active0: trip-active0 {
+ temperature = <40000>;
+ hysteresis = <5000>;
+ type = "active";
+ };
+
+ cpu_active1: trip-active1 {
+ temperature = <48000>;
+ hysteresis = <3000>;
+ type = "active";
+ };
+
+ cpu_active2: trip-active2 {
+ temperature = <60000>;
+ hysteresis = <10000>;
+ type = "active";
+ };
+ };
+
+ cooling-maps {
+ map1 {
+ trip = <&cpu_active0>;
+ cooling-device = <&fan 0 2>;
+ };
+
+ map2 {
+ trip = <&cpu_active1>;
+ cooling-device = <&fan 3 5>;
+ };
+
+ map3 {
+ trip = <&cpu_active2>;
+ cooling-device = <&fan 6 10>;
+ };
+ };
+ };
+};
+
+&tpm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_tpm3>;
+ status = "okay";
+};
+
+&tpm5 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_tpm5>;
+};
+
+&usb2 {
+ dr_mode = "otg";
+ hnp-disable;
+ srp-disable;
+ adp-disable;
+ usb-role-switch;
+ disable-over-current;
+ samsung,picophy-pre-emp-curr-control = <3>;
+ samsung,picophy-dc-vol-level-adjust = <7>;
+ status = "okay";
+
+ port {
+ typec_hs: endpoint {
+ remote-endpoint = <&typec_con_hs>;
+ };
+ };
+};
+
+&usb3 {
+ status = "okay";
+};
+
+&usb3_dwc3 {
+ dr_mode = "host";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ hub_2_0: hub@1 {
+ compatible = "usb451,8142";
+ reg = <1>;
+ peer-hub = <&hub_3_0>;
+ reset-gpios = <&expander2 3 GPIO_ACTIVE_LOW>;
+ vdd-supply = <®_v3v3_mb>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ hub_2_1: hub@1 {
+ compatible = "usb424,2514";
+ reg = <1>;
+ reset-gpios = <&expander2 4 GPIO_ACTIVE_LOW>;
+ vdd-supply = <®_v3v3_mb>;
+ vdda-supply = <®_v3v3_mb>;
+ };
+ };
+
+ hub_3_0: hub@2 {
+ compatible = "usb451,8140";
+ reg = <2>;
+ peer-hub = <&hub_2_0>;
+ reset-gpios = <&expander2 3 GPIO_ACTIVE_LOW>;
+ vdd-supply = <®_v3v3_mb>;
+ };
+};
+
+&usb3_phy {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb3>;
+ vbus-supply = <®_vbus_usb3>;
+ status = "okay";
+};
+
+/* X7 µSD */
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>;
+ vmmc-supply = <®_sdvmmc>;
+ cd-gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+ no-mmc;
+ no-sdio;
+ disable-wp;
+ bus-width = <4>;
+ status = "okay";
+};
+
+&scmi_iomuxc {
+ pinctrl_enetc0: enetc0grp {
+ fsl,pins = <IMX95_PAD_ENET1_RD0__NETCMIX_TOP_ETH0_RGMII_RD0 0x1100>,
+ <IMX95_PAD_ENET1_RD1__NETCMIX_TOP_ETH0_RGMII_RD1 0x1100>,
+ <IMX95_PAD_ENET1_RD2__NETCMIX_TOP_ETH0_RGMII_RD2 0x1100>,
+ <IMX95_PAD_ENET1_RD3__NETCMIX_TOP_ETH0_RGMII_RD3 0x1100>,
+ <IMX95_PAD_ENET1_RXC__NETCMIX_TOP_ETH0_RGMII_RX_CLK 0x1100>,
+ <IMX95_PAD_ENET1_RX_CTL__NETCMIX_TOP_ETH0_RGMII_RX_CTL 0x1100>,
+ <IMX95_PAD_ENET1_TD0__NETCMIX_TOP_ETH0_RGMII_TD0 0x11e>,
+ <IMX95_PAD_ENET1_TD1__NETCMIX_TOP_ETH0_RGMII_TD1 0x11e>,
+ <IMX95_PAD_ENET1_TD2__NETCMIX_TOP_ETH0_RGMII_TD2 0x11e>,
+ <IMX95_PAD_ENET1_TD3__NETCMIX_TOP_ETH0_RGMII_TD3 0x11e>,
+ <IMX95_PAD_ENET1_TXC__NETCMIX_TOP_ETH0_RGMII_TX_CLK 0x11e>,
+ <IMX95_PAD_ENET1_TX_CTL__NETCMIX_TOP_ETH0_RGMII_TX_CTL 0x11e>;
+ };
+
+ pinctrl_enetc1: enetc1grp {
+ fsl,pins = <IMX95_PAD_ENET2_RD0__NETCMIX_TOP_ETH1_RGMII_RD0 0x1100>,
+ <IMX95_PAD_ENET2_RD1__NETCMIX_TOP_ETH1_RGMII_RD1 0x1100>,
+ <IMX95_PAD_ENET2_RD2__NETCMIX_TOP_ETH1_RGMII_RD2 0x1100>,
+ <IMX95_PAD_ENET2_RD3__NETCMIX_TOP_ETH1_RGMII_RD3 0x1100>,
+ <IMX95_PAD_ENET2_RXC__NETCMIX_TOP_ETH1_RGMII_RX_CLK 0x1100>,
+ <IMX95_PAD_ENET2_RX_CTL__NETCMIX_TOP_ETH1_RGMII_RX_CTL 0x1100>,
+ <IMX95_PAD_ENET2_TD0__NETCMIX_TOP_ETH1_RGMII_TD0 0x11e>,
+ <IMX95_PAD_ENET2_TD1__NETCMIX_TOP_ETH1_RGMII_TD1 0x11e>,
+ <IMX95_PAD_ENET2_TD2__NETCMIX_TOP_ETH1_RGMII_TD2 0x11e>,
+ <IMX95_PAD_ENET2_TD3__NETCMIX_TOP_ETH1_RGMII_TD3 0x11e>,
+ <IMX95_PAD_ENET2_TXC__NETCMIX_TOP_ETH1_RGMII_TX_CLK 0x11e>,
+ <IMX95_PAD_ENET2_TX_CTL__NETCMIX_TOP_ETH1_RGMII_TX_CTL 0x11e>;
+ };
+
+ pinctrl_ethphy0: ethphy0grp {
+ fsl,pins = <IMX95_PAD_PDM_BIT_STREAM0__AONMIX_TOP_GPIO1_IO_BIT9 0x1100>;
+ };
+
+ pinctrl_ethphy1: ethphy1grp {
+ fsl,pins = <IMX95_PAD_ENET1_MDC__GPIO4_IO_BIT0 0x1100>;
+ };
+
+ pinctrl_expander1: expander1grp {
+ fsl,pins = <IMX95_PAD_GPIO_IO14__GPIO2_IO_BIT14 0x1100>;
+ };
+
+ pinctrl_flexcan1: flexcan1grp {
+ fsl,pins = <IMX95_PAD_SAI1_TXC__AONMIX_TOP_CAN1_RX 0x1300>,
+ <IMX95_PAD_SAI1_TXD0__AONMIX_TOP_CAN1_TX 0x31e>;
+ };
+
+ pinctrl_flexcan2: flexcan2grp {
+ fsl,pins = <IMX95_PAD_GPIO_IO25__CAN2_TX 0x31e>,
+ <IMX95_PAD_GPIO_IO27__CAN2_RX 0x1300>;
+ };
+
+ pinctrl_lpi2c7: lpi2c7grp {
+ fsl,pins = <IMX95_PAD_GPIO_IO07__LPI2C7_SCL 0x40001b1e>,
+ <IMX95_PAD_GPIO_IO06__LPI2C7_SDA 0x40001b1e>;
+ };
+
+ pinctrl_lpi2c7_recovery: lpi2c7recoverygrp {
+ fsl,pins = <IMX95_PAD_GPIO_IO07__GPIO2_IO_BIT7 0x40001b1e>,
+ <IMX95_PAD_GPIO_IO06__GPIO2_IO_BIT6 0x40001b1e>;
+ };
+
+ pinctrl_lpspi4: lpspi4grp {
+ fsl,pins = <IMX95_PAD_GPIO_IO37__LPSPI4_SCK 0x11e>,
+ <IMX95_PAD_GPIO_IO19__LPSPI4_SIN 0x111e>,
+ <IMX95_PAD_GPIO_IO36__LPSPI4_SOUT 0x11e>,
+ <IMX95_PAD_GPIO_IO34__GPIO5_IO_BIT14 0x11e>,
+ <IMX95_PAD_GPIO_IO33__GPIO5_IO_BIT13 0x11e>;
+ };
+
+ pinctrl_lpuart1: lpuart1grp {
+ fsl,pins = <IMX95_PAD_UART1_TXD__AONMIX_TOP_LPUART1_TX 0x31e>,
+ <IMX95_PAD_UART1_RXD__AONMIX_TOP_LPUART1_RX 0x1300>;
+ };
+
+ pinctrl_lpuart2: lpuart2grp {
+ fsl,pins = <IMX95_PAD_UART2_TXD__AONMIX_TOP_LPUART2_TX 0x31e>,
+ <IMX95_PAD_UART2_RXD__AONMIX_TOP_LPUART2_RX 0x1300>;
+ };
+
+ pinctrl_lpuart5: lpuart5grp {
+ fsl,pins = <IMX95_PAD_GPIO_IO00__LPUART5_TX 0x31e>,
+ <IMX95_PAD_GPIO_IO01__LPUART5_RX 0x1300>,
+ <IMX95_PAD_GPIO_IO02__LPUART5_CTS_B 0x1300>,
+ <IMX95_PAD_GPIO_IO03__LPUART5_RTS_B 0x31e>;
+ };
+
+ pinctrl_lpuart7: lpuart7grp {
+ fsl,pins = <IMX95_PAD_GPIO_IO08__LPUART7_TX 0x31e>,
+ <IMX95_PAD_GPIO_IO09__LPUART7_RX 0x1300>,
+ <IMX95_PAD_GPIO_IO10__LPUART7_CTS_B 0x1300>,
+ <IMX95_PAD_GPIO_IO11__LPUART7_RTS_B 0x31e>;
+ };
+
+ pinctrl_lpuart8: lpuart8grp {
+ fsl,pins = <IMX95_PAD_GPIO_IO12__LPUART8_TX 0x31e>,
+ <IMX95_PAD_GPIO_IO13__LPUART8_RX 0x1300>,
+ <IMX95_PAD_GPIO_IO15__LPUART8_RTS_B 0x31e>;
+ };
+
+ pinctrl_emdio: emdiogrp {
+ fsl,pins = <IMX95_PAD_ENET2_MDC__NETCMIX_TOP_NETC_MDC 0x51e>,
+ <IMX95_PAD_ENET2_MDIO__NETCMIX_TOP_NETC_MDIO 0x51e>;
+ };
+
+ pinctrl_pcie0: pcie0grp {
+ fsl,pins = <IMX95_PAD_GPIO_IO32__HSIOMIX_TOP_PCIE1_CLKREQ_B 0x111e>;
+ };
+
+ pinctrl_pcie1: pcie1grp {
+ fsl,pins = <IMX95_PAD_GPIO_IO35__HSIOMIX_TOP_PCIE2_CLKREQ_B 0x111e>;
+ };
+
+ pinctrl_sai3: sai3grp {
+ fsl,pins = <IMX95_PAD_GPIO_IO16__SAI3_TX_BCLK 0x51e>,
+ <IMX95_PAD_GPIO_IO17__SAI3_MCLK 0x51e>,
+ <IMX95_PAD_GPIO_IO20__SAI3_RX_DATA_BIT0 0x1300>,
+ <IMX95_PAD_GPIO_IO21__SAI3_TX_DATA_BIT0 0x51e>,
+ <IMX95_PAD_GPIO_IO26__SAI3_TX_SYNC 0x51e>;
+ };
+
+ pinctrl_retimer: retimergrp {
+ fsl,pins = <IMX95_PAD_GPIO_IO29__GPIO2_IO_BIT29 0x1100>;
+ };
+
+ pinctrl_sfp: sfpgrp {
+ fsl,pins = <IMX95_PAD_GPIO_IO30__GPIO2_IO_BIT30 0x1100>,
+ <IMX95_PAD_GPIO_IO31__GPIO2_IO_BIT31 0x1100>;
+ };
+
+ pinctrl_tpm3: tpm3grp {
+ fsl,pins = <IMX95_PAD_GPIO_IO24__TPM3_CH3 0x51e>;
+ };
+
+ pinctrl_tpm5: tpm5grp {
+ fsl,pins = <IMX95_PAD_GPIO_IO18__TPM5_CH2 0x51e>;
+ };
+
+ pinctrl_typec: typecgrp {
+ fsl,pins = <IMX95_PAD_GPIO_IO28__GPIO2_IO_BIT28 0x1100>;
+ };
+
+ pinctrl_usb3: usb3grp {
+ fsl,pins = <IMX95_PAD_ENET1_MDIO__GPIO4_IO_BIT1 0x31e>;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <IMX95_PAD_SD2_CD_B__GPIO3_IO_BIT0 0x1100>,
+ <IMX95_PAD_SD2_CLK__USDHC2_CLK 0x51e>,
+ <IMX95_PAD_SD2_CMD__USDHC2_CMD 0x31e>,
+ <IMX95_PAD_SD2_DATA0__USDHC2_DATA0 0x131e>,
+ <IMX95_PAD_SD2_DATA1__USDHC2_DATA1 0x131e>,
+ <IMX95_PAD_SD2_DATA2__USDHC2_DATA2 0x131e>,
+ <IMX95_PAD_SD2_DATA3__USDHC2_DATA3 0x131e>,
+ <IMX95_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e>;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
+ fsl,pins = <IMX95_PAD_SD2_CD_B__GPIO3_IO_BIT0 0x1100>,
+ <IMX95_PAD_SD2_CLK__USDHC2_CLK 0x58e>,
+ <IMX95_PAD_SD2_CMD__USDHC2_CMD 0x38e>,
+ <IMX95_PAD_SD2_DATA0__USDHC2_DATA0 0x138e>,
+ <IMX95_PAD_SD2_DATA1__USDHC2_DATA1 0x138e>,
+ <IMX95_PAD_SD2_DATA2__USDHC2_DATA2 0x138e>,
+ <IMX95_PAD_SD2_DATA3__USDHC2_DATA3 0x138e>,
+ <IMX95_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e>;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
+ fsl,pins = <IMX95_PAD_SD2_CD_B__GPIO3_IO_BIT0 0x1100>,
+ <IMX95_PAD_SD2_CLK__USDHC2_CLK 0x5fe>,
+ <IMX95_PAD_SD2_CMD__USDHC2_CMD 0x3fe>,
+ <IMX95_PAD_SD2_DATA0__USDHC2_DATA0 0x13fe>,
+ <IMX95_PAD_SD2_DATA1__USDHC2_DATA1 0x13fe>,
+ <IMX95_PAD_SD2_DATA2__USDHC2_DATA2 0x13fe>,
+ <IMX95_PAD_SD2_DATA3__USDHC2_DATA3 0x13fe>,
+ <IMX95_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e>;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx95-tqma9596la.dtsi b/arch/arm64/boot/dts/freescale/imx95-tqma9596la.dtsi
new file mode 100644
index 0000000000000..aa2756c14e461
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx95-tqma9596la.dtsi
@@ -0,0 +1,278 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+/*
+ * Copyright (c) 2024-2026 TQ-Systems GmbH <linux@ew.tq-group.com>,
+ * D-82229 Seefeld, Germany.
+ * Author: Alexander Stein
+ * Author: Markus Niebel
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "imx95.dtsi"
+
+/ {
+ memory@80000000 {
+ device_type = "memory";
+ /*
+ * DRAM base addr, size : 2048 MiB DRAM
+ * should be corrected by bootloader
+ */
+ reg = <0 0x80000000 0 0x80000000>;
+ };
+
+ reg_1v8: regulator-1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "V_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ reg_3v3: regulator-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "V_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_sdvmmc: regulator-sdvmmc {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sdvmmc>;
+ regulator-name = "SD_PWR_EN";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio3 7 GPIO_ACTIVE_HIGH>;
+ off-on-delay-us = <12000>;
+ enable-active-high;
+ /* can be enabled by mainboard with SD-Card support */
+ status = "disabled";
+ };
+};
+
+&adc1 {
+ vref-supply = <®_1v8>;
+};
+
+&flexspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexspi1>;
+ status = "okay";
+
+ flash0: flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <66000000>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+ vcc-supply = <®_1v8>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+ };
+};
+
+/* System Manager */
+&gpio1 {
+ status = "reserved";
+};
+
+/* System Manager */
+&lpi2c1 {
+ status = "reserved";
+};
+
+&lpi2c2 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpi2c2>;
+ status = "okay";
+
+ pcf85063: rtc@51 {
+ compatible = "nxp,pcf85063a";
+ reg = <0x51>;
+ quartz-load-femtofarads = <7000>;
+ };
+
+ m24c64: eeprom@54 {
+ compatible = "atmel,24c64";
+ reg = <0x54>;
+ pagesize = <32>;
+ vcc-supply = <®_3v3>;
+ };
+
+ /* protectable identification memory (part of M24C64-D @54) */
+ eeprom@5c {
+ compatible = "atmel,24c64d-wl";
+ reg = <0x5c>;
+ pagesize = <32>;
+ vcc-supply = <®_3v3>;
+ };
+
+ imu@6b {
+ compatible = "st,ism330dhcx";
+ reg = <0x6b>;
+ vdd-supply = <®_3v3>;
+ vddio-supply = <®_3v3>;
+ };
+};
+
+&thermal_zones {
+ pf09-thermal {
+ polling-delay = <2000>;
+ polling-delay-passive = <250>;
+ thermal-sensors = <&scmi_sensor 2>;
+
+ trips {
+ pf09_alert: trip0 {
+ hysteresis = <2000>;
+ temperature = <140000>;
+ type = "passive";
+ };
+
+ pf09_crit: trip1 {
+ hysteresis = <2000>;
+ temperature = <155000>;
+ type = "critical";
+ };
+ };
+ };
+
+ pf53arm-thermal {
+ polling-delay = <2000>;
+ polling-delay-passive = <250>;
+ thermal-sensors = <&scmi_sensor 4>;
+
+ cooling-maps {
+ map0 {
+ trip = <&pf5301_alert>;
+ cooling-device =
+ <&A55_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A55_1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A55_2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A55_3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A55_4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A55_5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+
+ trips {
+ pf5301_alert: trip0 {
+ hysteresis = <2000>;
+ temperature = <140000>;
+ type = "passive";
+ };
+
+ pf5301_crit: trip1 {
+ hysteresis = <2000>;
+ temperature = <155000>;
+ type = "critical";
+ };
+ };
+ };
+
+ pf53soc-thermal {
+ polling-delay = <2000>;
+ polling-delay-passive = <250>;
+ thermal-sensors = <&scmi_sensor 3>;
+
+ trips {
+ pf5302_alert: trip0 {
+ hysteresis = <2000>;
+ temperature = <140000>;
+ type = "passive";
+ };
+
+ pf5302_crit: trip1 {
+ hysteresis = <2000>;
+ temperature = <155000>;
+ type = "critical";
+ };
+ };
+ };
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ bus-width = <8>;
+ non-removable;
+ no-sdio;
+ no-sd;
+ status = "okay";
+};
+
+&wdog3 {
+ status = "okay";
+};
+
+&scmi_iomuxc {
+ pinctrl_flexspi1: flexspi1grp {
+ fsl,pins = <IMX95_PAD_XSPI1_SS0_B__FLEXSPI1_A_SS0_B 0x19e>,
+ <IMX95_PAD_XSPI1_DATA0__FLEXSPI1_A_DATA_BIT0 0x19e>,
+ <IMX95_PAD_XSPI1_DATA1__FLEXSPI1_A_DATA_BIT1 0x19e>,
+ <IMX95_PAD_XSPI1_DATA2__FLEXSPI1_A_DATA_BIT2 0x19e>,
+ <IMX95_PAD_XSPI1_DATA3__FLEXSPI1_A_DATA_BIT3 0x19e>,
+ /* SION to allow clock loopback from pad */
+ <IMX95_PAD_XSPI1_SCLK__FLEXSPI1_A_SCLK 0x4000019e>,
+ <IMX95_PAD_XSPI1_DQS__FLEXSPI1_A_DQS 0x4000019e>;
+ };
+
+ pinctrl_lpi2c2: lpi2c2grp {
+ fsl,pins = <IMX95_PAD_I2C2_SCL__AONMIX_TOP_LPI2C2_SCL 0x4000191e>,
+ <IMX95_PAD_I2C2_SDA__AONMIX_TOP_LPI2C2_SDA 0x4000191e>;
+ };
+
+ pinctrl_sdvmmc: sdvmmcgrp {
+ fsl,pins = <IMX95_PAD_SD2_RESET_B__GPIO3_IO_BIT7 0x11e>;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <IMX95_PAD_SD1_CLK__USDHC1_CLK 0x158e>,
+ <IMX95_PAD_SD1_CMD__USDHC1_CMD 0x138e>,
+ <IMX95_PAD_SD1_DATA0__USDHC1_DATA0 0x138e>,
+ <IMX95_PAD_SD1_DATA1__USDHC1_DATA1 0x138e>,
+ <IMX95_PAD_SD1_DATA2__USDHC1_DATA2 0x138e>,
+ <IMX95_PAD_SD1_DATA3__USDHC1_DATA3 0x138e>,
+ <IMX95_PAD_SD1_DATA4__USDHC1_DATA4 0x138e>,
+ <IMX95_PAD_SD1_DATA5__USDHC1_DATA5 0x138e>,
+ <IMX95_PAD_SD1_DATA6__USDHC1_DATA6 0x138e>,
+ <IMX95_PAD_SD1_DATA7__USDHC1_DATA7 0x138e>,
+ <IMX95_PAD_SD1_STROBE__USDHC1_STROBE 0x158e>;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp {
+ fsl,pins = <IMX95_PAD_SD1_CLK__USDHC1_CLK 0x158e>,
+ <IMX95_PAD_SD1_CMD__USDHC1_CMD 0x138e>,
+ <IMX95_PAD_SD1_DATA0__USDHC1_DATA0 0x138e>,
+ <IMX95_PAD_SD1_DATA1__USDHC1_DATA1 0x138e>,
+ <IMX95_PAD_SD1_DATA2__USDHC1_DATA2 0x138e>,
+ <IMX95_PAD_SD1_DATA3__USDHC1_DATA3 0x138e>,
+ <IMX95_PAD_SD1_DATA4__USDHC1_DATA4 0x138e>,
+ <IMX95_PAD_SD1_DATA5__USDHC1_DATA5 0x138e>,
+ <IMX95_PAD_SD1_DATA6__USDHC1_DATA6 0x138e>,
+ <IMX95_PAD_SD1_DATA7__USDHC1_DATA7 0x138e>,
+ <IMX95_PAD_SD1_STROBE__USDHC1_STROBE 0x158e>;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp {
+ fsl,pins = <IMX95_PAD_SD1_CLK__USDHC1_CLK 0x15fe>,
+ <IMX95_PAD_SD1_CMD__USDHC1_CMD 0x13fe>,
+ <IMX95_PAD_SD1_DATA0__USDHC1_DATA0 0x13fe>,
+ <IMX95_PAD_SD1_DATA1__USDHC1_DATA1 0x13fe>,
+ <IMX95_PAD_SD1_DATA2__USDHC1_DATA2 0x13fe>,
+ <IMX95_PAD_SD1_DATA3__USDHC1_DATA3 0x13fe>,
+ <IMX95_PAD_SD1_DATA4__USDHC1_DATA4 0x13fe>,
+ <IMX95_PAD_SD1_DATA5__USDHC1_DATA5 0x13fe>,
+ <IMX95_PAD_SD1_DATA6__USDHC1_DATA6 0x13fe>,
+ <IMX95_PAD_SD1_DATA7__USDHC1_DATA7 0x13fe>,
+ <IMX95_PAD_SD1_STROBE__USDHC1_STROBE 0x15fe>;
+ };
+};
--
2.54.0
^ permalink raw reply related
* [PATCH v3 0/2] arm64: dts: imx8mp-skov: add new 7" variant
From: Steffen Trumtrar @ 2026-07-01 8:30 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
Cc: Steffen Trumtrar, devicetree, linux-kernel, imx, linux-arm-kernel
Add a new board variant for the Skov i.MX8MP based family of boards.
This variant uses a different 7" panel than the existing ones.
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---
Changes in v3:
- rebase to v7.2-rc1
- Link to v2: https://patch.msgid.link/20260427-v7-0-topic-imx8mp-skov-dts-jutouch-7inch-v2-0-e2b79fc24391@pengutronix.de
Changes in v2:
- rebase to v7.1-rc1
- Link to v1: https://patch.msgid.link/20260325-v7-0-topic-imx8mp-skov-dts-jutouch-7inch-v1-0-10255d236439@pengutronix.de
To: Rob Herring <robh@kernel.org>
To: Krzysztof Kozlowski <krzk+dt@kernel.org>
To: Conor Dooley <conor+dt@kernel.org>
To: Shawn Guo <shawnguo@kernel.org>
To: Frank Li <Frank.Li@nxp.com>
To: Sascha Hauer <s.hauer@pengutronix.de>
To: Pengutronix Kernel Team <kernel@pengutronix.de>
To: Fabio Estevam <festevam@gmail.com>
Cc: devicetree@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: imx@lists.linux.dev
Cc: linux-arm-kernel@lists.infradead.org
---
Steffen Trumtrar (2):
dt-bindings: arm: fsl: add compatible for new Skov I.MX8MP variant
arm64: dts: imx8mp-skov: support new 7inch panel board
Documentation/devicetree/bindings/arm/fsl.yaml | 1 +
arch/arm64/boot/dts/freescale/Makefile | 1 +
.../imx8mp-skov-revc-jutouch-jt070tm041.dts | 79 ++++++++++++++++++++++
3 files changed, 81 insertions(+)
---
base-commit: dc59e4fea9d83f03bad6bddf3fa2e52491777482
change-id: 20260325-v7-0-topic-imx8mp-skov-dts-jutouch-7inch-3dbcb450a39c
Best regards,
--
Steffen Trumtrar <s.trumtrar@pengutronix.de>
^ permalink raw reply
* [PATCH v3 1/2] dt-bindings: arm: fsl: add compatible for new Skov I.MX8MP variant
From: Steffen Trumtrar @ 2026-07-01 8:30 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
Cc: Steffen Trumtrar, devicetree, linux-kernel, imx, linux-arm-kernel
In-Reply-To: <20260701-v7-0-topic-imx8mp-skov-dts-jutouch-7inch-v3-0-d74f7e3f8293@pengutronix.de>
In preparation for adding a new device tree variant with a different 7"
panel, describe the DT compatible in the binding.
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---
Documentation/devicetree/bindings/arm/fsl.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
index 86876311ec59a..402f140fb5170 100644
--- a/Documentation/devicetree/bindings/arm/fsl.yaml
+++ b/Documentation/devicetree/bindings/arm/fsl.yaml
@@ -1147,6 +1147,7 @@ properties:
- skov,imx8mp-skov-revb-mi1010ait-1cp1 # SKOV i.MX8MP climate control with 10.1" panel
- skov,imx8mp-skov-revc-hdmi # SKOV i.MX8MP climate control without panel
- skov,imx8mp-skov-revc-bd500 # SKOV i.MX8MP climate control with LED frontplate
+ - skov,imx8mp-skov-revc-jutouch-jt070tm041 # SKOV i.MX8MP climate control with 7" JuTouch panel
- skov,imx8mp-skov-revc-jutouch-jt101tm023 # SKOV i.MX8MP climate control with 10" JuTouch panel
- skov,imx8mp-skov-revc-tian-g07017 # SKOV i.MX8MP climate control with 7" panel
- ultratronik,imx8mp-ultra-mach-sbc # Ultratronik SBC i.MX8MP based board
--
2.51.0
^ permalink raw reply related
* [PATCH v3 2/2] arm64: dts: imx8mp-skov: support new 7inch panel board
From: Steffen Trumtrar @ 2026-07-01 8:30 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
Cc: Steffen Trumtrar, devicetree, linux-kernel, imx, linux-arm-kernel
In-Reply-To: <20260701-v7-0-topic-imx8mp-skov-dts-jutouch-7inch-v3-0-d74f7e3f8293@pengutronix.de>
This board is similar to the already upstream
imx8mp-skov-revc-tian-g07017.dts but uses a different 7" panel with a
different touch controller.
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---
arch/arm64/boot/dts/freescale/Makefile | 1 +
.../imx8mp-skov-revc-jutouch-jt070tm041.dts | 79 ++++++++++++++++++++++
2 files changed, 80 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 8ddaab127ab9c..efca29735b2cb 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -435,6 +435,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mp-skov-revb-mi1010ait-1cp1.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-skov-revc-bd500.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-skov-revc-hdmi.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-skov-revc-tian-g07017.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mp-skov-revc-jutouch-jt070tm041.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-skov-revc-jutouch-jt101tm023.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-toradex-smarc-dev.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8mp-tqma8mpql-mba8mpxl.dtb
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-skov-revc-jutouch-jt070tm041.dts b/arch/arm64/boot/dts/freescale/imx8mp-skov-revc-jutouch-jt070tm041.dts
new file mode 100644
index 0000000000000..56374f1e67663
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mp-skov-revc-jutouch-jt070tm041.dts
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+
+/dts-v1/;
+
+#include "imx8mp-skov-reva.dtsi"
+
+/ {
+ model = "SKOV IMX8MP CPU revC - JuTouch JT070TM041";
+ compatible = "skov,imx8mp-skov-revc-jutouch-jt070tm041", "fsl,imx8mp";
+
+ panel {
+ compatible = "jutouch,jt070tm041";
+ backlight = <&backlight>;
+ power-supply = <®_tft_vcom>;
+
+ port {
+ in_lvds0: endpoint {
+ remote-endpoint = <&ldb_lvds_ch0>;
+ };
+ };
+ };
+};
+
+&backlight {
+ status = "okay";
+};
+
+&i2c2 {
+ clock-frequency = <100000>;
+ status = "okay";
+
+ touchscreen@2a {
+ compatible = "eeti,exc81w32";
+ reg = <0x2a>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_touchscreen>;
+ interrupts-extended = <&gpio4 28 IRQ_TYPE_LEVEL_LOW>;
+ reset-gpios = <&gpio4 29 GPIO_ACTIVE_LOW>;
+ touchscreen-size-x = <1024>;
+ touchscreen-size-y = <600>;
+ vdd-supply = <®_vdd_3v3>;
+ };
+};
+
+&lcdif2 {
+ status = "okay";
+};
+
+&lvds_bridge {
+ assigned-clocks = <&clk IMX8MP_CLK_MEDIA_LDB>,
+ <&clk IMX8MP_VIDEO_PLL1>;
+ assigned-clock-parents = <&clk IMX8MP_VIDEO_PLL1_OUT>;
+ /* IMX8MP_VIDEO_PLL1 = IMX8MP_CLK_MEDIA_DISP2_PIX * 2 * 7 */
+ assigned-clock-rates = <0>, <358400000>;
+ status = "okay";
+
+ ports {
+ port@1 {
+ ldb_lvds_ch0: endpoint {
+ remote-endpoint = <&in_lvds0>;
+ };
+ };
+ };
+};
+
+&pwm4 {
+ status = "okay";
+};
+
+&pwm1 {
+ status = "okay";
+};
+
+®_tft_vcom {
+ regulator-min-microvolt = <3160000>;
+ regulator-max-microvolt = <3160000>;
+ voltage-table = <3160000 73>;
+ status = "okay";
+};
--
2.51.0
^ permalink raw reply related
* [PATCH v6 0/2] clk: amlogic: Add A9 peripherals clock controller
From: Jian Hu via B4 Relay @ 2026-07-01 8:30 UTC (permalink / raw)
To: Neil Armstrong, Jerome Brunet, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Xianwei Zhao,
Kevin Hilman, Martin Blumenstingl, Brian Masney
Cc: linux-amlogic, linux-clk, devicetree, linux-kernel,
linux-arm-kernel, Jian Hu, Conor Dooley
This series adds Amlogic A9 peripherals clock support,
including dt-binding and peripherals clock driver.
Note that this driver depends on the A9 PLL driver, which is not yet
upstream. The Meson PLL framework is currently undergoing refactoring,
and the A9 PLL driver will be submitted as a follow-up series after
that work has been completed.
Signed-off-by: Jian Hu <jian.hu@amlogic.com>
---
Changes in v6:
- Rebase onto the latest clk-meson-next.
- Update Kconfig and Makefile context to apply cleanly.
- No functional changes.
- Link to v5: https://lore.kernel.org/r/20260630-a9_peripherals-v5-0-bc4019730354@amlogic.com
Changes in v5:
- Include <linux/module.h>.
- Add missing '0' suffixes to some clocks.
- Fix typo: "encorder1" -> "encoder1".
- Fix the parent clock for a9_hdmitx1_pixel.
- Link to v4: https://lore.kernel.org/r/20260618-a9_peripherals-v4-0-fe120de44e77@amlogic.com
Changes in v4:
- Expose channel 3 for gen_clk.
- Add missing '0' suffixes to somes.
- Use helper macro for vclk clocks definitions.
- Drop forward declaration.
- Drop CLK_HW_INIT* and revert to explicit clock declarations.
- Fix can clock channel number comment.
- Rename enc clocks to encoder0/encoder1.
- Link to v3: https://lore.kernel.org/r/20260610-a9_peripherals-v3-0-d07a78085f71@amlogic.com
Changes in v3:
- Add "depend on A9 pll" instructions in the cover-letter.
- Move COMPILE_TEST after 'depends on ARM64' reported by sashiko-bot.
- Fix usb_48m_pre_sel's parent reported by sashiko-bot.
- Fix gen_div width reported by sashiko-bot.
- Fix hdmitx1_pixel's parent reported by sashiko-bot.
- Link to v2: https://lore.kernel.org/r/20260603-a9_peripherals-v2-0-ee1b8c0a1e6c@amlogic.com
Changes in v2:
- Split the A9 clock driver and send the peripherals clock separately.
- Add COMPILE_TEST in Kconfig.
- Drop the 'optional'.
- Rename apb4 to soc.
- Sort the header file.
- Rename hifi to hifi0.
- Use CLK_HW_INIT_PARENTS_DATA to describe clk_init_data.
- Use CLK_HW_INIT_HW to describe clk_init_data.
- Use CLK_HW_INIT_PARENTS_HW to describe clk_init_data.
- Link to v1: https://lore.kernel.org/all/20260511-b4-a9_clk-v1-0-41cb4071b7c9@amlogic.com/
---
Jian Hu (2):
dt-bindings: clock: Add Amlogic A9 peripherals clock controller
clk: amlogic: Add A9 peripherals clock controller driver
.../clock/amlogic,a9-peripherals-clkc.yaml | 164 ++
drivers/clk/meson/Kconfig | 15 +
drivers/clk/meson/Makefile | 1 +
drivers/clk/meson/a9-peripherals.c | 2089 ++++++++++++++++++++
.../clock/amlogic,a9-peripherals-clkc.h | 351 ++++
5 files changed, 2620 insertions(+)
---
base-commit: a1b4c3a63a7e56b98b2eccc3a82b9f31d51c2e35
change-id: 20260603-a9_peripherals-4214e79705dc
Best regards,
--
Jian Hu <jian.hu@amlogic.com>
^ permalink raw reply
* [PATCH v6 2/2] clk: amlogic: Add A9 peripherals clock controller driver
From: Jian Hu via B4 Relay @ 2026-07-01 8:30 UTC (permalink / raw)
To: Neil Armstrong, Jerome Brunet, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Xianwei Zhao,
Kevin Hilman, Martin Blumenstingl, Brian Masney
Cc: linux-amlogic, linux-clk, devicetree, linux-kernel,
linux-arm-kernel, Jian Hu
In-Reply-To: <20260701-a9_peripherals-v6-0-9630f39879e5@amlogic.com>
From: Jian Hu <jian.hu@amlogic.com>
Add the peripherals clock controller driver for the Amlogic A9 SoC family.
Signed-off-by: Jian Hu <jian.hu@amlogic.com>
---
drivers/clk/meson/Kconfig | 15 +
drivers/clk/meson/Makefile | 1 +
drivers/clk/meson/a9-peripherals.c | 2089 ++++++++++++++++++++++++++++++++++++
3 files changed, 2105 insertions(+)
diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index b71299898197..5152868e2ee6 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -132,6 +132,21 @@ config COMMON_CLK_A1_PERIPHERALS
device, A1 SoC Family. Say Y if you want A1 Peripherals clock
controller to work.
+config COMMON_CLK_A9_PERIPHERALS
+ tristate "Amlogic A9 SoC peripherals clock controller support"
+ depends on ARM64 || COMPILE_TEST
+ default ARCH_MESON
+ select COMMON_CLK_MESON_REGMAP
+ select COMMON_CLK_MESON_CLKC_UTILS
+ select COMMON_CLK_MESON_DUALDIV
+ select COMMON_CLK_MESON_VID_PLL_DIV
+ imply COMMON_CLK_SCMI
+ imply COMMON_CLK_A9_PLL
+ help
+ Support for the peripherals clock controller on Amlogic A311Y3 based
+ device, AKA A9. Peripherals are required by most peripheral to operate.
+ Say Y if you want A9 peripherals clock controller to work.
+
config COMMON_CLK_A9_AO
tristate "Amlogic A9 SoC AO clock controller support"
depends on ARM64 || COMPILE_TEST
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index f89d027c282c..56b04254eb1a 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o
obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
obj-$(CONFIG_COMMON_CLK_A1_PLL) += a1-pll.o
obj-$(CONFIG_COMMON_CLK_A1_PERIPHERALS) += a1-peripherals.o
+obj-$(CONFIG_COMMON_CLK_A9_PERIPHERALS) += a9-peripherals.o
obj-$(CONFIG_COMMON_CLK_A9_AO) += a9-aoclk.o
obj-$(CONFIG_COMMON_CLK_C3_PLL) += c3-pll.o
obj-$(CONFIG_COMMON_CLK_C3_PERIPHERALS) += c3-peripherals.o
diff --git a/drivers/clk/meson/a9-peripherals.c b/drivers/clk/meson/a9-peripherals.c
new file mode 100644
index 000000000000..b77e35f48c1f
--- /dev/null
+++ b/drivers/clk/meson/a9-peripherals.c
@@ -0,0 +1,2089 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR MIT)
+/*
+ * Copyright (C) 2026 Amlogic, Inc. All rights reserved
+ */
+
+#include <dt-bindings/clock/amlogic,a9-peripherals-clkc.h>
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include "clk-regmap.h"
+#include "clk-dualdiv.h"
+#include "meson-clkc-utils.h"
+#include "vid-pll-div.h"
+
+#define SYS_CLK_EN0_REG0 0x30
+#define SYS_CLK_EN0_REG1 0x34
+#define SYS_CLK_EN0_REG2 0x38
+#define SYS_CLK_EN0_REG3 0x3c
+#define SD_EMMC_CLK_CTRL0 0x90
+#define SD_EMMC_CLK_CTRL1 0x94
+#define PWM_CLK_H_CTRL 0xbc
+#define PWM_CLK_I_CTRL 0xc0
+#define PWM_CLK_J_CTRL 0xc4
+#define PWM_CLK_K_CTRL 0xc8
+#define PWM_CLK_L_CTRL 0xcc
+#define PWM_CLK_M_CTRL 0xd0
+#define PWM_CLK_N_CTRL 0xd4
+#define SPISG_CLK_CTRL 0x100
+#define SPISG_CLK_CTRL1 0x104
+#define SAR_CLK_CTRL 0x150
+#define AMFC_CLK_CTRL 0x154
+#define NNA_CLK_CTRL 0x15c
+#define USB_CLK_CTRL 0x160
+#define PCIE_TL_CLK_CTRL 0x164
+#define CMPR_CLK_CTRL 0x168
+#define DEWARP_CLK_CTRL 0x16c
+#define SC_CLK_CTRL 0x170
+#define DPTX_CLK_CTRL 0x178
+#define ISP_CLK_CTRL 0x17c
+#define CVE_CLK_CTRL 0x180
+#define PP_CLK_CTRL 0x184
+#define GLB_CLK_CTRL 0x188
+#define USB_CLK_CTRL0 0x18c
+#define USB_CLK_CTRL1 0x190
+#define CAN_CLK_CTRL 0x194
+#define CAN_CLK_CTRL1 0x198
+#define I3C_CLK_CTRL 0x19c
+#define TS_CLK_CTRL 0x1a0
+#define ETH_CLK_CTRL 0x1a4
+#define GEN_CLK_CTRL 0x1a8
+#define CLK12_24_CTRL 0x1ac
+#define MALI_CLK_CTRL 0x200
+#define MALI_STACK_CLK_CTRL 0x204
+#define DSPA_CLK_CTRL 0x220
+#define HEVCF_CLK_CTRL 0x240
+#define HCODEC_CLK_CTRL 0x244
+#define VPU_CLK_CTRL 0x260
+#define VAPB_CLK_CTRL 0x268
+#define VPU_CLKB_CTRL 0x280
+#define HDMI_CLK_CTRL 0x284
+#define HTX_CLK_CTRL 0x28c
+#define HTX_CLK_CTRL1 0x290
+#define HRX_CLK_CTRL 0x294
+#define HRX_CLK_CTRL1 0x298
+#define HRX_CLK_CTRL2 0x29c
+#define HRX_CLK_CTRL3 0x2a0
+#define VID_LOCK_CLK_CTRL 0x2a4
+#define VDIN_MEAS_CLK_CTRL 0x2a8
+#define VID_PLL_CLK_DIV 0x2b0
+#define VID_CLK_CTRL 0x2c0
+#define VID_CLK_CTRL2 0x2c4
+#define VID_CLK_DIV 0x2c8
+#define VIID_CLK_DIV 0x2cc
+#define VIID_CLK_CTRL 0x2d0
+#define MIPI_CSI_PHY_CLK_CTRL 0x2e0
+#define DSI_MEAS_CLK_CTRL 0x2f4
+
+#define A9_COMP_SEL(_name, _reg, _shift, _mask, _pdata, _table) \
+ MESON_COMP_SEL(a9_, _name, _reg, _shift, _mask, _pdata, _table, 0, 0)
+
+#define A9_COMP_DIV(_name, _reg, _shift, _width) \
+ MESON_COMP_DIV(a9_, _name, _reg, _shift, _width, 0, CLK_SET_RATE_PARENT)
+
+#define A9_COMP_GATE(_name, _reg, _bit, _iflags) \
+ MESON_COMP_GATE(a9_, _name, _reg, _bit, CLK_SET_RATE_PARENT | (_iflags))
+
+static const struct clk_parent_data a9_sys_pclk_parents = { .fw_name = "sys" };
+
+#define A9_SYS_PCLK(_name, _reg, _bit) \
+ MESON_PCLK(a9_##_name, _reg, _bit, &a9_sys_pclk_parents, 0)
+
+static A9_SYS_PCLK(sys_am_axi, SYS_CLK_EN0_REG0, 0);
+static A9_SYS_PCLK(sys_dos, SYS_CLK_EN0_REG0, 1);
+static A9_SYS_PCLK(sys_mipi_dsi0, SYS_CLK_EN0_REG0, 3);
+static A9_SYS_PCLK(sys_eth_phy, SYS_CLK_EN0_REG0, 4);
+static A9_SYS_PCLK(sys_amfc, SYS_CLK_EN0_REG0, 5);
+static A9_SYS_PCLK(sys_mali, SYS_CLK_EN0_REG0, 6);
+static A9_SYS_PCLK(sys_nna, SYS_CLK_EN0_REG0, 7);
+static A9_SYS_PCLK(sys_eth_axi, SYS_CLK_EN0_REG0, 8);
+static A9_SYS_PCLK(sys_dp_apb, SYS_CLK_EN0_REG0, 9);
+static A9_SYS_PCLK(sys_edptx_apb, SYS_CLK_EN0_REG0, 10);
+static A9_SYS_PCLK(sys_u3hsg, SYS_CLK_EN0_REG0, 11);
+static A9_SYS_PCLK(sys_aucpu, SYS_CLK_EN0_REG0, 14);
+static A9_SYS_PCLK(sys_glb, SYS_CLK_EN0_REG0, 15);
+static A9_SYS_PCLK(sys_combo_dphy_apb, SYS_CLK_EN0_REG0, 17);
+static A9_SYS_PCLK(sys_hdmirx_apb, SYS_CLK_EN0_REG0, 18);
+static A9_SYS_PCLK(sys_hdmirx_pclk, SYS_CLK_EN0_REG0, 19);
+static A9_SYS_PCLK(sys_mipi_dsi0_phy, SYS_CLK_EN0_REG0, 20);
+static A9_SYS_PCLK(sys_can0, SYS_CLK_EN0_REG0, 21);
+static A9_SYS_PCLK(sys_can1, SYS_CLK_EN0_REG0, 22);
+static A9_SYS_PCLK(sys_sd_emmc_a, SYS_CLK_EN0_REG0, 24);
+static A9_SYS_PCLK(sys_sd_emmc_b, SYS_CLK_EN0_REG0, 25);
+static A9_SYS_PCLK(sys_sd_emmc_c, SYS_CLK_EN0_REG0, 26);
+static A9_SYS_PCLK(sys_sc, SYS_CLK_EN0_REG0, 27);
+static A9_SYS_PCLK(sys_acodec, SYS_CLK_EN0_REG0, 28);
+static A9_SYS_PCLK(sys_mipi_isp, SYS_CLK_EN0_REG0, 29);
+static A9_SYS_PCLK(sys_msr, SYS_CLK_EN0_REG0, 30);
+static A9_SYS_PCLK(sys_audio, SYS_CLK_EN0_REG1, 0);
+static A9_SYS_PCLK(sys_mipi_dsi1, SYS_CLK_EN0_REG1, 1);
+static A9_SYS_PCLK(sys_mipi_dsi1_phy, SYS_CLK_EN0_REG1, 2);
+static A9_SYS_PCLK(sys_eth, SYS_CLK_EN0_REG1, 3);
+static A9_SYS_PCLK(sys_eth_1g_mac, SYS_CLK_EN0_REG1, 4);
+static A9_SYS_PCLK(sys_uart_a, SYS_CLK_EN0_REG1, 5);
+static A9_SYS_PCLK(sys_uart_f, SYS_CLK_EN0_REG1, 10);
+static A9_SYS_PCLK(sys_ts_a55, SYS_CLK_EN0_REG1, 11);
+static A9_SYS_PCLK(sys_eth_1g_axi, SYS_CLK_EN0_REG1, 12);
+static A9_SYS_PCLK(sys_ts_dos, SYS_CLK_EN0_REG1, 13);
+static A9_SYS_PCLK(sys_u3drd_b, SYS_CLK_EN0_REG1, 14);
+static A9_SYS_PCLK(sys_ts_core, SYS_CLK_EN0_REG1, 15);
+static A9_SYS_PCLK(sys_ts_pll, SYS_CLK_EN0_REG1, 16);
+static A9_SYS_PCLK(sys_csi_dig_clkin, SYS_CLK_EN0_REG1, 18);
+static A9_SYS_PCLK(sys_cve, SYS_CLK_EN0_REG1, 19);
+static A9_SYS_PCLK(sys_ge2d, SYS_CLK_EN0_REG1, 20);
+static A9_SYS_PCLK(sys_spisg, SYS_CLK_EN0_REG1, 21);
+static A9_SYS_PCLK(sys_u2h, SYS_CLK_EN0_REG1, 23);
+static A9_SYS_PCLK(sys_pcie_mac_a, SYS_CLK_EN0_REG1, 24);
+static A9_SYS_PCLK(sys_u3drd_a, SYS_CLK_EN0_REG1, 25);
+static A9_SYS_PCLK(sys_u2drd, SYS_CLK_EN0_REG1, 26);
+static A9_SYS_PCLK(sys_pcie_phy, SYS_CLK_EN0_REG1, 27);
+static A9_SYS_PCLK(sys_pcie_mac_b, SYS_CLK_EN0_REG1, 28);
+static A9_SYS_PCLK(sys_periph, SYS_CLK_EN0_REG1, 29);
+static A9_SYS_PCLK(sys_pio, SYS_CLK_EN0_REG2, 0);
+static A9_SYS_PCLK(sys_i3c, SYS_CLK_EN0_REG2, 1);
+static A9_SYS_PCLK(sys_i2c_m_e, SYS_CLK_EN0_REG2, 2);
+static A9_SYS_PCLK(sys_i2c_m_f, SYS_CLK_EN0_REG2, 3);
+static A9_SYS_PCLK(sys_hdmitx_apb, SYS_CLK_EN0_REG2, 4);
+static A9_SYS_PCLK(sys_i2c_m_i, SYS_CLK_EN0_REG2, 5);
+static A9_SYS_PCLK(sys_i2c_m_g, SYS_CLK_EN0_REG2, 6);
+static A9_SYS_PCLK(sys_i2c_m_h, SYS_CLK_EN0_REG2, 7);
+static A9_SYS_PCLK(sys_hdmi20_aes, SYS_CLK_EN0_REG2, 9);
+static A9_SYS_PCLK(sys_csi2_host, SYS_CLK_EN0_REG2, 16);
+static A9_SYS_PCLK(sys_csi2_adapt, SYS_CLK_EN0_REG2, 17);
+static A9_SYS_PCLK(sys_dspa, SYS_CLK_EN0_REG2, 21);
+static A9_SYS_PCLK(sys_pp_dma, SYS_CLK_EN0_REG2, 22);
+static A9_SYS_PCLK(sys_pp_wrapper, SYS_CLK_EN0_REG2, 23);
+static A9_SYS_PCLK(sys_vpu_intr, SYS_CLK_EN0_REG2, 25);
+static A9_SYS_PCLK(sys_csi2_phy, SYS_CLK_EN0_REG2, 27);
+static A9_SYS_PCLK(sys_saradc, SYS_CLK_EN0_REG2, 28);
+static A9_SYS_PCLK(sys_pwm_j, SYS_CLK_EN0_REG2, 30);
+static A9_SYS_PCLK(sys_pwm_i, SYS_CLK_EN0_REG2, 31);
+static A9_SYS_PCLK(sys_pwm_h, SYS_CLK_EN0_REG3, 0);
+static A9_SYS_PCLK(sys_pwm_n, SYS_CLK_EN0_REG3, 8);
+static A9_SYS_PCLK(sys_pwm_m, SYS_CLK_EN0_REG3, 9);
+static A9_SYS_PCLK(sys_pwm_l, SYS_CLK_EN0_REG3, 10);
+static A9_SYS_PCLK(sys_pwm_k, SYS_CLK_EN0_REG3, 11);
+
+/* Channel 5 is unconnected. */
+static u32 a9_sd_emmc_parents_val_table[] = { 0, 1, 2, 3, 4, 6, 7 };
+static const struct clk_parent_data a9_sd_emmc_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv2", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "hifi0", },
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "gp1", },
+ { .fw_name = "gp0", }
+};
+
+static A9_COMP_SEL(sd_emmc_a, SD_EMMC_CLK_CTRL0, 9, 0x7, a9_sd_emmc_parents,
+ a9_sd_emmc_parents_val_table);
+static A9_COMP_DIV(sd_emmc_a, SD_EMMC_CLK_CTRL0, 0, 7);
+static A9_COMP_GATE(sd_emmc_a, SD_EMMC_CLK_CTRL0, 8, 0);
+
+static A9_COMP_SEL(sd_emmc_b, SD_EMMC_CLK_CTRL0, 25, 0x7, a9_sd_emmc_parents,
+ a9_sd_emmc_parents_val_table);
+static A9_COMP_DIV(sd_emmc_b, SD_EMMC_CLK_CTRL0, 16, 7);
+static A9_COMP_GATE(sd_emmc_b, SD_EMMC_CLK_CTRL0, 24, 0);
+
+static A9_COMP_SEL(sd_emmc_c, SD_EMMC_CLK_CTRL1, 9, 0x7, a9_sd_emmc_parents,
+ a9_sd_emmc_parents_val_table);
+static A9_COMP_DIV(sd_emmc_c, SD_EMMC_CLK_CTRL1, 0, 7);
+static A9_COMP_GATE(sd_emmc_c, SD_EMMC_CLK_CTRL1, 8, 0);
+
+static const struct clk_parent_data a9_pwm_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", }
+};
+
+static A9_COMP_SEL(pwm_h, PWM_CLK_H_CTRL, 9, 0x7, a9_pwm_parents, NULL);
+static A9_COMP_DIV(pwm_h, PWM_CLK_H_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_h, PWM_CLK_H_CTRL, 8, 0);
+
+static A9_COMP_SEL(pwm_i, PWM_CLK_I_CTRL, 9, 0x7, a9_pwm_parents, NULL);
+static A9_COMP_DIV(pwm_i, PWM_CLK_I_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_i, PWM_CLK_I_CTRL, 8, 0);
+
+static A9_COMP_SEL(pwm_j, PWM_CLK_J_CTRL, 9, 0x7, a9_pwm_parents, NULL);
+static A9_COMP_DIV(pwm_j, PWM_CLK_J_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_j, PWM_CLK_J_CTRL, 8, 0);
+
+static A9_COMP_SEL(pwm_k, PWM_CLK_K_CTRL, 9, 0x7, a9_pwm_parents, NULL);
+static A9_COMP_DIV(pwm_k, PWM_CLK_K_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_k, PWM_CLK_K_CTRL, 8, 0);
+
+static A9_COMP_SEL(pwm_l, PWM_CLK_L_CTRL, 9, 0x7, a9_pwm_parents, NULL);
+static A9_COMP_DIV(pwm_l, PWM_CLK_L_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_l, PWM_CLK_L_CTRL, 8, 0);
+
+static A9_COMP_SEL(pwm_m, PWM_CLK_M_CTRL, 9, 0x7, a9_pwm_parents, NULL);
+static A9_COMP_DIV(pwm_m, PWM_CLK_M_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_m, PWM_CLK_M_CTRL, 8, 0);
+
+static A9_COMP_SEL(pwm_n, PWM_CLK_N_CTRL, 9, 0x7, a9_pwm_parents, NULL);
+static A9_COMP_DIV(pwm_n, PWM_CLK_N_CTRL, 0, 8);
+static A9_COMP_GATE(pwm_n, PWM_CLK_N_CTRL, 8, 0);
+
+static const struct clk_parent_data a9_spisg_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "sys", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv2", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv7", },
+ { .fw_name = "gp0", }
+};
+
+static A9_COMP_SEL(spisg0, SPISG_CLK_CTRL, 9, 0x7, a9_spisg_parents, NULL);
+static A9_COMP_DIV(spisg0, SPISG_CLK_CTRL, 0, 6);
+static A9_COMP_GATE(spisg0, SPISG_CLK_CTRL, 8, 0);
+
+static A9_COMP_SEL(spisg1, SPISG_CLK_CTRL, 25, 0x7, a9_spisg_parents, NULL);
+static A9_COMP_DIV(spisg1, SPISG_CLK_CTRL, 16, 6);
+static A9_COMP_GATE(spisg1, SPISG_CLK_CTRL, 24, 0);
+
+static A9_COMP_SEL(spisg2, SPISG_CLK_CTRL1, 9, 0x7, a9_spisg_parents, NULL);
+static A9_COMP_DIV(spisg2, SPISG_CLK_CTRL1, 0, 6);
+static A9_COMP_GATE(spisg2, SPISG_CLK_CTRL1, 8, 0);
+
+static const struct clk_parent_data a9_saradc_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "sys", }
+};
+
+static A9_COMP_SEL(saradc, SAR_CLK_CTRL, 9, 0x7, a9_saradc_parents, NULL);
+static A9_COMP_DIV(saradc, SAR_CLK_CTRL, 0, 8);
+static A9_COMP_GATE(saradc, SAR_CLK_CTRL, 8, 0);
+
+static const struct clk_parent_data a9_amfc_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "sys", },
+ { .fw_name = "fdiv2", },
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv7", }
+};
+
+static A9_COMP_SEL(amfc, AMFC_CLK_CTRL, 9, 0x7, a9_amfc_parents, NULL);
+static A9_COMP_DIV(amfc, AMFC_CLK_CTRL, 0, 6);
+static A9_COMP_GATE(amfc, AMFC_CLK_CTRL, 8, 0);
+
+static const struct clk_parent_data a9_nna_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv2", },
+ { .fw_name = "gp2", },
+ { .fw_name = "hifi0", }
+};
+
+static A9_COMP_SEL(nna, NNA_CLK_CTRL, 9, 0x7, a9_nna_parents, NULL);
+static A9_COMP_DIV(nna, NNA_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(nna, NNA_CLK_CTRL, 8, 0);
+
+/* Channel 5 and 6 are unconnected. */
+static u32 a9_usb_250m_parents_val_table[] = { 0, 1, 2, 3, 4, 7 };
+static const struct clk_parent_data a9_usb_250m_parents[] = {
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv2", },
+ { .fw_name = "fdiv7", },
+ { .fw_name = "fdiv2p5", }
+};
+
+static A9_COMP_SEL(usb_250m, USB_CLK_CTRL, 9, 0x7, a9_usb_250m_parents,
+ a9_usb_250m_parents_val_table);
+static A9_COMP_DIV(usb_250m, USB_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(usb_250m, USB_CLK_CTRL, 8, 0);
+
+static const struct clk_parent_data a9_usb_48m_pre_parents[] = {
+ { .fw_name = "gp0", },
+ { .fw_name = "gp1", },
+ { .fw_name = "gp2", },
+ { .fw_name = "fdiv2", }
+};
+
+static A9_COMP_SEL(usb_48m_pre, USB_CLK_CTRL, 25, 0x3, a9_usb_48m_pre_parents, NULL);
+static A9_COMP_DIV(usb_48m_pre, USB_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(usb_48m_pre, USB_CLK_CTRL, 24, 0);
+
+static const struct clk_parent_data a9_pcie_tl_parents[] = {
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv2", },
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "gp0", },
+ { .fw_name = "sys", },
+ { .fw_name = "xtal", }
+};
+
+static A9_COMP_SEL(pcie0_tl, PCIE_TL_CLK_CTRL, 9, 0x7, a9_pcie_tl_parents, NULL);
+static A9_COMP_DIV(pcie0_tl, PCIE_TL_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(pcie0_tl, PCIE_TL_CLK_CTRL, 8, 0);
+
+static A9_COMP_SEL(pcie1_tl, PCIE_TL_CLK_CTRL, 25, 0x7, a9_pcie_tl_parents, NULL);
+static A9_COMP_DIV(pcie1_tl, PCIE_TL_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(pcie1_tl, PCIE_TL_CLK_CTRL, 24, 0);
+
+static const struct clk_parent_data a9_cmpr_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv7", },
+ { .fw_name = "hifi0", },
+ { .fw_name = "gp1", }
+};
+
+static A9_COMP_SEL(cmpr, CMPR_CLK_CTRL, 25, 0x7, a9_cmpr_parents, NULL);
+static A9_COMP_DIV(cmpr, CMPR_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(cmpr, CMPR_CLK_CTRL, 24, 0);
+
+static const struct clk_parent_data a9_dewarpa_parents[] = {
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv7", },
+ { .fw_name = "gp0", },
+ { .fw_name = "hifi0", },
+ { .fw_name = "gp1", }
+};
+
+static A9_COMP_SEL(dewarpa, DEWARP_CLK_CTRL, 9, 0x7, a9_dewarpa_parents, NULL);
+static A9_COMP_DIV(dewarpa, DEWARP_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(dewarpa, DEWARP_CLK_CTRL, 8, 0);
+
+static const struct clk_parent_data a9_sc_parents[] = {
+ { .fw_name = "fdiv2", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "xtal", }
+};
+
+static A9_COMP_SEL(sc_pre, SC_CLK_CTRL, 9, 0x7, a9_sc_parents, NULL);
+static A9_COMP_DIV(sc_pre, SC_CLK_CTRL, 0, 8);
+static A9_COMP_GATE(sc_pre, SC_CLK_CTRL, 8, 0);
+
+static struct clk_regmap a9_sc = {
+ .data = &(struct clk_regmap_div_data) {
+ .offset = SC_CLK_CTRL,
+ .shift = 16,
+ .width = 4,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "sc",
+ .ops = &clk_regmap_divider_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &a9_sc_pre.hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static const struct clk_parent_data a9_dptx_apb2_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "sys", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", }
+};
+
+static A9_COMP_SEL(dptx_apb2, DPTX_CLK_CTRL, 9, 0x7, a9_dptx_apb2_parents, NULL);
+static A9_COMP_DIV(dptx_apb2, DPTX_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(dptx_apb2, DPTX_CLK_CTRL, 8, 0);
+
+static const struct clk_parent_data a9_dptx_aud_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "sys", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", }
+};
+
+static A9_COMP_SEL(dptx_aud, DPTX_CLK_CTRL, 25, 0x7, a9_dptx_aud_parents, NULL);
+static A9_COMP_DIV(dptx_aud, DPTX_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(dptx_aud, DPTX_CLK_CTRL, 24, 0);
+
+static const struct clk_parent_data a9_isp_parents[] = {
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "gp0", },
+ { .fw_name = "hifi0", },
+ { .fw_name = "fdiv2", },
+ { .fw_name = "xtal", }
+};
+
+static A9_COMP_SEL(isp, ISP_CLK_CTRL, 9, 0x7, a9_isp_parents, NULL);
+static A9_COMP_DIV(isp, ISP_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(isp, ISP_CLK_CTRL, 8, 0);
+
+static const struct clk_parent_data a9_cve_vge_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "hifi0", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "gp0", },
+ { .fw_name = "rtc", }
+};
+
+static A9_COMP_SEL(cve, CVE_CLK_CTRL, 9, 0x7, a9_cve_vge_parents, NULL);
+static A9_COMP_DIV(cve, CVE_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(cve, CVE_CLK_CTRL, 8, 0);
+
+static A9_COMP_SEL(vge, CVE_CLK_CTRL, 25, 0x7, a9_cve_vge_parents, NULL);
+static A9_COMP_DIV(vge, CVE_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(vge, CVE_CLK_CTRL, 24, 0);
+
+static const struct clk_parent_data a9_pp_parents[] = {
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv2", },
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "gp0", },
+ { .fw_name = "sys", },
+ { .fw_name = "xtal", }
+};
+
+static A9_COMP_SEL(pp, PP_CLK_CTRL, 9, 0x7, a9_pp_parents, NULL);
+static A9_COMP_DIV(pp, PP_CLK_CTRL, 0, 6);
+static A9_COMP_GATE(pp, PP_CLK_CTRL, 8, 0);
+
+static const struct clk_parent_data a9_dspa_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "gp2", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "hifi0", },
+ { .fw_name = "rtc", }
+};
+
+static A9_COMP_SEL(dspa_0, DSPA_CLK_CTRL, 9, 0x7, a9_dspa_parents, NULL);
+static A9_COMP_DIV(dspa_0, DSPA_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(dspa_0, DSPA_CLK_CTRL, 8, CLK_SET_RATE_GATE);
+
+static A9_COMP_SEL(dspa_1, DSPA_CLK_CTRL, 25, 0x7, a9_dspa_parents, NULL);
+static A9_COMP_DIV(dspa_1, DSPA_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(dspa_1, DSPA_CLK_CTRL, 24, CLK_SET_RATE_GATE);
+
+static struct clk_regmap a9_dspa = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = DSPA_CLK_CTRL,
+ .mask = 0x1,
+ .shift = 31,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "dspa",
+ .ops = &clk_regmap_mux_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &a9_dspa_0.hw,
+ &a9_dspa_1.hw
+ },
+ .num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+/* Channel 6 is unconnected. */
+static u32 a9_glb_parents_val_table[] = { 0, 1, 2, 3, 4, 5, 7 };
+static const struct clk_parent_data a9_glb_parents[] = {
+ { .fw_name = "xtal", },
+ { .hw = &a9_dspa.hw },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .hw = &a9_isp.hw },
+ { .fw_name = "rtc", }
+};
+
+static A9_COMP_SEL(glb, GLB_CLK_CTRL, 9, 0x7, a9_glb_parents, a9_glb_parents_val_table);
+static A9_COMP_DIV(glb, GLB_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(glb, GLB_CLK_CTRL, 8, 0);
+
+static struct clk_regmap a9_usb_48m_dualdiv_in = {
+ .data = &(struct clk_regmap_gate_data) {
+ .offset = USB_CLK_CTRL,
+ .bit_idx = 31,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "usb_48m_dualdiv_in",
+ .ops = &clk_regmap_gate_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &a9_usb_48m_pre.hw
+ },
+ .num_parents = 1,
+ },
+};
+
+static const struct meson_clk_dualdiv_param a9_usb_48m_dualdiv_div_table[] = {
+ { 733, 732, 8, 11, 1 },
+ { /* sentinel */ }
+};
+
+static struct clk_regmap a9_usb_48m_dualdiv_div = {
+ .data = &(struct meson_clk_dualdiv_data) {
+ .n1 = {
+ .reg_off = USB_CLK_CTRL0,
+ .shift = 0,
+ .width = 12,
+ },
+ .n2 = {
+ .reg_off = USB_CLK_CTRL0,
+ .shift = 12,
+ .width = 12,
+ },
+ .m1 = {
+ .reg_off = USB_CLK_CTRL1,
+ .shift = 0,
+ .width = 12,
+ },
+ .m2 = {
+ .reg_off = USB_CLK_CTRL1,
+ .shift = 12,
+ .width = 12,
+ },
+ .dual = {
+ .reg_off = USB_CLK_CTRL0,
+ .shift = 28,
+ .width = 1,
+ },
+ .table = a9_usb_48m_dualdiv_div_table,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "usb_48m_dualdiv_div",
+ .ops = &meson_clk_dualdiv_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &a9_usb_48m_dualdiv_in.hw
+ },
+ .num_parents = 1,
+ },
+};
+
+static struct clk_regmap a9_usb_48m_dualdiv_sel = {
+ .data = &(struct clk_regmap_mux_data) {
+ .offset = USB_CLK_CTRL1,
+ .mask = 0x1,
+ .shift = 24,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "usb_48m_dualdiv_sel",
+ .ops = &clk_regmap_mux_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &a9_usb_48m_dualdiv_in.hw,
+ &a9_usb_48m_dualdiv_div.hw,
+ },
+ .num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_regmap a9_usb_48m_dualdiv = {
+ .data = &(struct clk_regmap_gate_data) {
+ .offset = USB_CLK_CTRL0,
+ .bit_idx = 30,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "usb_48m_dualdiv",
+ .ops = &clk_regmap_gate_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &a9_usb_48m_dualdiv_sel.hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_regmap a9_usb_48m = {
+ .data = &(struct clk_regmap_mux_data) {
+ .offset = USB_CLK_CTRL1,
+ .mask = 0x3,
+ .shift = 30,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "usb_48m",
+ .ops = &clk_regmap_mux_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &a9_usb_48m_pre.hw,
+ &a9_usb_48m_dualdiv.hw,
+ },
+ .num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+/* Channel 2 is unconnected. */
+static u32 a9_can_pe_parents_val_table[] = { 0, 1, 3 };
+static const struct clk_parent_data a9_can_pe_parents[] = {
+ { .fw_name = "sys", },
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv5", }
+};
+
+static A9_COMP_SEL(can0_pe, CAN_CLK_CTRL, 9, 0x7, a9_can_pe_parents, a9_can_pe_parents_val_table);
+static A9_COMP_DIV(can0_pe, CAN_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(can0_pe, CAN_CLK_CTRL, 8, 0);
+
+static A9_COMP_SEL(can1_pe, CAN_CLK_CTRL, 25, 0x7, a9_can_pe_parents, a9_can_pe_parents_val_table);
+static A9_COMP_DIV(can1_pe, CAN_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(can1_pe, CAN_CLK_CTRL, 24, 0);
+
+static const struct clk_parent_data a9_can_filter_parents[] = {
+ { .fw_name = "sys", },
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", }
+};
+
+static A9_COMP_SEL(can0_filter, CAN_CLK_CTRL1, 9, 0x7, a9_can_filter_parents, NULL);
+static A9_COMP_DIV(can0_filter, CAN_CLK_CTRL1, 0, 7);
+static A9_COMP_GATE(can0_filter, CAN_CLK_CTRL1, 8, 0);
+
+static A9_COMP_SEL(can1_filter, CAN_CLK_CTRL1, 25, 0x7, a9_can_filter_parents, NULL);
+static A9_COMP_DIV(can1_filter, CAN_CLK_CTRL1, 16, 7);
+static A9_COMP_GATE(can1_filter, CAN_CLK_CTRL1, 24, 0);
+
+static const struct clk_parent_data a9_i3c_parents[] = {
+ { .fw_name = "sys", },
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv5", }
+};
+
+static A9_COMP_SEL(i3c, I3C_CLK_CTRL, 9, 0x7, a9_i3c_parents, NULL);
+static A9_COMP_DIV(i3c, I3C_CLK_CTRL, 0, 8);
+static A9_COMP_GATE(i3c, I3C_CLK_CTRL, 8, 0);
+
+static struct clk_regmap a9_ts_div = {
+ .data = &(struct clk_regmap_div_data) {
+ .offset = TS_CLK_CTRL,
+ .shift = 0,
+ .width = 8,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "ts_div",
+ .ops = &clk_regmap_divider_ops,
+ .parent_data = &(const struct clk_parent_data) {
+ .fw_name = "xtal",
+ },
+ .num_parents = 1,
+ },
+};
+
+static struct clk_regmap a9_ts = {
+ .data = &(struct clk_regmap_gate_data) {
+ .offset = TS_CLK_CTRL,
+ .bit_idx = 8,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "ts",
+ .ops = &clk_regmap_gate_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &a9_ts_div.hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_fixed_factor a9_eth_125m_div = {
+ .mult = 1,
+ .div = 8,
+ .hw.init = &(struct clk_init_data) {
+ .name = "eth_125m_div",
+ .ops = &clk_fixed_factor_ops,
+ .parent_data = &(const struct clk_parent_data) {
+ .fw_name = "fdiv2",
+ },
+ .num_parents = 1,
+ },
+};
+
+static struct clk_regmap a9_eth_125m = {
+ .data = &(struct clk_regmap_gate_data) {
+ .offset = ETH_CLK_CTRL,
+ .bit_idx = 7,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "eth_125m",
+ .ops = &clk_regmap_gate_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &a9_eth_125m_div.hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+/*
+ * Channel 1, 2, 3, 4, 5 and 6 are unconnected,
+ * Channel 7(ext_rmii) connects external PAD. Do not automatically reparent.
+ */
+static u32 a9_eth_rmii_parents_val_table[] = { 0, 7 };
+static const struct clk_parent_data a9_eth_rmii_parents[] = {
+ { .fw_name = "fdiv2", },
+ { .fw_name = "ext_rmii", }
+};
+
+static struct clk_regmap a9_eth_rmii_sel = {
+ .data = &(struct clk_regmap_mux_data) {
+ .offset = ETH_CLK_CTRL,
+ .mask = 0x7,
+ .shift = 9,
+ .table = a9_eth_rmii_parents_val_table,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "eth_rmii_sel",
+ .ops = &clk_regmap_mux_ops,
+ .parent_data = a9_eth_rmii_parents,
+ .num_parents = ARRAY_SIZE(a9_eth_rmii_parents),
+ .flags = CLK_SET_RATE_NO_REPARENT,
+ },
+};
+
+static struct clk_regmap a9_eth_rmii_div = {
+ .data = &(struct clk_regmap_div_data) {
+ .offset = ETH_CLK_CTRL,
+ .shift = 0,
+ .width = 7,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "eth_rmii_div",
+ .ops = &clk_regmap_divider_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &a9_eth_rmii_sel.hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_regmap a9_eth_rmii = {
+ .data = &(struct clk_regmap_gate_data) {
+ .offset = ETH_CLK_CTRL,
+ .bit_idx = 8,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "eth_rmii",
+ .ops = &clk_regmap_gate_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &a9_eth_rmii_div.hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_regmap a9_vid_pll_div = {
+ .data = &(struct meson_vid_pll_div_data){
+ .val = {
+ .reg_off = VID_PLL_CLK_DIV,
+ .shift = 0,
+ .width = 15,
+ },
+ .sel = {
+ .reg_off = VID_PLL_CLK_DIV,
+ .shift = 16,
+ .width = 2,
+ },
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "vid_pll_div",
+ .ops = &meson_vid_pll_div_ro_ops,
+ .parent_data = (const struct clk_parent_data []) {
+ { .fw_name = "hdmiout2", }
+ },
+ .num_parents = 1,
+ },
+};
+
+static struct clk_regmap a9_vid_pll_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = VID_PLL_CLK_DIV,
+ .mask = 0x1,
+ .shift = 18,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "vid_pll_sel",
+ .ops = &clk_regmap_mux_ops,
+ .parent_data = (const struct clk_parent_data []) {
+ { .hw = &a9_vid_pll_div.hw },
+ { .fw_name = "hdmiout2", }
+ },
+ .num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_regmap a9_vid_pll = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_PLL_CLK_DIV,
+ .bit_idx = 19,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "vid_pll",
+ .ops = &clk_regmap_gate_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &a9_vid_pll_sel.hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+/*
+ * Channel 12 (msr_clk) is managed by the clock measurement module and is not part of the clock
+ * tree. It depends on the measurement source selected through the measurement control registers.
+ *
+ * Channel 10, 11, 13, 14 and 16 are unconnected.
+ */
+static u32 a9_gen_parents_val_table[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 15, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26};
+static const struct clk_parent_data a9_gen_parents[] = {
+ { .fw_name = "xtal" },
+ { .fw_name = "rtc" },
+ { .fw_name = "sysplldiv16" },
+ { .fw_name = "ddr_test" },
+ { .hw = &a9_vid_pll.hw },
+ { .fw_name = "gp0" },
+ { .fw_name = "hifi1" },
+ { .fw_name = "hifi0" },
+ { .fw_name = "gp1" },
+ { .fw_name = "gp2" },
+ { .fw_name = "dsudiv16" },
+ { .fw_name = "cpudiv16" },
+ { .fw_name = "a78div16" },
+ { .fw_name = "fdiv2" },
+ { .fw_name = "fdiv2p5" },
+ { .fw_name = "fdiv3" },
+ { .fw_name = "fdiv4" },
+ { .fw_name = "fdiv5" },
+ { .fw_name = "fdiv7" },
+ { .fw_name = "mclk0" },
+ { .fw_name = "mclk1" }
+};
+
+static A9_COMP_SEL(gen, GEN_CLK_CTRL, 12, 0x1f, a9_gen_parents, a9_gen_parents_val_table);
+static A9_COMP_DIV(gen, GEN_CLK_CTRL, 0, 11);
+static A9_COMP_GATE(gen, GEN_CLK_CTRL, 11, 0);
+
+static struct clk_regmap a9_24m_in = {
+ .data = &(struct clk_regmap_gate_data) {
+ .offset = CLK12_24_CTRL,
+ .bit_idx = 11,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "24m_in",
+ .ops = &clk_regmap_gate_ops,
+ .parent_data = &(const struct clk_parent_data) {
+ .fw_name = "xtal",
+ },
+ .num_parents = 1,
+ },
+};
+
+static struct clk_regmap a9_12_24m = {
+ .data = &(struct clk_regmap_div_data) {
+ .offset = CLK12_24_CTRL,
+ .shift = 10,
+ .width = 1,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "12_24m",
+ .ops = &clk_regmap_divider_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &a9_24m_in.hw
+ },
+ .num_parents = 1,
+ },
+};
+
+static const struct clk_parent_data a9_mali_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "gp1", },
+ { .fw_name = "fdiv2", },
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv7", }
+};
+
+static A9_COMP_SEL(mali_0, MALI_CLK_CTRL, 9, 0x7, a9_mali_parents, NULL);
+static A9_COMP_DIV(mali_0, MALI_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(mali_0, MALI_CLK_CTRL, 8, CLK_SET_RATE_GATE);
+
+static A9_COMP_SEL(mali_1, MALI_CLK_CTRL, 25, 0x7, a9_mali_parents, NULL);
+static A9_COMP_DIV(mali_1, MALI_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(mali_1, MALI_CLK_CTRL, 24, CLK_SET_RATE_GATE);
+
+static struct clk_regmap a9_mali = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = MALI_CLK_CTRL,
+ .mask = 0x1,
+ .shift = 31,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "mali",
+ .ops = &clk_regmap_mux_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &a9_mali_0.hw,
+ &a9_mali_1.hw
+ },
+ .num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static A9_COMP_SEL(mali_stack_0, MALI_STACK_CLK_CTRL, 9, 0x7, a9_mali_parents, NULL);
+static A9_COMP_DIV(mali_stack_0, MALI_STACK_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(mali_stack_0, MALI_STACK_CLK_CTRL, 8, CLK_SET_RATE_GATE);
+
+static A9_COMP_SEL(mali_stack_1, MALI_STACK_CLK_CTRL, 25, 0x7, a9_mali_parents, NULL);
+static A9_COMP_DIV(mali_stack_1, MALI_STACK_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(mali_stack_1, MALI_STACK_CLK_CTRL, 24, CLK_SET_RATE_GATE);
+
+static struct clk_regmap a9_mali_stack = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = MALI_STACK_CLK_CTRL,
+ .mask = 0x1,
+ .shift = 31,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "mali_stack",
+ .ops = &clk_regmap_mux_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &a9_mali_stack_0.hw,
+ &a9_mali_stack_1.hw
+ },
+ .num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static const struct clk_parent_data a9_hevcf_parents[] = {
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv7", },
+ { .fw_name = "hifi0", },
+ { .fw_name = "gp1", },
+ { .fw_name = "xtal", }
+};
+
+static A9_COMP_SEL(hevcf_0, HEVCF_CLK_CTRL, 9, 0x7, a9_hevcf_parents, NULL);
+static A9_COMP_DIV(hevcf_0, HEVCF_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(hevcf_0, HEVCF_CLK_CTRL, 8, CLK_SET_RATE_GATE);
+
+static A9_COMP_SEL(hevcf_1, HEVCF_CLK_CTRL, 25, 0x7, a9_hevcf_parents, NULL);
+static A9_COMP_DIV(hevcf_1, HEVCF_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(hevcf_1, HEVCF_CLK_CTRL, 24, CLK_SET_RATE_GATE);
+
+static struct clk_regmap a9_hevcf = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = HEVCF_CLK_CTRL,
+ .mask = 0x1,
+ .shift = 31,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "hevcf",
+ .ops = &clk_regmap_mux_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &a9_hevcf_0.hw,
+ &a9_hevcf_1.hw
+ },
+ .num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static const struct clk_parent_data a9_hcodec_parents[] = {
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv7", },
+ { .fw_name = "hifi0", },
+ { .fw_name = "gp0", },
+ { .fw_name = "xtal", }
+};
+
+static A9_COMP_SEL(hcodec_0, HCODEC_CLK_CTRL, 9, 0x7, a9_hcodec_parents, NULL);
+static A9_COMP_DIV(hcodec_0, HCODEC_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(hcodec_0, HCODEC_CLK_CTRL, 8, CLK_SET_RATE_GATE);
+
+static A9_COMP_SEL(hcodec_1, HCODEC_CLK_CTRL, 25, 0x7, a9_hcodec_parents, NULL);
+static A9_COMP_DIV(hcodec_1, HCODEC_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(hcodec_1, HCODEC_CLK_CTRL, 24, CLK_SET_RATE_GATE);
+
+static struct clk_regmap a9_hcodec = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = HCODEC_CLK_CTRL,
+ .mask = 0x1,
+ .shift = 31,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "hcodec",
+ .ops = &clk_regmap_mux_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &a9_hcodec_0.hw,
+ &a9_hcodec_1.hw
+ },
+ .num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static const struct clk_parent_data a9_vpu_parents[] = {
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "vid1", },
+ { .fw_name = "fdiv2", },
+ { .hw = &a9_vid_pll.hw },
+ { .fw_name = "vid2", },
+ { .fw_name = "gp1", }
+};
+
+static A9_COMP_SEL(vpu_0, VPU_CLK_CTRL, 9, 0x7, a9_vpu_parents, NULL);
+static A9_COMP_DIV(vpu_0, VPU_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(vpu_0, VPU_CLK_CTRL, 8, CLK_SET_RATE_GATE);
+
+static A9_COMP_SEL(vpu_1, VPU_CLK_CTRL, 25, 0x7, a9_vpu_parents, NULL);
+static A9_COMP_DIV(vpu_1, VPU_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(vpu_1, VPU_CLK_CTRL, 24, CLK_SET_RATE_GATE);
+
+static struct clk_regmap a9_vpu = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = VPU_CLK_CTRL,
+ .mask = 0x1,
+ .shift = 31,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "vpu",
+ .ops = &clk_regmap_mux_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &a9_vpu_0.hw,
+ &a9_vpu_1.hw
+ },
+ .num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static const struct clk_parent_data a9_vapb_parents[] = {
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv7", },
+ { .fw_name = "fdiv2", },
+ { .hw = &a9_vid_pll.hw },
+ { .fw_name = "hifi0", },
+ { .fw_name = "fdiv2p5", }
+};
+
+static A9_COMP_SEL(vapb_0, VAPB_CLK_CTRL, 9, 0x7, a9_vapb_parents, NULL);
+static A9_COMP_DIV(vapb_0, VAPB_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(vapb_0, VAPB_CLK_CTRL, 8, CLK_SET_RATE_GATE);
+
+static A9_COMP_SEL(vapb_1, VAPB_CLK_CTRL, 25, 0x7, a9_vapb_parents, NULL);
+static A9_COMP_DIV(vapb_1, VAPB_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(vapb_1, VAPB_CLK_CTRL, 24, CLK_SET_RATE_GATE);
+
+static struct clk_regmap a9_vapb = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = VAPB_CLK_CTRL,
+ .mask = 0x1,
+ .shift = 31,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "vapb",
+ .ops = &clk_regmap_mux_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &a9_vapb_0.hw,
+ &a9_vapb_1.hw
+ },
+ .num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_regmap a9_ge2d = {
+ .data = &(struct clk_regmap_gate_data) {
+ .offset = VAPB_CLK_CTRL,
+ .bit_idx = 30,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "ge2d",
+ .ops = &clk_regmap_gate_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &a9_vapb.hw,
+ },
+ .num_parents = 1,
+ },
+};
+
+static const struct clk_parent_data a9_vpu_clkb_tmp_parents[] = {
+ { .hw = &a9_vpu.hw },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "fdiv7", }
+};
+
+static A9_COMP_SEL(vpu_clkb_tmp, VPU_CLKB_CTRL, 25, 0x7, a9_vpu_clkb_tmp_parents, NULL);
+static A9_COMP_DIV(vpu_clkb_tmp, VPU_CLKB_CTRL, 16, 4);
+static A9_COMP_GATE(vpu_clkb_tmp, VPU_CLKB_CTRL, 24, 0);
+
+static struct clk_regmap a9_vpu_clkb_div = {
+ .data = &(struct clk_regmap_div_data) {
+ .offset = VPU_CLKB_CTRL,
+ .shift = 0,
+ .width = 8,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "vpu_clkb_div",
+ .ops = &clk_regmap_divider_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &a9_vpu_clkb_tmp.hw,
+ },
+ .num_parents = 1,
+ },
+};
+
+static struct clk_regmap a9_vpu_clkb = {
+ .data = &(struct clk_regmap_gate_data) {
+ .offset = VPU_CLKB_CTRL,
+ .bit_idx = 8,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "vpu_clkb",
+ .ops = &clk_regmap_gate_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &a9_vpu_clkb_div.hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static const struct clk_parent_data a9_hdmi_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv5", }
+};
+
+static A9_COMP_SEL(hdmitx_sys, HDMI_CLK_CTRL, 9, 0x7, a9_hdmi_parents, NULL);
+static A9_COMP_DIV(hdmitx_sys, HDMI_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(hdmitx_sys, HDMI_CLK_CTRL, 8, 0);
+
+static A9_COMP_SEL(hdmitx_prif, HTX_CLK_CTRL, 9, 0x7, a9_hdmi_parents, NULL);
+static A9_COMP_DIV(hdmitx_prif, HTX_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(hdmitx_prif, HTX_CLK_CTRL, 8, 0);
+
+static A9_COMP_SEL(hdmitx_200m, HTX_CLK_CTRL, 25, 0x7, a9_hdmi_parents, NULL);
+static A9_COMP_DIV(hdmitx_200m, HTX_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(hdmitx_200m, HTX_CLK_CTRL, 24, 0);
+
+static A9_COMP_SEL(hdmitx_aud, HTX_CLK_CTRL1, 9, 0x7, a9_hdmi_parents, NULL);
+static A9_COMP_DIV(hdmitx_aud, HTX_CLK_CTRL1, 0, 7);
+static A9_COMP_GATE(hdmitx_aud, HTX_CLK_CTRL1, 8, 0);
+
+static A9_COMP_SEL(hdmirx_5m, HRX_CLK_CTRL, 9, 0x7, a9_hdmi_parents, NULL);
+static A9_COMP_DIV(hdmirx_5m, HRX_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(hdmirx_5m, HRX_CLK_CTRL, 8, 0);
+
+static A9_COMP_SEL(hdmirx_2m, HRX_CLK_CTRL, 25, 0x7, a9_hdmi_parents, NULL);
+static A9_COMP_DIV(hdmirx_2m, HRX_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(hdmirx_2m, HRX_CLK_CTRL, 24, 0);
+
+static A9_COMP_SEL(hdmirx_cfg, HRX_CLK_CTRL1, 9, 0x7, a9_hdmi_parents, NULL);
+static A9_COMP_DIV(hdmirx_cfg, HRX_CLK_CTRL1, 0, 7);
+static A9_COMP_GATE(hdmirx_cfg, HRX_CLK_CTRL1, 8, 0);
+
+static A9_COMP_SEL(hdmirx_hdcp2x, HRX_CLK_CTRL1, 25, 0x7, a9_hdmi_parents, NULL);
+static A9_COMP_DIV(hdmirx_hdcp2x, HRX_CLK_CTRL1, 16, 7);
+static A9_COMP_GATE(hdmirx_hdcp2x, HRX_CLK_CTRL1, 24, 0);
+
+static A9_COMP_SEL(hdmirx_acr_ref, HRX_CLK_CTRL2, 25, 0x7, a9_hdmi_parents, NULL);
+static A9_COMP_DIV(hdmirx_acr_ref, HRX_CLK_CTRL2, 16, 7);
+static A9_COMP_GATE(hdmirx_acr_ref, HRX_CLK_CTRL2, 24, 0);
+
+static A9_COMP_SEL(hdmirx_meter, HRX_CLK_CTRL3, 9, 0x7, a9_hdmi_parents, NULL);
+static A9_COMP_DIV(hdmirx_meter, HRX_CLK_CTRL3, 0, 7);
+static A9_COMP_GATE(hdmirx_meter, HRX_CLK_CTRL3, 8, 0);
+
+static struct clk_regmap a9_vid_pll_vclk = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = HDMI_CLK_CTRL,
+ .mask = 0x1,
+ .shift = 15,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "vid_pll_vclk",
+ .ops = &clk_regmap_mux_ops,
+ .parent_data = (const struct clk_parent_data []) {
+ { .hw = &a9_vid_pll.hw },
+ { .fw_name = "hdmipix", }
+ },
+ .num_parents = 2,
+ },
+};
+
+static const struct clk_parent_data a9_vclk_parents[] = {
+ { .hw = &a9_vid_pll_vclk.hw },
+ { .fw_name = "pix0", },
+ { .fw_name = "vid1", },
+ { .fw_name = "pix1", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "vid2", }
+};
+
+static struct clk_regmap a9_vclk0_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = VID_CLK_CTRL,
+ .mask = 0x7,
+ .shift = 16,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "vclk0_sel",
+ .ops = &clk_regmap_mux_ops,
+ .parent_data = a9_vclk_parents,
+ .num_parents = ARRAY_SIZE(a9_vclk_parents),
+ },
+};
+
+static struct clk_regmap a9_vclk0_in = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_DIV,
+ .bit_idx = 16,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "vclk0_in",
+ .ops = &clk_regmap_gate_ops,
+ .parent_hws = (const struct clk_hw *[]) { &a9_vclk0_sel.hw },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_regmap a9_vclk0_div = {
+ .data = &(struct clk_regmap_div_data){
+ .offset = VID_CLK_DIV,
+ .shift = 0,
+ .width = 8,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "vclk0_div",
+ .ops = &clk_regmap_divider_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &a9_vclk0_in.hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_regmap a9_vclk0 = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL,
+ .bit_idx = 19,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "vclk0",
+ .ops = &clk_regmap_gate_ops,
+ .parent_hws = (const struct clk_hw *[]) { &a9_vclk0_div.hw },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+#define A9_VCLK_GATE(_name, _reg, _bit, _parent) \
+struct clk_regmap a9_##_name##_en = { \
+ .data = &(struct clk_regmap_gate_data) { \
+ .offset = (_reg), \
+ .bit_idx = (_bit), \
+ }, \
+ .hw.init = &(struct clk_init_data) { \
+ .name = #_name "_en", \
+ .ops = &clk_regmap_gate_ops, \
+ .parent_hws = (const struct clk_hw *[]) { \
+ &(_parent).hw \
+ }, \
+ .num_parents = 1, \
+ .flags = CLK_SET_RATE_PARENT, \
+ }, \
+}
+
+#define A9_VCLK_DIV(_name, _div) \
+struct clk_fixed_factor a9_##_name = { \
+ .mult = 1, \
+ .div = (_div), \
+ .hw.init = &(struct clk_init_data) { \
+ .name = #_name, \
+ .ops = &clk_fixed_factor_ops, \
+ .parent_hws = (const struct clk_hw *[]) { \
+ &a9_##_name##_en.hw \
+ }, \
+ .num_parents = 1, \
+ .flags = CLK_SET_RATE_PARENT, \
+ }, \
+}
+
+static A9_VCLK_GATE(vclk0_div1, VID_CLK_CTRL, 0, a9_vclk0);
+static A9_VCLK_GATE(vclk0_div2, VID_CLK_CTRL, 1, a9_vclk0);
+static A9_VCLK_DIV(vclk0_div2, 2);
+static A9_VCLK_GATE(vclk0_div4, VID_CLK_CTRL, 2, a9_vclk0);
+static A9_VCLK_DIV(vclk0_div4, 4);
+static A9_VCLK_GATE(vclk0_div6, VID_CLK_CTRL, 3, a9_vclk0);
+static A9_VCLK_DIV(vclk0_div6, 6);
+static A9_VCLK_GATE(vclk0_div12, VID_CLK_CTRL, 4, a9_vclk0);
+static A9_VCLK_DIV(vclk0_div12, 12);
+
+static struct clk_regmap a9_vclk1_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = VIID_CLK_CTRL,
+ .mask = 0x7,
+ .shift = 16,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "vclk1_sel",
+ .ops = &clk_regmap_mux_ops,
+ .parent_data = a9_vclk_parents,
+ .num_parents = ARRAY_SIZE(a9_vclk_parents),
+ },
+};
+
+static struct clk_regmap a9_vclk1_in = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VIID_CLK_DIV,
+ .bit_idx = 16,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "vclk1_in",
+ .ops = &clk_regmap_gate_ops,
+ .parent_hws = (const struct clk_hw *[]) { &a9_vclk1_sel.hw },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_regmap a9_vclk1_div = {
+ .data = &(struct clk_regmap_div_data){
+ .offset = VIID_CLK_DIV,
+ .shift = 0,
+ .width = 8,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "vclk1_div",
+ .ops = &clk_regmap_divider_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &a9_vclk1_in.hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_regmap a9_vclk1 = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VIID_CLK_CTRL,
+ .bit_idx = 19,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "vclk1",
+ .ops = &clk_regmap_gate_ops,
+ .parent_hws = (const struct clk_hw *[]) { &a9_vclk1_div.hw },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static A9_VCLK_GATE(vclk1_div1, VIID_CLK_CTRL, 0, a9_vclk1);
+static A9_VCLK_GATE(vclk1_div2, VIID_CLK_CTRL, 1, a9_vclk1);
+static A9_VCLK_DIV(vclk1_div2, 2);
+static A9_VCLK_GATE(vclk1_div4, VIID_CLK_CTRL, 2, a9_vclk1);
+static A9_VCLK_DIV(vclk1_div4, 4);
+static A9_VCLK_GATE(vclk1_div6, VIID_CLK_CTRL, 3, a9_vclk1);
+static A9_VCLK_DIV(vclk1_div6, 6);
+static A9_VCLK_GATE(vclk1_div12, VIID_CLK_CTRL, 4, a9_vclk1);
+static A9_VCLK_DIV(vclk1_div12, 12);
+
+/* Channel 5, 6 and 7 are unconnected */
+static u32 a9_vid_parents_val_table[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 };
+static const struct clk_hw *a9_vid_parents[] = {
+ &a9_vclk0_div1_en.hw,
+ &a9_vclk0_div2.hw,
+ &a9_vclk0_div4.hw,
+ &a9_vclk0_div6.hw,
+ &a9_vclk0_div12.hw,
+ &a9_vclk1_div1_en.hw,
+ &a9_vclk1_div2.hw,
+ &a9_vclk1_div4.hw,
+ &a9_vclk1_div6.hw,
+ &a9_vclk1_div12.hw
+};
+
+static struct clk_regmap a9_encoder0_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = VIID_CLK_DIV,
+ .mask = 0xf,
+ .shift = 12,
+ .table = a9_vid_parents_val_table,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "encoder0_sel",
+ .ops = &clk_regmap_mux_ops,
+ .parent_hws = a9_vid_parents,
+ .num_parents = ARRAY_SIZE(a9_vid_parents),
+ },
+};
+
+static struct clk_regmap a9_encoder0 = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL2,
+ .bit_idx = 10,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "encoder0",
+ .ops = &clk_regmap_gate_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &a9_encoder0_sel.hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_regmap a9_encoder1_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = VIID_CLK_DIV,
+ .mask = 0xf,
+ .shift = 8,
+ .table = a9_vid_parents_val_table,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "encoder1_sel",
+ .ops = &clk_regmap_mux_ops,
+ .parent_hws = a9_vid_parents,
+ .num_parents = ARRAY_SIZE(a9_vid_parents),
+ },
+};
+
+static struct clk_regmap a9_encoder1 = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL2,
+ .bit_idx = 11,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "encoder1",
+ .ops = &clk_regmap_gate_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &a9_encoder1_sel.hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static const struct clk_parent_data a9_vid_lock_parents[] = {
+ { .fw_name = "xtal", },
+ { .hw = &a9_encoder0.hw },
+ { .hw = &a9_encoder1.hw }
+};
+
+static A9_COMP_SEL(vid_lock, VID_LOCK_CLK_CTRL, 9, 0x7, a9_vid_lock_parents, NULL);
+static A9_COMP_DIV(vid_lock, VID_LOCK_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(vid_lock, VID_LOCK_CLK_CTRL, 8, 0);
+
+static const struct clk_parent_data a9_vdin_meas_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv5", }
+};
+
+static A9_COMP_SEL(vdin_meas, VDIN_MEAS_CLK_CTRL, 9, 0x7, a9_vdin_meas_parents, NULL);
+static A9_COMP_DIV(vdin_meas, VDIN_MEAS_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(vdin_meas, VDIN_MEAS_CLK_CTRL, 8, 0);
+
+static struct clk_regmap a9_vdac_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = VIID_CLK_DIV,
+ .mask = 0xf,
+ .shift = 28,
+ .table = a9_vid_parents_val_table,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "vdac_sel",
+ .ops = &clk_regmap_mux_ops,
+ .parent_hws = a9_vid_parents,
+ .num_parents = ARRAY_SIZE(a9_vid_parents),
+ },
+};
+
+static struct clk_regmap a9_vdac = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL2,
+ .bit_idx = 4,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "vdac",
+ .ops = &clk_regmap_gate_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &a9_vdac_sel.hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_regmap a9_hdmitx0_pixel_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = HDMI_CLK_CTRL,
+ .mask = 0xf,
+ .shift = 16,
+ .table = a9_vid_parents_val_table,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "hdmitx0_pixel_sel",
+ .ops = &clk_regmap_mux_ops,
+ .parent_hws = a9_vid_parents,
+ .num_parents = ARRAY_SIZE(a9_vid_parents),
+ },
+};
+
+static struct clk_regmap a9_hdmitx0_pixel = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL2,
+ .bit_idx = 5,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "hdmitx0_pixel",
+ .ops = &clk_regmap_gate_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &a9_hdmitx0_pixel_sel.hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_regmap a9_hdmitx0_fe_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = HDMI_CLK_CTRL,
+ .mask = 0xf,
+ .shift = 20,
+ .table = a9_vid_parents_val_table,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "hdmitx0_fe_sel",
+ .ops = &clk_regmap_mux_ops,
+ .parent_hws = a9_vid_parents,
+ .num_parents = ARRAY_SIZE(a9_vid_parents),
+ },
+};
+
+static struct clk_regmap a9_hdmitx0_fe = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL2,
+ .bit_idx = 9,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "hdmitx0_fe",
+ .ops = &clk_regmap_gate_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &a9_hdmitx0_fe_sel.hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_regmap a9_hdmitx1_pixel_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = HDMI_CLK_CTRL,
+ .mask = 0xf,
+ .shift = 24,
+ .table = a9_vid_parents_val_table,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "hdmitx1_pixel_sel",
+ .ops = &clk_regmap_mux_ops,
+ .parent_hws = a9_vid_parents,
+ .num_parents = ARRAY_SIZE(a9_vid_parents),
+ },
+};
+
+static struct clk_regmap a9_hdmitx1_pixel = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL2,
+ .bit_idx = 12,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "hdmitx1_pixel",
+ .ops = &clk_regmap_gate_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &a9_hdmitx1_pixel_sel.hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static struct clk_regmap a9_hdmitx1_fe_sel = {
+ .data = &(struct clk_regmap_mux_data){
+ .offset = HDMI_CLK_CTRL,
+ .mask = 0xf,
+ .shift = 28,
+ .table = a9_vid_parents_val_table,
+ },
+ .hw.init = &(struct clk_init_data){
+ .name = "hdmitx1_fe_sel",
+ .ops = &clk_regmap_mux_ops,
+ .parent_hws = a9_vid_parents,
+ .num_parents = ARRAY_SIZE(a9_vid_parents),
+ },
+};
+
+static struct clk_regmap a9_hdmitx1_fe = {
+ .data = &(struct clk_regmap_gate_data){
+ .offset = VID_CLK_CTRL2,
+ .bit_idx = 13,
+ },
+ .hw.init = &(struct clk_init_data) {
+ .name = "hdmitx1_fe",
+ .ops = &clk_regmap_gate_ops,
+ .parent_hws = (const struct clk_hw *[]) {
+ &a9_hdmitx1_fe_sel.hw
+ },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ },
+};
+
+static const struct clk_parent_data a9_csi_phy_parents[] = {
+ { .fw_name = "fdiv2p5", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv5", },
+ { .fw_name = "gp0", },
+ { .fw_name = "hifi0", },
+ { .fw_name = "fdiv2", },
+ { .fw_name = "xtal", }
+};
+
+static A9_COMP_SEL(csi_phy, MIPI_CSI_PHY_CLK_CTRL, 9, 0x7, a9_csi_phy_parents, NULL);
+static A9_COMP_DIV(csi_phy, MIPI_CSI_PHY_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(csi_phy, MIPI_CSI_PHY_CLK_CTRL, 8, 0);
+
+static const struct clk_parent_data a9_dsi_meas_parents[] = {
+ { .fw_name = "xtal", },
+ { .fw_name = "fdiv4", },
+ { .fw_name = "fdiv3", },
+ { .fw_name = "fdiv5", },
+ { .hw = &a9_vid_pll.hw },
+ { .fw_name = "gp0", },
+ { .fw_name = "vid1", },
+ { .fw_name = "vid2", }
+};
+
+static A9_COMP_SEL(dsi0_meas, DSI_MEAS_CLK_CTRL, 9, 0x7, a9_dsi_meas_parents, NULL);
+static A9_COMP_DIV(dsi0_meas, DSI_MEAS_CLK_CTRL, 0, 7);
+static A9_COMP_GATE(dsi0_meas, DSI_MEAS_CLK_CTRL, 8, 0);
+
+static A9_COMP_SEL(dsi1_meas, DSI_MEAS_CLK_CTRL, 25, 0x7, a9_dsi_meas_parents, NULL);
+static A9_COMP_DIV(dsi1_meas, DSI_MEAS_CLK_CTRL, 16, 7);
+static A9_COMP_GATE(dsi1_meas, DSI_MEAS_CLK_CTRL, 24, 0);
+
+static struct clk_hw *a9_peripherals_hw_clks[] = {
+ [CLKID_SYS_AM_AXI] = &a9_sys_am_axi.hw,
+ [CLKID_SYS_DOS] = &a9_sys_dos.hw,
+ [CLKID_SYS_MIPI_DSI0] = &a9_sys_mipi_dsi0.hw,
+ [CLKID_SYS_ETH_PHY] = &a9_sys_eth_phy.hw,
+ [CLKID_SYS_AMFC] = &a9_sys_amfc.hw,
+ [CLKID_SYS_MALI] = &a9_sys_mali.hw,
+ [CLKID_SYS_NNA] = &a9_sys_nna.hw,
+ [CLKID_SYS_ETH_AXI] = &a9_sys_eth_axi.hw,
+ [CLKID_SYS_DP_APB] = &a9_sys_dp_apb.hw,
+ [CLKID_SYS_EDPTX_APB] = &a9_sys_edptx_apb.hw,
+ [CLKID_SYS_U3HSG] = &a9_sys_u3hsg.hw,
+ [CLKID_SYS_AUCPU] = &a9_sys_aucpu.hw,
+ [CLKID_SYS_GLB] = &a9_sys_glb.hw,
+ [CLKID_SYS_COMBO_DPHY_APB] = &a9_sys_combo_dphy_apb.hw,
+ [CLKID_SYS_HDMIRX_APB] = &a9_sys_hdmirx_apb.hw,
+ [CLKID_SYS_HDMIRX_PCLK] = &a9_sys_hdmirx_pclk.hw,
+ [CLKID_SYS_MIPI_DSI0_PHY] = &a9_sys_mipi_dsi0_phy.hw,
+ [CLKID_SYS_CAN0] = &a9_sys_can0.hw,
+ [CLKID_SYS_CAN1] = &a9_sys_can1.hw,
+ [CLKID_SYS_SD_EMMC_A] = &a9_sys_sd_emmc_a.hw,
+ [CLKID_SYS_SD_EMMC_B] = &a9_sys_sd_emmc_b.hw,
+ [CLKID_SYS_SD_EMMC_C] = &a9_sys_sd_emmc_c.hw,
+ [CLKID_SYS_SC] = &a9_sys_sc.hw,
+ [CLKID_SYS_ACODEC] = &a9_sys_acodec.hw,
+ [CLKID_SYS_MIPI_ISP] = &a9_sys_mipi_isp.hw,
+ [CLKID_SYS_MSR] = &a9_sys_msr.hw,
+ [CLKID_SYS_AUDIO] = &a9_sys_audio.hw,
+ [CLKID_SYS_MIPI_DSI1] = &a9_sys_mipi_dsi1.hw,
+ [CLKID_SYS_MIPI_DSI1_PHY] = &a9_sys_mipi_dsi1_phy.hw,
+ [CLKID_SYS_ETH] = &a9_sys_eth.hw,
+ [CLKID_SYS_ETH_1G_MAC] = &a9_sys_eth_1g_mac.hw,
+ [CLKID_SYS_UART_A] = &a9_sys_uart_a.hw,
+ [CLKID_SYS_UART_F] = &a9_sys_uart_f.hw,
+ [CLKID_SYS_TS_A55] = &a9_sys_ts_a55.hw,
+ [CLKID_SYS_ETH_1G_AXI] = &a9_sys_eth_1g_axi.hw,
+ [CLKID_SYS_TS_DOS] = &a9_sys_ts_dos.hw,
+ [CLKID_SYS_U3DRD_B] = &a9_sys_u3drd_b.hw,
+ [CLKID_SYS_TS_CORE] = &a9_sys_ts_core.hw,
+ [CLKID_SYS_TS_PLL] = &a9_sys_ts_pll.hw,
+ [CLKID_SYS_CSI_DIG_CLKIN] = &a9_sys_csi_dig_clkin.hw,
+ [CLKID_SYS_CVE] = &a9_sys_cve.hw,
+ [CLKID_SYS_GE2D] = &a9_sys_ge2d.hw,
+ [CLKID_SYS_SPISG] = &a9_sys_spisg.hw,
+ [CLKID_SYS_U2H] = &a9_sys_u2h.hw,
+ [CLKID_SYS_PCIE_MAC_A] = &a9_sys_pcie_mac_a.hw,
+ [CLKID_SYS_U3DRD_A] = &a9_sys_u3drd_a.hw,
+ [CLKID_SYS_U2DRD] = &a9_sys_u2drd.hw,
+ [CLKID_SYS_PCIE_PHY] = &a9_sys_pcie_phy.hw,
+ [CLKID_SYS_PCIE_MAC_B] = &a9_sys_pcie_mac_b.hw,
+ [CLKID_SYS_PERIPH] = &a9_sys_periph.hw,
+ [CLKID_SYS_PIO] = &a9_sys_pio.hw,
+ [CLKID_SYS_I3C] = &a9_sys_i3c.hw,
+ [CLKID_SYS_I2C_M_E] = &a9_sys_i2c_m_e.hw,
+ [CLKID_SYS_I2C_M_F] = &a9_sys_i2c_m_f.hw,
+ [CLKID_SYS_HDMITX_APB] = &a9_sys_hdmitx_apb.hw,
+ [CLKID_SYS_I2C_M_I] = &a9_sys_i2c_m_i.hw,
+ [CLKID_SYS_I2C_M_G] = &a9_sys_i2c_m_g.hw,
+ [CLKID_SYS_I2C_M_H] = &a9_sys_i2c_m_h.hw,
+ [CLKID_SYS_HDMI20_AES] = &a9_sys_hdmi20_aes.hw,
+ [CLKID_SYS_CSI2_HOST] = &a9_sys_csi2_host.hw,
+ [CLKID_SYS_CSI2_ADAPT] = &a9_sys_csi2_adapt.hw,
+ [CLKID_SYS_DSPA] = &a9_sys_dspa.hw,
+ [CLKID_SYS_PP_DMA] = &a9_sys_pp_dma.hw,
+ [CLKID_SYS_PP_WRAPPER] = &a9_sys_pp_wrapper.hw,
+ [CLKID_SYS_VPU_INTR] = &a9_sys_vpu_intr.hw,
+ [CLKID_SYS_CSI2_PHY] = &a9_sys_csi2_phy.hw,
+ [CLKID_SYS_SARADC] = &a9_sys_saradc.hw,
+ [CLKID_SYS_PWM_J] = &a9_sys_pwm_j.hw,
+ [CLKID_SYS_PWM_I] = &a9_sys_pwm_i.hw,
+ [CLKID_SYS_PWM_H] = &a9_sys_pwm_h.hw,
+ [CLKID_SYS_PWM_N] = &a9_sys_pwm_n.hw,
+ [CLKID_SYS_PWM_M] = &a9_sys_pwm_m.hw,
+ [CLKID_SYS_PWM_L] = &a9_sys_pwm_l.hw,
+ [CLKID_SYS_PWM_K] = &a9_sys_pwm_k.hw,
+ [CLKID_SD_EMMC_A_SEL] = &a9_sd_emmc_a_sel.hw,
+ [CLKID_SD_EMMC_A_DIV] = &a9_sd_emmc_a_div.hw,
+ [CLKID_SD_EMMC_A] = &a9_sd_emmc_a.hw,
+ [CLKID_SD_EMMC_B_SEL] = &a9_sd_emmc_b_sel.hw,
+ [CLKID_SD_EMMC_B_DIV] = &a9_sd_emmc_b_div.hw,
+ [CLKID_SD_EMMC_B] = &a9_sd_emmc_b.hw,
+ [CLKID_SD_EMMC_C_SEL] = &a9_sd_emmc_c_sel.hw,
+ [CLKID_SD_EMMC_C_DIV] = &a9_sd_emmc_c_div.hw,
+ [CLKID_SD_EMMC_C] = &a9_sd_emmc_c.hw,
+ [CLKID_PWM_H_SEL] = &a9_pwm_h_sel.hw,
+ [CLKID_PWM_H_DIV] = &a9_pwm_h_div.hw,
+ [CLKID_PWM_H] = &a9_pwm_h.hw,
+ [CLKID_PWM_I_SEL] = &a9_pwm_i_sel.hw,
+ [CLKID_PWM_I_DIV] = &a9_pwm_i_div.hw,
+ [CLKID_PWM_I] = &a9_pwm_i.hw,
+ [CLKID_PWM_J_SEL] = &a9_pwm_j_sel.hw,
+ [CLKID_PWM_J_DIV] = &a9_pwm_j_div.hw,
+ [CLKID_PWM_J] = &a9_pwm_j.hw,
+ [CLKID_PWM_K_SEL] = &a9_pwm_k_sel.hw,
+ [CLKID_PWM_K_DIV] = &a9_pwm_k_div.hw,
+ [CLKID_PWM_K] = &a9_pwm_k.hw,
+ [CLKID_PWM_L_SEL] = &a9_pwm_l_sel.hw,
+ [CLKID_PWM_L_DIV] = &a9_pwm_l_div.hw,
+ [CLKID_PWM_L] = &a9_pwm_l.hw,
+ [CLKID_PWM_M_SEL] = &a9_pwm_m_sel.hw,
+ [CLKID_PWM_M_DIV] = &a9_pwm_m_div.hw,
+ [CLKID_PWM_M] = &a9_pwm_m.hw,
+ [CLKID_PWM_N_SEL] = &a9_pwm_n_sel.hw,
+ [CLKID_PWM_N_DIV] = &a9_pwm_n_div.hw,
+ [CLKID_PWM_N] = &a9_pwm_n.hw,
+ [CLKID_SPISG0_SEL] = &a9_spisg0_sel.hw,
+ [CLKID_SPISG0_DIV] = &a9_spisg0_div.hw,
+ [CLKID_SPISG0] = &a9_spisg0.hw,
+ [CLKID_SPISG1_SEL] = &a9_spisg1_sel.hw,
+ [CLKID_SPISG1_DIV] = &a9_spisg1_div.hw,
+ [CLKID_SPISG1] = &a9_spisg1.hw,
+ [CLKID_SPISG2_SEL] = &a9_spisg2_sel.hw,
+ [CLKID_SPISG2_DIV] = &a9_spisg2_div.hw,
+ [CLKID_SPISG2] = &a9_spisg2.hw,
+ [CLKID_SARADC_SEL] = &a9_saradc_sel.hw,
+ [CLKID_SARADC_DIV] = &a9_saradc_div.hw,
+ [CLKID_SARADC] = &a9_saradc.hw,
+ [CLKID_AMFC_SEL] = &a9_amfc_sel.hw,
+ [CLKID_AMFC_DIV] = &a9_amfc_div.hw,
+ [CLKID_AMFC] = &a9_amfc.hw,
+ [CLKID_NNA_SEL] = &a9_nna_sel.hw,
+ [CLKID_NNA_DIV] = &a9_nna_div.hw,
+ [CLKID_NNA] = &a9_nna.hw,
+ [CLKID_USB_250M_SEL] = &a9_usb_250m_sel.hw,
+ [CLKID_USB_250M_DIV] = &a9_usb_250m_div.hw,
+ [CLKID_USB_250M] = &a9_usb_250m.hw,
+ [CLKID_USB_48M_PRE_SEL] = &a9_usb_48m_pre_sel.hw,
+ [CLKID_USB_48M_PRE_DIV] = &a9_usb_48m_pre_div.hw,
+ [CLKID_USB_48M_PRE] = &a9_usb_48m_pre.hw,
+ [CLKID_PCIE0_TL_SEL] = &a9_pcie0_tl_sel.hw,
+ [CLKID_PCIE0_TL_DIV] = &a9_pcie0_tl_div.hw,
+ [CLKID_PCIE0_TL] = &a9_pcie0_tl.hw,
+ [CLKID_PCIE1_TL_SEL] = &a9_pcie1_tl_sel.hw,
+ [CLKID_PCIE1_TL_DIV] = &a9_pcie1_tl_div.hw,
+ [CLKID_PCIE1_TL] = &a9_pcie1_tl.hw,
+ [CLKID_CMPR_SEL] = &a9_cmpr_sel.hw,
+ [CLKID_CMPR_DIV] = &a9_cmpr_div.hw,
+ [CLKID_CMPR] = &a9_cmpr.hw,
+ [CLKID_DEWARPA_SEL] = &a9_dewarpa_sel.hw,
+ [CLKID_DEWARPA_DIV] = &a9_dewarpa_div.hw,
+ [CLKID_DEWARPA] = &a9_dewarpa.hw,
+ [CLKID_SC_PRE_SEL] = &a9_sc_pre_sel.hw,
+ [CLKID_SC_PRE_DIV] = &a9_sc_pre_div.hw,
+ [CLKID_SC_PRE] = &a9_sc_pre.hw,
+ [CLKID_SC] = &a9_sc.hw,
+ [CLKID_DPTX_APB2_SEL] = &a9_dptx_apb2_sel.hw,
+ [CLKID_DPTX_APB2_DIV] = &a9_dptx_apb2_div.hw,
+ [CLKID_DPTX_APB2] = &a9_dptx_apb2.hw,
+ [CLKID_DPTX_AUD_SEL] = &a9_dptx_aud_sel.hw,
+ [CLKID_DPTX_AUD_DIV] = &a9_dptx_aud_div.hw,
+ [CLKID_DPTX_AUD] = &a9_dptx_aud.hw,
+ [CLKID_ISP_SEL] = &a9_isp_sel.hw,
+ [CLKID_ISP_DIV] = &a9_isp_div.hw,
+ [CLKID_ISP] = &a9_isp.hw,
+ [CLKID_CVE_SEL] = &a9_cve_sel.hw,
+ [CLKID_CVE_DIV] = &a9_cve_div.hw,
+ [CLKID_CVE] = &a9_cve.hw,
+ [CLKID_VGE_SEL] = &a9_vge_sel.hw,
+ [CLKID_VGE_DIV] = &a9_vge_div.hw,
+ [CLKID_VGE] = &a9_vge.hw,
+ [CLKID_PP_SEL] = &a9_pp_sel.hw,
+ [CLKID_PP_DIV] = &a9_pp_div.hw,
+ [CLKID_PP] = &a9_pp.hw,
+ [CLKID_GLB_SEL] = &a9_glb_sel.hw,
+ [CLKID_GLB_DIV] = &a9_glb_div.hw,
+ [CLKID_GLB] = &a9_glb.hw,
+ [CLKID_USB_48M_DUALDIV_IN] = &a9_usb_48m_dualdiv_in.hw,
+ [CLKID_USB_48M_DUALDIV_DIV] = &a9_usb_48m_dualdiv_div.hw,
+ [CLKID_USB_48M_DUALDIV_SEL] = &a9_usb_48m_dualdiv_sel.hw,
+ [CLKID_USB_48M_DUALDIV] = &a9_usb_48m_dualdiv.hw,
+ [CLKID_USB_48M] = &a9_usb_48m.hw,
+ [CLKID_CAN0_PE_SEL] = &a9_can0_pe_sel.hw,
+ [CLKID_CAN0_PE_DIV] = &a9_can0_pe_div.hw,
+ [CLKID_CAN0_PE] = &a9_can0_pe.hw,
+ [CLKID_CAN1_PE_SEL] = &a9_can1_pe_sel.hw,
+ [CLKID_CAN1_PE_DIV] = &a9_can1_pe_div.hw,
+ [CLKID_CAN1_PE] = &a9_can1_pe.hw,
+ [CLKID_CAN0_FILTER_SEL] = &a9_can0_filter_sel.hw,
+ [CLKID_CAN0_FILTER_DIV] = &a9_can0_filter_div.hw,
+ [CLKID_CAN0_FILTER] = &a9_can0_filter.hw,
+ [CLKID_CAN1_FILTER_SEL] = &a9_can1_filter_sel.hw,
+ [CLKID_CAN1_FILTER_DIV] = &a9_can1_filter_div.hw,
+ [CLKID_CAN1_FILTER] = &a9_can1_filter.hw,
+ [CLKID_I3C_SEL] = &a9_i3c_sel.hw,
+ [CLKID_I3C_DIV] = &a9_i3c_div.hw,
+ [CLKID_I3C] = &a9_i3c.hw,
+ [CLKID_TS_DIV] = &a9_ts_div.hw,
+ [CLKID_TS] = &a9_ts.hw,
+ [CLKID_ETH_125M_DIV] = &a9_eth_125m_div.hw,
+ [CLKID_ETH_125M] = &a9_eth_125m.hw,
+ [CLKID_ETH_RMII_SEL] = &a9_eth_rmii_sel.hw,
+ [CLKID_ETH_RMII_DIV] = &a9_eth_rmii_div.hw,
+ [CLKID_ETH_RMII] = &a9_eth_rmii.hw,
+ [CLKID_GEN_SEL] = &a9_gen_sel.hw,
+ [CLKID_GEN_DIV] = &a9_gen_div.hw,
+ [CLKID_GEN] = &a9_gen.hw,
+ [CLKID_CLK24M_IN] = &a9_24m_in.hw,
+ [CLKID_CLK12_24M] = &a9_12_24m.hw,
+ [CLKID_MALI_0_SEL] = &a9_mali_0_sel.hw,
+ [CLKID_MALI_0_DIV] = &a9_mali_0_div.hw,
+ [CLKID_MALI_0] = &a9_mali_0.hw,
+ [CLKID_MALI_1_SEL] = &a9_mali_1_sel.hw,
+ [CLKID_MALI_1_DIV] = &a9_mali_1_div.hw,
+ [CLKID_MALI_1] = &a9_mali_1.hw,
+ [CLKID_MALI] = &a9_mali.hw,
+ [CLKID_MALI_STACK_0_SEL] = &a9_mali_stack_0_sel.hw,
+ [CLKID_MALI_STACK_0_DIV] = &a9_mali_stack_0_div.hw,
+ [CLKID_MALI_STACK_0] = &a9_mali_stack_0.hw,
+ [CLKID_MALI_STACK_1_SEL] = &a9_mali_stack_1_sel.hw,
+ [CLKID_MALI_STACK_1_DIV] = &a9_mali_stack_1_div.hw,
+ [CLKID_MALI_STACK_1] = &a9_mali_stack_1.hw,
+ [CLKID_MALI_STACK] = &a9_mali_stack.hw,
+ [CLKID_DSPA_0_SEL] = &a9_dspa_0_sel.hw,
+ [CLKID_DSPA_0_DIV] = &a9_dspa_0_div.hw,
+ [CLKID_DSPA_0] = &a9_dspa_0.hw,
+ [CLKID_DSPA_1_SEL] = &a9_dspa_1_sel.hw,
+ [CLKID_DSPA_1_DIV] = &a9_dspa_1_div.hw,
+ [CLKID_DSPA_1] = &a9_dspa_1.hw,
+ [CLKID_DSPA] = &a9_dspa.hw,
+ [CLKID_HEVCF_0_SEL] = &a9_hevcf_0_sel.hw,
+ [CLKID_HEVCF_0_DIV] = &a9_hevcf_0_div.hw,
+ [CLKID_HEVCF_0] = &a9_hevcf_0.hw,
+ [CLKID_HEVCF_1_SEL] = &a9_hevcf_1_sel.hw,
+ [CLKID_HEVCF_1_DIV] = &a9_hevcf_1_div.hw,
+ [CLKID_HEVCF_1] = &a9_hevcf_1.hw,
+ [CLKID_HEVCF] = &a9_hevcf.hw,
+ [CLKID_HCODEC_0_SEL] = &a9_hcodec_0_sel.hw,
+ [CLKID_HCODEC_0_DIV] = &a9_hcodec_0_div.hw,
+ [CLKID_HCODEC_0] = &a9_hcodec_0.hw,
+ [CLKID_HCODEC_1_SEL] = &a9_hcodec_1_sel.hw,
+ [CLKID_HCODEC_1_DIV] = &a9_hcodec_1_div.hw,
+ [CLKID_HCODEC_1] = &a9_hcodec_1.hw,
+ [CLKID_HCODEC] = &a9_hcodec.hw,
+ [CLKID_VPU_0_SEL] = &a9_vpu_0_sel.hw,
+ [CLKID_VPU_0_DIV] = &a9_vpu_0_div.hw,
+ [CLKID_VPU_0] = &a9_vpu_0.hw,
+ [CLKID_VPU_1_SEL] = &a9_vpu_1_sel.hw,
+ [CLKID_VPU_1_DIV] = &a9_vpu_1_div.hw,
+ [CLKID_VPU_1] = &a9_vpu_1.hw,
+ [CLKID_VPU] = &a9_vpu.hw,
+ [CLKID_VAPB_0_SEL] = &a9_vapb_0_sel.hw,
+ [CLKID_VAPB_0_DIV] = &a9_vapb_0_div.hw,
+ [CLKID_VAPB_0] = &a9_vapb_0.hw,
+ [CLKID_VAPB_1_SEL] = &a9_vapb_1_sel.hw,
+ [CLKID_VAPB_1_DIV] = &a9_vapb_1_div.hw,
+ [CLKID_VAPB_1] = &a9_vapb_1.hw,
+ [CLKID_VAPB] = &a9_vapb.hw,
+ [CLKID_GE2D] = &a9_ge2d.hw,
+ [CLKID_VPU_CLKB_TMP_SEL] = &a9_vpu_clkb_tmp_sel.hw,
+ [CLKID_VPU_CLKB_TMP_DIV] = &a9_vpu_clkb_tmp_div.hw,
+ [CLKID_VPU_CLKB_TMP] = &a9_vpu_clkb_tmp.hw,
+ [CLKID_VPU_CLKB_DIV] = &a9_vpu_clkb_div.hw,
+ [CLKID_VPU_CLKB] = &a9_vpu_clkb.hw,
+ [CLKID_HDMITX_SYS_SEL] = &a9_hdmitx_sys_sel.hw,
+ [CLKID_HDMITX_SYS_DIV] = &a9_hdmitx_sys_div.hw,
+ [CLKID_HDMITX_SYS] = &a9_hdmitx_sys.hw,
+ [CLKID_HDMITX_PRIF_SEL] = &a9_hdmitx_prif_sel.hw,
+ [CLKID_HDMITX_PRIF_DIV] = &a9_hdmitx_prif_div.hw,
+ [CLKID_HDMITX_PRIF] = &a9_hdmitx_prif.hw,
+ [CLKID_HDMITX_200M_SEL] = &a9_hdmitx_200m_sel.hw,
+ [CLKID_HDMITX_200M_DIV] = &a9_hdmitx_200m_div.hw,
+ [CLKID_HDMITX_200M] = &a9_hdmitx_200m.hw,
+ [CLKID_HDMITX_AUD_SEL] = &a9_hdmitx_aud_sel.hw,
+ [CLKID_HDMITX_AUD_DIV] = &a9_hdmitx_aud_div.hw,
+ [CLKID_HDMITX_AUD] = &a9_hdmitx_aud.hw,
+ [CLKID_HDMIRX_5M_SEL] = &a9_hdmirx_5m_sel.hw,
+ [CLKID_HDMIRX_5M_DIV] = &a9_hdmirx_5m_div.hw,
+ [CLKID_HDMIRX_5M] = &a9_hdmirx_5m.hw,
+ [CLKID_HDMIRX_2M_SEL] = &a9_hdmirx_2m_sel.hw,
+ [CLKID_HDMIRX_2M_DIV] = &a9_hdmirx_2m_div.hw,
+ [CLKID_HDMIRX_2M] = &a9_hdmirx_2m.hw,
+ [CLKID_HDMIRX_CFG_SEL] = &a9_hdmirx_cfg_sel.hw,
+ [CLKID_HDMIRX_CFG_DIV] = &a9_hdmirx_cfg_div.hw,
+ [CLKID_HDMIRX_CFG] = &a9_hdmirx_cfg.hw,
+ [CLKID_HDMIRX_HDCP2X_SEL] = &a9_hdmirx_hdcp2x_sel.hw,
+ [CLKID_HDMIRX_HDCP2X_DIV] = &a9_hdmirx_hdcp2x_div.hw,
+ [CLKID_HDMIRX_HDCP2X] = &a9_hdmirx_hdcp2x.hw,
+ [CLKID_HDMIRX_ACR_REF_SEL] = &a9_hdmirx_acr_ref_sel.hw,
+ [CLKID_HDMIRX_ACR_REF_DIV] = &a9_hdmirx_acr_ref_div.hw,
+ [CLKID_HDMIRX_ACR_REF] = &a9_hdmirx_acr_ref.hw,
+ [CLKID_HDMIRX_METER_SEL] = &a9_hdmirx_meter_sel.hw,
+ [CLKID_HDMIRX_METER_DIV] = &a9_hdmirx_meter_div.hw,
+ [CLKID_HDMIRX_METER] = &a9_hdmirx_meter.hw,
+ [CLKID_VID_LOCK_SEL] = &a9_vid_lock_sel.hw,
+ [CLKID_VID_LOCK_DIV] = &a9_vid_lock_div.hw,
+ [CLKID_VID_LOCK] = &a9_vid_lock.hw,
+ [CLKID_VDIN_MEAS_SEL] = &a9_vdin_meas_sel.hw,
+ [CLKID_VDIN_MEAS_DIV] = &a9_vdin_meas_div.hw,
+ [CLKID_VDIN_MEAS] = &a9_vdin_meas.hw,
+ [CLKID_VID_PLL_DIV] = &a9_vid_pll_div.hw,
+ [CLKID_VID_PLL_SEL] = &a9_vid_pll_sel.hw,
+ [CLKID_VID_PLL] = &a9_vid_pll.hw,
+ [CLKID_VID_PLL_VCLK] = &a9_vid_pll_vclk.hw,
+ [CLKID_VCLK0_SEL] = &a9_vclk0_sel.hw,
+ [CLKID_VCLK0_IN] = &a9_vclk0_in.hw,
+ [CLKID_VCLK0_DIV] = &a9_vclk0_div.hw,
+ [CLKID_VCLK0] = &a9_vclk0.hw,
+ [CLKID_VCLK0_DIV1_EN] = &a9_vclk0_div1_en.hw,
+ [CLKID_VCLK0_DIV2_EN] = &a9_vclk0_div2_en.hw,
+ [CLKID_VCLK0_DIV2] = &a9_vclk0_div2.hw,
+ [CLKID_VCLK0_DIV4_EN] = &a9_vclk0_div4_en.hw,
+ [CLKID_VCLK0_DIV4] = &a9_vclk0_div4.hw,
+ [CLKID_VCLK0_DIV6_EN] = &a9_vclk0_div6_en.hw,
+ [CLKID_VCLK0_DIV6] = &a9_vclk0_div6.hw,
+ [CLKID_VCLK0_DIV12_EN] = &a9_vclk0_div12_en.hw,
+ [CLKID_VCLK0_DIV12] = &a9_vclk0_div12.hw,
+ [CLKID_VCLK1_SEL] = &a9_vclk1_sel.hw,
+ [CLKID_VCLK1_IN] = &a9_vclk1_in.hw,
+ [CLKID_VCLK1_DIV] = &a9_vclk1_div.hw,
+ [CLKID_VCLK1] = &a9_vclk1.hw,
+ [CLKID_VCLK1_DIV1_EN] = &a9_vclk1_div1_en.hw,
+ [CLKID_VCLK1_DIV2_EN] = &a9_vclk1_div2_en.hw,
+ [CLKID_VCLK1_DIV2] = &a9_vclk1_div2.hw,
+ [CLKID_VCLK1_DIV4_EN] = &a9_vclk1_div4_en.hw,
+ [CLKID_VCLK1_DIV4] = &a9_vclk1_div4.hw,
+ [CLKID_VCLK1_DIV6_EN] = &a9_vclk1_div6_en.hw,
+ [CLKID_VCLK1_DIV6] = &a9_vclk1_div6.hw,
+ [CLKID_VCLK1_DIV12_EN] = &a9_vclk1_div12_en.hw,
+ [CLKID_VCLK1_DIV12] = &a9_vclk1_div12.hw,
+ [CLKID_VDAC_SEL] = &a9_vdac_sel.hw,
+ [CLKID_VDAC] = &a9_vdac.hw,
+ [CLKID_ENCODER0_SEL] = &a9_encoder0_sel.hw,
+ [CLKID_ENCODER0] = &a9_encoder0.hw,
+ [CLKID_ENCODER1_SEL] = &a9_encoder1_sel.hw,
+ [CLKID_ENCODER1] = &a9_encoder1.hw,
+ [CLKID_HDMITX0_PIXEL_SEL] = &a9_hdmitx0_pixel_sel.hw,
+ [CLKID_HDMITX0_PIXEL] = &a9_hdmitx0_pixel.hw,
+ [CLKID_HDMITX0_FE_SEL] = &a9_hdmitx0_fe_sel.hw,
+ [CLKID_HDMITX0_FE] = &a9_hdmitx0_fe.hw,
+ [CLKID_HDMITX1_PIXEL_SEL] = &a9_hdmitx1_pixel_sel.hw,
+ [CLKID_HDMITX1_PIXEL] = &a9_hdmitx1_pixel.hw,
+ [CLKID_HDMITX1_FE_SEL] = &a9_hdmitx1_fe_sel.hw,
+ [CLKID_HDMITX1_FE] = &a9_hdmitx1_fe.hw,
+ [CLKID_CSI_PHY_SEL] = &a9_csi_phy_sel.hw,
+ [CLKID_CSI_PHY_DIV] = &a9_csi_phy_div.hw,
+ [CLKID_CSI_PHY] = &a9_csi_phy.hw,
+ [CLKID_DSI0_MEAS_SEL] = &a9_dsi0_meas_sel.hw,
+ [CLKID_DSI0_MEAS_DIV] = &a9_dsi0_meas_div.hw,
+ [CLKID_DSI0_MEAS] = &a9_dsi0_meas.hw,
+ [CLKID_DSI1_MEAS_SEL] = &a9_dsi1_meas_sel.hw,
+ [CLKID_DSI1_MEAS_DIV] = &a9_dsi1_meas_div.hw,
+ [CLKID_DSI1_MEAS] = &a9_dsi1_meas.hw,
+};
+
+static const struct meson_clkc_data a9_peripherals_clkc_data = {
+ .hw_clks = {
+ .hws = a9_peripherals_hw_clks,
+ .num = ARRAY_SIZE(a9_peripherals_hw_clks),
+ },
+};
+
+static const struct of_device_id a9_peripherals_clkc_match_table[] = {
+ {
+ .compatible = "amlogic,a9-peripherals-clkc",
+ .data = &a9_peripherals_clkc_data,
+ },
+ { /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, a9_peripherals_clkc_match_table);
+
+static struct platform_driver a9_peripherals_clkc_driver = {
+ .probe = meson_clkc_mmio_probe,
+ .driver = {
+ .name = "a9-peripherals-clkc",
+ .of_match_table = a9_peripherals_clkc_match_table,
+ },
+};
+module_platform_driver(a9_peripherals_clkc_driver);
+
+MODULE_DESCRIPTION("Amlogic A9 Peripherals Clock Controller driver");
+MODULE_AUTHOR("Jian Hu <jian.hu@amlogic.com>");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("CLK_MESON");
--
2.47.1
^ permalink raw reply related
* [PATCH v6 1/2] dt-bindings: clock: Add Amlogic A9 peripherals clock controller
From: Jian Hu via B4 Relay @ 2026-07-01 8:30 UTC (permalink / raw)
To: Neil Armstrong, Jerome Brunet, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Xianwei Zhao,
Kevin Hilman, Martin Blumenstingl, Brian Masney
Cc: linux-amlogic, linux-clk, devicetree, linux-kernel,
linux-arm-kernel, Jian Hu, Conor Dooley
In-Reply-To: <20260701-a9_peripherals-v6-0-9630f39879e5@amlogic.com>
From: Jian Hu <jian.hu@amlogic.com>
Add the peripherals clock controller dt-bindings for the Amlogic A9
SoC family.
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Jian Hu <jian.hu@amlogic.com>
---
.../clock/amlogic,a9-peripherals-clkc.yaml | 164 ++++++++++
.../clock/amlogic,a9-peripherals-clkc.h | 351 +++++++++++++++++++++
2 files changed, 515 insertions(+)
diff --git a/Documentation/devicetree/bindings/clock/amlogic,a9-peripherals-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,a9-peripherals-clkc.yaml
new file mode 100644
index 000000000000..f0aef005ecf3
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/amlogic,a9-peripherals-clkc.yaml
@@ -0,0 +1,164 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2026 Amlogic, Inc. All rights reserved
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/amlogic,a9-peripherals-clkc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic A9 Series Peripherals Clock Controller
+
+maintainers:
+ - Neil Armstrong <neil.armstrong@linaro.org>
+ - Jerome Brunet <jbrunet@baylibre.com>
+ - Jian Hu <jian.hu@amlogic.com>
+ - Xianwei Zhao <xianwei.zhao@amlogic.com>
+
+properties:
+ compatible:
+ const: amlogic,a9-peripherals-clkc
+
+ reg:
+ maxItems: 1
+
+ '#clock-cells':
+ const: 1
+
+ clocks:
+ minItems: 27
+ items:
+ - description: input oscillator
+ - description: input fclk div 2
+ - description: input fclk div 3
+ - description: input fclk div 4
+ - description: input fclk div 5
+ - description: input fclk div 7
+ - description: input fclk div 2p5
+ - description: input sys clk
+ - description: input gp1 pll
+ - description: input gp2 pll
+ - description: input sys pll div 16
+ - description: input cpu clk div 16
+ - description: input a78 clk div 16
+ - description: input dsu clk div 16
+ - description: input rtc clk
+ - description: input gp0 pll
+ - description: input hifi0 pll
+ - description: input hifi1 pll
+ - description: input mclk0 pll
+ - description: input mclk1 pll
+ - description: input video1 pll
+ - description: input video2 pll
+ - description: input hdmi out2 clk
+ - description: input hdmi pixel clk
+ - description: input pixel0 pll
+ - description: input pixel1 pll
+ - description: input ddr pll test clk
+ - description: external input rmii oscillator (optional)
+
+ clock-names:
+ minItems: 27
+ items:
+ - const: xtal
+ - const: fdiv2
+ - const: fdiv3
+ - const: fdiv4
+ - const: fdiv5
+ - const: fdiv7
+ - const: fdiv2p5
+ - const: sys
+ - const: gp1
+ - const: gp2
+ - const: sysplldiv16
+ - const: cpudiv16
+ - const: a78div16
+ - const: dsudiv16
+ - const: rtc
+ - const: gp0
+ - const: hifi0
+ - const: hifi1
+ - const: mclk0
+ - const: mclk1
+ - const: vid1
+ - const: vid2
+ - const: hdmiout2
+ - const: hdmipix
+ - const: pix0
+ - const: pix1
+ - const: ddr_test
+ - const: ext_rmii
+
+required:
+ - compatible
+ - reg
+ - '#clock-cells'
+ - clocks
+ - clock-names
+
+additionalProperties: false
+
+examples:
+ - |
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ clock-controller@200 {
+ compatible = "amlogic,a9-peripherals-clkc";
+ reg = <0x0 0x200 0x0 0x2f8>;
+ #clock-cells = <1>;
+ clocks = <&xtal>,
+ <&scmi_clk 10>,
+ <&scmi_clk 12>,
+ <&scmi_clk 14>,
+ <&scmi_clk 16>,
+ <&scmi_clk 18>,
+ <&scmi_clk 20>,
+ <&scmi_clk 21>,
+ <&scmi_clk 33>,
+ <&scmi_clk 34>,
+ <&scmi_clk 35>,
+ <&scmi_clk 36>,
+ <&scmi_clk 37>,
+ <&scmi_clk 38>,
+ <&scmi_clk 40>,
+ <&gp0 3>,
+ <&hifi0 3>,
+ <&hifi1 3>,
+ <&mclk0 3>,
+ <&mclk1 3>,
+ <&vid1>,
+ <&vid2>,
+ <&hdmitx 10>,
+ <&hdmitx 11>,
+ <&pix0>,
+ <&pix1>,
+ <&ddr 3>;
+ clock-names = "xtal",
+ "fdiv2",
+ "fdiv3",
+ "fdiv4",
+ "fdiv5",
+ "fdiv7",
+ "fdiv2p5",
+ "sys",
+ "gp1",
+ "gp2",
+ "sysplldiv16",
+ "cpudiv16",
+ "a78div16",
+ "dsudiv16",
+ "rtc",
+ "gp0",
+ "hifi0",
+ "hifi1",
+ "mclk0",
+ "mclk1",
+ "vid1",
+ "vid2",
+ "hdmiout2",
+ "hdmipix",
+ "pix0",
+ "pix1",
+ "ddr_test";
+ };
+ };
diff --git a/include/dt-bindings/clock/amlogic,a9-peripherals-clkc.h b/include/dt-bindings/clock/amlogic,a9-peripherals-clkc.h
new file mode 100644
index 000000000000..09487a414197
--- /dev/null
+++ b/include/dt-bindings/clock/amlogic,a9-peripherals-clkc.h
@@ -0,0 +1,351 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) 2026 Amlogic, Inc. All rights reserved.
+ */
+
+#ifndef __AMLOGIC_A9_PERIPHERALS_CLKC_H
+#define __AMLOGIC_A9_PERIPHERALS_CLKC_H
+
+#define CLKID_SYS_AM_AXI 0
+#define CLKID_SYS_DOS 1
+#define CLKID_SYS_MIPI_DSI0 2
+#define CLKID_SYS_ETH_PHY 3
+#define CLKID_SYS_AMFC 4
+#define CLKID_SYS_MALI 5
+#define CLKID_SYS_NNA 6
+#define CLKID_SYS_ETH_AXI 7
+#define CLKID_SYS_DP_APB 8
+#define CLKID_SYS_EDPTX_APB 9
+#define CLKID_SYS_U3HSG 10
+#define CLKID_SYS_AUCPU 11
+#define CLKID_SYS_GLB 12
+#define CLKID_SYS_COMBO_DPHY_APB 13
+#define CLKID_SYS_HDMIRX_APB 14
+#define CLKID_SYS_HDMIRX_PCLK 15
+#define CLKID_SYS_MIPI_DSI0_PHY 16
+#define CLKID_SYS_CAN0 17
+#define CLKID_SYS_CAN1 18
+#define CLKID_SYS_SD_EMMC_A 19
+#define CLKID_SYS_SD_EMMC_B 20
+#define CLKID_SYS_SD_EMMC_C 21
+#define CLKID_SYS_SC 22
+#define CLKID_SYS_ACODEC 23
+#define CLKID_SYS_MIPI_ISP 24
+#define CLKID_SYS_MSR 25
+#define CLKID_SYS_AUDIO 26
+#define CLKID_SYS_MIPI_DSI1 27
+#define CLKID_SYS_MIPI_DSI1_PHY 28
+#define CLKID_SYS_ETH 29
+#define CLKID_SYS_ETH_1G_MAC 30
+#define CLKID_SYS_UART_A 31
+#define CLKID_SYS_UART_F 32
+#define CLKID_SYS_TS_A55 33
+#define CLKID_SYS_ETH_1G_AXI 34
+#define CLKID_SYS_TS_DOS 35
+#define CLKID_SYS_U3DRD_B 36
+#define CLKID_SYS_TS_CORE 37
+#define CLKID_SYS_TS_PLL 38
+#define CLKID_SYS_CSI_DIG_CLKIN 39
+#define CLKID_SYS_CVE 40
+#define CLKID_SYS_GE2D 41
+#define CLKID_SYS_SPISG 42
+#define CLKID_SYS_U2H 43
+#define CLKID_SYS_PCIE_MAC_A 44
+#define CLKID_SYS_U3DRD_A 45
+#define CLKID_SYS_U2DRD 46
+#define CLKID_SYS_PCIE_PHY 47
+#define CLKID_SYS_PCIE_MAC_B 48
+#define CLKID_SYS_PERIPH 49
+#define CLKID_SYS_PIO 50
+#define CLKID_SYS_I3C 51
+#define CLKID_SYS_I2C_M_E 52
+#define CLKID_SYS_I2C_M_F 53
+#define CLKID_SYS_HDMITX_APB 54
+#define CLKID_SYS_I2C_M_I 55
+#define CLKID_SYS_I2C_M_G 56
+#define CLKID_SYS_I2C_M_H 57
+#define CLKID_SYS_HDMI20_AES 58
+#define CLKID_SYS_CSI2_HOST 59
+#define CLKID_SYS_CSI2_ADAPT 60
+#define CLKID_SYS_DSPA 61
+#define CLKID_SYS_PP_DMA 62
+#define CLKID_SYS_PP_WRAPPER 63
+#define CLKID_SYS_VPU_INTR 64
+#define CLKID_SYS_CSI2_PHY 65
+#define CLKID_SYS_SARADC 66
+#define CLKID_SYS_PWM_J 67
+#define CLKID_SYS_PWM_I 68
+#define CLKID_SYS_PWM_H 69
+#define CLKID_SYS_PWM_N 70
+#define CLKID_SYS_PWM_M 71
+#define CLKID_SYS_PWM_L 72
+#define CLKID_SYS_PWM_K 73
+#define CLKID_SD_EMMC_A_SEL 74
+#define CLKID_SD_EMMC_A_DIV 75
+#define CLKID_SD_EMMC_A 76
+#define CLKID_SD_EMMC_B_SEL 77
+#define CLKID_SD_EMMC_B_DIV 78
+#define CLKID_SD_EMMC_B 79
+#define CLKID_SD_EMMC_C_SEL 80
+#define CLKID_SD_EMMC_C_DIV 81
+#define CLKID_SD_EMMC_C 82
+#define CLKID_PWM_H_SEL 83
+#define CLKID_PWM_H_DIV 84
+#define CLKID_PWM_H 85
+#define CLKID_PWM_I_SEL 86
+#define CLKID_PWM_I_DIV 87
+#define CLKID_PWM_I 88
+#define CLKID_PWM_J_SEL 89
+#define CLKID_PWM_J_DIV 90
+#define CLKID_PWM_J 91
+#define CLKID_PWM_K_SEL 92
+#define CLKID_PWM_K_DIV 93
+#define CLKID_PWM_K 94
+#define CLKID_PWM_L_SEL 95
+#define CLKID_PWM_L_DIV 96
+#define CLKID_PWM_L 97
+#define CLKID_PWM_M_SEL 98
+#define CLKID_PWM_M_DIV 99
+#define CLKID_PWM_M 100
+#define CLKID_PWM_N_SEL 101
+#define CLKID_PWM_N_DIV 102
+#define CLKID_PWM_N 103
+#define CLKID_SPISG0_SEL 104
+#define CLKID_SPISG0_DIV 105
+#define CLKID_SPISG0 106
+#define CLKID_SPISG1_SEL 107
+#define CLKID_SPISG1_DIV 108
+#define CLKID_SPISG1 109
+#define CLKID_SPISG2_SEL 110
+#define CLKID_SPISG2_DIV 111
+#define CLKID_SPISG2 112
+#define CLKID_SARADC_SEL 113
+#define CLKID_SARADC_DIV 114
+#define CLKID_SARADC 115
+#define CLKID_AMFC_SEL 116
+#define CLKID_AMFC_DIV 117
+#define CLKID_AMFC 118
+#define CLKID_NNA_SEL 119
+#define CLKID_NNA_DIV 120
+#define CLKID_NNA 121
+#define CLKID_USB_250M_SEL 122
+#define CLKID_USB_250M_DIV 123
+#define CLKID_USB_250M 124
+#define CLKID_USB_48M_PRE_SEL 125
+#define CLKID_USB_48M_PRE_DIV 126
+#define CLKID_USB_48M_PRE 127
+#define CLKID_PCIE0_TL_SEL 128
+#define CLKID_PCIE0_TL_DIV 129
+#define CLKID_PCIE0_TL 130
+#define CLKID_PCIE1_TL_SEL 131
+#define CLKID_PCIE1_TL_DIV 132
+#define CLKID_PCIE1_TL 133
+#define CLKID_CMPR_SEL 134
+#define CLKID_CMPR_DIV 135
+#define CLKID_CMPR 136
+#define CLKID_DEWARPA_SEL 137
+#define CLKID_DEWARPA_DIV 138
+#define CLKID_DEWARPA 139
+#define CLKID_SC_PRE_SEL 140
+#define CLKID_SC_PRE_DIV 141
+#define CLKID_SC_PRE 142
+#define CLKID_SC 143
+#define CLKID_DPTX_APB2_SEL 144
+#define CLKID_DPTX_APB2_DIV 145
+#define CLKID_DPTX_APB2 146
+#define CLKID_DPTX_AUD_SEL 147
+#define CLKID_DPTX_AUD_DIV 148
+#define CLKID_DPTX_AUD 149
+#define CLKID_ISP_SEL 150
+#define CLKID_ISP_DIV 151
+#define CLKID_ISP 152
+#define CLKID_CVE_SEL 153
+#define CLKID_CVE_DIV 154
+#define CLKID_CVE 155
+#define CLKID_VGE_SEL 156
+#define CLKID_VGE_DIV 157
+#define CLKID_VGE 158
+#define CLKID_PP_SEL 159
+#define CLKID_PP_DIV 160
+#define CLKID_PP 161
+#define CLKID_GLB_SEL 162
+#define CLKID_GLB_DIV 163
+#define CLKID_GLB 164
+#define CLKID_USB_48M_DUALDIV_IN 165
+#define CLKID_USB_48M_DUALDIV_DIV 166
+#define CLKID_USB_48M_DUALDIV_SEL 167
+#define CLKID_USB_48M_DUALDIV 168
+#define CLKID_USB_48M 169
+#define CLKID_CAN0_PE_SEL 170
+#define CLKID_CAN0_PE_DIV 171
+#define CLKID_CAN0_PE 172
+#define CLKID_CAN1_PE_SEL 173
+#define CLKID_CAN1_PE_DIV 174
+#define CLKID_CAN1_PE 175
+#define CLKID_CAN0_FILTER_SEL 176
+#define CLKID_CAN0_FILTER_DIV 177
+#define CLKID_CAN0_FILTER 178
+#define CLKID_CAN1_FILTER_SEL 179
+#define CLKID_CAN1_FILTER_DIV 180
+#define CLKID_CAN1_FILTER 181
+#define CLKID_I3C_SEL 182
+#define CLKID_I3C_DIV 183
+#define CLKID_I3C 184
+#define CLKID_TS_DIV 185
+#define CLKID_TS 186
+#define CLKID_ETH_125M_DIV 187
+#define CLKID_ETH_125M 188
+#define CLKID_ETH_RMII_SEL 189
+#define CLKID_ETH_RMII_DIV 190
+#define CLKID_ETH_RMII 191
+#define CLKID_GEN_SEL 192
+#define CLKID_GEN_DIV 193
+#define CLKID_GEN 194
+#define CLKID_CLK24M_IN 195
+#define CLKID_CLK12_24M 196
+#define CLKID_MALI_0_SEL 197
+#define CLKID_MALI_0_DIV 198
+#define CLKID_MALI_0 199
+#define CLKID_MALI_1_SEL 200
+#define CLKID_MALI_1_DIV 201
+#define CLKID_MALI_1 202
+#define CLKID_MALI 203
+#define CLKID_MALI_STACK_0_SEL 204
+#define CLKID_MALI_STACK_0_DIV 205
+#define CLKID_MALI_STACK_0 206
+#define CLKID_MALI_STACK_1_SEL 207
+#define CLKID_MALI_STACK_1_DIV 208
+#define CLKID_MALI_STACK_1 209
+#define CLKID_MALI_STACK 210
+#define CLKID_DSPA_0_SEL 211
+#define CLKID_DSPA_0_DIV 212
+#define CLKID_DSPA_0 213
+#define CLKID_DSPA_1_SEL 214
+#define CLKID_DSPA_1_DIV 215
+#define CLKID_DSPA_1 216
+#define CLKID_DSPA 217
+#define CLKID_HEVCF_0_SEL 218
+#define CLKID_HEVCF_0_DIV 219
+#define CLKID_HEVCF_0 220
+#define CLKID_HEVCF_1_SEL 221
+#define CLKID_HEVCF_1_DIV 222
+#define CLKID_HEVCF_1 223
+#define CLKID_HEVCF 224
+#define CLKID_HCODEC_0_SEL 225
+#define CLKID_HCODEC_0_DIV 226
+#define CLKID_HCODEC_0 227
+#define CLKID_HCODEC_1_SEL 228
+#define CLKID_HCODEC_1_DIV 229
+#define CLKID_HCODEC_1 230
+#define CLKID_HCODEC 231
+#define CLKID_VPU_0_SEL 232
+#define CLKID_VPU_0_DIV 233
+#define CLKID_VPU_0 234
+#define CLKID_VPU_1_SEL 235
+#define CLKID_VPU_1_DIV 236
+#define CLKID_VPU_1 237
+#define CLKID_VPU 238
+#define CLKID_VAPB_0_SEL 239
+#define CLKID_VAPB_0_DIV 240
+#define CLKID_VAPB_0 241
+#define CLKID_VAPB_1_SEL 242
+#define CLKID_VAPB_1_DIV 243
+#define CLKID_VAPB_1 244
+#define CLKID_VAPB 245
+#define CLKID_GE2D 246
+#define CLKID_VPU_CLKB_TMP_SEL 247
+#define CLKID_VPU_CLKB_TMP_DIV 248
+#define CLKID_VPU_CLKB_TMP 249
+#define CLKID_VPU_CLKB_DIV 250
+#define CLKID_VPU_CLKB 251
+#define CLKID_HDMITX_SYS_SEL 252
+#define CLKID_HDMITX_SYS_DIV 253
+#define CLKID_HDMITX_SYS 254
+#define CLKID_HDMITX_PRIF_SEL 255
+#define CLKID_HDMITX_PRIF_DIV 256
+#define CLKID_HDMITX_PRIF 257
+#define CLKID_HDMITX_200M_SEL 258
+#define CLKID_HDMITX_200M_DIV 259
+#define CLKID_HDMITX_200M 260
+#define CLKID_HDMITX_AUD_SEL 261
+#define CLKID_HDMITX_AUD_DIV 262
+#define CLKID_HDMITX_AUD 263
+#define CLKID_HDMIRX_5M_SEL 264
+#define CLKID_HDMIRX_5M_DIV 265
+#define CLKID_HDMIRX_5M 266
+#define CLKID_HDMIRX_2M_SEL 267
+#define CLKID_HDMIRX_2M_DIV 268
+#define CLKID_HDMIRX_2M 269
+#define CLKID_HDMIRX_CFG_SEL 270
+#define CLKID_HDMIRX_CFG_DIV 271
+#define CLKID_HDMIRX_CFG 272
+#define CLKID_HDMIRX_HDCP2X_SEL 273
+#define CLKID_HDMIRX_HDCP2X_DIV 274
+#define CLKID_HDMIRX_HDCP2X 275
+#define CLKID_HDMIRX_ACR_REF_SEL 276
+#define CLKID_HDMIRX_ACR_REF_DIV 277
+#define CLKID_HDMIRX_ACR_REF 278
+#define CLKID_HDMIRX_METER_SEL 279
+#define CLKID_HDMIRX_METER_DIV 280
+#define CLKID_HDMIRX_METER 281
+#define CLKID_VID_LOCK_SEL 282
+#define CLKID_VID_LOCK_DIV 283
+#define CLKID_VID_LOCK 284
+#define CLKID_VDIN_MEAS_SEL 285
+#define CLKID_VDIN_MEAS_DIV 286
+#define CLKID_VDIN_MEAS 287
+#define CLKID_VID_PLL_DIV 288
+#define CLKID_VID_PLL_SEL 289
+#define CLKID_VID_PLL 290
+#define CLKID_VID_PLL_VCLK 291
+#define CLKID_VCLK0_SEL 292
+#define CLKID_VCLK0_IN 293
+#define CLKID_VCLK0_DIV 294
+#define CLKID_VCLK0 295
+#define CLKID_VCLK0_DIV1_EN 296
+#define CLKID_VCLK0_DIV2_EN 297
+#define CLKID_VCLK0_DIV2 298
+#define CLKID_VCLK0_DIV4_EN 299
+#define CLKID_VCLK0_DIV4 300
+#define CLKID_VCLK0_DIV6_EN 301
+#define CLKID_VCLK0_DIV6 302
+#define CLKID_VCLK0_DIV12_EN 303
+#define CLKID_VCLK0_DIV12 304
+#define CLKID_VCLK1_SEL 305
+#define CLKID_VCLK1_IN 306
+#define CLKID_VCLK1_DIV 307
+#define CLKID_VCLK1 308
+#define CLKID_VCLK1_DIV1_EN 309
+#define CLKID_VCLK1_DIV2_EN 310
+#define CLKID_VCLK1_DIV2 311
+#define CLKID_VCLK1_DIV4_EN 312
+#define CLKID_VCLK1_DIV4 313
+#define CLKID_VCLK1_DIV6_EN 314
+#define CLKID_VCLK1_DIV6 315
+#define CLKID_VCLK1_DIV12_EN 316
+#define CLKID_VCLK1_DIV12 317
+#define CLKID_VDAC_SEL 318
+#define CLKID_VDAC 319
+#define CLKID_ENCODER0_SEL 320
+#define CLKID_ENCODER0 321
+#define CLKID_ENCODER1_SEL 322
+#define CLKID_ENCODER1 323
+#define CLKID_HDMITX0_PIXEL_SEL 324
+#define CLKID_HDMITX0_PIXEL 325
+#define CLKID_HDMITX0_FE_SEL 326
+#define CLKID_HDMITX0_FE 327
+#define CLKID_HDMITX1_PIXEL_SEL 328
+#define CLKID_HDMITX1_PIXEL 329
+#define CLKID_HDMITX1_FE_SEL 330
+#define CLKID_HDMITX1_FE 331
+#define CLKID_CSI_PHY_SEL 332
+#define CLKID_CSI_PHY_DIV 333
+#define CLKID_CSI_PHY 334
+#define CLKID_DSI0_MEAS_SEL 335
+#define CLKID_DSI0_MEAS_DIV 336
+#define CLKID_DSI0_MEAS 337
+#define CLKID_DSI1_MEAS_SEL 338
+#define CLKID_DSI1_MEAS_DIV 339
+#define CLKID_DSI1_MEAS 340
+
+#endif /* __AMLOGIC_A9_PERIPHERALS_CLKC_H */
--
2.47.1
^ permalink raw reply related
* Re: [PATCH] [RFC] gpiolib: introduce gpio_name() helper
From: Arnd Bergmann @ 2026-07-01 8:31 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Arnd Bergmann, Linus Walleij, Bartosz Golaszewski,
Marcel Holtmann, MyungJoo Ham, Chanwoo Choi, Geert Uytterhoeven,
Andy Shevchenko, Dmitry Torokhov, Ulf Hansson, linux-bluetooth,
linux-kernel, open list:GPIO SUBSYSTEM, dri-devel, linux-i2c,
linux-iio, linux-input, linux-mmc @ vger . kernel . org,
linux-arm-kernel, linux-pm, linux-usb
In-Reply-To: <CAMuHMdWhv8i6tkmOJU_ee9LAV7mMcQHe9FXgqTHCjGiEMWvn8Q@mail.gmail.com>
On Tue, Jun 30, 2026, at 18:01, Geert Uytterhoeven wrote:
> On Mon, 29 Jun 2026 at 19:54, Arnd Bergmann <arnd@arndb.de> wrote:
>> On Mon, Jun 29, 2026, at 17:29, Geert Uytterhoeven wrote:
>> > Same results for instantiation using sysfs or configfs[1], although
>> > the latter does have optional support for specifying the name.
>>
>> I wonder how many of the other instances have the same problem
>> then. Would it be appropriate for gpiochip_fwd_desc_add() to set
>> a name itself to address this one?
>
> I don't think it would be appropriate for the GPIO aggregator to set
> that name. What we want to print here (for debugging) is the physical
> GPIO that an aggregator's GPIO is mapped to, not some consumer or line
> name (which is not guaranteed to be unique).
Ok.
> E.g. "<chip-name>.<offset>" would be fine. As gpiod_name() can only
> return a fixed string or an existing string, it can't return such a
> formatted string, though. And consumers don't have access to chip info?
The gpiod_hwgpio() function is exported to consumers, so they can
already print that instead of desc_to_gpio() if the local number
is sufficient. If we really care about the <chip-name> portion for
any of the debug prints, we could export another function that
returns maybe gpiod_to_chip(gpiod)->label or
dev_name(&gpiod_to_gpio_device(gpiod)->dev), which are both
constant strings we can print.
It looks like we can also replace most of the remaining callers
of desc_to_gpio() with gpiod_hwgpio().
Arnd
^ permalink raw reply
* Re: [PATCH v4 1/7] dt-bindings: mtd: jedec,spi-nor: allow the SFDP to be exposed via NVMEM
From: Michael Walle @ 2026-07-01 8:34 UTC (permalink / raw)
To: Linus Walleij, Manikandan Muralidharan
Cc: pratyush, mwalle, takahiro.kuwano, miquel.raynal, richard,
vigneshr, robh, krzk+dt, conor+dt, srini, nicolas.ferre,
alexandre.belloni, claudiu.beznea, linux, richardcochran, arnd,
linux-mtd, devicetree, linux-kernel, linux-arm-kernel, netdev
In-Reply-To: <CAD++jL=FkEfpz-LW0vmPpZ28fLfGFMWo5E479Mapz55YUxKNAQ@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1630 bytes --]
Hi,
>> Add an optional "sfdp" child node (compatible "jedec,sfdp") that
>> describes the SFDP as a read-only NVMEM provider via nvmem.yaml, so its
>> contents (e.g. a vendor EUI-48/EUI-64) can be read through NVMEM cells.
>>
>> Signed-off-by: Manikandan Muralidharan <manikandan.m@microchip.com>
>
> I would expect it to follow nvmem conventions like this, notice
> compatibles specific-to-general with sfdp first:
> sfdp {
> /* NVMEM provided by SFDP */
> compatible = "jedec,sfdp", "nvmem-cells";
> label = "SFDP";
Isn't using label frowned upon? I wouldn't add that to the example.
> read-only;
> #address-cells = <1>;
> #size-cells = <1>;
>
> mac0: macaddr@0x00 {
> reg = <0x00 0x06>;
> };
> mac1: macaddr@0x06 {
> reg = <0x06 0x06>;
> };
> };
If I'm correct, this is the old style, see commit bd912c991d2e
("dt-bindings: nvmem: layouts: add fixed-layout"). So it should
eventually look like:
sfdp {
compatible = "jedec,sfdp";
nvmem-layout {
compatible = "microchip,sst26vf-sfdp-eui";
};
};
Which is what patch series will lead to.
Also I'm not sure if we really need to add the "nvmem-cells" here.
IIRC in MTD it was there to tell a driver to add an nvmem device to
an already existing compatible/node.
Apart from the MTD case, I've just found qcom,smem-part,yaml which
has compatible = "nvmem-cells".
-michael
> Your example should definitely be more elaborate like this,
> just an opaque sfdp node will not suffice. Maybe a separate
> example?
>
> Yours,
> Linus Walleij
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 297 bytes --]
^ permalink raw reply
* [PATCH v2] arm64: dts: mediatek: mt6359: use proper compatible for rtc
From: Louis-Alexis Eyraud @ 2026-07-01 8:38 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno
Cc: kernel, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Louis-Alexis Eyraud
The MT6359 PMIC include file uses directly "mediatek,mt6358-rtc"
compatible string for the rtc subnode, but not its own compatible
string.
Now that the "mediatek,mt6359-rtc" compatible is properly declared in
the dt-bindings, use it with "mediatek,mt6358-rtc" as fallback.
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
Several Mediatek and Radxa boards, based on MT8370, MT8390 or MT8395
SoC, integrate the MT6365 PMIC, that is a MT6359P variant:
- Mediatek Genio 1200-EVK
- Mediatek Genio 700-EVK
- Mediatek Genio 510-EVK
- Radxa NIO-12L
It is compatible with the MT6359 PMIC.
But both MT6365 PMIC support and compatibility were never expressed in
the dt-bindings and there is no MT6365 include file as well.
So, since these board support was introduced, their devicetrees use the
mt6359 include file to enable this PMIC support.
The goal of this series is to clean this support by adding the missing
compatible strings for this MFD main and subdevices in the dt-bindings,
and add a include for MT6365 definitions to replace the MT6359 include
in these board devicetrees and for future ones (like Genio 520/720
EVKs).
The series is based on linux-next tree (tag: next-20260630) and has
been tested on Mediatek Genio 510, 700 and 1200-EVK boards.
---
Changes in v2:
- Rebased over next-20260630 tag
- Removed already merged patches from series
- Removed useless regulator label addition from patch
- Link to v1: https://lore.kernel.org/r/20260429-mediatek-genio-mt6365-cleanup-v1-0-6f43838be92f@collabora.com
---
arch/arm64/boot/dts/mediatek/mt6359.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/mediatek/mt6359.dtsi b/arch/arm64/boot/dts/mediatek/mt6359.dtsi
index a953fb527b69..52fb0f832260 100644
--- a/arch/arm64/boot/dts/mediatek/mt6359.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt6359.dtsi
@@ -287,7 +287,7 @@ mt6359_vsram_others_sshub_ldo: ldo_vsram_others_sshub {
};
mt6359rtc: rtc {
- compatible = "mediatek,mt6358-rtc";
+ compatible = "mediatek,mt6359-rtc", "mediatek,mt6358-rtc";
};
};
};
---
base-commit: ba7c57499e5999aeae8dd4f954eb2600589d80aa
change-id: 20260428-mediatek-genio-mt6365-cleanup-6cdd84c3f098
Best regards,
--
Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
^ permalink raw reply related
* Re: [PATCH v2 1/9] time: Respect COMPAT_32BIT_TIME for old time type functions
From: Thomas Weißschuh @ 2026-07-01 8:40 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Andy Lutomirski, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
Dave Hansen, x86, H. Peter Anvin, Russell King, Catalin Marinas,
Will Deacon, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Thomas Bogendoerfer,
Vincenzo Frascino, John Stultz, Stephen Boyd, David S . Miller,
Andreas Larsson, linux-kernel, linux-arm-kernel, linuxppc-dev,
linux-mips, linux-api, sparclinux
In-Reply-To: <0cda7366-2eb9-4ecb-b76a-b3b68ee10043@app.fastmail.com>
On Tue, Jun 30, 2026 at 03:00:37PM +0200, Arnd Bergmann wrote:
> On Tue, Jun 30, 2026, at 09:38, Thomas Weißschuh wrote:
> > The "old" time types use 32-bit seconds which are not y2038-safe.
> > Respect COMPAT_32BIT_TIME for functions using those types.
> > time(), stime() and gettimeofday() are disabled completely.
>
> Looks good, yes
Sashiko found an issue [0], which I think is valid. I'll change that for v3.
> > settimeofday() is kept as it is required to do the initial timewarping
> > after boot. However the 'tv' argument will be rejected.
>
> Not sure about this part, did we already discuss this last time?
This is my interpretation of [1].
> I can see how keeping the timewarping functionality is the easy way
> out, but completely disabling the settimeofday syscall the same
> way we do on new architectures seems so much more consistent.
Shouldn't we then do this completely? Irrespective of COMPAT_32BIT_TIME?
And then remove all of the timewarping and kernel timezone bits.
It would be nice however if this series, and my other ones blocked behind it,
are not blocked on that larger rework.
(...)
[0] https://sashiko.dev/#/patchset/20260630-vdso-compat_32bit_time-v2-0-520d194640dd%40linutronix.de?part=1
[1] https://lore.kernel.org/all/e9487ebe-3730-438a-9c23-e45f75986ecc@app.fastmail.com/
Thomas
^ permalink raw reply
* Re: [PATCH v5 8/8] futex: Use runtime constants for __futex_hash() hot path
From: Sebastian Andrzej Siewior @ 2026-07-01 8:41 UTC (permalink / raw)
To: Peter Zijlstra
Cc: K Prateek Nayak, Arnd Bergmann, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, x86, Catalin Marinas, Will Deacon,
Paul Walmsley, Palmer Dabbelt, Albert Ou, Heiko Carstens,
Vasily Gorbik, Alexander Gordeev, Darren Hart, Davidlohr Bueso,
André Almeida, linux-arch, linux-kernel, Samuel Holland,
Charlie Jenkins, linux-arm-kernel, linux-riscv, linux-s390,
H. Peter Anvin, Thomas Huth, Sean Christopherson, Jisheng Zhang,
Alexandre Ghiti, Christian Borntraeger, Sven Schnelle
In-Reply-To: <20260701075714.GP48970@noisy.programming.kicks-ass.net>
On 2026-07-01 09:57:14 [+0200], Peter Zijlstra wrote:
> The big $1M question: does it actually make it go faster? The whole
> point here was performance, right? But I'm not seeing numbers showing
> how awesome these patches are.
I did complain about the about the size of __futex_data which is blown
on distro kernels due to CONFIG_NODES_SHIFT=10 on Debian for instance.
This makes it go away at no extra price but yeah let me boot a big box
and see.
If the performance remains unchanged it is still worth considering due
to size savings on the average box with 1 node. The biggest box I have
access to has four nodes. If I remember correctly, Prateek was saying
that AMD has "normal" boxes which would require =9 for normal operation
and they do run distro kernels so lowering that value is not an option.
Sebastian
^ permalink raw reply
* RE: [PATCH V4 0/7] PCI: imx6: Integrate pwrctrl API and update device trees
From: Sherry Sun @ 2026-07-01 8:44 UTC (permalink / raw)
To: Frank Li (OSS), robh@kernel.org, krzk+dt@kernel.org,
conor+dt@kernel.org, s.hauer@pengutronix.de,
kernel@pengutronix.de, festevam@gmail.com, lpieralisi@kernel.org,
kwilczynski@kernel.org, mani@kernel.org, bhelgaas@google.com,
Hongxing Zhu, l.stach@pengutronix.de, Sherry Sun (OSS)
Cc: Frank Li, imx@lists.linux.dev, linux-pci@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <akPmK--SgmTTAjFw@SMW015318>
> Subject: Re: [PATCH V4 0/7] PCI: imx6: Integrate pwrctrl API and update device
> trees
>
> On Tue, Jun 30, 2026 at 11:31:10AM -0400, Frank.Li@oss.nxp.com wrote:
> > From: Frank Li <Frank.Li@nxp.com>
> >
> >
> > On Tue, 30 Jun 2026 14:07:03 +0800, Sherry Sun (OSS) wrote:
> > > From: Sherry Sun <sherry.sun@nxp.com>
> > >
> > > This series integrates the PCI pwrctrl framework into the pci-imx6
> > > driver and updates i.MX EVK board device trees to support it.
> > >
> > > Patches 2-8 update device trees for i.MX EVK boards which maintained
> > > by NXP to move power supply properties from the PCIe controller node
> > > to the Root Port child node, which is required for pwrctrl framework.
> > > Affected boards:
> > > - i.MX6Q/DL SABRESD
> > > - i.MX6SX SDB
> > > - i.MX8MM EVK
> > > - i.MX8MP EVK
> > > - i.MX8MQ EVK
> > > - i.MX8DXL/QM/QXP EVK
> > > - i.MX95 15x15/19x19 EVK
> > >
> > > [...]
> >
> > Applied, thanks!
> >
> > [1/7] arm: dts: imx6qdl-sabresd: Move power supply property to Root Port
> node
> > commit: b16fded592305f04ae40764f5fa91d5ac6f02a65
> > [2/7] arm: dts: imx6sx-sdb: Move power supply property to Root Port node
> > commit: a1af6cf5a6ce526ea41d4686fa14580a48b2e768
> > [3/7] arm64: dts: imx8mm-evk: Move power supply property to Root Port
> node
> > commit: b6a38d70bcbf0893ce5493f3daf0cb19e5102269
> > [4/7] arm64: dts: imx8mp-evk: Move power supply properties to Root Port
> node
> > commit: fde093c386a64c820a704abaab9ffd9ec738cd4d
> > [5/7] arm64: dts: imx8mq-evk: Move power supply properties to Root Port
> node
> > commit: 78610987333b0811a456f9a4782472fad00f4a19
> > [6/7] arm64: dts: imx8dxl/qm/qxp: Move power supply properties to Root
> Port node
> > commit: 240950f3ad76761066ffe399f62670321c1be1f1
> > [7/7] arm64: dts: imx95: Move power supply properties to Root Port node
> > commit: 6e53e8b854bc6f8330d07905b73e53ad02aff62b
>
> Sorry, I have to drop again because miss consider back compatible problem.
>
> All old platform, 1 - 6, need keep both under pcie and root port.
>
> iMX95, you can move under root becasue it is new platform, it should be fine
> to break compatible since development phase.
>
Hi Frank,
Ok. Will keep the old vpcie-supply and vpcie3v3aux-supply in the parent PCIe
controller node for patch 1-6.
Best Regards
Sherry
^ permalink raw reply
* Re: [PATCH v3 2/7] gpio: regmap: add gpio_regmap_get_gpiochip() accessor
From: Michael Walle @ 2026-07-01 8:44 UTC (permalink / raw)
To: Linus Walleij
Cc: Bartosz Golaszewski, Andy Shevchenko, robh@kernel.org,
krzk+dt@kernel.org, conor+dt@kernel.org, afaerber@suse.com,
wbg@kernel.org, mathieu.dubois-briand@bootlin.com,
lars@metafoo.de, Michael.Hennerich@analog.com, jic23@kernel.org,
nuno.sa@analog.com, andy@kernel.org, dlechner@baylibre.com,
TY_Chang[張子逸], linux-gpio@vger.kernel.org,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-realtek-soc@lists.infradead.org, linux-iio@vger.kernel.org,
CY_Huang[黃鉦晏],
Stanley Chang[昌育德],
James Tai [戴志峰],
Yu-Chun Lin [林祐君]
In-Reply-To: <CAD++jLncD2ZjH3aedOkGNYP3FyZ=i7Pb0OcKKZKuMOPGNjM_nQ@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1229 bytes --]
On Fri Jun 19, 2026 at 11:08 PM CEST, Linus Walleij wrote:
> On Mon, Jun 8, 2026 at 4:41 PM Michael Walle <mwalle@kernel.org> wrote:
>
>> >>> Without an accessor like gpio_regmap_get_gpiochip(), we cannot retrieve the
>> >>> gpio_chip instantiated inside gpio-regmap.c to fulfill these requirements in our
>> >>> map() function.
>>
>> Why is gpiochip_irq_reqres() called in the first place? Isn't that
>> only called if the irq handling is set up via gc->irq.chip and not
>> via gpiochip_irqchip_add_domain() like in gpio-regmap?
>
> Not really, the gpiochip_irq_reqres() is called to mark that a
> GPIO line is used for IRQ, so the gpiolib cannot turn this
> GPIO into an output line, gpiod_direction_out() will fail
> on lines used for IRQ. So it's a failsafe.
>
> You can live without it of course, but then you don't get
> this failsafe.
Thanks for the explanation! So did I make a mistake years ago by
adding the gpiochip_irqchip_add_domain(), see commit 6a45b0e2589f
("gpiolib: Introduce gpiochip_irqchip_add_domain()")
As Yu-Chun found, gpiochip_irq_reqres() expect the irq chip data
to be a gpio_chip, which isn't the case (in general) for an
externally allocated domain, is it?
-michael
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 297 bytes --]
^ permalink raw reply
* [PATCH v8 00/22] Add Counter delegation ISA extension support
From: Atish Patra @ 2026-07-01 8:46 UTC (permalink / raw)
To: Jiri Olsa, Paul Walmsley, Mark Rutland, Rob Herring, Anup Patel,
Namhyung Kim, Arnaldo Carvalho de Melo, Krzysztof Kozlowski,
Atish Patra, Ian Rogers, Will Deacon, James Clark
Cc: linux-arm-kernel, linux-riscv, linux-kernel, devicetree,
linux-perf-users, Conor Dooley
This series adds the counter delegation extension support. It is based on
very early PoC work done by Kevin Xue and mostly rewritten after that.
The counter delegation ISA extension(Smcdeleg/Ssccfg) actually depends
on multiple ISA extensions.
1. S[m|s]csrind : The indirect CSR extension[1] which defines additional
5 ([M|S|VS]IREG2-[M|S|VS]IREG6) register to address size limitation of
RISC-V CSR address space.
2. Smstateen: The stateen bit[60] controls the access to the registers
indirectly via the above indirect registers.
3. Smcdeleg/Ssccfg: The counter delegation extensions[2]
The counter delegation extension allows Supervisor mode to program the
hpmevent and hpmcounters directly without needing the assistance from the
M-mode via SBI calls. This results in a faster perf profiling and very
few traps. This extension also introduces a scountinhibit CSR which allows
to stop/start any counter directly from the S-mode. As the counter
delegation extension potentially can have more than 100 CSRs, the specification
leverages the indirect CSR extension to save the precious CSR address range.
Due to the dependency of these extensions, the following extensions must be
enabled in qemu to use the counter delegation feature in S-mode.
"smstateen=true,sscofpmf=true,ssccfg=true,smcdeleg=true,smcsrind=true,sscsrind=true"
or Virt machine users can just "max" cpu instead.
When we access the counters directly in S-mode, we also need to solve the
following problems.
1. Event to counter mapping
2. Event encoding discovery
The RISC-V ISA doesn't define any standard either for event encoding or the
event to counter mapping rules. Until now, the SBI PMU implementation relies
on device tree binding[3] to discover the event to counter mapping in RISC-V
platform in the firmware. The SBI PMU specification[4] defines event encoding
for standard perf events as well. Thus, the kernel can query the appropriate
counter for an given event from the firmware.
However, the kernel doesn't need any firmware interaction for hardware
counters if counter delegation is available in the hardware. Thus, the driver
needs to discover the above mappings/encodings by itself without any assistance
from firmware.
Solution to Problem #1:
This patch series solves the above problem #1 by extending the perf tool in a
way so that event json file can specify the counter constraints of each event
and that can be passed to the driver to choose the best counter for a given
event.
This series introduces a RISC-V specific event field in "CounterIDMask" in
event_fields that describes a bitmask of counters supported for a specific eventi.
This is the similar approach for few other existing properties in the event_fields
which were used by single architecture as well. The counter constraint bitmap is
passed to the perf driver via newly introduced "counterid_mask" property set in "config2".
The platform vendor have these three ways to encode/use the platform specific
events.
1. Directly in driver with appropriate constraints (discouraged due to bloating
of the driver)
2. Encode in Json with with CounterIDMask field (preferred as it is contained
within platform specific json file)
3. Directly pass counterid_mask at while invoking perf
cpu/event=<code>,counterid_mask=<mask>/
The last two patches show cases these use cases and not intended for merging.
Solution to problem #2:
The event encoding can come from the json or commandline as well.
The Qemu patches are available in upstream now.
The Linux kernel patches can be found here:
https://github.com/atishp04/linux/tree/b4/counter_delegation_v8
[1] https://github.com/riscv/riscv-indirect-csr-access
[2] https://github.com/riscv/riscv-smcdeleg-ssccfg
[3] https://www.kernel.org/doc/Documentation/devicetree/bindings/perf/riscv%2Cpmu.yaml
[4] https://github.com/riscv-non-isa/riscv-sbi-doc/blob/master/src/ext-pmu.adoc
[5] https://lore.kernel.org/qemu-devel/20260625-marchid-v2-1-3821c351028b@gmail.com/
To: Paul Walmsley <pjw@kernel.org>
To: Rob Herring <robh@kernel.org>
To: Krzysztof Kozlowski <krzk+dt@kernel.org>
To: Will Deacon <will@kernel.org>
To: Mark Rutland <mark.rutland@arm.com>
To: Atish Patra <atish.patra@linux.dev>
To: Anup Patel <anup@brainfault.org>
To: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Namhyung Kim <namhyung@kernel.org>
To: Jiri Olsa <jolsa@kernel.org>
To: Ian Rogers <irogers@google.com>
To: James Clark <james.clark@linaro.org>
Cc: linux-riscv@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Cc: Conor Dooley <conor@kernel.org>
Cc: devicetree@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-perf-users@vger.kernel.org
Signed-off-by: Atish Patra <atishp@meta.com>
Changes in v8:
- Fixed few more issues reported by Sashiko. Remaining sashiko reviews are moot.
- Added support for Qemu ARCH ID 0x42 introduced by the qemu patch[5]
- Link to v7: https://lore.kernel.org/r/20260622-counter_delegation-v7-0-0ba2fd34614e@meta.com
Changes in v7:
- Fixed various issues pointed by Sashiko.
- Rebased on top of v7.1
- Added a separate patch to fix various memory leak issues in probe error path
- Link to v6: https://lore.kernel.org/r/20260608-counter_delegation-v6-0-285b72ed65a9@meta.com
Changes in v6:
- Reverted the file name changes as suggested by Will. Now pmu-sbi.c will continue
to support both counter delegation and SBI PMU with different function prefixes.
- No longer depends up old upstream patch for reusing the Counter property to
encode event to counter mapping property. It directly uses additional field in
json event fields similar to other architectures.
- Added few test patches (not intended for upstreaming) to show case different
possibilities of providing mapping/event encodings.
- Fixed review comments and miscellenous minor typos/fixes on v5
- Rebased on top of v7.1-rc6
Changes in v5:
- Fixed dt_binding_check errors.
- Added the ISA extension dependancy for counter delegation extensions.
- Replaced the boolean variables with static key conditional check required at boot time.
- Miscellaneous minor code restructuring.
- Link to v4: https://lore.kernel.org/r/20250205-counter_delegation-v4-0-835cfa88e3b1@rivosinc.com
Changes in v4:
- Added ISA dependencies as per dt schema instead of description.
- Fixed few compilation issues due to patch reordering in v3.
- Link to v3: https://lore.kernel.org/r/20250127-counter_delegation-v3-0-64894d7e16d5@rivosinc.com
Changes in v3:
- Fixed the dtb binding check failures.
- Inlcuded the fix reported by Rajnesh Kanwal for guest counter overflow.
- Rearranged the overflow handling more efficiently for better modularity.
- Link to v2: https://lore.kernel.org/r/20250114-counter_delegation-v2-0-8ba74cdb851b@rivosinc.com
Changes in v2:
- Dropped architecture specific overrides for event encoding.
- Dropped hwprobe bits.
- Added a vendor specific event encoding table to support vendor specific event
encoding and counter mapping.
- Fixed few bugs and cleanup.
- Link to v1: https://lore.kernel.org/r/20240217005738.3744121-1-atishp@rivosinc.com
---
Atish Patra (19):
RISC-V: perf: fix resource cleanup on driver probe failure
RISC-V: Add Sxcsrind ISA extension definition and parsing
dt-bindings: riscv: add Sxcsrind ISA extension description
RISC-V: Define indirect CSR access helpers
RISC-V: Add Smcntrpmf extension parsing
dt-bindings: riscv: add Smcntrpmf ISA extension description
RISC-V: Add Ssccfg/Smcdeleg ISA extension definition and parsing
dt-bindings: riscv: add Counter delegation ISA extensions description
RISC-V: perf: Restructure the SBI PMU code
RISC-V: perf: Modify the counter discovery mechanism
RISC-V: perf: Add a mechanism to defined legacy event encoding
RISC-V: perf: Implement supervisor counter delegation support
RISC-V: perf: Use config2/vendor table for event to counter mapping
RISC-V: perf: Add legacy event encodings via sysfs
RISC-V: perf: Add Qemu virt machine events
tools/perf: Support event code for arch standard events
tools/perf: Add RISC-V CounterIDMask event field
TEST(do-not-upstream): fake qemu-virt PMU events for cdeleg counter-mask testing
TEST(do-not-upstream): fake qemu vendor JSON + mapfile entry for CounterIDMask path
Charlie Jenkins (1):
RISC-V: perf: Skip PMU SBI extension when not implemented
Kaiwen Xue (2):
RISC-V: Add Sxcsrind ISA extension CSR definitions
RISC-V: Add Sscfg extension CSR definition
.../devicetree/bindings/riscv/extensions.yaml | 63 ++
arch/riscv/include/asm/csr.h | 49 +
arch/riscv/include/asm/csr_ind.h | 41 +
arch/riscv/include/asm/hwcap.h | 7 +
arch/riscv/include/asm/vendorid_list.h | 6 +
arch/riscv/kernel/cpufeature.c | 27 +
drivers/perf/Kconfig | 14 +-
drivers/perf/riscv_pmu_sbi.c | 1116 ++++++++++++++++----
include/linux/perf/riscv_pmu.h | 5 +
.../perf/pmu-events/arch/riscv/arch-standard.json | 10 +
tools/perf/pmu-events/arch/riscv/mapfile.csv | 2 +
.../pmu-events/arch/riscv/qemu/virt/events.json | 26 +
tools/perf/pmu-events/jevents.py | 10 +-
13 files changed, 1167 insertions(+), 209 deletions(-)
---
base-commit: 8cd9520d35a6c38db6567e97dd93b1f11f185dc6
change-id: 20240715-counter_delegation-628a32f8c9cc
Best regards,
--
Atish Patra <atishp@meta.com>
^ permalink raw reply
* [PATCH v8 01/22] RISC-V: perf: fix resource cleanup on driver probe failure
From: Atish Patra @ 2026-07-01 8:46 UTC (permalink / raw)
To: Jiri Olsa, Paul Walmsley, Mark Rutland, Rob Herring, Anup Patel,
Namhyung Kim, Arnaldo Carvalho de Melo, Krzysztof Kozlowski,
Atish Patra, Ian Rogers, Will Deacon, James Clark
Cc: linux-arm-kernel, linux-riscv, linux-kernel, devicetree,
linux-perf-users, Conor Dooley
In-Reply-To: <20260701-counter_delegation-v8-0-7909f863a645@meta.com>
From: Atish Patra <atishp@meta.com>
Sashiko pointed out various UAF and memory leak issues around
pmu_sbi_device_probe() error paths.
If the probe fails, here are list of cleanups needed.
a. Already registered pmu must be freed
b. per cpu IRQ must be released
c. pmu_ctr_list data structure must be freed
d. cpu hotplug state must be cleaned up only if added.
Fix the resource cleanup by reorganizing the code around probe failure.
Reported-by: Sashiko AI <sashiko-bot@kernel.org>
Signed-off-by: Atish Patra <atishp@meta.com>
---
drivers/perf/riscv_pmu_sbi.c | 33 +++++++++++++++++++++++++++------
1 file changed, 27 insertions(+), 6 deletions(-)
diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
index 385af5e6e6d0..5c8924ce1f38 100644
--- a/drivers/perf/riscv_pmu_sbi.c
+++ b/drivers/perf/riscv_pmu_sbi.c
@@ -1220,22 +1220,29 @@ static int pmu_sbi_setup_irqs(struct riscv_pmu *pmu, struct platform_device *pde
DOMAIN_BUS_ANY);
if (!domain) {
pr_err("Failed to find INTC IRQ root domain\n");
- return -ENODEV;
+ ret = -ENODEV;
+ goto err;
}
riscv_pmu_irq = irq_create_mapping(domain, riscv_pmu_irq_num);
if (!riscv_pmu_irq) {
pr_err("Failed to map PMU interrupt for node\n");
- return -ENODEV;
+ ret = -ENODEV;
+ goto err;
}
ret = request_percpu_irq(riscv_pmu_irq, pmu_sbi_ovf_handler, "riscv-pmu", hw_events);
if (ret) {
pr_err("registering percpu irq failed [%d]\n", ret);
- return ret;
+ irq_dispose_mapping(riscv_pmu_irq);
+ riscv_pmu_irq = 0;
+ goto err;
}
return 0;
+err:
+ riscv_pmu_use_irq = false;
+ return ret;
}
#ifdef CONFIG_CPU_PM
@@ -1302,7 +1309,8 @@ static void riscv_pmu_destroy(struct riscv_pmu *pmu)
}
}
riscv_pm_pmu_unregister(pmu);
- cpuhp_state_remove_instance(CPUHP_AP_PERF_RISCV_STARTING, &pmu->node);
+ if (!hlist_unhashed(&pmu->node))
+ cpuhp_state_remove_instance(CPUHP_AP_PERF_RISCV_STARTING, &pmu->node);
}
static void pmu_sbi_event_init(struct perf_event *event)
@@ -1424,6 +1432,7 @@ static int pmu_sbi_device_probe(struct platform_device *pdev)
struct riscv_pmu *pmu = NULL;
int ret = -ENODEV;
int num_counters;
+ bool irq_requested = false;
pr_info("SBI PMU extension is available\n");
pmu = riscv_pmu_alloc();
@@ -1452,6 +1461,7 @@ static int pmu_sbi_device_probe(struct platform_device *pdev)
pmu->pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
pmu->pmu.capabilities |= PERF_PMU_CAP_NO_EXCLUDE;
}
+ irq_requested = (ret == 0);
pmu->pmu.attr_groups = riscv_pmu_attr_groups;
pmu->pmu.parent = &pdev->dev;
@@ -1470,11 +1480,11 @@ static int pmu_sbi_device_probe(struct platform_device *pdev)
ret = riscv_pm_pmu_register(pmu);
if (ret)
- goto out_unregister;
+ goto out_destroy;
ret = perf_pmu_register(&pmu->pmu, "cpu", PERF_TYPE_RAW);
if (ret)
- goto out_unregister;
+ goto out_destroy;
/* SBI PMU Snapsphot is only available in SBI v2.0 */
if (sbi_v2_available) {
@@ -1515,9 +1525,20 @@ static int pmu_sbi_device_probe(struct platform_device *pdev)
return 0;
out_unregister:
+ perf_pmu_unregister(&pmu->pmu);
+
+out_destroy:
riscv_pmu_destroy(pmu);
+ if (irq_requested) {
+ free_percpu_irq(riscv_pmu_irq, pmu->hw_events);
+ irq_dispose_mapping(riscv_pmu_irq);
+ riscv_pmu_irq = 0;
+ }
out_free:
+ free_percpu(pmu->hw_events);
+ kfree(pmu_ctr_list);
+ pmu_ctr_list = NULL;
kfree(pmu);
return ret;
}
--
2.53.0-Meta
^ permalink raw reply related
* [PATCH v8 02/22] RISC-V: Add Sxcsrind ISA extension CSR definitions
From: Atish Patra @ 2026-07-01 8:46 UTC (permalink / raw)
To: Jiri Olsa, Paul Walmsley, Mark Rutland, Rob Herring, Anup Patel,
Namhyung Kim, Arnaldo Carvalho de Melo, Krzysztof Kozlowski,
Atish Patra, Ian Rogers, Will Deacon, James Clark
Cc: linux-arm-kernel, linux-riscv, linux-kernel, devicetree,
linux-perf-users, Conor Dooley
In-Reply-To: <20260701-counter_delegation-v8-0-7909f863a645@meta.com>
From: Kaiwen Xue <kaiwenx@rivosinc.com>
This adds definitions of new CSRs and bits defined in Sxcsrind ISA
extension. These CSR enables indirect accesses mechanism to access
any CSRs in M-, S-, and VS-mode. The range of the select values
and ireg will be define by the ISA extension using Sxcsrind extension.
Signed-off-by: Kaiwen Xue <kaiwenx@rivosinc.com>
Reviewed-by: Clément Léger <cleger@rivosinc.com>
Signed-off-by: Atish Patra <atishp@rivosinc.com>
---
arch/riscv/include/asm/csr.h | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
index 31b8988f4488..b4551a6cf7cb 100644
--- a/arch/riscv/include/asm/csr.h
+++ b/arch/riscv/include/asm/csr.h
@@ -347,6 +347,12 @@
/* Supervisor-Level Window to Indirectly Accessed Registers (AIA) */
#define CSR_SISELECT 0x150
#define CSR_SIREG 0x151
+/* Supervisor-Level Window to Indirectly Accessed Registers (Sxcsrind) */
+#define CSR_SIREG2 0x152
+#define CSR_SIREG3 0x153
+#define CSR_SIREG4 0x155
+#define CSR_SIREG5 0x156
+#define CSR_SIREG6 0x157
/* Supervisor-Level Interrupts (AIA) */
#define CSR_STOPEI 0x15c
@@ -394,6 +400,14 @@
/* VS-Level Window to Indirectly Accessed Registers (H-extension with AIA) */
#define CSR_VSISELECT 0x250
#define CSR_VSIREG 0x251
+/*
+ * VS-Level Window to Indirectly Accessed Registers (H-extension with Sxcsrind)
+ */
+#define CSR_VSIREG2 0x252
+#define CSR_VSIREG3 0x253
+#define CSR_VSIREG4 0x255
+#define CSR_VSIREG5 0x256
+#define CSR_VSIREG6 0x257
/* VS-Level Interrupts (H-extension with AIA) */
#define CSR_VSTOPEI 0x25c
@@ -436,6 +450,12 @@
/* Machine-Level Window to Indirectly Accessed Registers (AIA) */
#define CSR_MISELECT 0x350
#define CSR_MIREG 0x351
+/* Machine-Level Window to Indirectly Accessed Registers (Sxcsrind) */
+#define CSR_MIREG2 0x352
+#define CSR_MIREG3 0x353
+#define CSR_MIREG4 0x355
+#define CSR_MIREG5 0x356
+#define CSR_MIREG6 0x357
/* Machine-Level Interrupts (AIA) */
#define CSR_MTOPEI 0x35c
@@ -498,6 +518,11 @@
# define CSR_IEH CSR_MIEH
# define CSR_ISELECT CSR_MISELECT
# define CSR_IREG CSR_MIREG
+# define CSR_IREG2 CSR_MIREG2
+# define CSR_IREG3 CSR_MIREG3
+# define CSR_IREG4 CSR_MIREG4
+# define CSR_IREG5 CSR_MIREG5
+# define CSR_IREG6 CSR_MIREG6
# define CSR_IPH CSR_MIPH
# define CSR_TOPEI CSR_MTOPEI
# define CSR_TOPI CSR_MTOPI
@@ -523,6 +548,11 @@
# define CSR_IEH CSR_SIEH
# define CSR_ISELECT CSR_SISELECT
# define CSR_IREG CSR_SIREG
+# define CSR_IREG2 CSR_SIREG2
+# define CSR_IREG3 CSR_SIREG3
+# define CSR_IREG4 CSR_SIREG4
+# define CSR_IREG5 CSR_SIREG5
+# define CSR_IREG6 CSR_SIREG6
# define CSR_IPH CSR_SIPH
# define CSR_TOPEI CSR_STOPEI
# define CSR_TOPI CSR_STOPI
--
2.53.0-Meta
^ permalink raw reply related
* [PATCH v8 04/22] dt-bindings: riscv: add Sxcsrind ISA extension description
From: Atish Patra @ 2026-07-01 8:46 UTC (permalink / raw)
To: Jiri Olsa, Paul Walmsley, Mark Rutland, Rob Herring, Anup Patel,
Namhyung Kim, Arnaldo Carvalho de Melo, Krzysztof Kozlowski,
Atish Patra, Ian Rogers, Will Deacon, James Clark
Cc: linux-arm-kernel, linux-riscv, linux-kernel, devicetree,
linux-perf-users, Conor Dooley
In-Reply-To: <20260701-counter_delegation-v8-0-7909f863a645@meta.com>
From: Atish Patra <atishp@rivosinc.com>
Add the S[m|s]csrind ISA extension description.
Acked-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Atish Patra <atishp@rivosinc.com>
---
Documentation/devicetree/bindings/riscv/extensions.yaml | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/Documentation/devicetree/bindings/riscv/extensions.yaml b/Documentation/devicetree/bindings/riscv/extensions.yaml
index 2b0a8a93bb21..15cf0e2ee3ed 100644
--- a/Documentation/devicetree/bindings/riscv/extensions.yaml
+++ b/Documentation/devicetree/bindings/riscv/extensions.yaml
@@ -181,6 +181,14 @@ properties:
changes to interrupts as frozen at commit ccbddab ("Merge pull
request #42 from riscv/jhauser-2023-RC4") of riscv-aia.
+ - const: smcsrind
+ description: |
+ The standard Smcsrind machine-level extension extends the
+ indirect CSR access mechanism defined by the Smaia extension. This
+ extension allows other ISA extensions to use indirect CSR access
+ mechanism in M-mode as ratified in the 20240326 version of the
+ privileged ISA specification.
+
- const: smmpm
description: |
The standard Smmpm extension for M-mode pointer masking as
@@ -226,6 +234,14 @@ properties:
Profiles Version 1.0, with commit b1d806605f87 ("Updated to
ratified state.")
+ - const: sscsrind
+ description: |
+ The standard Sscsrind supervisor-level extension extends the
+ indirect CSR access mechanism defined by the Ssaia extension. This
+ extension allows other ISA extensions to use indirect CSR access
+ mechanism in S-mode as ratified in the 20240326 version of the
+ privileged ISA specification.
+
- const: ssnpm
description: |
The standard Ssnpm extension for next-mode pointer masking as
--
2.53.0-Meta
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox