Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V4 1/7] arm: dts: imx6qdl-sabresd: Move power supply property to Root Port node
From: Sherry Sun (OSS) @ 2026-06-30  6:07 UTC (permalink / raw)
  To: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel, festevam,
	lpieralisi, kwilczynski, mani, bhelgaas, hongxing.zhu, l.stach
  Cc: imx, linux-pci, linux-arm-kernel, devicetree, linux-kernel,
	sherry.sun
In-Reply-To: <20260630060710.3294811-1-sherry.sun@oss.nxp.com>

From: Sherry Sun <sherry.sun@nxp.com>

Move the power supply property from the PCIe controller node to the Root
Port child node to support the new PCI pwrctrl framework.

Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
---
 arch/arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi
index fe9046c03ddd..c52b8897f999 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi
@@ -756,12 +756,12 @@ &pcie {
 	pinctrl-0 = <&pinctrl_pcie>;
 	/* This property is deprecated, use reset-gpios from the Root Port node. */
 	reset-gpio = <&gpio7 12 GPIO_ACTIVE_LOW>;
-	vpcie-supply = <&reg_pcie>;
 	status = "okay";
 };
 
 &pcie_port0 {
 	reset-gpios = <&gpio7 12 GPIO_ACTIVE_LOW>;
+	vpcie3v3-supply = <&reg_pcie>;
 };
 
 &pwm1 {
-- 
2.50.1



^ permalink raw reply related

* [PATCH V4 0/7] PCI: imx6: Integrate pwrctrl API and update device trees
From: Sherry Sun (OSS) @ 2026-06-30  6:07 UTC (permalink / raw)
  To: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, kernel, festevam,
	lpieralisi, kwilczynski, mani, bhelgaas, hongxing.zhu, l.stach
  Cc: imx, linux-pci, linux-arm-kernel, devicetree, linux-kernel,
	sherry.sun

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

The driver maintains legacy regulator handling for device trees that
haven't been updated yet. Both old and new device tree structures are
supported.

Signed-off-by: Sherry Sun <sherry.sun@nxp.com>

---
Changes in V4:
1. Fix the CHECK_DTBS warnings. 
2. Drop pci-imx6 pwrctrl support patch as it got applied.

Changes in V3:
1. Rebased on top of latest 7.1.0-rc4

Changes in V2:
1. After commit 2d8c5098b847 ("PCI/pwrctrl: Do not power off on pwrctrl
   device removal"), the pwrctrl drivers no longer power off devices
   during removal. Update pci-imx6 driver's shutdown callback in patch#1
   to explicitly call pci_pwrctrl_power_off_devices() before 
   pci_pwrctrl_destroy_devices() to ensure devices are properly powered
   off.
---

Sherry Sun (7):
  arm: dts: imx6qdl-sabresd: Move power supply property to Root Port
    node
  arm: dts: imx6sx-sdb: Move power supply property to Root Port node
  arm64: dts: imx8mm-evk: Move power supply property to Root Port node
  arm64: dts: imx8mp-evk: Move power supply properties to Root Port node
  arm64: dts: imx8mq-evk: Move power supply properties to Root Port node
  arm64: dts: imx8dxl/qm/qxp: Move power supply properties to Root Port
    node
  arm64: dts: imx95: Move power supply properties to Root Port node

 arch/arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi    | 2 +-
 arch/arm/boot/dts/nxp/imx/imx6sx-sdb.dtsi         | 2 +-
 arch/arm64/boot/dts/freescale/imx8dxl-evk.dts     | 4 ++--
 arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi     | 2 +-
 arch/arm64/boot/dts/freescale/imx8mp-evk.dts      | 4 ++--
 arch/arm64/boot/dts/freescale/imx8mq-evk.dts      | 4 ++--
 arch/arm64/boot/dts/freescale/imx8qm-mek.dts      | 4 ++--
 arch/arm64/boot/dts/freescale/imx8qxp-mek.dts     | 4 ++--
 arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts | 4 ++--
 arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts | 8 ++++----
 10 files changed, 19 insertions(+), 19 deletions(-)


base-commit: 7de6ae9e12207ec146f2f3f1e58d1a99317e88bc
-- 
2.50.1



^ permalink raw reply

* Re: [PATCH rc v6 3/7] iommu/arm-smmu-v3: Do not enable EVTQ/PRIQ interrupts in kdump kernel
From: Nicolin Chen @ 2026-06-30  5:36 UTC (permalink / raw)
  To: Pranjal Shrivastava
  Cc: will, robin.murphy, jgg, joro, kees, baolu.lu, kevin.tian,
	miko.lenczewski, smostafa, linux-arm-kernel, iommu, linux-kernel,
	stable, jamien
In-Reply-To: <akNM5peYovV3GdV4@google.com>

On Tue, Jun 30, 2026 at 04:58:14AM +0000, Pranjal Shrivastava wrote:
> is_kdump_kernel() ? 0 : IRQF_ONESHOT, note that devm_request_irq is just:
> 
> static inline int __must_check
> devm_request_irq(struct device *dev, unsigned int irq, irq_handler_t handler,
> 		 unsigned long irqflags, const char *devname, void *dev_id)
> {
> 	return devm_request_threaded_irq(dev, irq, handler, NULL, irqflags | IRQF_COND_ONESHOT,
> 					 devname, dev_id);
> }
> 
> Not a strong opinion though, just suggesting a way to remove the if.

I've thought about that but kept the if-else on purpose:
 - Using two ternaries doesn't seem a common practice to me.
 - request_threaded_irq doesn't read as clean as request_irq
   for GERROR to use -- one could wonder why "threaded".

Thanks
Nicolin


^ permalink raw reply

* RE: [5/7] soc: aspeed: Add eSPI flash channel support
From: YH Chung @ 2026-06-30  5:02 UTC (permalink / raw)
  To: Markus Elfring, linux-aspeed@lists.ozlabs.org,
	openbmc@lists.ozlabs.org, linux-arm-kernel@lists.infradead.org,
	devicetree@vger.kernel.org, Andrew Jeffery, Conor Dooley,
	Joel Stanley, Krzysztof Kozlowski, Philipp Zabel, Rob Herring,
	Ryan Chen
  Cc: LKML, Maciej Lawniczak
In-Reply-To: <1df6b921-368e-461a-af01-d453a3898cf7@web.de>

Hi Markus,

> >>> +++ b/drivers/soc/aspeed/espi/aspeed-espi.c
> >> …
> >>> +static void aspeed_espi_flash_rx_work(struct work_struct *work) {
> …
> > Thanks for the suggestion. I agree that guard(mutex) is helpful when a
> > locked section has multiple exit paths. Since this worker currently
> > has a single simple path, I would prefer to keep the explicit
> > mutex_lock()/mutex_unlock() pair for readability. I can switch to
> > guard(mutex) if you think it would be better in this case.
> I hope that development interests can increase more also for the application of
> scope-based resource management.
> 
Thanks for the clarification. I will switch this worker to use guard(mutex)
so that the code follows the scope-based resource management style.

Best regards,
Yun Hsuan

^ permalink raw reply

* Re: [PATCH rc v6 4/7] iommu/arm-smmu-v3: Skip EVTQ/PRIQ setup in kdump kernel
From: Pranjal Shrivastava @ 2026-06-30  5:01 UTC (permalink / raw)
  To: Nicolin Chen
  Cc: will, robin.murphy, jgg, joro, kees, baolu.lu, kevin.tian,
	miko.lenczewski, smostafa, linux-arm-kernel, iommu, linux-kernel,
	stable, jamien
In-Reply-To: <akNDZM7n/EpBmajY@nvidia.com>

On Mon, Jun 29, 2026 at 09:17:40PM -0700, Nicolin Chen wrote:
> On Mon, Jun 29, 2026 at 03:15:21PM +0000, Pranjal Shrivastava wrote:
> > On Wed, May 20, 2026 at 10:03:21AM -0700, Nicolin Chen wrote:
> > > +	if (!is_kdump_kernel()) {
> > > +		writeq_relaxed(smmu->evtq.q.q_base,
> > > +			       smmu->base + ARM_SMMU_EVTQ_BASE);
> > > +		writel_relaxed(smmu->evtq.q.llq.prod,
> > > +			       smmu->page1 + ARM_SMMU_EVTQ_PROD);
> > > +		writel_relaxed(smmu->evtq.q.llq.cons,
> > > +			       smmu->page1 + ARM_SMMU_EVTQ_CONS);
> > > +
> > > +		enables |= CR0_EVTQEN;
> > > +		ret = arm_smmu_write_reg_sync(smmu, enables, ARM_SMMU_CR0,
> > > +					      ARM_SMMU_CR0ACK);
> > 
> > Nit:
> > I believe only the write_reg_sync(CR0) should be under this if condition
> > do we see any weird behavior if we perform the reg writes in
> > kdump_kernel?
> 
> Since CR0_EVTQEN isn't set, the other three writes are dead code.
> 
> So, I skipped them.

Ack,

Praan


^ permalink raw reply

* Re: [PATCH rc v6 3/7] iommu/arm-smmu-v3: Do not enable EVTQ/PRIQ interrupts in kdump kernel
From: Pranjal Shrivastava @ 2026-06-30  5:00 UTC (permalink / raw)
  To: Nicolin Chen
  Cc: will, robin.murphy, jgg, joro, kees, baolu.lu, kevin.tian,
	miko.lenczewski, smostafa, linux-arm-kernel, iommu, linux-kernel,
	stable, jamien
In-Reply-To: <akNM5peYovV3GdV4@google.com>

On Tue, Jun 30, 2026 at 04:58:14AM +0000, Pranjal Shrivastava wrote:
> On Mon, Jun 29, 2026 at 09:14:48PM -0700, Nicolin Chen wrote:
> > On Mon, Jun 29, 2026 at 08:48:11AM +0000, Pranjal Shrivastava wrote:
> > > On Wed, May 20, 2026 at 10:03:20AM -0700, Nicolin Chen wrote:
> > > > @@ -5020,19 +5029,30 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu)
> > > >  		/*
> > > >  		 * Cavium ThunderX2 implementation doesn't support unique irq
> > > >  		 * lines. Use a single irq line for all the SMMUv3 interrupts.
> > > > +		 *
> > > > +		 * In kdump, EVTQ/PRIQ are disabled, so no threaded handling.
> > > >  		 */
> > > > -		ret = devm_request_threaded_irq(smmu->dev, irq,
> > > > -					arm_smmu_combined_irq_handler,
> > > > -					arm_smmu_combined_irq_thread,
> > > > -					IRQF_ONESHOT,
> > > > -					"arm-smmu-v3-combined-irq", smmu);
> > > > +		if (is_kdump_kernel())
> > > > +			ret = devm_request_irq(smmu->dev, irq,
> > > > +					       arm_smmu_combined_irq_handler, 0,
> > > > +					       "arm-smmu-v3-combined-irq",
> > > > +					       smmu);
> > > 
> > 
> > Are you sure?
> > 
> > __setup_irq():
> > 1497-   /*
> > 1498:    * IRQF_ONESHOT means the interrupt source in the IRQ chip will be
> > 1499-    * masked until the threaded handled is done. If there is no thread
> > 1500:    * handler then it makes no sense to have IRQF_ONESHOT.
> > 1501-    */
> > 1502:   WARN_ON_ONCE(new->flags & IRQF_ONESHOT && !new->thread_fn);
> 
> I meant without IRQF_ONESHOT: 
> 
> is_kdump_kernel() ? 0 : IRQF_ONESHOT, note that devm_request_irq is just:
> 
> static inline int __must_check
> devm_request_irq(struct device *dev, unsigned int irq, irq_handler_t handler,
> 		 unsigned long irqflags, const char *devname, void *dev_id)
> {
> 	return devm_request_threaded_irq(dev, irq, handler, NULL, irqflags | IRQF_COND_ONESHOT,
> 					 devname, dev_id);
> }
> 
> Not a strong opinion though, just suggesting a way to remove the if.
> 

I though I had given an R-b earlier, but I didn't.
With that nit:
Reviewed-by: Pranjal Shrivastava <praan@google.com>

Thanks,
Praan


^ permalink raw reply

* [PATCH v5 8/8] futex: Use runtime constants for __futex_hash() hot path
From: K Prateek Nayak @ 2026-06-30  4:55 UTC (permalink / raw)
  To: Arnd Bergmann, Thomas Gleixner, Ingo Molnar, Peter Zijlstra,
	Sebastian Andrzej Siewior, Borislav Petkov, Dave Hansen, x86,
	Catalin Marinas, Will Deacon, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Heiko Carstens, Vasily Gorbik, Alexander Gordeev
  Cc: Darren Hart, Davidlohr Bueso, André Almeida, linux-arch,
	linux-kernel, Samuel Holland, Charlie Jenkins, K Prateek Nayak,
	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-1-kprateek.nayak@amd.com>

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>
---
changelog v4..v5:

o Rebased on latest tip:master.
---
 include/asm-generic/vmlinux.lds.h |  5 +++-
 kernel/futex/core.c               | 42 +++++++++++++++++--------------
 2 files changed, 27 insertions(+), 20 deletions(-)

diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 5659f4b5a1252..53207901d4c15 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -970,7 +970,10 @@
 		RUNTIME_CONST(ptr, __dentry_cache)			\
 		RUNTIME_CONST(ptr, __names_cache)			\
 		RUNTIME_CONST(ptr, __filp_cache)			\
-		RUNTIME_CONST(ptr, __bfilp_cache)
+		RUNTIME_CONST(ptr, __bfilp_cache)			\
+		RUNTIME_CONST(shift, __futex_shift)			\
+		RUNTIME_CONST(mask,  __futex_mask)			\
+		RUNTIME_CONST(ptr,   __futex_queues)
 
 /* Alignment must be consistent with (kunit_suite *) in include/kunit/test.h */
 #define KUNIT_TABLE()							\
diff --git a/kernel/futex/core.c b/kernel/futex/core.c
index 179b26e9c9341..b2a63ceb6ce98 100644
--- a/kernel/futex/core.c
+++ b/kernel/futex/core.c
@@ -48,23 +48,19 @@
 
 #include <vdso/futex.h>
 
+#include <asm/runtime-const.h>
+
 #include "futex.h"
 #include "../locking/rtmutex_common.h"
 
-/*
- * The base of the bucket array and its size are always used together
- * (after initialization only in futex_hash()), so ensure that they
- * reside in the same cacheline.
- */
-static struct {
-	unsigned long            hashmask;
-	unsigned int		 hashshift;
-	struct futex_hash_bucket *queues[MAX_NUMNODES];
-} __futex_data __read_mostly __aligned(2*sizeof(long));
+static u32 __futex_mask __ro_after_init;
+static u32 __futex_shift __ro_after_init;
+static struct futex_hash_bucket **__futex_queues __ro_after_init;
 
-#define futex_hashmask	(__futex_data.hashmask)
-#define futex_hashshift	(__futex_data.hashshift)
-#define futex_queues	(__futex_data.queues)
+static __always_inline struct futex_hash_bucket **futex_queues(void)
+{
+	return runtime_const_ptr(__futex_queues);
+}
 
 struct futex_private_hash {
 	int		state;
@@ -395,13 +391,13 @@ __futex_hash(union futex_key *key, struct futex_private_hash *fph, struct futex_
 		 * NOTE: this isn't perfectly uniform, but it is fast and
 		 * handles sparse node masks.
 		 */
-		node = (hash >> futex_hashshift) % nr_node_ids;
+		node = runtime_const_shift_right_32(hash, __futex_shift) % nr_node_ids;
 		if (!node_possible(node)) {
 			node = find_next_bit_wrap(node_possible_map.bits, nr_node_ids, node);
 		}
 	}
 
-	return &futex_queues[node][hash & futex_hashmask];
+	return &futex_queues()[node][runtime_const_mask_32(hash, __futex_mask)];
 }
 
 /**
@@ -1922,7 +1918,7 @@ int futex_hash_allocate_default(void)
 	 *   16 <= threads * 4 <= global hash size
 	 */
 	buckets = roundup_pow_of_two(4 * threads);
-	buckets = clamp(buckets, 16, futex_hashmask + 1);
+	buckets = clamp(buckets, 16, __futex_mask + 1);
 
 	if (current_buckets >= buckets)
 		return 0;
@@ -2020,10 +2016,19 @@ static int __init futex_init(void)
 	hashsize = max(4, hashsize);
 	hashsize = roundup_pow_of_two(hashsize);
 #endif
-	futex_hashshift = ilog2(hashsize);
+	__futex_mask = hashsize - 1;
+	__futex_shift = ilog2(hashsize);
 	size = sizeof(struct futex_hash_bucket) * hashsize;
 	order = get_order(size);
 
+	__futex_queues = kcalloc(nr_node_ids, sizeof(*__futex_queues), GFP_KERNEL);
+
+	runtime_const_init(shift, __futex_shift);
+	runtime_const_init(mask,  __futex_mask);
+	runtime_const_init(ptr,   __futex_queues);
+
+	BUG_ON(!futex_queues());
+
 	for_each_node(n) {
 		struct futex_hash_bucket *table;
 
@@ -2037,10 +2042,9 @@ static int __init futex_init(void)
 		for (i = 0; i < hashsize; i++)
 			futex_hash_bucket_init(&table[i]);
 
-		futex_queues[n] = table;
+		futex_queues()[n] = table;
 	}
 
-	futex_hashmask = hashsize - 1;
 	pr_info("futex hash table entries: %lu (%lu bytes on %d NUMA nodes, total %lu KiB, %s).\n",
 		hashsize, size, num_possible_nodes(), size * num_possible_nodes() / 1024,
 		order > MAX_PAGE_ORDER ? "vmalloc" : "linear");
-- 
2.34.1



^ permalink raw reply related

* Re: [PATCH rc v6 3/7] iommu/arm-smmu-v3: Do not enable EVTQ/PRIQ interrupts in kdump kernel
From: Pranjal Shrivastava @ 2026-06-30  4:58 UTC (permalink / raw)
  To: Nicolin Chen
  Cc: will, robin.murphy, jgg, joro, kees, baolu.lu, kevin.tian,
	miko.lenczewski, smostafa, linux-arm-kernel, iommu, linux-kernel,
	stable, jamien
In-Reply-To: <akNCuEfZ30Gf21iQ@nvidia.com>

On Mon, Jun 29, 2026 at 09:14:48PM -0700, Nicolin Chen wrote:
> On Mon, Jun 29, 2026 at 08:48:11AM +0000, Pranjal Shrivastava wrote:
> > On Wed, May 20, 2026 at 10:03:20AM -0700, Nicolin Chen wrote:
> > > @@ -5020,19 +5029,30 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu)
> > >  		/*
> > >  		 * Cavium ThunderX2 implementation doesn't support unique irq
> > >  		 * lines. Use a single irq line for all the SMMUv3 interrupts.
> > > +		 *
> > > +		 * In kdump, EVTQ/PRIQ are disabled, so no threaded handling.
> > >  		 */
> > > -		ret = devm_request_threaded_irq(smmu->dev, irq,
> > > -					arm_smmu_combined_irq_handler,
> > > -					arm_smmu_combined_irq_thread,
> > > -					IRQF_ONESHOT,
> > > -					"arm-smmu-v3-combined-irq", smmu);
> > > +		if (is_kdump_kernel())
> > > +			ret = devm_request_irq(smmu->dev, irq,
> > > +					       arm_smmu_combined_irq_handler, 0,
> > > +					       "arm-smmu-v3-combined-irq",
> > > +					       smmu);
> > 
> > This `if` isn't needed, we can continue using devm_request_threaded_irq,
> > if you look at the doc for devm_request_threaded_irq [1] it says:
> [...]
> > So, we can pass handler() here while leaving the thread_fn == NULL:
> > 
> > ret = devm_request_threaded_irq(smmu->dev, irq,
> >          arm_smmu_combined_irq_handler,
> >          is_kdump_kernel() ? NULL : arm_smmu_combined_irq_thread,
> >          IRQF_ONESHOT,
> >          "arm-smmu-v3-combined-irq", smmu);
> 
> Are you sure?
> 
> __setup_irq():
> 1497-   /*
> 1498:    * IRQF_ONESHOT means the interrupt source in the IRQ chip will be
> 1499-    * masked until the threaded handled is done. If there is no thread
> 1500:    * handler then it makes no sense to have IRQF_ONESHOT.
> 1501-    */
> 1502:   WARN_ON_ONCE(new->flags & IRQF_ONESHOT && !new->thread_fn);

I meant without IRQF_ONESHOT: 

is_kdump_kernel() ? 0 : IRQF_ONESHOT, note that devm_request_irq is just:

static inline int __must_check
devm_request_irq(struct device *dev, unsigned int irq, irq_handler_t handler,
		 unsigned long irqflags, const char *devname, void *dev_id)
{
	return devm_request_threaded_irq(dev, irq, handler, NULL, irqflags | IRQF_COND_ONESHOT,
					 devname, dev_id);
}

Not a strong opinion though, just suggesting a way to remove the if.

> 
> > Additionally, the arm_smmu_combined_irq_handler() returns 
> > IRQ_WAKE_THREAD unconditionally, which causes us to hit the warn_on[3] in
> > __handle_irq_event_percpu.
> 
> arm_smmu_combined_irq_handler() does not return IRQ_WAKE_THREAD
> unconditionally.
> 
> This is the first part of PATCH-3 in v6:

Ahh I missed that, somehow.

Thanks,
Praan


^ permalink raw reply

* [PATCH v5 7/8] asm-generic/runtime-const: Add dummy runtime_const_mask_32()
From: K Prateek Nayak @ 2026-06-30  4:55 UTC (permalink / raw)
  To: Arnd Bergmann, Thomas Gleixner, Ingo Molnar, Peter Zijlstra,
	Sebastian Andrzej Siewior
  Cc: Darren Hart, Davidlohr Bueso, André Almeida, linux-arch,
	linux-kernel, Samuel Holland, Charlie Jenkins, K Prateek Nayak,
	linux-arm-kernel, linux-riscv, linux-s390
In-Reply-To: <20260630045531.3939-1-kprateek.nayak@amd.com>

From: Peter Zijlstra <peterz@infradead.org>

Add a dummy runtime_const_mask_32() for all the architectures that do
not support runtime-const.

Link: https://patch.msgid.link/20260227161841.GH606826@noisy.programming.kicks-ass.net
Not-yet-signed-off-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
---
changelog v4..v5:

o No changes.
---
 include/asm-generic/runtime-const.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/asm-generic/runtime-const.h b/include/asm-generic/runtime-const.h
index 6704994595145..03e6e3e02401e 100644
--- a/include/asm-generic/runtime-const.h
+++ b/include/asm-generic/runtime-const.h
@@ -10,6 +10,7 @@
  */
 #define runtime_const_ptr(sym) (sym)
 #define runtime_const_shift_right_32(val, sym) ((u32)(val)>>(sym))
+#define runtime_const_mask_32(val, sym) ((u32)(val)&(sym))
 #define runtime_const_init(type,sym) do { } while (0)
 
 #endif
-- 
2.34.1



^ permalink raw reply related

* [PATCH v5 6/8] s390/runtime-const: Introduce runtime_const_mask_32()
From: K Prateek Nayak @ 2026-06-30  4:55 UTC (permalink / raw)
  To: Arnd Bergmann, Thomas Gleixner, Ingo Molnar, Peter Zijlstra,
	Sebastian Andrzej Siewior, Heiko Carstens, Vasily Gorbik,
	Alexander Gordeev
  Cc: Darren Hart, Davidlohr Bueso, André Almeida, linux-arch,
	linux-kernel, Samuel Holland, Charlie Jenkins, K Prateek Nayak,
	linux-arm-kernel, linux-riscv, linux-s390, Christian Borntraeger,
	Sven Schnelle
In-Reply-To: <20260630045531.3939-1-kprateek.nayak@amd.com>

Futex hash computation requires a mask operation with read-only after
init data that will be converted to a runtime constant in the subsequent
commit.

Introduce runtime_const_mask_32 to further optimize the mask operation
in the futex hash computation hot path.

GCC generates a:

  nilf %r1,<imm32>

to tackle arbitrary 32-bit masks and the same is implemented here.
Immediate patching pattern for __runtime_fixup_mask() has been adopted
from __runtime_fixup_ptr().

Acked-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
---
changelog v4..v5:

o No changes.
---
 arch/s390/include/asm/runtime-const.h | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/arch/s390/include/asm/runtime-const.h b/arch/s390/include/asm/runtime-const.h
index 17878b1d048cf..7b71156031ecb 100644
--- a/arch/s390/include/asm/runtime-const.h
+++ b/arch/s390/include/asm/runtime-const.h
@@ -33,6 +33,20 @@
 	__ret;							\
 })
 
+#define runtime_const_mask_32(val, sym)				\
+({								\
+	unsigned int __ret = (val);				\
+								\
+	asm_inline(						\
+		"0:	nilf	%[__ret],12\n"			\
+		".pushsection runtime_mask_" #sym ",\"a\"\n"	\
+		".long 0b - .\n"				\
+		".popsection"					\
+		: [__ret] "+d" (__ret)				\
+		: : "cc");					\
+	__ret;							\
+})
+
 #define runtime_const_init(type, sym) do {			\
 	extern s32 __start_runtime_##type##_##sym[];		\
 	extern s32 __stop_runtime_##type##_##sym[];		\
@@ -43,12 +57,12 @@
 			    __stop_runtime_##type##_##sym);	\
 } while (0)
 
-/* 32-bit immediate for iihf and iilf in bits in I2 field */
 static inline void __runtime_fixup_32(u32 *p, unsigned int val)
 {
 	s390_kernel_write(p, &val, sizeof(val));
 }
 
+/* 32-bit immediate for iihf and iilf in bits in I2 field */
 static inline void __runtime_fixup_ptr(void *where, unsigned long val)
 {
 	__runtime_fixup_32(where + 2, val >> 32);
@@ -65,6 +79,12 @@ static inline void __runtime_fixup_shift(void *where, unsigned long val)
 	s390_kernel_write(where, &insn, sizeof(insn));
 }
 
+/* 32-bit immediate for nilf in bits in I2 field */
+static inline void __runtime_fixup_mask(void *where, unsigned long val)
+{
+	__runtime_fixup_32(where + 2, val);
+}
+
 static inline void runtime_const_fixup(void (*fn)(void *, unsigned long),
 				       unsigned long val, s32 *start, s32 *end)
 {
-- 
2.34.1



^ permalink raw reply related

* [PATCH v5 5/8] riscv/runtime-const: Introduce runtime_const_mask_32()
From: K Prateek Nayak @ 2026-06-30  4:55 UTC (permalink / raw)
  To: Arnd Bergmann, Thomas Gleixner, Ingo Molnar, Peter Zijlstra,
	Sebastian Andrzej Siewior, Paul Walmsley, Palmer Dabbelt,
	Albert Ou
  Cc: Darren Hart, Davidlohr Bueso, André Almeida, linux-arch,
	linux-kernel, Samuel Holland, Charlie Jenkins, K Prateek Nayak,
	linux-arm-kernel, linux-riscv, linux-s390, Alexandre Ghiti,
	Jisheng Zhang
In-Reply-To: <20260630045531.3939-1-kprateek.nayak@amd.com>

Futex hash computation requires a mask operation with read-only after
init data that will be converted to a runtime constant in the subsequent
commit.

Introduce runtime_const_mask_32 to further optimize the mask operation
in the futex hash computation hot path. Since all the current use-cases
are of the form GENMASK(n, 0), with n > 0, following sequence:

  srli a0, a1, imm
  slli a0, a0, imm

is used for RISC-V where imm = (31 - width) to improve instruction
density and performance.

"The RISC-V Instruction Set Manual, Volume I - Unprivileged
Architecture" [1] Sec. 2.4.1 "Integer Register-Immediate Instructions"
notes the immediate shift for SRLI and SLLI are 5 bits wide starting at
bit #10. __runtime_fixup_shift() is reused to patch the immediate shifts
for the two instructions.

If a future use case arises that needs to tackle arbitrary mask,
consider using:

  lui   a0, 0x12346       # upper; +0x800 then >>12 for correct rounding
  addi  a0, a0, 0x678     # lower 12 bits

to patch the 32-bit mask in the asm block and return "__ret & (val)"
from runtime_const_mask_32() which allows compiler to further optimize
the logical and operation. __runtime_fixup_ptr() already patches a
lui + addi sequence which can be reused when the need arises.

A possible implementation for this alternate scheme can be found at [2].

Assisted-by: Claude:claude-sonnet-4-5
Suggested-by: Samuel Holland <samuel.holland@sifive.com>
Suggested-by: Charlie Jenkins <thecharlesjenkins@gmail.com>
Link: https://docs.riscv.org/reference/isa/_attachments/riscv-unprivileged.pdf [1]
Link: https://lore.kernel.org/lkml/20260430094730.31624-6-kprateek.nayak@amd.com/ [2]
Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
---
changelog v4..v5:

o Pivoted to SRLI + SLLI sequence for mask operation to extract the
  lower bits for improved instruction desnity (Charlie, Samuel on v2).
---
 arch/riscv/include/asm/asm.h           |  1 +
 arch/riscv/include/asm/runtime-const.h | 44 ++++++++++++++++++++++++++
 2 files changed, 45 insertions(+)

diff --git a/arch/riscv/include/asm/asm.h b/arch/riscv/include/asm/asm.h
index e9e8ba83e632f..b8bf842d4c136 100644
--- a/arch/riscv/include/asm/asm.h
+++ b/arch/riscv/include/asm/asm.h
@@ -34,6 +34,7 @@
 #define SZREG		__REG_SEL(8, 4)
 #define LGREG		__REG_SEL(3, 2)
 #define SRLI		__REG_SEL(srliw, srli)
+#define SLLI		__REG_SEL(slliw, slli)
 
 #if __SIZEOF_POINTER__ == 8
 #ifdef __ASSEMBLER__
diff --git a/arch/riscv/include/asm/runtime-const.h b/arch/riscv/include/asm/runtime-const.h
index 1ce02605d2e43..dbf96c937dbb9 100644
--- a/arch/riscv/include/asm/runtime-const.h
+++ b/arch/riscv/include/asm/runtime-const.h
@@ -159,6 +159,23 @@
 	__ret;							\
 })
 
+#define runtime_const_mask_32(val, sym)				\
+({								\
+	u32 __ret;						\
+	asm_inline(".option push\n\t"				\
+		".option norvc\n\t"				\
+		"1:\t"						\
+		SLLI " %[__ret],%[__val],12\n\t"		\
+		SRLI " %[__ret],%[__ret],12\n\t"		\
+		".option pop\n\t"				\
+		".pushsection runtime_mask_" #sym ",\"a\"\n\t"	\
+		".long 1b - .\n\t"				\
+		".popsection"					\
+		: [__ret] "=r" (__ret)				\
+		: [__val] "r" (val));				\
+	__ret;							\
+})
+
 #define runtime_const_init(type, sym) do {			\
 	extern s32 __start_runtime_##type##_##sym[];		\
 	extern s32 __stop_runtime_##type##_##sym[];		\
@@ -262,6 +279,33 @@ static inline void __runtime_fixup_shift(void *where, unsigned long val)
 	mutex_unlock(&text_mutex);
 }
 
+static inline void __runtime_fixup_mask(void *where, unsigned long val)
+{
+	unsigned int width = __fls(val) + 1;
+
+	/*
+	 * XXX: Current implementation only supports patching masks of
+	 * form GENMASK(width, 0) (width >= 0) using a SRLI + SLLI
+	 * sequence instead of LUI + ADDI + AND sequence to improve
+	 * performance, density, and covers all the current use-cases.
+	 *
+	 * When the need arises to support any generic mask, and this
+	 * BUG_ON() is tripped, consider using a:
+	 *
+	 *   lui  %[__ret], #imm16
+	 *   addi %[__ret], #imm16
+	 *
+	 * sequence to load the 32bit const mask, and perform a logical
+	 * and outside the asm block before returning the result. Fixup
+	 * can simply reuse the existing __runtime_fixup_32() to patch
+	 * the LUI + ADDI sequence.
+	 */
+	BUG_ON(!val || width > 31 || (GENMASK(width - 1, 0) != val));
+
+	__runtime_fixup_shift(where, 32 - width);
+	__runtime_fixup_shift(where + 4, 32 - width);
+}
+
 static inline void runtime_const_fixup(void (*fn)(void *, unsigned long),
 				       unsigned long val, s32 *start, s32 *end)
 {
-- 
2.34.1



^ permalink raw reply related

* [PATCH v5 4/8] riscv/runtime-const: Replace open-coded placeholder with RUNTIME_MAGIC
From: K Prateek Nayak @ 2026-06-30  4:55 UTC (permalink / raw)
  To: Arnd Bergmann, Thomas Gleixner, Ingo Molnar, Peter Zijlstra,
	Sebastian Andrzej Siewior, Paul Walmsley, Palmer Dabbelt,
	Albert Ou
  Cc: Darren Hart, Davidlohr Bueso, André Almeida, linux-arch,
	linux-kernel, Samuel Holland, Charlie Jenkins, K Prateek Nayak,
	linux-arm-kernel, linux-riscv, linux-s390, Alexandre Ghiti,
	Jisheng Zhang, Guo Ren
In-Reply-To: <20260630045531.3939-1-kprateek.nayak@amd.com>

Define the placeholder used for lui + addi[w] patching sequence as
RUNTIME_MAGIC and use that instead of open coding the constants in the
inline assembly.

No functional changes intended.

Suggested-by: Guo Ren <guoren@kernel.org>
Reviewed-by: Charlie Jenkins <thecharlesjenkins@gmail.com>
Tested-by: Charlie Jenkins <thecharlesjenkins@gmail.com>
Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
---
changelog v4..v5:

o Collected tags from Charlie (Thanks a ton!)
---
 arch/riscv/include/asm/runtime-const.h | 38 ++++++++++++++------------
 1 file changed, 20 insertions(+), 18 deletions(-)

diff --git a/arch/riscv/include/asm/runtime-const.h b/arch/riscv/include/asm/runtime-const.h
index 900db0a103d05..1ce02605d2e43 100644
--- a/arch/riscv/include/asm/runtime-const.h
+++ b/arch/riscv/include/asm/runtime-const.h
@@ -15,21 +15,23 @@
 
 #include <linux/uaccess.h>
 
+#define RUNTIME_MAGIC __ASM_STR(0x89ABCDEF)
+
 #ifdef CONFIG_32BIT
-#define runtime_const_ptr(sym)					\
-({								\
-	typeof(sym) __ret;					\
-	asm_inline(".option push\n\t"				\
-		".option norvc\n\t"				\
-		"1:\t"						\
-		"lui	%[__ret],0x89abd\n\t"			\
-		"addi	%[__ret],%[__ret],-0x211\n\t"		\
-		".option pop\n\t"				\
-		".pushsection runtime_ptr_" #sym ",\"a\"\n\t"	\
-		".long 1b - .\n\t"				\
-		".popsection"					\
-		: [__ret] "=r" (__ret));			\
-	__ret;							\
+#define runtime_const_ptr(sym)						\
+({									\
+	typeof(sym) __ret;						\
+	asm_inline(".option push\n\t"					\
+		".option norvc\n\t"					\
+		"1:\t"							\
+		"lui	%[__ret], %%hi(" RUNTIME_MAGIC ")\n\t"		\
+		"addi	%[__ret],%[__ret], %%lo(" RUNTIME_MAGIC ")\n\t"	\
+		".option pop\n\t"					\
+		".pushsection runtime_ptr_" #sym ",\"a\"\n\t"		\
+		".long 1b - .\n\t"					\
+		".popsection"						\
+		: [__ret] "=r" (__ret));				\
+	__ret;								\
 })
 #else
 /*
@@ -46,10 +48,10 @@
 	".option push\n\t"					\
 	".option norvc\n\t"					\
 	"1:\t"							\
-	"lui	%[__ret],0x89abd\n\t"				\
-	"lui	%[__tmp],0x1234\n\t"				\
-	"addiw	%[__ret],%[__ret],-0x211\n\t"			\
-	"addiw	%[__tmp],%[__tmp],0x567\n\t"			\
+	"lui	%[__ret], %%hi(" RUNTIME_MAGIC ")\n\t"		\
+	"lui	%[__tmp], %%hi(" RUNTIME_MAGIC ")\n\t"		\
+	"addiw	%[__ret],%[__ret], %%lo(" RUNTIME_MAGIC ")\n\t"	\
+	"addiw	%[__tmp],%[__tmp], %%lo(" RUNTIME_MAGIC ")\n\t"	\
 
 #define RISCV_RUNTIME_CONST_64_BASE				\
 	"slli	%[__tmp],%[__tmp],32\n\t"			\
-- 
2.34.1



^ permalink raw reply related

* [PATCH v5 3/8] arm64/runtime-const: Introduce runtime_const_mask_32()
From: K Prateek Nayak @ 2026-06-30  4:55 UTC (permalink / raw)
  To: Arnd Bergmann, Thomas Gleixner, Ingo Molnar, Peter Zijlstra,
	Sebastian Andrzej Siewior, Catalin Marinas, Will Deacon
  Cc: Darren Hart, Davidlohr Bueso, André Almeida, linux-arch,
	linux-kernel, Samuel Holland, Charlie Jenkins, K Prateek Nayak,
	linux-arm-kernel, linux-riscv, linux-s390, Jisheng Zhang
In-Reply-To: <20260630045531.3939-1-kprateek.nayak@amd.com>

Futex hash computation requires a mask operation with read-only after
init data that will be converted to a runtime constant in the subsequent
commit.

Introduce runtime_const_mask_32 to further optimize the mask operation
in the futex hash computation hot path. Since all the current use-cases
are of the form GENMASK(n, 0), with n > 0, a single:

  ubfx  w0, w0, #0, #widthm1     // w0 = w0 [widthm1:0]

instruction is used for amd64 to improve instruction dinsity and
performance.

"Arm A-profile A64 Instruction Set Architecture" manual, Sec.
"A64 -- Base Instructions" [1] for UBFX instruction highlights the
immediate "width" is encoded as width minus 1 in imms (Bits [15:10])
which is patched by __runtime_fixup_mask() once the mask is known.

If a future use case arises that needs to tackle arbitrary mask,
consider using:

  movz  w1, #lo16, lsl #0
  movk  w1, #hi16, lsl #16

to patch the 32-bit mask in the asm block and return "__ret & (val)"
from runtime_const_mask_32() which allows compiler to further optimize
the logical and operation. __runtime_fixup_ptr() already patches a
"movz, + movk lsl #16" sequence which can be reused when the need
arises.

A possible implementation for this alternate scheme can be found at [2].

Assisted-by: Claude:claude-sonnet-4-6
Suggested-by: Samuel Holland <samuel.holland@sifive.com>
Suggested-by: Charlie Jenkins <thecharlesjenkins@gmail.com>
Link: https://developer.arm.com/documentation/ddi0602/2026-03/Base-Instructions/ [1]
Link: https://lore.kernel.org/lkml/20260430094730.31624-4-kprateek.nayak@amd.com/ [2]
Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
---
changelog v4..v5:

o Pivoted to using the UBFX instruction for masking since the futex
  use-case use masks of form 2^n - 1 (n > 1) since there was enough
  interest to improve instruction density for ARM64 and RISC-V.
  (Charlie, Samuel on v2)

o Dropped Catalin's tag as a result of changed approach.
---
 arch/arm64/include/asm/runtime-const.h | 46 ++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/arch/arm64/include/asm/runtime-const.h b/arch/arm64/include/asm/runtime-const.h
index 838145bc289d2..371c9a4bc2d4b 100644
--- a/arch/arm64/include/asm/runtime-const.h
+++ b/arch/arm64/include/asm/runtime-const.h
@@ -36,6 +36,17 @@
 		:"r" (0u+(val)));				\
 	__ret; })
 
+#define runtime_const_mask_32(val, sym) ({			\
+	unsigned long __ret;					\
+	asm_inline("1:\t"					\
+		"ubfx %w0, %w1, #0, #32\n\t"			\
+		".pushsection runtime_mask_" #sym ",\"a\"\n\t"	\
+		".long 1b - .\n\t"				\
+		".popsection"					\
+		:"=r" (__ret)					\
+		:"r" (0u+(val)));				\
+	__ret; })
+
 #define runtime_const_init(type, sym) do {		\
 	extern s32 __start_runtime_##type##_##sym[];	\
 	extern s32 __stop_runtime_##type##_##sym[];	\
@@ -73,6 +84,41 @@ static inline void __runtime_fixup_shift(void *where, unsigned long val)
 	aarch64_insn_patch_text_nosync(p, insn);
 }
 
+static inline void __runtime_fixup_mask(void *where, unsigned long val)
+{
+	unsigned int width = __fls(val) + 1;
+	__le32 *p = where;
+	u32 insn;
+
+	/*
+	 * XXX: Current implementation only supports patching masks of
+	 * form GENMASK(n, 0) (n >= 0) using a single UBFX instruction
+	 * to improve performance, density, and covers all the current
+	 * use-cases.
+	 *
+	 * When the need arises to support any generic mask, and this
+	 * BUG_ON() is tripped, consider using a:
+	 *
+	 *   movz %w0, #imm16
+	 *   movk %w0, #imm16, lsl #16
+	 *
+	 * sequence to load the 32bit const mask, and perform a logical
+	 * and outside the asm block before returning the result. Fixup
+	 * can simply reuse the existing __runtime_fixup_16() to patch
+	 * the individual mov instructions.
+	 */
+	BUG_ON(!val || width > 32 || (GENMASK(width - 1, 0) != val));
+
+	/*
+	 * The width of the mask is encoded as (width - 1) in imms
+	 * which is 6 bits starting at bit #10.
+	 */
+	insn = le32_to_cpu(*p);
+	insn &= 0xffff03ff;
+	insn |= ((width - 1) & 0x1f) << 10;
+	aarch64_insn_patch_text_nosync(p, insn);
+}
+
 static inline void runtime_const_fixup(void (*fn)(void *, unsigned long),
 	unsigned long val, s32 *start, s32 *end)
 {
-- 
2.34.1



^ permalink raw reply related

* [PATCH v5 2/8] arm64/runtime-const: Use aarch64_insn_patch_text_nosync() for patching
From: K Prateek Nayak @ 2026-06-30  4:55 UTC (permalink / raw)
  To: Arnd Bergmann, Thomas Gleixner, Ingo Molnar, Peter Zijlstra,
	Sebastian Andrzej Siewior, Catalin Marinas, Will Deacon
  Cc: Darren Hart, Davidlohr Bueso, André Almeida, linux-arch,
	linux-kernel, Samuel Holland, Charlie Jenkins, K Prateek Nayak,
	linux-arm-kernel, linux-riscv, linux-s390, Jisheng Zhang
In-Reply-To: <20260630045531.3939-1-kprateek.nayak@amd.com>

The current scheme to directly patch the kernel text for runtime
constants runs into the following issue with futex adapted to using
runtime constants on arm64:

  Unable to handle kernel write to read-only memory at virtual address ...

The pc points to the *p assignment in the following call chain:

  futex_init()
    runtime_const_init(shift, __futex_shift)
      __runtime_fixup_shift()
        *p = cpu_to_le32(insn);

which suggests that core_initcall() is too late to patch the kernel text
directly unlike the "d_hash_shift" which is initialized during
vfs_caches_init_early() before the protections are in place.

Use aarch64_insn_patch_text_nosync() to patch the runtime constants
instead of doing it directly to allow runtime_const_init() slightly
later into the boot.

Since aarch64_insn_patch_text_nosync() calls caches_clean_inval_pou()
internally, __runtime_fixup_caches() ends up being redundant.
runtime_const_init() are rare and the overheads of multiple calls to
caches_clean_inval_pou() instead of batching them together should be
negligible in practice.

The cpu_to_le32() conversion of instruction isn't necessary since it is
handled later in the aarch64_insn_patch_text_nosync() call-chain:

  aarch64_insn_patch_text_nosync(addr, insn)
    aarch64_insn_write(addr, insn)
      __aarch64_insn_write(addr, cpu_to_le32(insn))

Sashiko noted that aarch64_insn_patch_text_nosync() does not expect a
lm_alias() address and Catalin suggested it is safe to drop the
lm_alias() for runtime patching since the kernel text is readable. The
address passed to fixup function is interpreted as a __le32 and
dereferenced as is to read the opcode at the patch site.

No functional changes are intended.

Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
---
changelog v4..v5:

o Collected tag from Catalin (Thanks a ton!)
---
 arch/arm64/include/asm/runtime-const.h | 17 +++++------------
 1 file changed, 5 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/include/asm/runtime-const.h b/arch/arm64/include/asm/runtime-const.h
index c3dbd3ae68f69..838145bc289d2 100644
--- a/arch/arm64/include/asm/runtime-const.h
+++ b/arch/arm64/include/asm/runtime-const.h
@@ -7,6 +7,7 @@
 #endif
 
 #include <asm/cacheflush.h>
+#include <asm/text-patching.h>
 
 /* Sigh. You can still run arm64 in BE mode */
 #include <asm/byteorder.h>
@@ -50,34 +51,26 @@ static inline void __runtime_fixup_16(__le32 *p, unsigned int val)
 	u32 insn = le32_to_cpu(*p);
 	insn &= 0xffe0001f;
 	insn |= (val & 0xffff) << 5;
-	*p = cpu_to_le32(insn);
-}
-
-static inline void __runtime_fixup_caches(void *where, unsigned int insns)
-{
-	unsigned long va = (unsigned long)where;
-	caches_clean_inval_pou(va, va + 4*insns);
+	aarch64_insn_patch_text_nosync(p, insn);
 }
 
 static inline void __runtime_fixup_ptr(void *where, unsigned long val)
 {
-	__le32 *p = lm_alias(where);
+	__le32 *p = where;
 	__runtime_fixup_16(p, val);
 	__runtime_fixup_16(p+1, val >> 16);
 	__runtime_fixup_16(p+2, val >> 32);
 	__runtime_fixup_16(p+3, val >> 48);
-	__runtime_fixup_caches(where, 4);
 }
 
 /* Immediate value is 6 bits starting at bit #16 */
 static inline void __runtime_fixup_shift(void *where, unsigned long val)
 {
-	__le32 *p = lm_alias(where);
+	__le32 *p = where;
 	u32 insn = le32_to_cpu(*p);
 	insn &= 0xffc0ffff;
 	insn |= (val & 63) << 16;
-	*p = cpu_to_le32(insn);
-	__runtime_fixup_caches(where, 1);
+	aarch64_insn_patch_text_nosync(p, insn);
 }
 
 static inline void runtime_const_fixup(void (*fn)(void *, unsigned long),
-- 
2.34.1



^ permalink raw reply related

* [PATCH v5 1/8] x86/runtime-const: Introduce runtime_const_mask_32()
From: K Prateek Nayak @ 2026-06-30  4:55 UTC (permalink / raw)
  To: Arnd Bergmann, Thomas Gleixner, Ingo Molnar, Peter Zijlstra,
	Sebastian Andrzej Siewior, Borislav Petkov, Dave Hansen, x86
  Cc: Darren Hart, Davidlohr Bueso, André Almeida, linux-arch,
	linux-kernel, Samuel Holland, Charlie Jenkins, K Prateek Nayak,
	linux-arm-kernel, linux-riscv, linux-s390, H. Peter Anvin,
	Thomas Huth, Sean Christopherson
In-Reply-To: <20260630045531.3939-1-kprateek.nayak@amd.com>

From: Peter Zijlstra <peterz@infradead.org>

Futex hash computation requires a mask operation with read-only after
init data that will be converted to a runtime constant in the subsequent
commit.

Introduce runtime_const_mask_32 to further optimize the mask operation
in the futex hash computation hot path.

  [ prateek: Broke off the x86 chunk, commit message. ]

Link: https://patch.msgid.link/20260227161841.GH606826@noisy.programming.kicks-ass.net
Not-yet-signed-off-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
---
changelog v4..v5:

o No changes.
---
 arch/x86/include/asm/runtime-const.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/x86/include/asm/runtime-const.h b/arch/x86/include/asm/runtime-const.h
index 4cd94fdcb45e2..b13f7036c1c9b 100644
--- a/arch/x86/include/asm/runtime-const.h
+++ b/arch/x86/include/asm/runtime-const.h
@@ -41,6 +41,15 @@
 		:"+r" (__ret));					\
 	__ret; })
 
+#define runtime_const_mask_32(val, sym) ({			\
+	typeof(0u+(val)) __ret = (val);				\
+	asm_inline("and $0x12345678, %k0\n1:\n"				\
+		   ".pushsection runtime_mask_" #sym ",\"a\"\n\t"\
+		   ".long 1b - 4 - .\n"				\
+		   ".popsection"				\
+		   : "+r" (__ret));				\
+	__ret; })
+
 #define runtime_const_init(type, sym) do {		\
 	extern s32 __start_runtime_##type##_##sym[];	\
 	extern s32 __stop_runtime_##type##_##sym[];	\
@@ -65,6 +74,11 @@ static inline void __runtime_fixup_shift(void *where, unsigned long val)
 	*(unsigned char *)where = val;
 }
 
+static inline void __runtime_fixup_mask(void *where, unsigned long val)
+{
+	*(unsigned int *)where = val;
+}
+
 static inline void runtime_const_fixup(void (*fn)(void *, unsigned long),
 	unsigned long val, s32 *start, s32 *end)
 {
-- 
2.34.1



^ permalink raw reply related

* [PATCH v5 0/8] futex: Use runtime constants for futex_hash computation
From: K Prateek Nayak @ 2026-06-30  4:55 UTC (permalink / raw)
  To: Arnd Bergmann, Thomas Gleixner, Ingo Molnar, Peter Zijlstra,
	Sebastian Andrzej Siewior, Borislav Petkov, Dave Hansen, x86,
	Catalin Marinas, Will Deacon, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Heiko Carstens, Vasily Gorbik, Alexander Gordeev
  Cc: Darren Hart, Davidlohr Bueso, André Almeida, linux-arch,
	linux-kernel, Samuel Holland, Charlie Jenkins, K Prateek Nayak,
	linux-arm-kernel, linux-riscv, linux-s390, H. Peter Anvin,
	Thomas Huth, Sean Christopherson, Jisheng Zhang, Alexandre Ghiti,
	Christian Borntraeger, Sven Schnelle

tl;dr

This series introduces runtime_const_mask_32() and uses runtime
constants for __ro_after_init data in futex_hash() hot path. More
information can be found on v2 at
https://lore.kernel.org/lkml/20260316052401.18910-1-kprateek.nayak@amd.com/

Major changes in v5
===================

There was enough interest to use better instruction sequence to cater to
the current use case on ARM and RISC-V so the two implementations have
pivoted to using UBFX and SRLI + SLLI instructions respectively.

This saves two instructions on ARM64 and one instruction on RISC-V per
mask operation.

Future use cases that requires a generic mask patching on these
architectures will trip a BUG_ON() in arch/ specific patching functions
and enough bread crumbs have been left in comments and commit log to
allow an easy switch to the more generic implementation from v4.

Addressing sashiko reviews
==========================

o The operator precedence issue noted on Patch 3 and Patch 5 no longer
  exist as the mask operations are done indirectly within the ASM block
  now.

o The issue regarding usage of runtime_const before their init is moot
  since they are setup before thier first usage. AS for the comments on
  weakly ordered architectures, the platform init is done on BSP before
  the userspace is active.

Testing
=======

Apart from x86, which was build and boot tested on baremetal, all the
other architectures have been build and boot tested with cross-compile +
QEMU with some light sanity testing on each.

Patches are based on:

  git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git master

at commit ea9c52e91213d ("Merge branch into tip/master: 'irq/msi'")
(29-06-2026)

Few comments from checkpatch.pl have been ignored to adhere to the style
of the particular file. If something needs addressing, please let me
know and I'll address it with a v5.X fixups unless there is a larger
change that will require a re-spin

Everyone has been Cc'd on the cover-letter and the futex bits for the
context. Respective arch maintainers, reviewers, and whoever got lucky
with get_maintainer.pl have been Cc'd on their respective arch specific
changes. Futex maintainers and the lists will be receiving the whole
series (sorry in advance!)
---
changelog v4..v5:

o Collected tags from Catalin and Charlie on patches that remain
  unchanged in v5. (Thanks a ton!)

o Switched mask operations on ARM64 and RISC-V to use UBFX and SRLI +
  SLLI instructions respectively. (Charlie, Samuel on v2)

o Rebased changes on latest tip:master.

v4: https://lore.kernel.org/lkml/20260430094730.31624-1-kprateek.nayak@amd.com/
---
K Prateek Nayak (5):
  arm64/runtime-const: Use aarch64_insn_patch_text_nosync() for patching
  arm64/runtime-const: Introduce runtime_const_mask_32()
  riscv/runtime-const: Replace open-coded placeholder with RUNTIME_MAGIC
  riscv/runtime-const: Introduce runtime_const_mask_32()
  s390/runtime-const: Introduce runtime_const_mask_32()

Peter Zijlstra (3):
  x86/runtime-const: Introduce runtime_const_mask_32()
  asm-generic/runtime-const: Add dummy runtime_const_mask_32()
  futex: Use runtime constants for __futex_hash() hot path

 arch/arm64/include/asm/runtime-const.h | 63 ++++++++++++++++----
 arch/riscv/include/asm/asm.h           |  1 +
 arch/riscv/include/asm/runtime-const.h | 82 ++++++++++++++++++++------
 arch/s390/include/asm/runtime-const.h  | 22 ++++++-
 arch/x86/include/asm/runtime-const.h   | 14 +++++
 include/asm-generic/runtime-const.h    |  1 +
 include/asm-generic/vmlinux.lds.h      |  5 +-
 kernel/futex/core.c                    | 42 +++++++------
 8 files changed, 179 insertions(+), 51 deletions(-)


base-commit: ea9c52e91213d5427c6a2e90cd41bf912fd1ea36
-- 
2.34.1



^ permalink raw reply

* Re: [PATCH 1/2] dt-bindings: iio: adc: Add Nuvoton MA35D1 EADC
From: Chi-Wen Weng @ 2026-06-30  4:21 UTC (permalink / raw)
  To: David Lechner, jic23, robh, krzk+dt, conor+dt
  Cc: nuno.sa, andy, linux-arm-kernel, linux-iio, devicetree,
	linux-kernel, cwweng
In-Reply-To: <2f01a3a0-3698-41e6-8fee-1d2e1629726c@baylibre.com>

Hi David,

Thanks for the clarification.

 > We always want the devicetree to be as complete as possible even
 > if the drier doesn't use all of the information.
 >
 > So for trivial/well-known bindings like dmas, we should be able to
 > add it now.

Understood. I will add optional DMA properties in v2.

The hardware supports PDMA for EADC transfers, so I will describe it in
the binding even though the initial driver does not use DMA yet.

I plan to add:

   dmas:
     maxItems: 1

   dma-names:
     const: rx

These properties will not be required.

 > Same reasoning as above, we want the binding to be as complete as
 > possible, so we should not omit diff-channels since we know what
 > the bindings should look like already.

Understood. I will keep diff-channels in the binding.

I will still limit the DT child channel nodes to the external ADC input
channels 0 to 7, since channel 8 is the fixed internal VBAT input and
does not describe board wiring.

For differential inputs, I will keep diff-channels in the channel child
node schema and restrict it to valid external ADC input channels. I will
also check the hardware-supported differential pair constraints and
encode them in the schema if the hardware only supports fixed pairs.

For v2, I will update the binding to:
- allow up to four interrupt entries for ADINT0 to ADINT3,
- add optional vref-supply,
- add optional dmas and dma-names,
- keep diff-channels,
- limit DT child channel nodes to external channels 0 to 7,
- keep the internal VBAT channel out of the DT child nodes.

Thanks,
Chi-Wen



^ permalink raw reply

* Re: [PATCH rc v6 7/7] iommu/arm-smmu-v3: Detect ARM_SMMU_OPT_KDUMP_ADOPT in probe()
From: Nicolin Chen @ 2026-06-30  4:19 UTC (permalink / raw)
  To: Pranjal Shrivastava
  Cc: will, robin.murphy, jgg, joro, kees, baolu.lu, kevin.tian,
	miko.lenczewski, smostafa, linux-arm-kernel, iommu, linux-kernel,
	stable, jamien
In-Reply-To: <akKf9S1TURJJq6em@google.com>

On Mon, Jun 29, 2026 at 04:40:21PM +0000, Pranjal Shrivastava wrote:
> On Wed, May 20, 2026 at 10:03:24AM -0700, Nicolin Chen wrote:
> > +static void arm_smmu_device_hw_probe_kdump(struct arm_smmu_device *smmu)
> > +{
> > +	u32 gerror, gerrorn, active;
> > +
> > +	/* No adoption if SMMU is disabled (i.e., there is no in-flight DMA) */
> > +	if (!(readl_relaxed(smmu->base + ARM_SMMU_CR0) & CR0_SMMUEN))
> > +		return;
> > +
> > +	/* For now, only support a coherent SMMU that works with MEMREMAP_WB */
> > +	if (!(smmu->features & ARM_SMMU_FEAT_COHERENCY)) {
> > +		dev_warn(smmu->dev,
> > +			 "kdump: non-coherent SMMU unsupported; reset to block all DMAs\n");
> > +		return;
> > +	}
> 
> We seem to be checking it here right at the beginning, let's remove the
> redundant checks downstream?

Seems there is one redundancy. I can drop them.

Thanks
Nicolin


^ permalink raw reply

* Re: [PATCH rc v6 4/7] iommu/arm-smmu-v3: Skip EVTQ/PRIQ setup in kdump kernel
From: Nicolin Chen @ 2026-06-30  4:17 UTC (permalink / raw)
  To: Pranjal Shrivastava
  Cc: will, robin.murphy, jgg, joro, kees, baolu.lu, kevin.tian,
	miko.lenczewski, smostafa, linux-arm-kernel, iommu, linux-kernel,
	stable, jamien
In-Reply-To: <akKMCYsdH4lVSyf7@google.com>

On Mon, Jun 29, 2026 at 03:15:21PM +0000, Pranjal Shrivastava wrote:
> On Wed, May 20, 2026 at 10:03:21AM -0700, Nicolin Chen wrote:
> > +	if (!is_kdump_kernel()) {
> > +		writeq_relaxed(smmu->evtq.q.q_base,
> > +			       smmu->base + ARM_SMMU_EVTQ_BASE);
> > +		writel_relaxed(smmu->evtq.q.llq.prod,
> > +			       smmu->page1 + ARM_SMMU_EVTQ_PROD);
> > +		writel_relaxed(smmu->evtq.q.llq.cons,
> > +			       smmu->page1 + ARM_SMMU_EVTQ_CONS);
> > +
> > +		enables |= CR0_EVTQEN;
> > +		ret = arm_smmu_write_reg_sync(smmu, enables, ARM_SMMU_CR0,
> > +					      ARM_SMMU_CR0ACK);
> 
> Nit:
> I believe only the write_reg_sync(CR0) should be under this if condition
> do we see any weird behavior if we perform the reg writes in
> kdump_kernel?

Since CR0_EVTQEN isn't set, the other three writes are dead code.

So, I skipped them.

Nicolin


^ permalink raw reply

* Re: [PATCH rc v6 3/7] iommu/arm-smmu-v3: Do not enable EVTQ/PRIQ interrupts in kdump kernel
From: Nicolin Chen @ 2026-06-30  4:14 UTC (permalink / raw)
  To: Pranjal Shrivastava
  Cc: will, robin.murphy, jgg, joro, kees, baolu.lu, kevin.tian,
	miko.lenczewski, smostafa, linux-arm-kernel, iommu, linux-kernel,
	stable, jamien
In-Reply-To: <akIxS7kuhuLRHAMg@google.com>

On Mon, Jun 29, 2026 at 08:48:11AM +0000, Pranjal Shrivastava wrote:
> On Wed, May 20, 2026 at 10:03:20AM -0700, Nicolin Chen wrote:
> > @@ -5020,19 +5029,30 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu)
> >  		/*
> >  		 * Cavium ThunderX2 implementation doesn't support unique irq
> >  		 * lines. Use a single irq line for all the SMMUv3 interrupts.
> > +		 *
> > +		 * In kdump, EVTQ/PRIQ are disabled, so no threaded handling.
> >  		 */
> > -		ret = devm_request_threaded_irq(smmu->dev, irq,
> > -					arm_smmu_combined_irq_handler,
> > -					arm_smmu_combined_irq_thread,
> > -					IRQF_ONESHOT,
> > -					"arm-smmu-v3-combined-irq", smmu);
> > +		if (is_kdump_kernel())
> > +			ret = devm_request_irq(smmu->dev, irq,
> > +					       arm_smmu_combined_irq_handler, 0,
> > +					       "arm-smmu-v3-combined-irq",
> > +					       smmu);
> 
> This `if` isn't needed, we can continue using devm_request_threaded_irq,
> if you look at the doc for devm_request_threaded_irq [1] it says:
[...]
> So, we can pass handler() here while leaving the thread_fn == NULL:
> 
> ret = devm_request_threaded_irq(smmu->dev, irq,
>          arm_smmu_combined_irq_handler,
>          is_kdump_kernel() ? NULL : arm_smmu_combined_irq_thread,
>          IRQF_ONESHOT,
>          "arm-smmu-v3-combined-irq", smmu);

Are you sure?

__setup_irq():
1497-   /*
1498:    * IRQF_ONESHOT means the interrupt source in the IRQ chip will be
1499-    * masked until the threaded handled is done. If there is no thread
1500:    * handler then it makes no sense to have IRQF_ONESHOT.
1501-    */
1502:   WARN_ON_ONCE(new->flags & IRQF_ONESHOT && !new->thread_fn);

> Additionally, the arm_smmu_combined_irq_handler() returns 
> IRQ_WAKE_THREAD unconditionally, which causes us to hit the warn_on[3] in
> __handle_irq_event_percpu.

arm_smmu_combined_irq_handler() does not return IRQ_WAKE_THREAD
unconditionally.

This is the first part of PATCH-3 in v6:

@@ -2464,7 +2464,11 @@ static irqreturn_t arm_smmu_combined_irq_thread(int irq, void *dev)
 
 static irqreturn_t arm_smmu_combined_irq_handler(int irq, void *dev)
 {
-	arm_smmu_gerror_handler(irq, dev);
+	irqreturn_t ret = arm_smmu_gerror_handler(irq, dev);
+
+	/* In kdump, EVTQ/PRIQ are disabled and there is no thread to wake */
+	if (is_kdump_kernel())
+		return ret;
 	return IRQ_WAKE_THREAD;
 }
 
Nicolin


^ permalink raw reply

* Re: [PATCH 2/2] iio: adc: Add Nuvoton MA35D1 EADC driver
From: Chi-Wen Weng @ 2026-06-30  4:28 UTC (permalink / raw)
  To: David Lechner, jic23, robh, krzk+dt, conor+dt
  Cc: nuno.sa, andy, linux-arm-kernel, linux-iio, devicetree,
	linux-kernel, cwweng
In-Reply-To: <f759ad9b-56ef-482a-9389-85ea1e3fd7d3@baylibre.com>

Hi David,

Thanks for the clarification, and sorry for top-posting. I will reply
inline and trim the irrelevant context next time.

 > This is a simple/small enough driver that it would be fine to still
 > keep all of those features in v2. It would still be fine to split
 > them into separate patches, but you could still send them all as
 > a single patch series.

Understood. I will keep the driver as a single driver patch in v2, but I
will keep the features in the patch and fix the issues raised during
review instead of dropping them only to reduce the initial scope.

For v2, I will keep direct reads, differential channels and triggered
buffer support in the driver patch. DMA support will still not be used by
the driver yet, although the binding will describe the optional DMA
property as discussed in the binding review.

I will address the driver comments in v2, including:
- use regmap for register access and update_bits,
- add optional vref-supply handling and avoid forcing the external
   reference path unconditionally,
- add IIO_CHAN_INFO_SCALE based on the selected reference source,
- handle differential channels with the proper hardware constraints and
   signed output handling,
- fix the buffered scan sequencing so samples are read only after the
   requested scan has completed,
- avoid an unpaced software re-triggering loop,
- use IIO_DECLARE_BUFFER_WITH_TS() for the scan buffer,
- use the new scan_type.format field,
- drop datasheet_name,
- use device_for_each_child_node_scoped(),
- use devm_mutex_init(),
- remove the unused struct device pointer and other cleanup items.

Thanks,
Chi-Wen



^ permalink raw reply

* RE: [PATCH v3 3/3] clk: samsung: exynos990: Fix PERIS gate clock parents
From: Alim Akhtar @ 2026-06-30  3:53 UTC (permalink / raw)
  To: 'Peter Griffin', 'Denzeel Oliva'
  Cc: 'Krzysztof Kozlowski', 'Sylwester Nawrocki',
	'Chanwoo Choi', 'Michael Turquette',
	'Stephen Boyd', 'Brian Masney',
	'Rob	Herring', 'Conor Dooley', linux-samsung-soc,
	linux-clk, devicetree, linux-arm-kernel, linux-kernel
In-Reply-To: <CADrjBPpNQd6WgwVo-a3Mz74d1EptPm9D9BisLEmoFRsdUb3izw@mail.gmail.com>



> -----Original Message-----
> From: Peter Griffin <peter.griffin@linaro.org>
> Sent: Monday, June 29, 2026 6:02 PM
> To: Denzeel Oliva <wachiturroxd150@gmail.com>
> Cc: Krzysztof Kozlowski <krzk@kernel.org>; Sylwester Nawrocki
> <s.nawrocki@samsung.com>; Chanwoo Choi <cw00.choi@samsung.com>;
> Alim Akhtar <alim.akhtar@samsung.com>; Michael Turquette
> <mturquette@baylibre.com>; Stephen Boyd <sboyd@kernel.org>; Brian
> Masney <bmasney@redhat.com>; Rob Herring <robh@kernel.org>; Conor
> Dooley <conor+dt@kernel.org>; linux-samsung-soc@vger.kernel.org; linux-
> clk@vger.kernel.org; devicetree@vger.kernel.org; linux-arm-
> kernel@lists.infradead.org; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH v3 3/3] clk: samsung: exynos990: Fix PERIS gate clock
> parents
> 
> Hi Krysztof & Denzeel,
> 
> On Sat, 13 Jun 2026 at 13:36, Denzeel Oliva <wachiturroxd150@gmail.com>
> wrote:
> >
> > Correct eight PERIS gate clock parents to match the hardware clock
> > tree and reorder the GIC mux parents so mout_peris_bus_user is the
> > default source.
> >
> > Signed-off-by: Denzeel Oliva <wachiturroxd150@gmail.com>
> > ---
> 
> Reviewed-by: Peter Griffin <peter.griffin@linaro.org>
> 
> @Krysztof: I was thinking, maybe we should establish a new rule/best
> practice for Samsung clock upstream submissions whereby patch
> contributors should link to the downstream cal-if code for the SoC after the --
> - line. That would make reviewing the patches' correctness a bit easier, as the
> downstream cal-if code would be readily available to the reviewer.
> 
We can leave this choice to the reviewer if they want to refer to downstream cal-if code.

Regards
Alim

> regards,
> 
> Peter
> 



^ permalink raw reply

* RE: (subset) [PATCH V3 0/8] PCI: imx6: Integrate pwrctrl API and update device trees
From: Sherry Sun @ 2026-06-30  2:23 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: <akLCY21tQ6o-f43V@lizhi-Precision-Tower-5810>

> Subject: Re: (subset) [PATCH V3 0/8] PCI: imx6: Integrate pwrctrl API and
> update device trees
> 
> On Mon, Jun 29, 2026 at 12:18:15PM -0400, Frank.Li@oss.nxp.com wrote:
> > From: Frank Li <Frank.Li@nxp.com>
> >
> >
> > On Wed, 20 May 2026 16:48:56 +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!
> >
> > [2/8] arm: dts: imx6qdl-sabresd: Move power supply property to Root Port
> node
> >       commit: 6ae623838bba6b1d7dab2164bd12a166eae670b7
> > [3/8] arm: dts: imx6sx-sdb: Move power supply property to Root Port node
> >       commit: 090ca78c5f5b8b475d51d729a7b79c5b7d8bbc47
> 
> Patches dropped since CHECK_DTBS warnings.
> 

Sorry, will fix and re-send.

Best Regards
Sherry


^ permalink raw reply

* [PATCH v5 2/2] clk: amlogic: Add A9 peripherals clock controller driver
From: Jian Hu via B4 Relay @ 2026-06-30  2:36 UTC (permalink / raw)
  To: Neil Armstrong, Jerome Brunet, Michael Turquette, Stephen Boyd,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Xianwei Zhao,
	Kevin Hilman, Martin Blumenstingl
  Cc: linux-amlogic, linux-clk, devicetree, linux-kernel,
	linux-arm-kernel, Jian Hu
In-Reply-To: <20260630-a9_peripherals-v5-0-bc4019730354@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 | 2095 ++++++++++++++++++++++++++++++++++++
 3 files changed, 2111 insertions(+)

diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index cf8cf3f9e4ee..86d2e270e1b8 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_C3_PLL
 	tristate "Amlogic C3 PLL clock controller"
 	depends on ARM64
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index c6719694a242..bccd9ace9201 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_C3_PLL) += c3-pll.o
 obj-$(CONFIG_COMMON_CLK_C3_PERIPHERALS) += c3-peripherals.o
 obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
diff --git a/drivers/clk/meson/a9-peripherals.c b/drivers/clk/meson/a9-peripherals.c
new file mode 100644
index 000000000000..b943429f7b8a
--- /dev/null
+++ b/drivers/clk/meson/a9-peripherals.c
@@ -0,0 +1,2095 @@
+// 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,
+	},
+};
+
+/*
+ * 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 struct clk_regmap a9_vid_pll;
+
+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_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,
+	},
+};
+
+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 v5 1/2] dt-bindings: clock: Add Amlogic A9 peripherals clock controller
From: Jian Hu via B4 Relay @ 2026-06-30  2:36 UTC (permalink / raw)
  To: Neil Armstrong, Jerome Brunet, Michael Turquette, Stephen Boyd,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Xianwei Zhao,
	Kevin Hilman, Martin Blumenstingl
  Cc: linux-amlogic, linux-clk, devicetree, linux-kernel,
	linux-arm-kernel, Jian Hu, Conor Dooley
In-Reply-To: <20260630-a9_peripherals-v5-0-bc4019730354@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


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox