[v5,7/8] clk: sunxi-ng: a733: Add bus clock gates

Message ID 20260930-a733-clk-v5-7-11175b41cd2d@pigmoral.tech (mailing list archive)
State New
Headers
Series clk: sunxi-ng: Add support for Allwinner A733 CCU and PRCM |

Commit Message

Junhui Liu Sept. 29, 2026, 5:26 p.m. UTC
Add the bus clock gates that control access to the devices' register
interface on the Allwinner A733 SoC. These clocks are typically
single-bit controls in the BGR registers, covering UARTs, SPI, I2C, and
various multimedia engines. It also includes bus gates for system
components like the IOMMU and MSI-lite interfaces.

Also mark the ahb-store, mbus-store and ahb-cpus clocks as critical.
Disabling either store gate breaks access to boot/storage devices such
as MMC and SPI NOR, while gating ahb-cpus hangs any access to the CPUS
power domain registers when unused clocks are disabled.

Tested-by: Jerome Brunet <jbrunet@baylibre.com>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Signed-off-by: Junhui Liu <junhui.liu@pigmoral.tech>
---
 drivers/clk/sunxi-ng/ccu-sun60i-a733.c | 492 ++++++++++++++++++++++++++++++++-
 1 file changed, 491 insertions(+), 1 deletion(-)
  

Comments

Chen-Yu Tsai Oct. 4, 2026, 11:03 a.m. UTC | #1
On Tue, Sep 29, 2026 at 7:28 PM Junhui Liu <junhui.liu@pigmoral.tech> wrote:
>
> Add the bus clock gates that control access to the devices' register
> interface on the Allwinner A733 SoC. These clocks are typically
> single-bit controls in the BGR registers, covering UARTs, SPI, I2C, and
> various multimedia engines. It also includes bus gates for system
> components like the IOMMU and MSI-lite interfaces.
>
> Also mark the ahb-store, mbus-store and ahb-cpus clocks as critical.
> Disabling either store gate breaks access to boot/storage devices such
> as MMC and SPI NOR, while gating ahb-cpus hangs any access to the CPUS
> power domain registers when unused clocks are disabled.
>
> Tested-by: Jerome Brunet <jbrunet@baylibre.com>
> Reviewed-by: Andre Przywara <andre.przywara@arm.com>
> Signed-off-by: Junhui Liu <junhui.liu@pigmoral.tech>
> ---
>  drivers/clk/sunxi-ng/ccu-sun60i-a733.c | 492 ++++++++++++++++++++++++++++++++-
>  1 file changed, 491 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/clk/sunxi-ng/ccu-sun60i-a733.c b/drivers/clk/sunxi-ng/ccu-sun60i-a733.c
> index 1b2d4d36ec4c..b077e5d2f32c 100644
> --- a/drivers/clk/sunxi-ng/ccu-sun60i-a733.c
> +++ b/drivers/clk/sunxi-ng/ccu-sun60i-a733.c
> @@ -4,6 +4,10 @@
>   * Copyright (C) 2026 Junhui Liu <junhui.liu@pigmoral.tech>
>   * Based on the A523 CCU driver:
>   *   Copyright (C) 2023-2024 Arm Ltd.
> + *
> + * TODO: The real parents of some bus gates, including its-pcie0-aclk,
> + * msi-lite, npu, ufs, sgpio, lpc and i2spcm, are not documented in the
> + * manual. For now, follow the vendor BSP, which keeps them on hosc.
>   */

[...]

> @@ -510,9 +522,118 @@ static SUNXI_CCU_M_DATA_WITH_MUX_GATE_FEAT(mbus_clk, "mbus", mbus_parents, 0x588
>                                            BIT(31),     /* gate */
>                                            CLK_IS_CRITICAL,
>                                            CCU_FEATURE_UPDATE_BIT);
> +static const struct clk_hw *mbus_hws[] = { &mbus_clk.common.hw };
> +
> +static SUNXI_CCU_GATE_HWS(mbus_iommu0_sys_clk, "mbus-iommu0-sys", mbus_hws, 0x58c, BIT(0), 0);
> +static SUNXI_CCU_GATE_HWS(apb_iommu0_sys_clk, "apb-iommu0-sys", apb0_hws, 0x58c, BIT(1), 0);
> +static SUNXI_CCU_GATE_HWS(ahb_iommu0_sys_clk, "ahb-iommu0-sys", ahb_hws, 0x58c, BIT(2), 0);
> +
> +static SUNXI_CCU_GATE_DATA(bus_msi_lite0_clk, "bus-msi-lite0", hosc, 0x594, BIT(0), 0);
> +static SUNXI_CCU_GATE_DATA(bus_msi_lite1_clk, "bus-msi-lite1", hosc, 0x59c, BIT(0), 0);
> +static SUNXI_CCU_GATE_DATA(bus_msi_lite2_clk, "bus-msi-lite2", hosc, 0x5a4, BIT(0), 0);
> +
> +static SUNXI_CCU_GATE_HWS(mbus_iommu1_sys_clk, "mbus-iommu1-sys", mbus_hws, 0x5b4, BIT(0), 0);
> +static SUNXI_CCU_GATE_HWS(apb_iommu1_sys_clk, "apb-iommu1-sys", apb0_hws, 0x5b4, BIT(1), 0);
> +static SUNXI_CCU_GATE_HWS(ahb_iommu1_sys_clk, "ahb-iommu1-sys", ahb_hws, 0x5b4, BIT(2), 0);

> +static SUNXI_CCU_GATE_HWS(ahb_ve_dec_clk, "ahb-ve-dec", ahb_hws,
> +                         0x5c0, BIT(0), 0);
> +static SUNXI_CCU_GATE_HWS(ahb_ve_enc_clk, "ahb-ve-enc", ahb_hws,
> +                         0x5c0, BIT(1), 0);
> +static SUNXI_CCU_GATE_HWS(ahb_vid_in_clk, "ahb-vid-in", ahb_hws,
> +                         0x5c0, BIT(2), 0);
> +static SUNXI_CCU_GATE_HWS(ahb_vid_cout0_clk, "ahb-vid-cout0", ahb_hws,
> +                         0x5c0, BIT(3), 0);
> +static SUNXI_CCU_GATE_HWS(ahb_vid_cout1_clk, "ahb-vid-cout1", ahb_hws,
> +                         0x5c0, BIT(4), 0);
> +static SUNXI_CCU_GATE_HWS(ahb_de_clk, "ahb-de", ahb_hws,
> +                         0x5c0, BIT(5), 0);
> +static SUNXI_CCU_GATE_HWS(ahb_npu_clk, "ahb-npu", ahb_hws,
> +                         0x5c0, BIT(6), 0);
> +static SUNXI_CCU_GATE_HWS(ahb_gpu0_clk, "ahb-gpu0", ahb_hws,
> +                         0x5c0, BIT(7), 0);
> +static SUNXI_CCU_GATE_HWS(ahb_serdes_clk, "ahb-serdes", ahb_hws,
> +                         0x5c0, BIT(8), 0);
> +static SUNXI_CCU_GATE_HWS(ahb_usb_sys_clk, "ahb-usb-sys", ahb_hws,
> +                         0x5c0, BIT(9), 0);
> +static SUNXI_CCU_GATE_HWS(ahb_msi_lite0_clk, "ahb-msi-lite0", ahb_hws,
> +                         0x5c0, BIT(16), 0);
> +static SUNXI_CCU_GATE_HWS(ahb_store_clk, "ahb-store", ahb_hws,
> +                         0x5c0, BIT(24), CLK_IS_CRITICAL);
> +static SUNXI_CCU_GATE_HWS(ahb_cpus_clk, "ahb-cpus", ahb_hws,
> +                         0x5c0, BIT(28), CLK_IS_CRITICAL);

I suspect these refer to a AHB-AHB bridge for the various subsystems shown
in the memory map. That would explain why when the "ahb-store" clock is
gated, the storage bits stop working.

If that's the case, we should describe it as the parent of each storage
peripheral bus gate's parent. Same would go for the other types. I haven't
checked what the BSP does though.

> +static SUNXI_CCU_GATE_HWS(mbus_iommu0_clk, "mbus-iommu0", mbus_hws,
> +                         0x5e0, BIT(0), 0);
> +static SUNXI_CCU_GATE_HWS(mbus_iommu1_clk, "mbus-iommu1", mbus_hws,
> +                         0x5e0, BIT(1), 0);
> +static SUNXI_CCU_GATE_HWS(mbus_desys_clk, "mbus-desys", mbus_hws,
> +                         0x5e0, BIT(11), 0);
> +static SUNXI_CCU_GATE_HWS(mbus_ve_enc0_gate_clk, "mbus-ve-enc0-gate", mbus_hws,
> +                         0x5e0, BIT(12), 0);
> +static SUNXI_CCU_GATE_HWS(mbus_ve_dec0_gate_clk, "mbus-ve-dec0-gate", mbus_hws,
> +                         0x5e0, BIT(14), 0);
> +static SUNXI_CCU_GATE_HWS(mbus_gpu0_clk, "mbus-gpu0", mbus_hws,
> +                         0x5e0, BIT(16), 0);
> +static SUNXI_CCU_GATE_HWS(mbus_npu_clk, "mbus-npu", mbus_hws,
> +                         0x5e0, BIT(18), 0);
> +static SUNXI_CCU_GATE_HWS(mbus_vid_in_clk, "mbus-vid-in", mbus_hws,
> +                         0x5e0, BIT(24), 0);
> +static SUNXI_CCU_GATE_HWS(mbus_serdes_clk, "mbus-serdes", mbus_hws,
> +                         0x5e0, BIT(28), 0);
> +static SUNXI_CCU_GATE_HWS(mbus_msi_lite0_clk, "mbus-msi-lite0", mbus_hws,
> +                         0x5e0, BIT(29), 0);
> +static SUNXI_CCU_GATE_HWS(mbus_store_clk, "mbus-store", mbus_hws,
> +                         0x5e0, BIT(30), CLK_IS_CRITICAL);

Same thing for the MBUS clocks.

> +static SUNXI_CCU_GATE_HWS(mbus_msi_lite2_clk, "mbus-msi-lite2", mbus_hws,
> +                         0x5e0, BIT(31), 0);
> +
> +static SUNXI_CCU_GATE_HWS(mbus_dma0_clk, "mbus-dma0", mbus_hws,
> +                         0x5e4, BIT(0), 0);
> +static SUNXI_CCU_GATE_HWS(mbus_ve_enc0_clk, "mbus-ve-enc0", mbus_hws,
> +                         0x5e4, BIT(1), 0);
> +static SUNXI_CCU_GATE_HWS(mbus_ce_clk, "mbus-ce", mbus_hws,
> +                         0x5e4, BIT(2), 0);
> +static SUNXI_CCU_GATE_HWS(mbus_dma1_clk, "mbus-dma1", mbus_hws,
> +                         0x5e4, BIT(3), 0);
> +static SUNXI_CCU_GATE_HWS(mbus_nand_clk, "mbus-nand", mbus_hws,
> +                         0x5e4, BIT(5), 0);
> +static SUNXI_CCU_GATE_HWS(mbus_csi_clk, "mbus-csi", mbus_hws,
> +                         0x5e4, BIT(8), 0);
> +static SUNXI_CCU_GATE_HWS(mbus_isp_clk, "mbus-isp", mbus_hws,
> +                         0x5e4, BIT(9), 0);
> +static SUNXI_CCU_GATE_HWS(mbus_gmac0_clk, "mbus-gmac0", mbus_hws,
> +                         0x5e4, BIT(11), 0);
> +/* Undocumented, taken from the vendor kernel. */
> +static SUNXI_CCU_GATE_HWS(mbus_gmac1_clk, "mbus-gmac1", mbus_hws,
> +                         0x5e4, BIT(12), 0);
> +static SUNXI_CCU_GATE_HWS(mbus_ve_dec0_clk, "mbus-ve-dec0", mbus_hws,
> +                         0x5e4, BIT(18), 0);

[...]

The remaining definitions look correct (minus the vendor BSP ones which I
couldn't check at this time).

I didn't check the clock list additions.

Consider this

Reviewed-by: Chen-Yu Tsai <wens@kernel.org>


We can change the AHB / MBUS clock parents later if we do figure it out.


ChenYu
  
Norman Herms Oct. 4, 2026, 11:14 a.m. UTC | #2
On Sun, Oct 4, 2026 at 1:03 PM Chen-Yu Tsai <wens@kernel.org> wrote:
> > +static SUNXI_CCU_GATE_HWS(ahb_store_clk, "ahb-store", ahb_hws,
> > +                         0x5c0, BIT(24), CLK_IS_CRITICAL);
> > +static SUNXI_CCU_GATE_HWS(ahb_cpus_clk, "ahb-cpus", ahb_hws,
> > +                         0x5c0, BIT(28), CLK_IS_CRITICAL);
>
> I suspect these refer to a AHB-AHB bridge for the various subsystems shown
> in the memory map. That would explain why when the "ahb-store" clock is
> gated, the storage bits stop working.
>
> If that's the case, we should describe it as the parent of each storage
> peripheral bus gate's parent. Same would go for the other types. I haven't
> checked what the BSP does though.

Two data points, in case they help.

The vendor BSP (radxa/allwinner-bsp, branch cubie-aiot-v1.5.0,
drivers/clk/sunxi-ng/ccu-sun60iw2.c) models no hierarchy either. It
registers every gate in 0x5c0 and 0x5e0 as a keyed gate on the
oscillator and marks each one CLK_IS_CRITICAL or CLK_IGNORE_UNUSED, so
clk_disable_unused() never closes any of them.

On a Cubie A7S running our own 6.18-based tree, with the GPU power
domain up and ahb-gpu0 (0x5c0 bit 7) and mbus-gpu0 (0x5e0 bit 16) both
closed, drm/powervr still bound, read the core ID and loaded the
matching firmware, but the firmware then failed to boot ("Firmware
failed to boot"). With both bits set, the same modprobe initialized the
GPU. So for the GPU, register access worked with these two gates
closed; what failed was the firmware running on the GPU.

The measurements were run on my boards by AI agents.

Norman
  
Junhui Liu Oct. 5, 2026, 4:41 a.m. UTC | #3
Hi Chen-Yu,

On Sun Oct 4, 2026 at 7:03 PM CST, Chen-Yu Tsai wrote:
> On Tue, Sep 29, 2026 at 7:28 PM Junhui Liu <junhui.liu@pigmoral.tech> wrote:
>>
>> Add the bus clock gates that control access to the devices' register
>> interface on the Allwinner A733 SoC. These clocks are typically
>> single-bit controls in the BGR registers, covering UARTs, SPI, I2C, and
>> various multimedia engines. It also includes bus gates for system
>> components like the IOMMU and MSI-lite interfaces.
>>
>> Also mark the ahb-store, mbus-store and ahb-cpus clocks as critical.
>> Disabling either store gate breaks access to boot/storage devices such
>> as MMC and SPI NOR, while gating ahb-cpus hangs any access to the CPUS
>> power domain registers when unused clocks are disabled.
>>
>> Tested-by: Jerome Brunet <jbrunet@baylibre.com>
>> Reviewed-by: Andre Przywara <andre.przywara@arm.com>
>> Signed-off-by: Junhui Liu <junhui.liu@pigmoral.tech>
>> ---
>>  drivers/clk/sunxi-ng/ccu-sun60i-a733.c | 492 ++++++++++++++++++++++++++++++++-
>>  1 file changed, 491 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/clk/sunxi-ng/ccu-sun60i-a733.c b/drivers/clk/sunxi-ng/ccu-sun60i-a733.c
>> index 1b2d4d36ec4c..b077e5d2f32c 100644
>> --- a/drivers/clk/sunxi-ng/ccu-sun60i-a733.c
>> +++ b/drivers/clk/sunxi-ng/ccu-sun60i-a733.c
>> @@ -4,6 +4,10 @@
>>   * Copyright (C) 2026 Junhui Liu <junhui.liu@pigmoral.tech>
>>   * Based on the A523 CCU driver:
>>   *   Copyright (C) 2023-2024 Arm Ltd.
>> + *
>> + * TODO: The real parents of some bus gates, including its-pcie0-aclk,
>> + * msi-lite, npu, ufs, sgpio, lpc and i2spcm, are not documented in the
>> + * manual. For now, follow the vendor BSP, which keeps them on hosc.
>>   */
>
> [...]
>
>> @@ -510,9 +522,118 @@ static SUNXI_CCU_M_DATA_WITH_MUX_GATE_FEAT(mbus_clk, "mbus", mbus_parents, 0x588
>>                                            BIT(31),     /* gate */
>>                                            CLK_IS_CRITICAL,
>>                                            CCU_FEATURE_UPDATE_BIT);
>> +static const struct clk_hw *mbus_hws[] = { &mbus_clk.common.hw };
>> +
>> +static SUNXI_CCU_GATE_HWS(mbus_iommu0_sys_clk, "mbus-iommu0-sys", mbus_hws, 0x58c, BIT(0), 0);
>> +static SUNXI_CCU_GATE_HWS(apb_iommu0_sys_clk, "apb-iommu0-sys", apb0_hws, 0x58c, BIT(1), 0);
>> +static SUNXI_CCU_GATE_HWS(ahb_iommu0_sys_clk, "ahb-iommu0-sys", ahb_hws, 0x58c, BIT(2), 0);
>> +
>> +static SUNXI_CCU_GATE_DATA(bus_msi_lite0_clk, "bus-msi-lite0", hosc, 0x594, BIT(0), 0);
>> +static SUNXI_CCU_GATE_DATA(bus_msi_lite1_clk, "bus-msi-lite1", hosc, 0x59c, BIT(0), 0);
>> +static SUNXI_CCU_GATE_DATA(bus_msi_lite2_clk, "bus-msi-lite2", hosc, 0x5a4, BIT(0), 0);
>> +
>> +static SUNXI_CCU_GATE_HWS(mbus_iommu1_sys_clk, "mbus-iommu1-sys", mbus_hws, 0x5b4, BIT(0), 0);
>> +static SUNXI_CCU_GATE_HWS(apb_iommu1_sys_clk, "apb-iommu1-sys", apb0_hws, 0x5b4, BIT(1), 0);
>> +static SUNXI_CCU_GATE_HWS(ahb_iommu1_sys_clk, "ahb-iommu1-sys", ahb_hws, 0x5b4, BIT(2), 0);
>
>> +static SUNXI_CCU_GATE_HWS(ahb_ve_dec_clk, "ahb-ve-dec", ahb_hws,
>> +                         0x5c0, BIT(0), 0);
>> +static SUNXI_CCU_GATE_HWS(ahb_ve_enc_clk, "ahb-ve-enc", ahb_hws,
>> +                         0x5c0, BIT(1), 0);
>> +static SUNXI_CCU_GATE_HWS(ahb_vid_in_clk, "ahb-vid-in", ahb_hws,
>> +                         0x5c0, BIT(2), 0);
>> +static SUNXI_CCU_GATE_HWS(ahb_vid_cout0_clk, "ahb-vid-cout0", ahb_hws,
>> +                         0x5c0, BIT(3), 0);
>> +static SUNXI_CCU_GATE_HWS(ahb_vid_cout1_clk, "ahb-vid-cout1", ahb_hws,
>> +                         0x5c0, BIT(4), 0);
>> +static SUNXI_CCU_GATE_HWS(ahb_de_clk, "ahb-de", ahb_hws,
>> +                         0x5c0, BIT(5), 0);
>> +static SUNXI_CCU_GATE_HWS(ahb_npu_clk, "ahb-npu", ahb_hws,
>> +                         0x5c0, BIT(6), 0);
>> +static SUNXI_CCU_GATE_HWS(ahb_gpu0_clk, "ahb-gpu0", ahb_hws,
>> +                         0x5c0, BIT(7), 0);
>> +static SUNXI_CCU_GATE_HWS(ahb_serdes_clk, "ahb-serdes", ahb_hws,
>> +                         0x5c0, BIT(8), 0);
>> +static SUNXI_CCU_GATE_HWS(ahb_usb_sys_clk, "ahb-usb-sys", ahb_hws,
>> +                         0x5c0, BIT(9), 0);
>> +static SUNXI_CCU_GATE_HWS(ahb_msi_lite0_clk, "ahb-msi-lite0", ahb_hws,
>> +                         0x5c0, BIT(16), 0);
>> +static SUNXI_CCU_GATE_HWS(ahb_store_clk, "ahb-store", ahb_hws,
>> +                         0x5c0, BIT(24), CLK_IS_CRITICAL);
>> +static SUNXI_CCU_GATE_HWS(ahb_cpus_clk, "ahb-cpus", ahb_hws,
>> +                         0x5c0, BIT(28), CLK_IS_CRITICAL);
>
> I suspect these refer to a AHB-AHB bridge for the various subsystems shown
> in the memory map. That would explain why when the "ahb-store" clock is
> gated, the storage bits stop working.
>
> If that's the case, we should describe it as the parent of each storage
> peripheral bus gate's parent. Same would go for the other types. I haven't
> checked what the BSP does though.

As Norman mentioned in his reply, the vendor BSP also does not model
this hierarchy and instead models these gates as independent clocks
parented to the oscillator. The manual does not describe the hierarchy
either, so I don't think we have enough information to model it
differently at this point.

I will add comments explaining why ahb_store_clk, mbus_store_clk, and
ahb_cpus_clk are marked critical.

>
>> +static SUNXI_CCU_GATE_HWS(mbus_iommu0_clk, "mbus-iommu0", mbus_hws,
>> +                         0x5e0, BIT(0), 0);
>> +static SUNXI_CCU_GATE_HWS(mbus_iommu1_clk, "mbus-iommu1", mbus_hws,
>> +                         0x5e0, BIT(1), 0);
>> +static SUNXI_CCU_GATE_HWS(mbus_desys_clk, "mbus-desys", mbus_hws,
>> +                         0x5e0, BIT(11), 0);
>> +static SUNXI_CCU_GATE_HWS(mbus_ve_enc0_gate_clk, "mbus-ve-enc0-gate", mbus_hws,
>> +                         0x5e0, BIT(12), 0);
>> +static SUNXI_CCU_GATE_HWS(mbus_ve_dec0_gate_clk, "mbus-ve-dec0-gate", mbus_hws,
>> +                         0x5e0, BIT(14), 0);
>> +static SUNXI_CCU_GATE_HWS(mbus_gpu0_clk, "mbus-gpu0", mbus_hws,
>> +                         0x5e0, BIT(16), 0);
>> +static SUNXI_CCU_GATE_HWS(mbus_npu_clk, "mbus-npu", mbus_hws,
>> +                         0x5e0, BIT(18), 0);
>> +static SUNXI_CCU_GATE_HWS(mbus_vid_in_clk, "mbus-vid-in", mbus_hws,
>> +                         0x5e0, BIT(24), 0);
>> +static SUNXI_CCU_GATE_HWS(mbus_serdes_clk, "mbus-serdes", mbus_hws,
>> +                         0x5e0, BIT(28), 0);
>> +static SUNXI_CCU_GATE_HWS(mbus_msi_lite0_clk, "mbus-msi-lite0", mbus_hws,
>> +                         0x5e0, BIT(29), 0);
>> +static SUNXI_CCU_GATE_HWS(mbus_store_clk, "mbus-store", mbus_hws,
>> +                         0x5e0, BIT(30), CLK_IS_CRITICAL);
>
> Same thing for the MBUS clocks.
>
>> +static SUNXI_CCU_GATE_HWS(mbus_msi_lite2_clk, "mbus-msi-lite2", mbus_hws,
>> +                         0x5e0, BIT(31), 0);
>> +
>> +static SUNXI_CCU_GATE_HWS(mbus_dma0_clk, "mbus-dma0", mbus_hws,
>> +                         0x5e4, BIT(0), 0);
>> +static SUNXI_CCU_GATE_HWS(mbus_ve_enc0_clk, "mbus-ve-enc0", mbus_hws,
>> +                         0x5e4, BIT(1), 0);
>> +static SUNXI_CCU_GATE_HWS(mbus_ce_clk, "mbus-ce", mbus_hws,
>> +                         0x5e4, BIT(2), 0);
>> +static SUNXI_CCU_GATE_HWS(mbus_dma1_clk, "mbus-dma1", mbus_hws,
>> +                         0x5e4, BIT(3), 0);
>> +static SUNXI_CCU_GATE_HWS(mbus_nand_clk, "mbus-nand", mbus_hws,
>> +                         0x5e4, BIT(5), 0);
>> +static SUNXI_CCU_GATE_HWS(mbus_csi_clk, "mbus-csi", mbus_hws,
>> +                         0x5e4, BIT(8), 0);
>> +static SUNXI_CCU_GATE_HWS(mbus_isp_clk, "mbus-isp", mbus_hws,
>> +                         0x5e4, BIT(9), 0);
>> +static SUNXI_CCU_GATE_HWS(mbus_gmac0_clk, "mbus-gmac0", mbus_hws,
>> +                         0x5e4, BIT(11), 0);
>> +/* Undocumented, taken from the vendor kernel. */
>> +static SUNXI_CCU_GATE_HWS(mbus_gmac1_clk, "mbus-gmac1", mbus_hws,
>> +                         0x5e4, BIT(12), 0);
>> +static SUNXI_CCU_GATE_HWS(mbus_ve_dec0_clk, "mbus-ve-dec0", mbus_hws,
>> +                         0x5e4, BIT(18), 0);
>
> [...]
>
> The remaining definitions look correct (minus the vendor BSP ones which I
> couldn't check at this time).
>
> I didn't check the clock list additions.
>
> Consider this
>
> Reviewed-by: Chen-Yu Tsai <wens@kernel.org>
>

Thanks!

>
> We can change the AHB / MBUS clock parents later if we do figure it out.
>
>
> ChenYu
  
Andre Przywara Oct. 5, 2026, 9:17 a.m. UTC | #4
Hi,

On 10/5/26 06:41, Junhui Liu wrote:
> Hi Chen-Yu,
> 
> On Sun Oct 4, 2026 at 7:03 PM CST, Chen-Yu Tsai wrote:
>> On Tue, Sep 29, 2026 at 7:28 PM Junhui Liu <junhui.liu@pigmoral.tech> wrote:
>>>
>>> Add the bus clock gates that control access to the devices' register
>>> interface on the Allwinner A733 SoC. These clocks are typically
>>> single-bit controls in the BGR registers, covering UARTs, SPI, I2C, and
>>> various multimedia engines. It also includes bus gates for system
>>> components like the IOMMU and MSI-lite interfaces.
>>>
>>> Also mark the ahb-store, mbus-store and ahb-cpus clocks as critical.
>>> Disabling either store gate breaks access to boot/storage devices such
>>> as MMC and SPI NOR, while gating ahb-cpus hangs any access to the CPUS
>>> power domain registers when unused clocks are disabled.
>>>
>>> Tested-by: Jerome Brunet <jbrunet@baylibre.com>
>>> Reviewed-by: Andre Przywara <andre.przywara@arm.com>
>>> Signed-off-by: Junhui Liu <junhui.liu@pigmoral.tech>
>>> ---
>>>   drivers/clk/sunxi-ng/ccu-sun60i-a733.c | 492 ++++++++++++++++++++++++++++++++-
>>>   1 file changed, 491 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/clk/sunxi-ng/ccu-sun60i-a733.c b/drivers/clk/sunxi-ng/ccu-sun60i-a733.c
>>> index 1b2d4d36ec4c..b077e5d2f32c 100644
>>> --- a/drivers/clk/sunxi-ng/ccu-sun60i-a733.c
>>> +++ b/drivers/clk/sunxi-ng/ccu-sun60i-a733.c
>>> @@ -4,6 +4,10 @@
>>>    * Copyright (C) 2026 Junhui Liu <junhui.liu@pigmoral.tech>
>>>    * Based on the A523 CCU driver:
>>>    *   Copyright (C) 2023-2024 Arm Ltd.
>>> + *
>>> + * TODO: The real parents of some bus gates, including its-pcie0-aclk,
>>> + * msi-lite, npu, ufs, sgpio, lpc and i2spcm, are not documented in the
>>> + * manual. For now, follow the vendor BSP, which keeps them on hosc.
>>>    */
>>
>> [...]
>>
>>> @@ -510,9 +522,118 @@ static SUNXI_CCU_M_DATA_WITH_MUX_GATE_FEAT(mbus_clk, "mbus", mbus_parents, 0x588
>>>                                             BIT(31),     /* gate */
>>>                                             CLK_IS_CRITICAL,
>>>                                             CCU_FEATURE_UPDATE_BIT);
>>> +static const struct clk_hw *mbus_hws[] = { &mbus_clk.common.hw };
>>> +
>>> +static SUNXI_CCU_GATE_HWS(mbus_iommu0_sys_clk, "mbus-iommu0-sys", mbus_hws, 0x58c, BIT(0), 0);
>>> +static SUNXI_CCU_GATE_HWS(apb_iommu0_sys_clk, "apb-iommu0-sys", apb0_hws, 0x58c, BIT(1), 0);
>>> +static SUNXI_CCU_GATE_HWS(ahb_iommu0_sys_clk, "ahb-iommu0-sys", ahb_hws, 0x58c, BIT(2), 0);
>>> +
>>> +static SUNXI_CCU_GATE_DATA(bus_msi_lite0_clk, "bus-msi-lite0", hosc, 0x594, BIT(0), 0);
>>> +static SUNXI_CCU_GATE_DATA(bus_msi_lite1_clk, "bus-msi-lite1", hosc, 0x59c, BIT(0), 0);
>>> +static SUNXI_CCU_GATE_DATA(bus_msi_lite2_clk, "bus-msi-lite2", hosc, 0x5a4, BIT(0), 0);
>>> +
>>> +static SUNXI_CCU_GATE_HWS(mbus_iommu1_sys_clk, "mbus-iommu1-sys", mbus_hws, 0x5b4, BIT(0), 0);
>>> +static SUNXI_CCU_GATE_HWS(apb_iommu1_sys_clk, "apb-iommu1-sys", apb0_hws, 0x5b4, BIT(1), 0);
>>> +static SUNXI_CCU_GATE_HWS(ahb_iommu1_sys_clk, "ahb-iommu1-sys", ahb_hws, 0x5b4, BIT(2), 0);
>>
>>> +static SUNXI_CCU_GATE_HWS(ahb_ve_dec_clk, "ahb-ve-dec", ahb_hws,
>>> +                         0x5c0, BIT(0), 0);
>>> +static SUNXI_CCU_GATE_HWS(ahb_ve_enc_clk, "ahb-ve-enc", ahb_hws,
>>> +                         0x5c0, BIT(1), 0);
>>> +static SUNXI_CCU_GATE_HWS(ahb_vid_in_clk, "ahb-vid-in", ahb_hws,
>>> +                         0x5c0, BIT(2), 0);
>>> +static SUNXI_CCU_GATE_HWS(ahb_vid_cout0_clk, "ahb-vid-cout0", ahb_hws,
>>> +                         0x5c0, BIT(3), 0);
>>> +static SUNXI_CCU_GATE_HWS(ahb_vid_cout1_clk, "ahb-vid-cout1", ahb_hws,
>>> +                         0x5c0, BIT(4), 0);
>>> +static SUNXI_CCU_GATE_HWS(ahb_de_clk, "ahb-de", ahb_hws,
>>> +                         0x5c0, BIT(5), 0);
>>> +static SUNXI_CCU_GATE_HWS(ahb_npu_clk, "ahb-npu", ahb_hws,
>>> +                         0x5c0, BIT(6), 0);
>>> +static SUNXI_CCU_GATE_HWS(ahb_gpu0_clk, "ahb-gpu0", ahb_hws,
>>> +                         0x5c0, BIT(7), 0);
>>> +static SUNXI_CCU_GATE_HWS(ahb_serdes_clk, "ahb-serdes", ahb_hws,
>>> +                         0x5c0, BIT(8), 0);
>>> +static SUNXI_CCU_GATE_HWS(ahb_usb_sys_clk, "ahb-usb-sys", ahb_hws,
>>> +                         0x5c0, BIT(9), 0);
>>> +static SUNXI_CCU_GATE_HWS(ahb_msi_lite0_clk, "ahb-msi-lite0", ahb_hws,
>>> +                         0x5c0, BIT(16), 0);
>>> +static SUNXI_CCU_GATE_HWS(ahb_store_clk, "ahb-store", ahb_hws,
>>> +                         0x5c0, BIT(24), CLK_IS_CRITICAL);
>>> +static SUNXI_CCU_GATE_HWS(ahb_cpus_clk, "ahb-cpus", ahb_hws,
>>> +                         0x5c0, BIT(28), CLK_IS_CRITICAL);
>>
>> I suspect these refer to a AHB-AHB bridge for the various subsystems shown
>> in the memory map. That would explain why when the "ahb-store" clock is
>> gated, the storage bits stop working.
>>
>> If that's the case, we should describe it as the parent of each storage
>> peripheral bus gate's parent. Same would go for the other types. I haven't
>> checked what the BSP does though.
> 
> As Norman mentioned in his reply, the vendor BSP also does not model
> this hierarchy and instead models these gates as independent clocks
> parented to the oscillator. The manual does not describe the hierarchy
> either, so I don't think we have enough information to model it
> differently at this point.

Well, I wouldn't use the BSP as a good example on how to model the clock 
tree, they have been very misguided in the past.
What the BSP does is to add just more input/gate MBUS clocks for each 
device, which is something I think we should avoid.
To that regard using them as parent clocks for the existing gates, as 
Chen-Yu suggested, sounds like a good idea: We keep a single clock for 
the devices, but still can turn both clocks off (I think, not tested).

Cheers,
Andre

> I will add comments explaining why ahb_store_clk, mbus_store_clk, and
> ahb_cpus_clk are marked critical.
> 
>>
>>> +static SUNXI_CCU_GATE_HWS(mbus_iommu0_clk, "mbus-iommu0", mbus_hws,
>>> +                         0x5e0, BIT(0), 0);
>>> +static SUNXI_CCU_GATE_HWS(mbus_iommu1_clk, "mbus-iommu1", mbus_hws,
>>> +                         0x5e0, BIT(1), 0);
>>> +static SUNXI_CCU_GATE_HWS(mbus_desys_clk, "mbus-desys", mbus_hws,
>>> +                         0x5e0, BIT(11), 0);
>>> +static SUNXI_CCU_GATE_HWS(mbus_ve_enc0_gate_clk, "mbus-ve-enc0-gate", mbus_hws,
>>> +                         0x5e0, BIT(12), 0);
>>> +static SUNXI_CCU_GATE_HWS(mbus_ve_dec0_gate_clk, "mbus-ve-dec0-gate", mbus_hws,
>>> +                         0x5e0, BIT(14), 0);
>>> +static SUNXI_CCU_GATE_HWS(mbus_gpu0_clk, "mbus-gpu0", mbus_hws,
>>> +                         0x5e0, BIT(16), 0);
>>> +static SUNXI_CCU_GATE_HWS(mbus_npu_clk, "mbus-npu", mbus_hws,
>>> +                         0x5e0, BIT(18), 0);
>>> +static SUNXI_CCU_GATE_HWS(mbus_vid_in_clk, "mbus-vid-in", mbus_hws,
>>> +                         0x5e0, BIT(24), 0);
>>> +static SUNXI_CCU_GATE_HWS(mbus_serdes_clk, "mbus-serdes", mbus_hws,
>>> +                         0x5e0, BIT(28), 0);
>>> +static SUNXI_CCU_GATE_HWS(mbus_msi_lite0_clk, "mbus-msi-lite0", mbus_hws,
>>> +                         0x5e0, BIT(29), 0);
>>> +static SUNXI_CCU_GATE_HWS(mbus_store_clk, "mbus-store", mbus_hws,
>>> +                         0x5e0, BIT(30), CLK_IS_CRITICAL);
>>
>> Same thing for the MBUS clocks.
>>
>>> +static SUNXI_CCU_GATE_HWS(mbus_msi_lite2_clk, "mbus-msi-lite2", mbus_hws,
>>> +                         0x5e0, BIT(31), 0);
>>> +
>>> +static SUNXI_CCU_GATE_HWS(mbus_dma0_clk, "mbus-dma0", mbus_hws,
>>> +                         0x5e4, BIT(0), 0);
>>> +static SUNXI_CCU_GATE_HWS(mbus_ve_enc0_clk, "mbus-ve-enc0", mbus_hws,
>>> +                         0x5e4, BIT(1), 0);
>>> +static SUNXI_CCU_GATE_HWS(mbus_ce_clk, "mbus-ce", mbus_hws,
>>> +                         0x5e4, BIT(2), 0);
>>> +static SUNXI_CCU_GATE_HWS(mbus_dma1_clk, "mbus-dma1", mbus_hws,
>>> +                         0x5e4, BIT(3), 0);
>>> +static SUNXI_CCU_GATE_HWS(mbus_nand_clk, "mbus-nand", mbus_hws,
>>> +                         0x5e4, BIT(5), 0);
>>> +static SUNXI_CCU_GATE_HWS(mbus_csi_clk, "mbus-csi", mbus_hws,
>>> +                         0x5e4, BIT(8), 0);
>>> +static SUNXI_CCU_GATE_HWS(mbus_isp_clk, "mbus-isp", mbus_hws,
>>> +                         0x5e4, BIT(9), 0);
>>> +static SUNXI_CCU_GATE_HWS(mbus_gmac0_clk, "mbus-gmac0", mbus_hws,
>>> +                         0x5e4, BIT(11), 0);
>>> +/* Undocumented, taken from the vendor kernel. */
>>> +static SUNXI_CCU_GATE_HWS(mbus_gmac1_clk, "mbus-gmac1", mbus_hws,
>>> +                         0x5e4, BIT(12), 0);
>>> +static SUNXI_CCU_GATE_HWS(mbus_ve_dec0_clk, "mbus-ve-dec0", mbus_hws,
>>> +                         0x5e4, BIT(18), 0);
>>
>> [...]
>>
>> The remaining definitions look correct (minus the vendor BSP ones which I
>> couldn't check at this time).
>>
>> I didn't check the clock list additions.
>>
>> Consider this
>>
>> Reviewed-by: Chen-Yu Tsai <wens@kernel.org>
>>
> 
> Thanks!
> 
>>
>> We can change the AHB / MBUS clock parents later if we do figure it out.
>>
>>
>> ChenYu
>
  
Junhui Liu Oct. 6, 2026, 2:50 p.m. UTC | #5
Hi Andre, Chen-Yu,

I ran some tests and now have a better understanding of the clock
hierarchy. Please see the results below.

On Mon Oct 5, 2026 at 5:17 PM CST, Andre Przywara wrote:
> Hi,
>
> On 10/5/26 06:41, Junhui Liu wrote:
>> Hi Chen-Yu,
>> 
>> On Sun Oct 4, 2026 at 7:03 PM CST, Chen-Yu Tsai wrote:
>>> On Tue, Sep 29, 2026 at 7:28 PM Junhui Liu <junhui.liu@pigmoral.tech> wrote:
>>>>
>>>> Add the bus clock gates that control access to the devices' register
>>>> interface on the Allwinner A733 SoC. These clocks are typically
>>>> single-bit controls in the BGR registers, covering UARTs, SPI, I2C, and
>>>> various multimedia engines. It also includes bus gates for system
>>>> components like the IOMMU and MSI-lite interfaces.
>>>>
>>>> Also mark the ahb-store, mbus-store and ahb-cpus clocks as critical.
>>>> Disabling either store gate breaks access to boot/storage devices such
>>>> as MMC and SPI NOR, while gating ahb-cpus hangs any access to the CPUS
>>>> power domain registers when unused clocks are disabled.
>>>>
>>>> Tested-by: Jerome Brunet <jbrunet@baylibre.com>
>>>> Reviewed-by: Andre Przywara <andre.przywara@arm.com>
>>>> Signed-off-by: Junhui Liu <junhui.liu@pigmoral.tech>
>>>> ---
>>>>   drivers/clk/sunxi-ng/ccu-sun60i-a733.c | 492 ++++++++++++++++++++++++++++++++-
>>>>   1 file changed, 491 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/clk/sunxi-ng/ccu-sun60i-a733.c b/drivers/clk/sunxi-ng/ccu-sun60i-a733.c
>>>> index 1b2d4d36ec4c..b077e5d2f32c 100644
>>>> --- a/drivers/clk/sunxi-ng/ccu-sun60i-a733.c
>>>> +++ b/drivers/clk/sunxi-ng/ccu-sun60i-a733.c
>>>> @@ -4,6 +4,10 @@
>>>>    * Copyright (C) 2026 Junhui Liu <junhui.liu@pigmoral.tech>
>>>>    * Based on the A523 CCU driver:
>>>>    *   Copyright (C) 2023-2024 Arm Ltd.
>>>> + *
>>>> + * TODO: The real parents of some bus gates, including its-pcie0-aclk,
>>>> + * msi-lite, npu, ufs, sgpio, lpc and i2spcm, are not documented in the
>>>> + * manual. For now, follow the vendor BSP, which keeps them on hosc.
>>>>    */
>>>
>>> [...]
>>>
>>>> @@ -510,9 +522,118 @@ static SUNXI_CCU_M_DATA_WITH_MUX_GATE_FEAT(mbus_clk, "mbus", mbus_parents, 0x588
>>>>                                             BIT(31),     /* gate */
>>>>                                             CLK_IS_CRITICAL,
>>>>                                             CCU_FEATURE_UPDATE_BIT);
>>>> +static const struct clk_hw *mbus_hws[] = { &mbus_clk.common.hw };
>>>> +
>>>> +static SUNXI_CCU_GATE_HWS(mbus_iommu0_sys_clk, "mbus-iommu0-sys", mbus_hws, 0x58c, BIT(0), 0);
>>>> +static SUNXI_CCU_GATE_HWS(apb_iommu0_sys_clk, "apb-iommu0-sys", apb0_hws, 0x58c, BIT(1), 0);
>>>> +static SUNXI_CCU_GATE_HWS(ahb_iommu0_sys_clk, "ahb-iommu0-sys", ahb_hws, 0x58c, BIT(2), 0);
>>>> +
>>>> +static SUNXI_CCU_GATE_DATA(bus_msi_lite0_clk, "bus-msi-lite0", hosc, 0x594, BIT(0), 0);
>>>> +static SUNXI_CCU_GATE_DATA(bus_msi_lite1_clk, "bus-msi-lite1", hosc, 0x59c, BIT(0), 0);
>>>> +static SUNXI_CCU_GATE_DATA(bus_msi_lite2_clk, "bus-msi-lite2", hosc, 0x5a4, BIT(0), 0);
>>>> +
>>>> +static SUNXI_CCU_GATE_HWS(mbus_iommu1_sys_clk, "mbus-iommu1-sys", mbus_hws, 0x5b4, BIT(0), 0);
>>>> +static SUNXI_CCU_GATE_HWS(apb_iommu1_sys_clk, "apb-iommu1-sys", apb0_hws, 0x5b4, BIT(1), 0);
>>>> +static SUNXI_CCU_GATE_HWS(ahb_iommu1_sys_clk, "ahb-iommu1-sys", ahb_hws, 0x5b4, BIT(2), 0);
>>>
>>>> +static SUNXI_CCU_GATE_HWS(ahb_ve_dec_clk, "ahb-ve-dec", ahb_hws,
>>>> +                         0x5c0, BIT(0), 0);
>>>> +static SUNXI_CCU_GATE_HWS(ahb_ve_enc_clk, "ahb-ve-enc", ahb_hws,
>>>> +                         0x5c0, BIT(1), 0);
>>>> +static SUNXI_CCU_GATE_HWS(ahb_vid_in_clk, "ahb-vid-in", ahb_hws,
>>>> +                         0x5c0, BIT(2), 0);
>>>> +static SUNXI_CCU_GATE_HWS(ahb_vid_cout0_clk, "ahb-vid-cout0", ahb_hws,
>>>> +                         0x5c0, BIT(3), 0);
>>>> +static SUNXI_CCU_GATE_HWS(ahb_vid_cout1_clk, "ahb-vid-cout1", ahb_hws,
>>>> +                         0x5c0, BIT(4), 0);
>>>> +static SUNXI_CCU_GATE_HWS(ahb_de_clk, "ahb-de", ahb_hws,
>>>> +                         0x5c0, BIT(5), 0);
>>>> +static SUNXI_CCU_GATE_HWS(ahb_npu_clk, "ahb-npu", ahb_hws,
>>>> +                         0x5c0, BIT(6), 0);
>>>> +static SUNXI_CCU_GATE_HWS(ahb_gpu0_clk, "ahb-gpu0", ahb_hws,
>>>> +                         0x5c0, BIT(7), 0);
>>>> +static SUNXI_CCU_GATE_HWS(ahb_serdes_clk, "ahb-serdes", ahb_hws,
>>>> +                         0x5c0, BIT(8), 0);
>>>> +static SUNXI_CCU_GATE_HWS(ahb_usb_sys_clk, "ahb-usb-sys", ahb_hws,
>>>> +                         0x5c0, BIT(9), 0);
>>>> +static SUNXI_CCU_GATE_HWS(ahb_msi_lite0_clk, "ahb-msi-lite0", ahb_hws,
>>>> +                         0x5c0, BIT(16), 0);
>>>> +static SUNXI_CCU_GATE_HWS(ahb_store_clk, "ahb-store", ahb_hws,
>>>> +                         0x5c0, BIT(24), CLK_IS_CRITICAL);
>>>> +static SUNXI_CCU_GATE_HWS(ahb_cpus_clk, "ahb-cpus", ahb_hws,
>>>> +                         0x5c0, BIT(28), CLK_IS_CRITICAL);
>>>
>>> I suspect these refer to a AHB-AHB bridge for the various subsystems shown
>>> in the memory map. That would explain why when the "ahb-store" clock is
>>> gated, the storage bits stop working.
>>>
>>> If that's the case, we should describe it as the parent of each storage
>>> peripheral bus gate's parent. Same would go for the other types. I haven't
>>> checked what the BSP does though.
>> 
>> As Norman mentioned in his reply, the vendor BSP also does not model
>> this hierarchy and instead models these gates as independent clocks
>> parented to the oscillator. The manual does not describe the hierarchy
>> either, so I don't think we have enough information to model it
>> differently at this point.
>
> Well, I wouldn't use the BSP as a good example on how to model the clock 
> tree, they have been very misguided in the past.

Understood. I will not rely on the BSP's clock hierarchy.

> What the BSP does is to add just more input/gate MBUS clocks for each 
> device, which is something I think we should avoid.
> To that regard using them as parent clocks for the existing gates, as 
> Chen-Yu suggested, sounds like a good idea: We keep a single clock for 
> the devices, but still can turn both clocks off (I think, not tested).

I tested bus-mmc0, bus-mmc2, bus-spi0, bus-ufs, bus-nand0, and
bus-spif individually. Disabling each bus gate made the corresponding
controller's MMIO registers inaccessible: reads either returned zero or
a fixed invalid value.

With those individual bus gates enabled, disabling ahb-store made the
MMIO registers of all those controllers inaccessible. Restoring
ahb-store made them accessible again.

Based on these results, I plan to make ahb-store the parent of the
following bus clocks in the next version:

  bus-nand0
  bus-mmc0
  bus-mmc1
  bus-mmc2
  bus-mmc3
  bus-spi0
  bus-spi1
  bus-spi2
  bus-spif
  bus-spi3
  bus-spi4
  bus-ufs

I directly tested MMC0, MMC2, SPI0, SPIF, NAND0, and UFS. The remaining
instances use the same type of bus gates in the same storage subsystem,
so I plan to model them in the same way.

For mbus-store, testing with MMC0 and UFS showed that disabling it
breaks the storage DMA paths.

Most of these storage controllers do not have dedicated MBUS gate
clocks, so there is no clock that can be parented to mbus-store to model
their DMA dependency. I therefore plan to keep mbus-store marked as
CLK_IS_CRITICAL, as we already do for the main mbus clock. For NAND,
which does have a dedicated mbus-nand gate, I will make mbus-store its
parent.

I also tested NVMe, but disabling either ahb-store or mbus-store had no
effect on it.

Does this approach look reasonable to you?

Best regards,
Junhui Liu

>
> Cheers,
> Andre
>
>> I will add comments explaining why ahb_store_clk, mbus_store_clk, and
>> ahb_cpus_clk are marked critical.
>> 
>>>
>>>> +static SUNXI_CCU_GATE_HWS(mbus_iommu0_clk, "mbus-iommu0", mbus_hws,
>>>> +                         0x5e0, BIT(0), 0);
>>>> +static SUNXI_CCU_GATE_HWS(mbus_iommu1_clk, "mbus-iommu1", mbus_hws,
>>>> +                         0x5e0, BIT(1), 0);
>>>> +static SUNXI_CCU_GATE_HWS(mbus_desys_clk, "mbus-desys", mbus_hws,
>>>> +                         0x5e0, BIT(11), 0);
>>>> +static SUNXI_CCU_GATE_HWS(mbus_ve_enc0_gate_clk, "mbus-ve-enc0-gate", mbus_hws,
>>>> +                         0x5e0, BIT(12), 0);
>>>> +static SUNXI_CCU_GATE_HWS(mbus_ve_dec0_gate_clk, "mbus-ve-dec0-gate", mbus_hws,
>>>> +                         0x5e0, BIT(14), 0);
>>>> +static SUNXI_CCU_GATE_HWS(mbus_gpu0_clk, "mbus-gpu0", mbus_hws,
>>>> +                         0x5e0, BIT(16), 0);
>>>> +static SUNXI_CCU_GATE_HWS(mbus_npu_clk, "mbus-npu", mbus_hws,
>>>> +                         0x5e0, BIT(18), 0);
>>>> +static SUNXI_CCU_GATE_HWS(mbus_vid_in_clk, "mbus-vid-in", mbus_hws,
>>>> +                         0x5e0, BIT(24), 0);
>>>> +static SUNXI_CCU_GATE_HWS(mbus_serdes_clk, "mbus-serdes", mbus_hws,
>>>> +                         0x5e0, BIT(28), 0);
>>>> +static SUNXI_CCU_GATE_HWS(mbus_msi_lite0_clk, "mbus-msi-lite0", mbus_hws,
>>>> +                         0x5e0, BIT(29), 0);
>>>> +static SUNXI_CCU_GATE_HWS(mbus_store_clk, "mbus-store", mbus_hws,
>>>> +                         0x5e0, BIT(30), CLK_IS_CRITICAL);
>>>
>>> Same thing for the MBUS clocks.
>>>
>>>> +static SUNXI_CCU_GATE_HWS(mbus_msi_lite2_clk, "mbus-msi-lite2", mbus_hws,
>>>> +                         0x5e0, BIT(31), 0);
>>>> +
>>>> +static SUNXI_CCU_GATE_HWS(mbus_dma0_clk, "mbus-dma0", mbus_hws,
>>>> +                         0x5e4, BIT(0), 0);
>>>> +static SUNXI_CCU_GATE_HWS(mbus_ve_enc0_clk, "mbus-ve-enc0", mbus_hws,
>>>> +                         0x5e4, BIT(1), 0);
>>>> +static SUNXI_CCU_GATE_HWS(mbus_ce_clk, "mbus-ce", mbus_hws,
>>>> +                         0x5e4, BIT(2), 0);
>>>> +static SUNXI_CCU_GATE_HWS(mbus_dma1_clk, "mbus-dma1", mbus_hws,
>>>> +                         0x5e4, BIT(3), 0);
>>>> +static SUNXI_CCU_GATE_HWS(mbus_nand_clk, "mbus-nand", mbus_hws,
>>>> +                         0x5e4, BIT(5), 0);
>>>> +static SUNXI_CCU_GATE_HWS(mbus_csi_clk, "mbus-csi", mbus_hws,
>>>> +                         0x5e4, BIT(8), 0);
>>>> +static SUNXI_CCU_GATE_HWS(mbus_isp_clk, "mbus-isp", mbus_hws,
>>>> +                         0x5e4, BIT(9), 0);
>>>> +static SUNXI_CCU_GATE_HWS(mbus_gmac0_clk, "mbus-gmac0", mbus_hws,
>>>> +                         0x5e4, BIT(11), 0);
>>>> +/* Undocumented, taken from the vendor kernel. */
>>>> +static SUNXI_CCU_GATE_HWS(mbus_gmac1_clk, "mbus-gmac1", mbus_hws,
>>>> +                         0x5e4, BIT(12), 0);
>>>> +static SUNXI_CCU_GATE_HWS(mbus_ve_dec0_clk, "mbus-ve-dec0", mbus_hws,
>>>> +                         0x5e4, BIT(18), 0);
>>>
>>> [...]
>>>
>>> The remaining definitions look correct (minus the vendor BSP ones which I
>>> couldn't check at this time).
>>>
>>> I didn't check the clock list additions.
>>>
>>> Consider this
>>>
>>> Reviewed-by: Chen-Yu Tsai <wens@kernel.org>
>>>
>> 
>> Thanks!
>> 
>>>
>>> We can change the AHB / MBUS clock parents later if we do figure it out.
>>>
>>>
>>> ChenYu
>>
  
Andre Przywara Oct. 6, 2026, 3:29 p.m. UTC | #6
Hi,

On 10/6/26 16:50, Junhui Liu wrote:
> Hi Andre, Chen-Yu,
> 
> I ran some tests and now have a better understanding of the clock
> hierarchy. Please see the results below.
> 
> On Mon Oct 5, 2026 at 5:17 PM CST, Andre Przywara wrote:
>> Hi,
>>
>> On 10/5/26 06:41, Junhui Liu wrote:
>>> Hi Chen-Yu,
>>>
>>> On Sun Oct 4, 2026 at 7:03 PM CST, Chen-Yu Tsai wrote:
>>>> On Tue, Sep 29, 2026 at 7:28 PM Junhui Liu <junhui.liu@pigmoral.tech> wrote:
>>>>>
>>>>> Add the bus clock gates that control access to the devices' register
>>>>> interface on the Allwinner A733 SoC. These clocks are typically
>>>>> single-bit controls in the BGR registers, covering UARTs, SPI, I2C, and
>>>>> various multimedia engines. It also includes bus gates for system
>>>>> components like the IOMMU and MSI-lite interfaces.
>>>>>
>>>>> Also mark the ahb-store, mbus-store and ahb-cpus clocks as critical.
>>>>> Disabling either store gate breaks access to boot/storage devices such
>>>>> as MMC and SPI NOR, while gating ahb-cpus hangs any access to the CPUS
>>>>> power domain registers when unused clocks are disabled.
>>>>>
>>>>> Tested-by: Jerome Brunet <jbrunet@baylibre.com>
>>>>> Reviewed-by: Andre Przywara <andre.przywara@arm.com>
>>>>> Signed-off-by: Junhui Liu <junhui.liu@pigmoral.tech>
>>>>> ---
>>>>>    drivers/clk/sunxi-ng/ccu-sun60i-a733.c | 492 ++++++++++++++++++++++++++++++++-
>>>>>    1 file changed, 491 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/drivers/clk/sunxi-ng/ccu-sun60i-a733.c b/drivers/clk/sunxi-ng/ccu-sun60i-a733.c
>>>>> index 1b2d4d36ec4c..b077e5d2f32c 100644
>>>>> --- a/drivers/clk/sunxi-ng/ccu-sun60i-a733.c
>>>>> +++ b/drivers/clk/sunxi-ng/ccu-sun60i-a733.c
>>>>> @@ -4,6 +4,10 @@
>>>>>     * Copyright (C) 2026 Junhui Liu <junhui.liu@pigmoral.tech>
>>>>>     * Based on the A523 CCU driver:
>>>>>     *   Copyright (C) 2023-2024 Arm Ltd.
>>>>> + *
>>>>> + * TODO: The real parents of some bus gates, including its-pcie0-aclk,
>>>>> + * msi-lite, npu, ufs, sgpio, lpc and i2spcm, are not documented in the
>>>>> + * manual. For now, follow the vendor BSP, which keeps them on hosc.
>>>>>     */
>>>>
>>>> [...]
>>>>
>>>>> @@ -510,9 +522,118 @@ static SUNXI_CCU_M_DATA_WITH_MUX_GATE_FEAT(mbus_clk, "mbus", mbus_parents, 0x588
>>>>>                                              BIT(31),     /* gate */
>>>>>                                              CLK_IS_CRITICAL,
>>>>>                                              CCU_FEATURE_UPDATE_BIT);
>>>>> +static const struct clk_hw *mbus_hws[] = { &mbus_clk.common.hw };
>>>>> +
>>>>> +static SUNXI_CCU_GATE_HWS(mbus_iommu0_sys_clk, "mbus-iommu0-sys", mbus_hws, 0x58c, BIT(0), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(apb_iommu0_sys_clk, "apb-iommu0-sys", apb0_hws, 0x58c, BIT(1), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(ahb_iommu0_sys_clk, "ahb-iommu0-sys", ahb_hws, 0x58c, BIT(2), 0);
>>>>> +
>>>>> +static SUNXI_CCU_GATE_DATA(bus_msi_lite0_clk, "bus-msi-lite0", hosc, 0x594, BIT(0), 0);
>>>>> +static SUNXI_CCU_GATE_DATA(bus_msi_lite1_clk, "bus-msi-lite1", hosc, 0x59c, BIT(0), 0);
>>>>> +static SUNXI_CCU_GATE_DATA(bus_msi_lite2_clk, "bus-msi-lite2", hosc, 0x5a4, BIT(0), 0);
>>>>> +
>>>>> +static SUNXI_CCU_GATE_HWS(mbus_iommu1_sys_clk, "mbus-iommu1-sys", mbus_hws, 0x5b4, BIT(0), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(apb_iommu1_sys_clk, "apb-iommu1-sys", apb0_hws, 0x5b4, BIT(1), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(ahb_iommu1_sys_clk, "ahb-iommu1-sys", ahb_hws, 0x5b4, BIT(2), 0);
>>>>
>>>>> +static SUNXI_CCU_GATE_HWS(ahb_ve_dec_clk, "ahb-ve-dec", ahb_hws,
>>>>> +                         0x5c0, BIT(0), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(ahb_ve_enc_clk, "ahb-ve-enc", ahb_hws,
>>>>> +                         0x5c0, BIT(1), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(ahb_vid_in_clk, "ahb-vid-in", ahb_hws,
>>>>> +                         0x5c0, BIT(2), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(ahb_vid_cout0_clk, "ahb-vid-cout0", ahb_hws,
>>>>> +                         0x5c0, BIT(3), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(ahb_vid_cout1_clk, "ahb-vid-cout1", ahb_hws,
>>>>> +                         0x5c0, BIT(4), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(ahb_de_clk, "ahb-de", ahb_hws,
>>>>> +                         0x5c0, BIT(5), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(ahb_npu_clk, "ahb-npu", ahb_hws,
>>>>> +                         0x5c0, BIT(6), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(ahb_gpu0_clk, "ahb-gpu0", ahb_hws,
>>>>> +                         0x5c0, BIT(7), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(ahb_serdes_clk, "ahb-serdes", ahb_hws,
>>>>> +                         0x5c0, BIT(8), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(ahb_usb_sys_clk, "ahb-usb-sys", ahb_hws,
>>>>> +                         0x5c0, BIT(9), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(ahb_msi_lite0_clk, "ahb-msi-lite0", ahb_hws,
>>>>> +                         0x5c0, BIT(16), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(ahb_store_clk, "ahb-store", ahb_hws,
>>>>> +                         0x5c0, BIT(24), CLK_IS_CRITICAL);
>>>>> +static SUNXI_CCU_GATE_HWS(ahb_cpus_clk, "ahb-cpus", ahb_hws,
>>>>> +                         0x5c0, BIT(28), CLK_IS_CRITICAL);
>>>>
>>>> I suspect these refer to a AHB-AHB bridge for the various subsystems shown
>>>> in the memory map. That would explain why when the "ahb-store" clock is
>>>> gated, the storage bits stop working.
>>>>
>>>> If that's the case, we should describe it as the parent of each storage
>>>> peripheral bus gate's parent. Same would go for the other types. I haven't
>>>> checked what the BSP does though.
>>>
>>> As Norman mentioned in his reply, the vendor BSP also does not model
>>> this hierarchy and instead models these gates as independent clocks
>>> parented to the oscillator. The manual does not describe the hierarchy
>>> either, so I don't think we have enough information to model it
>>> differently at this point.
>>
>> Well, I wouldn't use the BSP as a good example on how to model the clock
>> tree, they have been very misguided in the past.
> 
> Understood. I will not rely on the BSP's clock hierarchy.

Well, I meant more the BSP software/DT modelling, as in: this device 
know needs now two input clocks. As you mentioned, the manual does not 
describe every relation, so we need to rely on the BSP for knowing the 
parents. But ...

>> What the BSP does is to add just more input/gate MBUS clocks for each
>> device, which is something I think we should avoid.
>> To that regard using them as parent clocks for the existing gates, as
>> Chen-Yu suggested, sounds like a good idea: We keep a single clock for
>> the devices, but still can turn both clocks off (I think, not tested).
> 
> I tested bus-mmc0, bus-mmc2, bus-spi0, bus-ufs, bus-nand0, and
> bus-spif individually. Disabling each bus gate made the corresponding
> controller's MMIO registers inaccessible: reads either returned zero or
> a fixed invalid value.
> 
> With those individual bus gates enabled, disabling ahb-store made the
> MMIO registers of all those controllers inaccessible. Restoring
> ahb-store made them accessible again.

Ah, awesome, that's a good test, thanks for doing this! I thought that 
this clock is really about the data path, not the (MMIO register) 
control part, which is typically a separate low-speed bus (APB).
Since that is somewhat surprising, it's probably best to add a comment 
in the code about that.

> Based on these results, I plan to make ahb-store the parent of the
> following bus clocks in the next version:

Is ahb-store ungated at reset?

>    bus-nand0
>    bus-mmc0
>    bus-mmc1
>    bus-mmc2
>    bus-mmc3
>    bus-spi0
>    bus-spi1
>    bus-spi2
>    bus-spif
>    bus-spi3
>    bus-spi4
>    bus-ufs
> 
> I directly tested MMC0, MMC2, SPI0, SPIF, NAND0, and UFS. The remaining
> instances use the same type of bus gates in the same storage subsystem,
> so I plan to model them in the same way.
> 
> For mbus-store, testing with MMC0 and UFS showed that disabling it
> breaks the storage DMA paths.

When you say "storage DMA", you mean the actual DMA data path, using 
those chained descriptors? Does it work for PIO accesses, as U-Boot uses?

> Most of these storage controllers do not have dedicated MBUS gate
> clocks, so there is no clock that can be parented to mbus-store to model
> their DMA dependency.

Could this be like mbus-store -> ahb_store -> bus-{mmc,spi,ufs,nand}<n>?

Cheers,
Andre

> I therefore plan to keep mbus-store marked as
> CLK_IS_CRITICAL, as we already do for the main mbus clock. For NAND,
> which does have a dedicated mbus-nand gate, I will make mbus-store its
> parent.
> 
> I also tested NVMe, but disabling either ahb-store or mbus-store had no
> effect on it.
> 
> Does this approach look reasonable to you?
> 
> Best regards,
> Junhui Liu
> 
>>
>> Cheers,
>> Andre
>>
>>> I will add comments explaining why ahb_store_clk, mbus_store_clk, and
>>> ahb_cpus_clk are marked critical.
>>>
>>>>
>>>>> +static SUNXI_CCU_GATE_HWS(mbus_iommu0_clk, "mbus-iommu0", mbus_hws,
>>>>> +                         0x5e0, BIT(0), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(mbus_iommu1_clk, "mbus-iommu1", mbus_hws,
>>>>> +                         0x5e0, BIT(1), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(mbus_desys_clk, "mbus-desys", mbus_hws,
>>>>> +                         0x5e0, BIT(11), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(mbus_ve_enc0_gate_clk, "mbus-ve-enc0-gate", mbus_hws,
>>>>> +                         0x5e0, BIT(12), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(mbus_ve_dec0_gate_clk, "mbus-ve-dec0-gate", mbus_hws,
>>>>> +                         0x5e0, BIT(14), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(mbus_gpu0_clk, "mbus-gpu0", mbus_hws,
>>>>> +                         0x5e0, BIT(16), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(mbus_npu_clk, "mbus-npu", mbus_hws,
>>>>> +                         0x5e0, BIT(18), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(mbus_vid_in_clk, "mbus-vid-in", mbus_hws,
>>>>> +                         0x5e0, BIT(24), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(mbus_serdes_clk, "mbus-serdes", mbus_hws,
>>>>> +                         0x5e0, BIT(28), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(mbus_msi_lite0_clk, "mbus-msi-lite0", mbus_hws,
>>>>> +                         0x5e0, BIT(29), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(mbus_store_clk, "mbus-store", mbus_hws,
>>>>> +                         0x5e0, BIT(30), CLK_IS_CRITICAL);
>>>>
>>>> Same thing for the MBUS clocks.
>>>>
>>>>> +static SUNXI_CCU_GATE_HWS(mbus_msi_lite2_clk, "mbus-msi-lite2", mbus_hws,
>>>>> +                         0x5e0, BIT(31), 0);
>>>>> +
>>>>> +static SUNXI_CCU_GATE_HWS(mbus_dma0_clk, "mbus-dma0", mbus_hws,
>>>>> +                         0x5e4, BIT(0), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(mbus_ve_enc0_clk, "mbus-ve-enc0", mbus_hws,
>>>>> +                         0x5e4, BIT(1), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(mbus_ce_clk, "mbus-ce", mbus_hws,
>>>>> +                         0x5e4, BIT(2), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(mbus_dma1_clk, "mbus-dma1", mbus_hws,
>>>>> +                         0x5e4, BIT(3), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(mbus_nand_clk, "mbus-nand", mbus_hws,
>>>>> +                         0x5e4, BIT(5), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(mbus_csi_clk, "mbus-csi", mbus_hws,
>>>>> +                         0x5e4, BIT(8), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(mbus_isp_clk, "mbus-isp", mbus_hws,
>>>>> +                         0x5e4, BIT(9), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(mbus_gmac0_clk, "mbus-gmac0", mbus_hws,
>>>>> +                         0x5e4, BIT(11), 0);
>>>>> +/* Undocumented, taken from the vendor kernel. */
>>>>> +static SUNXI_CCU_GATE_HWS(mbus_gmac1_clk, "mbus-gmac1", mbus_hws,
>>>>> +                         0x5e4, BIT(12), 0);
>>>>> +static SUNXI_CCU_GATE_HWS(mbus_ve_dec0_clk, "mbus-ve-dec0", mbus_hws,
>>>>> +                         0x5e4, BIT(18), 0);
>>>>
>>>> [...]
>>>>
>>>> The remaining definitions look correct (minus the vendor BSP ones which I
>>>> couldn't check at this time).
>>>>
>>>> I didn't check the clock list additions.
>>>>
>>>> Consider this
>>>>
>>>> Reviewed-by: Chen-Yu Tsai <wens@kernel.org>
>>>>
>>>
>>> Thanks!
>>>
>>>>
>>>> We can change the AHB / MBUS clock parents later if we do figure it out.
>>>>
>>>>
>>>> ChenYu
>>>
  
Junhui Liu Oct. 6, 2026, 3:59 p.m. UTC | #7
Hi Andre,

On Tue Oct 6, 2026 at 11:29 PM CST, Andre Przywara wrote:
> Hi,
>
> On 10/6/26 16:50, Junhui Liu wrote:
>> Hi Andre, Chen-Yu,
>> 
>> I ran some tests and now have a better understanding of the clock
>> hierarchy. Please see the results below.
>> 
>> On Mon Oct 5, 2026 at 5:17 PM CST, Andre Przywara wrote:
>>> Hi,
>>>
>>> On 10/5/26 06:41, Junhui Liu wrote:
>>>> Hi Chen-Yu,
>>>>
>>>> On Sun Oct 4, 2026 at 7:03 PM CST, Chen-Yu Tsai wrote:
>>>>> On Tue, Sep 29, 2026 at 7:28 PM Junhui Liu <junhui.liu@pigmoral.tech> wrote:
>>>>>>
>>>>>> Add the bus clock gates that control access to the devices' register
>>>>>> interface on the Allwinner A733 SoC. These clocks are typically
>>>>>> single-bit controls in the BGR registers, covering UARTs, SPI, I2C, and
>>>>>> various multimedia engines. It also includes bus gates for system
>>>>>> components like the IOMMU and MSI-lite interfaces.
>>>>>>
>>>>>> Also mark the ahb-store, mbus-store and ahb-cpus clocks as critical.
>>>>>> Disabling either store gate breaks access to boot/storage devices such
>>>>>> as MMC and SPI NOR, while gating ahb-cpus hangs any access to the CPUS
>>>>>> power domain registers when unused clocks are disabled.
>>>>>>
>>>>>> Tested-by: Jerome Brunet <jbrunet@baylibre.com>
>>>>>> Reviewed-by: Andre Przywara <andre.przywara@arm.com>
>>>>>> Signed-off-by: Junhui Liu <junhui.liu@pigmoral.tech>
>>>>>> ---
>>>>>>    drivers/clk/sunxi-ng/ccu-sun60i-a733.c | 492 ++++++++++++++++++++++++++++++++-
>>>>>>    1 file changed, 491 insertions(+), 1 deletion(-)
>>>>>>
>>>>>> diff --git a/drivers/clk/sunxi-ng/ccu-sun60i-a733.c b/drivers/clk/sunxi-ng/ccu-sun60i-a733.c
>>>>>> index 1b2d4d36ec4c..b077e5d2f32c 100644
>>>>>> --- a/drivers/clk/sunxi-ng/ccu-sun60i-a733.c
>>>>>> +++ b/drivers/clk/sunxi-ng/ccu-sun60i-a733.c
>>>>>> @@ -4,6 +4,10 @@
>>>>>>     * Copyright (C) 2026 Junhui Liu <junhui.liu@pigmoral.tech>
>>>>>>     * Based on the A523 CCU driver:
>>>>>>     *   Copyright (C) 2023-2024 Arm Ltd.
>>>>>> + *
>>>>>> + * TODO: The real parents of some bus gates, including its-pcie0-aclk,
>>>>>> + * msi-lite, npu, ufs, sgpio, lpc and i2spcm, are not documented in the
>>>>>> + * manual. For now, follow the vendor BSP, which keeps them on hosc.
>>>>>>     */
>>>>>
>>>>> [...]
>>>>>
>>>>>> @@ -510,9 +522,118 @@ static SUNXI_CCU_M_DATA_WITH_MUX_GATE_FEAT(mbus_clk, "mbus", mbus_parents, 0x588
>>>>>>                                              BIT(31),     /* gate */
>>>>>>                                              CLK_IS_CRITICAL,
>>>>>>                                              CCU_FEATURE_UPDATE_BIT);
>>>>>> +static const struct clk_hw *mbus_hws[] = { &mbus_clk.common.hw };
>>>>>> +
>>>>>> +static SUNXI_CCU_GATE_HWS(mbus_iommu0_sys_clk, "mbus-iommu0-sys", mbus_hws, 0x58c, BIT(0), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(apb_iommu0_sys_clk, "apb-iommu0-sys", apb0_hws, 0x58c, BIT(1), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(ahb_iommu0_sys_clk, "ahb-iommu0-sys", ahb_hws, 0x58c, BIT(2), 0);
>>>>>> +
>>>>>> +static SUNXI_CCU_GATE_DATA(bus_msi_lite0_clk, "bus-msi-lite0", hosc, 0x594, BIT(0), 0);
>>>>>> +static SUNXI_CCU_GATE_DATA(bus_msi_lite1_clk, "bus-msi-lite1", hosc, 0x59c, BIT(0), 0);
>>>>>> +static SUNXI_CCU_GATE_DATA(bus_msi_lite2_clk, "bus-msi-lite2", hosc, 0x5a4, BIT(0), 0);
>>>>>> +
>>>>>> +static SUNXI_CCU_GATE_HWS(mbus_iommu1_sys_clk, "mbus-iommu1-sys", mbus_hws, 0x5b4, BIT(0), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(apb_iommu1_sys_clk, "apb-iommu1-sys", apb0_hws, 0x5b4, BIT(1), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(ahb_iommu1_sys_clk, "ahb-iommu1-sys", ahb_hws, 0x5b4, BIT(2), 0);
>>>>>
>>>>>> +static SUNXI_CCU_GATE_HWS(ahb_ve_dec_clk, "ahb-ve-dec", ahb_hws,
>>>>>> +                         0x5c0, BIT(0), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(ahb_ve_enc_clk, "ahb-ve-enc", ahb_hws,
>>>>>> +                         0x5c0, BIT(1), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(ahb_vid_in_clk, "ahb-vid-in", ahb_hws,
>>>>>> +                         0x5c0, BIT(2), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(ahb_vid_cout0_clk, "ahb-vid-cout0", ahb_hws,
>>>>>> +                         0x5c0, BIT(3), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(ahb_vid_cout1_clk, "ahb-vid-cout1", ahb_hws,
>>>>>> +                         0x5c0, BIT(4), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(ahb_de_clk, "ahb-de", ahb_hws,
>>>>>> +                         0x5c0, BIT(5), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(ahb_npu_clk, "ahb-npu", ahb_hws,
>>>>>> +                         0x5c0, BIT(6), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(ahb_gpu0_clk, "ahb-gpu0", ahb_hws,
>>>>>> +                         0x5c0, BIT(7), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(ahb_serdes_clk, "ahb-serdes", ahb_hws,
>>>>>> +                         0x5c0, BIT(8), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(ahb_usb_sys_clk, "ahb-usb-sys", ahb_hws,
>>>>>> +                         0x5c0, BIT(9), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(ahb_msi_lite0_clk, "ahb-msi-lite0", ahb_hws,
>>>>>> +                         0x5c0, BIT(16), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(ahb_store_clk, "ahb-store", ahb_hws,
>>>>>> +                         0x5c0, BIT(24), CLK_IS_CRITICAL);
>>>>>> +static SUNXI_CCU_GATE_HWS(ahb_cpus_clk, "ahb-cpus", ahb_hws,
>>>>>> +                         0x5c0, BIT(28), CLK_IS_CRITICAL);
>>>>>
>>>>> I suspect these refer to a AHB-AHB bridge for the various subsystems shown
>>>>> in the memory map. That would explain why when the "ahb-store" clock is
>>>>> gated, the storage bits stop working.
>>>>>
>>>>> If that's the case, we should describe it as the parent of each storage
>>>>> peripheral bus gate's parent. Same would go for the other types. I haven't
>>>>> checked what the BSP does though.
>>>>
>>>> As Norman mentioned in his reply, the vendor BSP also does not model
>>>> this hierarchy and instead models these gates as independent clocks
>>>> parented to the oscillator. The manual does not describe the hierarchy
>>>> either, so I don't think we have enough information to model it
>>>> differently at this point.
>>>
>>> Well, I wouldn't use the BSP as a good example on how to model the clock
>>> tree, they have been very misguided in the past.
>> 
>> Understood. I will not rely on the BSP's clock hierarchy.
>
> Well, I meant more the BSP software/DT modelling, as in: this device 
> know needs now two input clocks. As you mentioned, the manual does not 
> describe every relation, so we need to rely on the BSP for knowing the 
> parents. But ...

Got it, thanks for clarifying.

>
>>> What the BSP does is to add just more input/gate MBUS clocks for each
>>> device, which is something I think we should avoid.
>>> To that regard using them as parent clocks for the existing gates, as
>>> Chen-Yu suggested, sounds like a good idea: We keep a single clock for
>>> the devices, but still can turn both clocks off (I think, not tested).
>> 
>> I tested bus-mmc0, bus-mmc2, bus-spi0, bus-ufs, bus-nand0, and
>> bus-spif individually. Disabling each bus gate made the corresponding
>> controller's MMIO registers inaccessible: reads either returned zero or
>> a fixed invalid value.
>> 
>> With those individual bus gates enabled, disabling ahb-store made the
>> MMIO registers of all those controllers inaccessible. Restoring
>> ahb-store made them accessible again.
>
> Ah, awesome, that's a good test, thanks for doing this! I thought that 
> this clock is really about the data path, not the (MMIO register) 
> control part, which is typically a separate low-speed bus (APB).
> Since that is somewhat surprising, it's probably best to add a comment 
> in the code about that.

Okay, I will add a comment.

>
>> Based on these results, I plan to make ahb-store the parent of the
>> following bus clocks in the next version:
>
> Is ahb-store ungated at reset?

Yes. Both the manual and a read through FEL before loading any external
firmware confirmed that ahb-store is ungated at reset. The same is true
for mbus-store.

>
>>    bus-nand0
>>    bus-mmc0
>>    bus-mmc1
>>    bus-mmc2
>>    bus-mmc3
>>    bus-spi0
>>    bus-spi1
>>    bus-spi2
>>    bus-spif
>>    bus-spi3
>>    bus-spi4
>>    bus-ufs
>> 
>> I directly tested MMC0, MMC2, SPI0, SPIF, NAND0, and UFS. The remaining
>> instances use the same type of bus gates in the same storage subsystem,
>> so I plan to model them in the same way.
>> 
>> For mbus-store, testing with MMC0 and UFS showed that disabling it
>> breaks the storage DMA paths.
>
> When you say "storage DMA", you mean the actual DMA data path, using 
> those chained descriptors? Does it work for PIO accesses, as U-Boot uses?

Yes, I mean the actual DMA data path.

In my tests, MMC and SPI PIO transfers in U-Boot still worked with
mbus-store disabled, and the controller MMIO registers remained
accessible.

>
>> Most of these storage controllers do not have dedicated MBUS gate
>> clocks, so there is no clock that can be parented to mbus-store to model
>> their DMA dependency.
>
> Could this be like mbus-store -> ahb_store -> bus-{mmc,spi,ufs,nand}<n>?

I don't think that would reflect the hardware topology. mbus-store is
fed by mbus, while ahb-store is fed by ahb. Chaining them would also
make the AHB bus gates inherit the MBUS rate in the CCF model.

I would therefore prefer to keep mbus-store marked as CLK_IS_CRITICAL,
or use a better way to model this dependency if there is one.

Best regards,
Junhui Liu

>
> Cheers,
> Andre
>
>> I therefore plan to keep mbus-store marked as
>> CLK_IS_CRITICAL, as we already do for the main mbus clock. For NAND,
>> which does have a dedicated mbus-nand gate, I will make mbus-store its
>> parent.
>> 
>> I also tested NVMe, but disabling either ahb-store or mbus-store had no
>> effect on it.
>> 
>> Does this approach look reasonable to you?
>> 
>> Best regards,
>> Junhui Liu
>> 
>>>
>>> Cheers,
>>> Andre
>>>
>>>> I will add comments explaining why ahb_store_clk, mbus_store_clk, and
>>>> ahb_cpus_clk are marked critical.
>>>>
>>>>>
>>>>>> +static SUNXI_CCU_GATE_HWS(mbus_iommu0_clk, "mbus-iommu0", mbus_hws,
>>>>>> +                         0x5e0, BIT(0), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(mbus_iommu1_clk, "mbus-iommu1", mbus_hws,
>>>>>> +                         0x5e0, BIT(1), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(mbus_desys_clk, "mbus-desys", mbus_hws,
>>>>>> +                         0x5e0, BIT(11), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(mbus_ve_enc0_gate_clk, "mbus-ve-enc0-gate", mbus_hws,
>>>>>> +                         0x5e0, BIT(12), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(mbus_ve_dec0_gate_clk, "mbus-ve-dec0-gate", mbus_hws,
>>>>>> +                         0x5e0, BIT(14), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(mbus_gpu0_clk, "mbus-gpu0", mbus_hws,
>>>>>> +                         0x5e0, BIT(16), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(mbus_npu_clk, "mbus-npu", mbus_hws,
>>>>>> +                         0x5e0, BIT(18), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(mbus_vid_in_clk, "mbus-vid-in", mbus_hws,
>>>>>> +                         0x5e0, BIT(24), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(mbus_serdes_clk, "mbus-serdes", mbus_hws,
>>>>>> +                         0x5e0, BIT(28), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(mbus_msi_lite0_clk, "mbus-msi-lite0", mbus_hws,
>>>>>> +                         0x5e0, BIT(29), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(mbus_store_clk, "mbus-store", mbus_hws,
>>>>>> +                         0x5e0, BIT(30), CLK_IS_CRITICAL);
>>>>>
>>>>> Same thing for the MBUS clocks.
>>>>>
>>>>>> +static SUNXI_CCU_GATE_HWS(mbus_msi_lite2_clk, "mbus-msi-lite2", mbus_hws,
>>>>>> +                         0x5e0, BIT(31), 0);
>>>>>> +
>>>>>> +static SUNXI_CCU_GATE_HWS(mbus_dma0_clk, "mbus-dma0", mbus_hws,
>>>>>> +                         0x5e4, BIT(0), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(mbus_ve_enc0_clk, "mbus-ve-enc0", mbus_hws,
>>>>>> +                         0x5e4, BIT(1), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(mbus_ce_clk, "mbus-ce", mbus_hws,
>>>>>> +                         0x5e4, BIT(2), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(mbus_dma1_clk, "mbus-dma1", mbus_hws,
>>>>>> +                         0x5e4, BIT(3), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(mbus_nand_clk, "mbus-nand", mbus_hws,
>>>>>> +                         0x5e4, BIT(5), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(mbus_csi_clk, "mbus-csi", mbus_hws,
>>>>>> +                         0x5e4, BIT(8), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(mbus_isp_clk, "mbus-isp", mbus_hws,
>>>>>> +                         0x5e4, BIT(9), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(mbus_gmac0_clk, "mbus-gmac0", mbus_hws,
>>>>>> +                         0x5e4, BIT(11), 0);
>>>>>> +/* Undocumented, taken from the vendor kernel. */
>>>>>> +static SUNXI_CCU_GATE_HWS(mbus_gmac1_clk, "mbus-gmac1", mbus_hws,
>>>>>> +                         0x5e4, BIT(12), 0);
>>>>>> +static SUNXI_CCU_GATE_HWS(mbus_ve_dec0_clk, "mbus-ve-dec0", mbus_hws,
>>>>>> +                         0x5e4, BIT(18), 0);
>>>>>
>>>>> [...]
>>>>>
>>>>> The remaining definitions look correct (minus the vendor BSP ones which I
>>>>> couldn't check at this time).
>>>>>
>>>>> I didn't check the clock list additions.
>>>>>
>>>>> Consider this
>>>>>
>>>>> Reviewed-by: Chen-Yu Tsai <wens@kernel.org>
>>>>>
>>>>
>>>> Thanks!
>>>>
>>>>>
>>>>> We can change the AHB / MBUS clock parents later if we do figure it out.
>>>>>
>>>>>
>>>>> ChenYu
>>>>
  

Patch

diff --git a/drivers/clk/sunxi-ng/ccu-sun60i-a733.c b/drivers/clk/sunxi-ng/ccu-sun60i-a733.c
index 1b2d4d36ec4c..b077e5d2f32c 100644
--- a/drivers/clk/sunxi-ng/ccu-sun60i-a733.c
+++ b/drivers/clk/sunxi-ng/ccu-sun60i-a733.c
@@ -4,6 +4,10 @@ 
  * Copyright (C) 2026 Junhui Liu <junhui.liu@pigmoral.tech>
  * Based on the A523 CCU driver:
  *   Copyright (C) 2023-2024 Arm Ltd.
+ *
+ * TODO: The real parents of some bus gates, including its-pcie0-aclk,
+ * msi-lite, npu, ufs, sgpio, lpc and i2spcm, are not documented in the
+ * manual. For now, follow the vendor BSP, which keeps them on hosc.
  */
 
 #include <linux/clk-provider.h>
@@ -447,16 +451,19 @@  static SUNXI_CCU_M_DATA_WITH_MUX(ahb_clk, "ahb", ahb_apb_parents, 0x500,
 				 0, 5,		/* M */
 				 24, 2,		/* mux */
 				 0);
+static const struct clk_hw *ahb_hws[] = { &ahb_clk.common.hw };
 
 static SUNXI_CCU_M_DATA_WITH_MUX(apb0_clk, "apb0", ahb_apb_parents, 0x510,
 				 0, 5,		/* M */
 				 24, 2,		/* mux */
 				 0);
+static const struct clk_hw *apb0_hws[] = { &apb0_clk.common.hw };
 
 static SUNXI_CCU_M_DATA_WITH_MUX(apb1_clk, "apb1", ahb_apb_parents, 0x518,
 				 0, 5,		/* M */
 				 24, 2,		/* mux */
 				 0);
+static const struct clk_hw *apb1_hws[] = { &apb1_clk.common.hw };
 
 static const struct clk_parent_data apb_uart_parents[] = {
 	{ .hw = &sys_24M_clk.hw },
@@ -469,6 +476,9 @@  static SUNXI_CCU_M_DATA_WITH_MUX(apb_uart_clk, "apb-uart", apb_uart_parents, 0x5
 				 0, 5,		/* M */
 				 24, 3,		/* mux */
 				 0);
+static const struct clk_hw *apb_uart_hws[] = {
+	&apb_uart_clk.common.hw
+};
 
 static const struct clk_parent_data trace_parents[] = {
 	{ .hw = &sys_24M_clk.hw },
@@ -496,6 +506,8 @@  static SUNXI_CCU_M_DATA_WITH_MUX_GATE(gic_clk, "gic", gic_parents, 0x560,
 				      BIT(31),	/* gate */
 				      CLK_IS_CRITICAL);
 
+static SUNXI_CCU_GATE_DATA(bus_its_pcie0_aclk_clk, "bus-its-pcie0-aclk", hosc, 0x574, BIT(1), 0);
+
 static const struct clk_parent_data mbus_parents[] = {
 	{ .hw = &sys_24M_clk.hw },
 	{ .hw = &pll_periph1_600M_clk.hw },
@@ -510,9 +522,118 @@  static SUNXI_CCU_M_DATA_WITH_MUX_GATE_FEAT(mbus_clk, "mbus", mbus_parents, 0x588
 					   BIT(31),	/* gate */
 					   CLK_IS_CRITICAL,
 					   CCU_FEATURE_UPDATE_BIT);
+static const struct clk_hw *mbus_hws[] = { &mbus_clk.common.hw };
+
+static SUNXI_CCU_GATE_HWS(mbus_iommu0_sys_clk, "mbus-iommu0-sys", mbus_hws, 0x58c, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(apb_iommu0_sys_clk, "apb-iommu0-sys", apb0_hws, 0x58c, BIT(1), 0);
+static SUNXI_CCU_GATE_HWS(ahb_iommu0_sys_clk, "ahb-iommu0-sys", ahb_hws, 0x58c, BIT(2), 0);
+
+static SUNXI_CCU_GATE_DATA(bus_msi_lite0_clk, "bus-msi-lite0", hosc, 0x594, BIT(0), 0);
+static SUNXI_CCU_GATE_DATA(bus_msi_lite1_clk, "bus-msi-lite1", hosc, 0x59c, BIT(0), 0);
+static SUNXI_CCU_GATE_DATA(bus_msi_lite2_clk, "bus-msi-lite2", hosc, 0x5a4, BIT(0), 0);
+
+static SUNXI_CCU_GATE_HWS(mbus_iommu1_sys_clk, "mbus-iommu1-sys", mbus_hws, 0x5b4, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(apb_iommu1_sys_clk, "apb-iommu1-sys", apb0_hws, 0x5b4, BIT(1), 0);
+static SUNXI_CCU_GATE_HWS(ahb_iommu1_sys_clk, "ahb-iommu1-sys", ahb_hws, 0x5b4, BIT(2), 0);
+
+static SUNXI_CCU_GATE_HWS(ahb_ve_dec_clk, "ahb-ve-dec", ahb_hws,
+			  0x5c0, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(ahb_ve_enc_clk, "ahb-ve-enc", ahb_hws,
+			  0x5c0, BIT(1), 0);
+static SUNXI_CCU_GATE_HWS(ahb_vid_in_clk, "ahb-vid-in", ahb_hws,
+			  0x5c0, BIT(2), 0);
+static SUNXI_CCU_GATE_HWS(ahb_vid_cout0_clk, "ahb-vid-cout0", ahb_hws,
+			  0x5c0, BIT(3), 0);
+static SUNXI_CCU_GATE_HWS(ahb_vid_cout1_clk, "ahb-vid-cout1", ahb_hws,
+			  0x5c0, BIT(4), 0);
+static SUNXI_CCU_GATE_HWS(ahb_de_clk, "ahb-de", ahb_hws,
+			  0x5c0, BIT(5), 0);
+static SUNXI_CCU_GATE_HWS(ahb_npu_clk, "ahb-npu", ahb_hws,
+			  0x5c0, BIT(6), 0);
+static SUNXI_CCU_GATE_HWS(ahb_gpu0_clk, "ahb-gpu0", ahb_hws,
+			  0x5c0, BIT(7), 0);
+static SUNXI_CCU_GATE_HWS(ahb_serdes_clk, "ahb-serdes", ahb_hws,
+			  0x5c0, BIT(8), 0);
+static SUNXI_CCU_GATE_HWS(ahb_usb_sys_clk, "ahb-usb-sys", ahb_hws,
+			  0x5c0, BIT(9), 0);
+static SUNXI_CCU_GATE_HWS(ahb_msi_lite0_clk, "ahb-msi-lite0", ahb_hws,
+			  0x5c0, BIT(16), 0);
+static SUNXI_CCU_GATE_HWS(ahb_store_clk, "ahb-store", ahb_hws,
+			  0x5c0, BIT(24), CLK_IS_CRITICAL);
+static SUNXI_CCU_GATE_HWS(ahb_cpus_clk, "ahb-cpus", ahb_hws,
+			  0x5c0, BIT(28), CLK_IS_CRITICAL);
+
+static SUNXI_CCU_GATE_HWS(mbus_iommu0_clk, "mbus-iommu0", mbus_hws,
+			  0x5e0, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(mbus_iommu1_clk, "mbus-iommu1", mbus_hws,
+			  0x5e0, BIT(1), 0);
+static SUNXI_CCU_GATE_HWS(mbus_desys_clk, "mbus-desys", mbus_hws,
+			  0x5e0, BIT(11), 0);
+static SUNXI_CCU_GATE_HWS(mbus_ve_enc0_gate_clk, "mbus-ve-enc0-gate", mbus_hws,
+			  0x5e0, BIT(12), 0);
+static SUNXI_CCU_GATE_HWS(mbus_ve_dec0_gate_clk, "mbus-ve-dec0-gate", mbus_hws,
+			  0x5e0, BIT(14), 0);
+static SUNXI_CCU_GATE_HWS(mbus_gpu0_clk, "mbus-gpu0", mbus_hws,
+			  0x5e0, BIT(16), 0);
+static SUNXI_CCU_GATE_HWS(mbus_npu_clk, "mbus-npu", mbus_hws,
+			  0x5e0, BIT(18), 0);
+static SUNXI_CCU_GATE_HWS(mbus_vid_in_clk, "mbus-vid-in", mbus_hws,
+			  0x5e0, BIT(24), 0);
+static SUNXI_CCU_GATE_HWS(mbus_serdes_clk, "mbus-serdes", mbus_hws,
+			  0x5e0, BIT(28), 0);
+static SUNXI_CCU_GATE_HWS(mbus_msi_lite0_clk, "mbus-msi-lite0", mbus_hws,
+			  0x5e0, BIT(29), 0);
+static SUNXI_CCU_GATE_HWS(mbus_store_clk, "mbus-store", mbus_hws,
+			  0x5e0, BIT(30), CLK_IS_CRITICAL);
+static SUNXI_CCU_GATE_HWS(mbus_msi_lite2_clk, "mbus-msi-lite2", mbus_hws,
+			  0x5e0, BIT(31), 0);
+
+static SUNXI_CCU_GATE_HWS(mbus_dma0_clk, "mbus-dma0", mbus_hws,
+			  0x5e4, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(mbus_ve_enc0_clk, "mbus-ve-enc0", mbus_hws,
+			  0x5e4, BIT(1), 0);
+static SUNXI_CCU_GATE_HWS(mbus_ce_clk, "mbus-ce", mbus_hws,
+			  0x5e4, BIT(2), 0);
+static SUNXI_CCU_GATE_HWS(mbus_dma1_clk, "mbus-dma1", mbus_hws,
+			  0x5e4, BIT(3), 0);
+static SUNXI_CCU_GATE_HWS(mbus_nand_clk, "mbus-nand", mbus_hws,
+			  0x5e4, BIT(5), 0);
+static SUNXI_CCU_GATE_HWS(mbus_csi_clk, "mbus-csi", mbus_hws,
+			  0x5e4, BIT(8), 0);
+static SUNXI_CCU_GATE_HWS(mbus_isp_clk, "mbus-isp", mbus_hws,
+			  0x5e4, BIT(9), 0);
+static SUNXI_CCU_GATE_HWS(mbus_gmac0_clk, "mbus-gmac0", mbus_hws,
+			  0x5e4, BIT(11), 0);
+/* Undocumented, taken from the vendor kernel. */
+static SUNXI_CCU_GATE_HWS(mbus_gmac1_clk, "mbus-gmac1", mbus_hws,
+			  0x5e4, BIT(12), 0);
+static SUNXI_CCU_GATE_HWS(mbus_ve_dec0_clk, "mbus-ve-dec0", mbus_hws,
+			  0x5e4, BIT(18), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_dma0_clk, "bus-dma0", ahb_hws,
+			  0x704, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_dma1_clk, "bus-dma1", ahb_hws,
+			  0x70c, BIT(0), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_spinlock_clk, "bus-spinlock", ahb_hws,
+			  0x724, BIT(0), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_msgbox0_clk, "bus-msgbox0", ahb_hws,
+			  0x744, BIT(0), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_pwm0_clk, "bus-pwm0", apb0_hws,
+			  0x784, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_pwm1_clk, "bus-pwm1", apb0_hws,
+			  0x78c, BIT(0), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_dbg_clk, "bus-dbg", sys_24M_hws,
+			  0x7a4, BIT(0), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_sysdap_clk, "bus-sysdap", apb1_hws,
+			  0x7ac, BIT(0), 0);
 
 /**************************************************************************
- *                          mod clocks                                    *
+ *                          mod clocks with gates                         *
  **************************************************************************/
 
 static const struct clk_parent_data timer_parents[] = {
@@ -572,6 +693,7 @@  static SUNXI_CCU_P_DATA_WITH_MUX_GATE(timer9_clk, "timer9", timer_parents, 0x824
 				      24, 3,		/* mux */
 				      BIT(31),		/* gate */
 				      0);
+static SUNXI_CCU_GATE_HWS(bus_timer_clk, "bus-timer", ahb_hws, 0x850, BIT(0), 0);
 
 /* Undocumented, taken from the vendor kernel. */
 static const struct clk_parent_data avs_parents[] = {
@@ -597,6 +719,7 @@  static SUNXI_CCU_M_HW_WITH_MUX_GATE(de0_clk, "de0", de_parents, 0xa00,
 				    24, 3,	/* mux */
 				    BIT(31),	/* gate */
 				    CLK_SET_RATE_PARENT);
+static SUNXI_CCU_GATE_HWS(bus_de0_clk, "bus-de0", ahb_hws, 0xa04, BIT(0), 0);
 
 static const struct clk_hw *di_parents[] = {
 	&pll_periph0_600M_clk.hw,
@@ -610,6 +733,7 @@  static SUNXI_CCU_M_HW_WITH_MUX_GATE(di_clk, "di", di_parents, 0xa20,
 				    24, 3,	/* mux */
 				    BIT(31),	/* gate */
 				    CLK_SET_RATE_PARENT);
+static SUNXI_CCU_GATE_HWS(bus_di_clk, "bus-di", ahb_hws, 0xa24, BIT(0), 0);
 
 static const struct clk_hw *g2d_parents[] = {
 	&pll_periph0_400M_clk.hw,
@@ -622,6 +746,7 @@  static SUNXI_CCU_M_HW_WITH_MUX_GATE(g2d_clk, "g2d", g2d_parents, 0xa40,
 				    24, 3,	/* mux */
 				    BIT(31),	/* gate */
 				    CLK_SET_RATE_PARENT);
+static SUNXI_CCU_GATE_HWS(bus_g2d_clk, "bus-g2d", ahb_hws, 0xa44, BIT(0), 0);
 
 static const struct clk_hw *eink_parents[] = {
 	&pll_periph0_480M_clk.common.hw,
@@ -645,6 +770,7 @@  static SUNXI_CCU_M_HW_WITH_MUX_GATE(eink_panel_clk, "eink-panel", eink_panel_par
 				    24, 3,	/* mux */
 				    BIT(31),	/* gate */
 				    CLK_SET_RATE_PARENT);
+static SUNXI_CCU_GATE_HWS(bus_eink_clk, "bus-eink", ahb_hws, 0xa6c, BIT(0), 0);
 
 static const struct clk_hw *ve_enc_parents[] = {
 	&pll_ve0_clk.common.hw,
@@ -676,6 +802,9 @@  static SUNXI_CCU_M_HW_WITH_MUX_GATE(ve_dec0_clk, "ve-dec0", ve_dec_parents, 0xa8
 				    BIT(31),	/* gate */
 				    CLK_SET_RATE_PARENT);
 
+static SUNXI_CCU_GATE_HWS(bus_ve_enc0_clk, "bus-ve-enc0", ahb_hws, 0xa8c, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_ve_dec0_clk, "bus-ve-dec0", ahb_hws, 0xa8c, BIT(2), 0);
+
 static const struct clk_hw *ce_parents[] = {
 	&sys_24M_clk.hw,
 	&pll_periph0_400M_clk.hw,
@@ -686,6 +815,8 @@  static SUNXI_CCU_M_HW_WITH_MUX_GATE(ce_clk, "ce", ce_parents, 0xac0,
 				    24, 3,	/* mux */
 				    BIT(31),	/* gate */
 				    0);
+static SUNXI_CCU_GATE_HWS(bus_ce_clk, "bus-ce", ahb_hws, 0xac4, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_ce_sys_clk, "bus-ce-sys", ahb_hws, 0xac4, BIT(1), 0);
 
 static const struct clk_hw *npu_parents[] = {
 	&pll_npu_clk.common.hw,
@@ -701,6 +832,7 @@  static SUNXI_CCU_M_HW_WITH_MUX_GATE(npu_clk, "npu", npu_parents, 0xb00,
 				    24, 3,	/* mux */
 				    BIT(31),	/* gate */
 				    0);
+static SUNXI_CCU_GATE_DATA(bus_npu_clk, "bus-npu", hosc, 0xb04, BIT(0), 0);
 
 /*
  * GPU_CLK = ClockSource * ((16 - M) / 16)
@@ -733,6 +865,7 @@  static struct ccu_div gpu0_clk = {
 							   &ccu_div_ops, 0),
 	}
 };
+static SUNXI_CCU_GATE_HWS(bus_gpu0_clk, "bus-gpu0", ahb_hws, 0xb24, BIT(0), 0);
 
 static const struct clk_parent_data dram_parents[] = {
 	{ .hw = &pll_ddr_clk.common.hw, },
@@ -747,6 +880,8 @@  static SUNXI_CCU_M_DATA_WITH_MUX_GATE_FEAT(dram0_clk, "dram0", dram_parents, 0xc
 					   BIT(31),	/* gate */
 					   CLK_IS_CRITICAL,
 					   CCU_FEATURE_UPDATE_BIT);
+static SUNXI_CCU_GATE_HWS(bus_dram0_clk, "bus-dram0", ahb_hws, 0xc0c,
+			  BIT(0), CLK_IS_CRITICAL);
 
 static const struct clk_parent_data nand_mmc_parents[] = {
 	{ .hw = &sys_24M_clk.hw, },
@@ -765,6 +900,7 @@  static SUNXI_CCU_M_DATA_WITH_MUX_GATE(nand0_clk1_clk, "nand0-clk1", nand_mmc_par
 				      24, 3,	/* mux */
 				      BIT(31),	/* gate */
 				      0);
+static SUNXI_CCU_GATE_HWS(bus_nand0_clk, "bus-nand0", ahb_hws, 0xc8c, BIT(0), 0);
 
 static SUNXI_CCU_MP_MUX_GATE_POSTDIV_DUALDIV(mmc0_clk, "mmc0", nand_mmc_parents, 0xd00,
 					     0, 5,	/* M */
@@ -773,6 +909,8 @@  static SUNXI_CCU_MP_MUX_GATE_POSTDIV_DUALDIV(mmc0_clk, "mmc0", nand_mmc_parents,
 					     BIT(31),	/* gate */
 					     2,		/* post div */
 					     0);
+static SUNXI_CCU_GATE_HWS(bus_mmc0_clk, "bus-mmc0", ahb_hws, 0xd0c, BIT(0), 0);
+
 static SUNXI_CCU_MP_MUX_GATE_POSTDIV_DUALDIV(mmc1_clk, "mmc1", nand_mmc_parents, 0xd10,
 					     0, 5,	/* M */
 					     8, 5,	/* P */
@@ -780,6 +918,7 @@  static SUNXI_CCU_MP_MUX_GATE_POSTDIV_DUALDIV(mmc1_clk, "mmc1", nand_mmc_parents,
 					     BIT(31),	/* gate */
 					     2,		/* post div */
 					     0);
+static SUNXI_CCU_GATE_HWS(bus_mmc1_clk, "bus-mmc1", ahb_hws, 0xd1c, BIT(0), 0);
 
 static const struct clk_parent_data mmc2_mmc3_parents[] = {
 	{ .hw = &sys_24M_clk.hw, },
@@ -795,6 +934,8 @@  static SUNXI_CCU_MP_MUX_GATE_POSTDIV_DUALDIV(mmc2_clk, "mmc2", mmc2_mmc3_parents
 					     BIT(31),	/* gate */
 					     2,		/* post div */
 					     0);
+static SUNXI_CCU_GATE_HWS(bus_mmc2_clk, "bus-mmc2", ahb_hws, 0xd2c, BIT(0), 0);
+
 static SUNXI_CCU_MP_MUX_GATE_POSTDIV_DUALDIV(mmc3_clk, "mmc3", mmc2_mmc3_parents, 0xd30,
 					     0, 5,	/* M */
 					     8, 5,	/* P */
@@ -802,6 +943,7 @@  static SUNXI_CCU_MP_MUX_GATE_POSTDIV_DUALDIV(mmc3_clk, "mmc3", mmc2_mmc3_parents
 					     BIT(31),	/* gate */
 					     2,		/* post div */
 					     0);
+static SUNXI_CCU_GATE_HWS(bus_mmc3_clk, "bus-mmc3", ahb_hws, 0xd3c, BIT(0), 0);
 
 static const struct clk_hw *ufs_axi_parents[] = {
 	&pll_periph0_300M_clk.hw,
@@ -822,6 +964,29 @@  static SUNXI_CCU_M_DATA_WITH_MUX_GATE(ufs_cfg_clk, "ufs-cfg", ufs_cfg_parents, 0
 				      24, 3,	/* mux */
 				      BIT(31),	/* gate */
 				      0);
+static SUNXI_CCU_GATE_DATA(bus_ufs_clk, "bus-ufs", hosc, 0xd8c, BIT(0), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_uart0_clk, "bus-uart0", apb_uart_hws, 0xe00, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_uart1_clk, "bus-uart1", apb_uart_hws, 0xe04, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_uart2_clk, "bus-uart2", apb_uart_hws, 0xe08, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_uart3_clk, "bus-uart3", apb_uart_hws, 0xe0c, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_uart4_clk, "bus-uart4", apb_uart_hws, 0xe10, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_uart5_clk, "bus-uart5", apb_uart_hws, 0xe14, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_uart6_clk, "bus-uart6", apb_uart_hws, 0xe18, BIT(0), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_i2c0_clk, "bus-i2c0", apb1_hws, 0xe80, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_i2c1_clk, "bus-i2c1", apb1_hws, 0xe84, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_i2c2_clk, "bus-i2c2", apb1_hws, 0xe88, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_i2c3_clk, "bus-i2c3", apb1_hws, 0xe8c, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_i2c4_clk, "bus-i2c4", apb1_hws, 0xe90, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_i2c5_clk, "bus-i2c5", apb1_hws, 0xe94, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_i2c6_clk, "bus-i2c6", apb1_hws, 0xe98, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_i2c7_clk, "bus-i2c7", apb1_hws, 0xe9c, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_i2c8_clk, "bus-i2c8", apb1_hws, 0xea0, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_i2c9_clk, "bus-i2c9", apb1_hws, 0xea4, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_i2c10_clk, "bus-i2c10", apb1_hws, 0xea8, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_i2c11_clk, "bus-i2c11", apb1_hws, 0xeac, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_i2c12_clk, "bus-i2c12", apb1_hws, 0xeb0, BIT(0), 0);
 
 static const struct clk_parent_data spi_parents[] = {
 	{ .hw = &sys_24M_clk.hw },
@@ -839,18 +1004,23 @@  static SUNXI_CCU_DUALDIV_MUX_GATE(spi0_clk, "spi0", spi_parents, 0xf00,
 				  24, 3,	/* mux */
 				  BIT(31),	/* gate */
 				  0);
+static SUNXI_CCU_GATE_HWS(bus_spi0_clk, "bus-spi0", ahb_hws, 0xf04, BIT(0), 0);
+
 static SUNXI_CCU_DUALDIV_MUX_GATE(spi1_clk, "spi1", spi_parents, 0xf08,
 				  0, 5,		/* M */
 				  8, 5,		/* N */
 				  24, 3,	/* mux */
 				  BIT(31),	/* gate */
 				  0);
+static SUNXI_CCU_GATE_HWS(bus_spi1_clk, "bus-spi1", ahb_hws, 0xf0c, BIT(0), 0);
+
 static SUNXI_CCU_DUALDIV_MUX_GATE(spi2_clk, "spi2", spi_parents, 0xf10,
 				  0, 5,		/* M */
 				  8, 5,		/* N */
 				  24, 3,	/* mux */
 				  BIT(31),	/* gate */
 				  0);
+static SUNXI_CCU_GATE_HWS(bus_spi2_clk, "bus-spi2", ahb_hws, 0xf14, BIT(0), 0);
 
 static const struct clk_parent_data spif_parents[] = {
 	{ .hw = &sys_24M_clk.hw },
@@ -868,12 +1038,16 @@  static SUNXI_CCU_DUALDIV_MUX_GATE(spif_clk, "spif", spif_parents, 0xf18,
 				  24, 3,	/* mux */
 				  BIT(31),	/* gate */
 				  0);
+static SUNXI_CCU_GATE_HWS(bus_spif_clk, "bus-spif", ahb_hws, 0xf1c, BIT(0), 0);
+
 static SUNXI_CCU_DUALDIV_MUX_GATE(spi3_clk, "spi3", spi_parents, 0xf20,
 				  0, 5,		/* M */
 				  8, 5,		/* N */
 				  24, 3,	/* mux */
 				  BIT(31),	/* gate */
 				  0);
+static SUNXI_CCU_GATE_HWS(bus_spi3_clk, "bus-spi3", ahb_hws, 0xf24, BIT(0), 0);
+
 /* Undocumented, taken from the vendor kernel. */
 static SUNXI_CCU_DUALDIV_MUX_GATE(spi4_clk, "spi4", spi_parents, 0xf28,
 				  0, 5,		/* M */
@@ -881,6 +1055,7 @@  static SUNXI_CCU_DUALDIV_MUX_GATE(spi4_clk, "spi4", spi_parents, 0xf28,
 				  24, 3,	/* mux */
 				  BIT(31),	/* gate */
 				  0);
+static SUNXI_CCU_GATE_HWS(bus_spi4_clk, "bus-spi4", ahb_hws, 0xf2c, BIT(0), 0);
 
 static const struct clk_parent_data gpadc0_24m_parents[] = {
 	{ .hw = &sys_24M_clk.hw },
@@ -891,6 +1066,9 @@  static SUNXI_CCU_M_DATA_WITH_MUX_GATE(gpadc0_24m_clk, "gpadc0-24m", gpadc0_24m_p
 				      24, 3,	/* mux */
 				      BIT(31),	/* gate */
 				      0);
+static SUNXI_CCU_GATE_HWS(bus_gpadc0_clk, "bus-gpadc0", ahb_hws, 0xfc4, BIT(0), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_ths0_clk, "bus-ths0", apb0_hws, 0xfe4, BIT(0), 0);
 
 static const struct clk_parent_data irrx_parents[] = {
 	{ .fw_name = "losc"},
@@ -902,6 +1080,7 @@  static SUNXI_CCU_M_DATA_WITH_MUX_GATE(irrx_clk, "irrx", irrx_parents, 0x1000,
 				      24, 3,	/* mux */
 				      BIT(31),	/* gate */
 				      0);
+static SUNXI_CCU_GATE_HWS(bus_irrx_clk, "bus-irrx", apb0_hws, 0x1004, BIT(0), 0);
 
 static const struct clk_parent_data irtx_parents[] = {
 	{ .fw_name = "losc"},
@@ -913,6 +1092,9 @@  static SUNXI_CCU_M_DATA_WITH_MUX_GATE(irtx_clk, "irtx", irtx_parents, 0x1008,
 				      24, 3,	/* mux */
 				      BIT(31),	/* gate */
 				      0);
+static SUNXI_CCU_GATE_HWS(bus_irtx_clk, "bus-irtx", apb0_hws, 0x100c, BIT(0), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_lradc_clk, "bus-lradc", apb0_hws, 0x1024, BIT(0), 0);
 
 /* Undocumented, taken from the vendor kernel. */
 static const struct clk_parent_data sgpio_parents[] = {
@@ -924,6 +1106,7 @@  static SUNXI_CCU_M_DATA_WITH_MUX_GATE(sgpio_clk, "sgpio", sgpio_parents, 0x1060,
 				      24, 3,	/* mux */
 				      BIT(31),	/* gate */
 				      0);
+static SUNXI_CCU_GATE_DATA(bus_sgpio_clk, "bus-sgpio", hosc, 0x1064, BIT(0), 0);
 
 /* Undocumented, taken from the vendor kernel. */
 static const struct clk_hw *lpc_parents[] = {
@@ -937,6 +1120,7 @@  static SUNXI_CCU_M_HW_WITH_MUX_GATE(lpc_clk, "lpc", lpc_parents, 0x1080,
 				    24, 3,	/* mux */
 				    BIT(31),	/* gate */
 				    0);
+static SUNXI_CCU_GATE_DATA(bus_lpc_clk, "bus-lpc", hosc, 0x1084, BIT(0), 0);
 
 static const struct clk_hw *i2spcm_parents[] = {
 	&pll_audio0_4x_clk.common.hw,
@@ -949,11 +1133,15 @@  static SUNXI_CCU_M_HW_WITH_MUX_GATE(i2spcm0_clk, "i2spcm0", i2spcm_parents, 0x12
 				    24, 3,	/* mux */
 				    BIT(31),	/* gate */
 				    0);
+static SUNXI_CCU_GATE_DATA(bus_i2spcm0_clk, "bus-i2spcm0", hosc, 0x120c, BIT(0), 0);
+
 static SUNXI_CCU_M_HW_WITH_MUX_GATE(i2spcm1_clk, "i2spcm1", i2spcm_parents, 0x1210,
 				    0, 5,	/* M */
 				    24, 3,	/* mux */
 				    BIT(31),	/* gate */
 				    0);
+static SUNXI_CCU_GATE_DATA(bus_i2spcm1_clk, "bus-i2spcm1", hosc, 0x121c, BIT(0), 0);
+
 static SUNXI_CCU_M_HW_WITH_MUX_GATE(i2spcm2_clk, "i2spcm2", i2spcm_parents, 0x1220,
 				    0, 5,	/* M */
 				    24, 3,	/* mux */
@@ -972,16 +1160,22 @@  static SUNXI_CCU_M_HW_WITH_MUX_GATE(i2spcm2_asrc_clk, "i2spcm2_asrc", i2spcm2_as
 				    24, 3,	/* mux */
 				    BIT(31),	/* gate */
 				    0);
+
+static SUNXI_CCU_GATE_DATA(bus_i2spcm2_clk, "bus-i2spcm2", hosc, 0x122c, BIT(0), 0);
+
 static SUNXI_CCU_M_HW_WITH_MUX_GATE(i2spcm3_clk, "i2spcm3", i2spcm_parents, 0x1230,
 				    0, 5,	/* M */
 				    24, 3,	/* mux */
 				    BIT(31),	/* gate */
 				    0);
+static SUNXI_CCU_GATE_DATA(bus_i2spcm3_clk, "bus-i2spcm3", hosc, 0x123c, BIT(0), 0);
+
 static SUNXI_CCU_M_HW_WITH_MUX_GATE(i2spcm4_clk, "i2spcm4", i2spcm_parents, 0x1240,
 				    0, 5,	/* M */
 				    24, 3,	/* mux */
 				    BIT(31),	/* gate */
 				    0);
+static SUNXI_CCU_GATE_DATA(bus_i2spcm4_clk, "bus-i2spcm4", hosc, 0x124c, BIT(0), 0);
 
 static const struct clk_hw *spdif_tx_parents[] = {
 	&pll_audio0_4x_clk.common.hw,
@@ -1005,6 +1199,8 @@  static SUNXI_CCU_M_HW_WITH_MUX_GATE(spdif_rx_clk, "spdif-rx", spdif_rx_parents,
 				    BIT(31),	/* gate */
 				    0);
 
+static SUNXI_CCU_GATE_HWS(bus_spdif_clk, "bus-spdif", apb1_hws, 0x128c, BIT(0), 0);
+
 static const struct clk_hw *dmic_parents[] = {
 	&pll_audio0_4x_clk.common.hw,
 	&pll_audio1_div2_clk.hw,
@@ -1016,6 +1212,8 @@  static SUNXI_CCU_M_HW_WITH_MUX_GATE(dmic_clk, "dmic", dmic_parents, 0x12c0,
 				    BIT(31),	/* gate */
 				    0);
 
+static SUNXI_CCU_GATE_HWS(bus_dmic_clk, "bus-dmic", apb1_hws, 0x12cc, BIT(0), 0);
+
 /*
  * The first parent is a 48 MHz input clock divided by 4. That 48 MHz clock is
  * a 2x multiplier from pll-ref synchronized by pll-periph0, and is also used by
@@ -1047,6 +1245,9 @@  static struct ccu_mux usb_ohci0_clk = {
 							   &ccu_mux_ops, 0),
 	},
 };
+static SUNXI_CCU_GATE_HWS(bus_ohci0_clk, "bus-ohci0", ahb_hws, 0x1304, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_ehci0_clk, "bus-ehci0", ahb_hws, 0x1304, BIT(4), 0);
+static SUNXI_CCU_GATE_HWS(bus_otg_clk, "bus-otg", ahb_hws, 0x1304, BIT(8), 0);
 
 static struct ccu_mux usb_ohci1_clk = {
 	.enable		= BIT(31),
@@ -1063,6 +1264,8 @@  static struct ccu_mux usb_ohci1_clk = {
 							   &ccu_mux_ops, 0),
 	},
 };
+static SUNXI_CCU_GATE_HWS(bus_ohci1_clk, "bus-ohci1", ahb_hws, 0x130c, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_ehci1_clk, "bus-ehci1", ahb_hws, 0x130c, BIT(4), 0);
 
 static const struct clk_parent_data usb01_ref_parents[] = {
 	{ .hw = &sys_24M_clk.hw },
@@ -1165,11 +1368,14 @@  static SUNXI_CCU_M_HWS_WITH_GATE(gmac0_phy_clk, "gmac0-phy", pll_periph0_150M_hw
 				 0, 5,		/* M */
 				 BIT(31),	/* gate */
 				 0);
+static SUNXI_CCU_GATE_HWS(bus_gmac0_clk, "bus-gmac0", ahb_hws, 0x141c, BIT(0), 0);
+
 /* Undocumented, taken from the vendor kernel. */
 static SUNXI_CCU_M_HWS_WITH_GATE(gmac1_phy_clk, "gmac1-phy", pll_periph0_150M_hws, 0x1420,
 				 0, 5,		/* M */
 				 BIT(31),	/* gate */
 				 0);
+static SUNXI_CCU_GATE_HWS(bus_gmac1_clk, "bus-gmac1", ahb_hws, 0x142c, BIT(0), 0);
 
 static const struct clk_hw *tcon_lcd_parents[] = {
 	&pll_video0_4x_clk.common.hw,
@@ -1182,17 +1388,22 @@  static SUNXI_CCU_M_HW_WITH_MUX_GATE(tcon_lcd0_clk, "tcon-lcd0", tcon_lcd_parents
 				    24, 3,	/* mux */
 				    BIT(31),	/* gate */
 				    0);
+static SUNXI_CCU_GATE_HWS(bus_tcon_lcd0_clk, "bus-tcon-lcd0", ahb_hws, 0x1504, BIT(0), 0);
+
 static SUNXI_CCU_M_HW_WITH_MUX_GATE(tcon_lcd1_clk, "tcon-lcd1", tcon_lcd_parents, 0x1508,
 				    0, 5,	/* M */
 				    24, 3,	/* mux */
 				    BIT(31),	/* gate */
 				    0);
+static SUNXI_CCU_GATE_HWS(bus_tcon_lcd1_clk, "bus-tcon-lcd1", ahb_hws, 0x150c, BIT(0), 0);
+
 /* Undocumented, taken from the vendor kernel. */
 static SUNXI_CCU_M_HW_WITH_MUX_GATE(tcon_lcd2_clk, "tcon-lcd2", tcon_lcd_parents, 0x1510,
 				    0, 5,	/* M */
 				    24, 3,	/* mux */
 				    BIT(31),	/* gate */
 				    0);
+static SUNXI_CCU_GATE_HWS(bus_tcon_lcd2_clk, "bus-tcon-lcd2", ahb_hws, 0x1514, BIT(0), 0);
 
 static const struct clk_hw *dsi_parents[] = {
 	&sys_24M_clk.hw,
@@ -1204,11 +1415,14 @@  static SUNXI_CCU_M_HW_WITH_MUX_GATE(dsi0_clk, "dsi0", dsi_parents, 0x1580,
 				    24, 3,	/* mux */
 				    BIT(31),	/* gate */
 				    0);
+static SUNXI_CCU_GATE_HWS(bus_dsi0_clk, "bus-dsi0", ahb_hws, 0x1584, BIT(0), 0);
+
 static SUNXI_CCU_M_HW_WITH_MUX_GATE(dsi1_clk, "dsi1", dsi_parents, 0x1588,
 				    0, 5,	/* M */
 				    24, 3,	/* mux */
 				    BIT(31),	/* gate */
 				    0);
+static SUNXI_CCU_GATE_HWS(bus_dsi1_clk, "bus-dsi1", ahb_hws, 0x158c, BIT(0), 0);
 
 static const struct clk_hw *combphy_parents[] = {
 	&pll_video0_4x_clk.common.hw,
@@ -1228,6 +1442,9 @@  static SUNXI_CCU_M_HW_WITH_MUX_GATE(combphy1_clk, "combphy1", combphy_parents, 0
 				    BIT(31),	/* gate */
 				    0);
 
+static SUNXI_CCU_GATE_HWS(bus_tcon_tv0_clk, "bus-tcon-tv0", ahb_hws, 0x1604, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_tcon_tv1_clk, "bus-tcon-tv1", ahb_hws, 0x160c, BIT(0), 0);
+
 static const struct clk_hw *edp_tv_parents[] = {
 	&pll_video0_4x_clk.common.hw,
 	&pll_video1_4x_clk.common.hw,
@@ -1239,6 +1456,7 @@  static SUNXI_CCU_M_HW_WITH_MUX_GATE(edp_tv_clk, "edp-tv", edp_tv_parents, 0x1640
 				    24, 3,	/* mux */
 				    BIT(31),	/* gate */
 				    0);
+static SUNXI_CCU_GATE_HWS(bus_edp_tv_clk, "bus-edp-tv", ahb_hws, 0x164c, BIT(0), 0);
 
 static SUNXI_CCU_GATE_HWS_WITH_PREDIV(hdmi_cec_32k_clk, "hdmi-cec-32k", pll_periph0_2x_hws, 0x1680,
 				      BIT(30),	/* gate */
@@ -1266,6 +1484,7 @@  static SUNXI_CCU_DUALDIV_MUX_GATE(hdmi_tv_clk, "hdmi-tv", hdmi_tv_parents, 0x168
 				  24, 3,	/* mux */
 				  BIT(31),	/* gate */
 				  0);
+static SUNXI_CCU_GATE_HWS(bus_hdmi_tv_clk, "bus-hdmi-tv", ahb_hws, 0x168c, BIT(0), 0);
 
 static const struct clk_parent_data hdmi_sfr_parents[] = {
 	{ .hw = &sys_24M_clk.hw },
@@ -1278,6 +1497,9 @@  static SUNXI_CCU_MUX_DATA_WITH_GATE(hdmi_sfr_clk, "hdmi-sfr", hdmi_sfr_parents,
 
 static SUNXI_CCU_GATE_HWS(hdcp_esm_clk, "hdcp-esm", pll_periph0_300M_hws, 0x1694, BIT(31), 0);
 
+static SUNXI_CCU_GATE_HWS(bus_dpss_top0_clk, "bus-dpss-top0", ahb_hws, 0x16c4, BIT(0), 0);
+static SUNXI_CCU_GATE_HWS(bus_dpss_top1_clk, "bus-dpss-top1", ahb_hws, 0x16cc, BIT(0), 0);
+
 static const struct clk_parent_data ledc_parents[] = {
 	{ .hw = &sys_24M_clk.hw },
 	{ .hw = &pll_periph0_600M_clk.hw },
@@ -1288,6 +1510,9 @@  static SUNXI_CCU_M_DATA_WITH_MUX_GATE(ledc_clk, "ledc", ledc_parents, 0x1700,
 				      24, 3,	/* mux */
 				      BIT(31),	/* gate */
 				      0);
+static SUNXI_CCU_GATE_HWS(bus_ledc_clk, "bus-ledc", apb0_hws, 0x1704, BIT(0), 0);
+
+static SUNXI_CCU_GATE_HWS(bus_dsc_clk, "bus-dsc", ahb_hws, 0x1744, BIT(0), 0);
 
 static const struct clk_parent_data csi_master_parents[] = {
 	{ .hw = &sys_24M_clk.hw },
@@ -1329,6 +1554,7 @@  static SUNXI_CCU_M_HW_WITH_MUX_GATE(csi_clk, "csi", csi_parents, 0x1840,
 				    24, 3,	/* mux */
 				    BIT(31),	/* gate */
 				    0);
+static SUNXI_CCU_GATE_HWS(bus_csi_clk, "bus-csi", ahb_hws, 0x1844, BIT(0), 0);
 
 static const struct clk_hw *isp_parents[] = {
 	&pll_video2_4x_clk.common.hw,
@@ -1457,7 +1683,60 @@  static struct ccu_common *sun60i_a733_ccu_clks[] = {
 	&apb_uart_clk.common,
 	&trace_clk.common,
 	&gic_clk.common,
+	&bus_its_pcie0_aclk_clk.common,
 	&mbus_clk.common,
+	&mbus_iommu0_sys_clk.common,
+	&apb_iommu0_sys_clk.common,
+	&ahb_iommu0_sys_clk.common,
+	&bus_msi_lite0_clk.common,
+	&bus_msi_lite1_clk.common,
+	&bus_msi_lite2_clk.common,
+	&mbus_iommu1_sys_clk.common,
+	&apb_iommu1_sys_clk.common,
+	&ahb_iommu1_sys_clk.common,
+	&ahb_ve_dec_clk.common,
+	&ahb_ve_enc_clk.common,
+	&ahb_vid_in_clk.common,
+	&ahb_vid_cout0_clk.common,
+	&ahb_vid_cout1_clk.common,
+	&ahb_de_clk.common,
+	&ahb_npu_clk.common,
+	&ahb_gpu0_clk.common,
+	&ahb_serdes_clk.common,
+	&ahb_usb_sys_clk.common,
+	&ahb_msi_lite0_clk.common,
+	&ahb_store_clk.common,
+	&ahb_cpus_clk.common,
+	&mbus_iommu0_clk.common,
+	&mbus_iommu1_clk.common,
+	&mbus_desys_clk.common,
+	&mbus_ve_enc0_gate_clk.common,
+	&mbus_ve_dec0_gate_clk.common,
+	&mbus_gpu0_clk.common,
+	&mbus_npu_clk.common,
+	&mbus_vid_in_clk.common,
+	&mbus_serdes_clk.common,
+	&mbus_msi_lite0_clk.common,
+	&mbus_store_clk.common,
+	&mbus_msi_lite2_clk.common,
+	&mbus_dma0_clk.common,
+	&mbus_ve_enc0_clk.common,
+	&mbus_ce_clk.common,
+	&mbus_dma1_clk.common,
+	&mbus_nand_clk.common,
+	&mbus_csi_clk.common,
+	&mbus_isp_clk.common,
+	&mbus_gmac0_clk.common,
+	&mbus_gmac1_clk.common,
+	&mbus_ve_dec0_clk.common,
+	&bus_dma0_clk.common,
+	&bus_dma1_clk.common,
+	&bus_spinlock_clk.common,
+	&bus_msgbox0_clk.common,
+	&bus_pwm0_clk.common,
+	&bus_pwm1_clk.common,
+	&bus_dbg_clk.common,
+	&bus_sysdap_clk.common,
 	&timer0_clk.common,
 	&timer1_clk.common,
 	&timer2_clk.common,
@@ -1468,48 +1747,111 @@  static struct ccu_common *sun60i_a733_ccu_clks[] = {
 	&timer7_clk.common,
 	&timer8_clk.common,
 	&timer9_clk.common,
+	&bus_timer_clk.common,
 	&avs_clk.common,
 	&de0_clk.common,
+	&bus_de0_clk.common,
 	&di_clk.common,
+	&bus_di_clk.common,
 	&g2d_clk.common,
+	&bus_g2d_clk.common,
 	&eink_clk.common,
 	&eink_panel_clk.common,
+	&bus_eink_clk.common,
 	&ve_enc0_clk.common,
 	&ve_dec0_clk.common,
+	&bus_ve_enc0_clk.common,
+	&bus_ve_dec0_clk.common,
 	&ce_clk.common,
+	&bus_ce_clk.common,
+	&bus_ce_sys_clk.common,
 	&npu_clk.common,
+	&bus_npu_clk.common,
 	&gpu0_clk.common,
+	&bus_gpu0_clk.common,
 	&dram0_clk.common,
+	&bus_dram0_clk.common,
 	&nand0_clk0_clk.common,
 	&nand0_clk1_clk.common,
+	&bus_nand0_clk.common,
 	&mmc0_clk.common,
+	&bus_mmc0_clk.common,
 	&mmc1_clk.common,
+	&bus_mmc1_clk.common,
 	&mmc2_clk.common,
+	&bus_mmc2_clk.common,
 	&mmc3_clk.common,
+	&bus_mmc3_clk.common,
 	&ufs_axi_clk.common,
 	&ufs_cfg_clk.common,
+	&bus_ufs_clk.common,
+	&bus_uart0_clk.common,
+	&bus_uart1_clk.common,
+	&bus_uart2_clk.common,
+	&bus_uart3_clk.common,
+	&bus_uart4_clk.common,
+	&bus_uart5_clk.common,
+	&bus_uart6_clk.common,
+	&bus_i2c0_clk.common,
+	&bus_i2c1_clk.common,
+	&bus_i2c2_clk.common,
+	&bus_i2c3_clk.common,
+	&bus_i2c4_clk.common,
+	&bus_i2c5_clk.common,
+	&bus_i2c6_clk.common,
+	&bus_i2c7_clk.common,
+	&bus_i2c8_clk.common,
+	&bus_i2c9_clk.common,
+	&bus_i2c10_clk.common,
+	&bus_i2c11_clk.common,
+	&bus_i2c12_clk.common,
 	&spi0_clk.common,
+	&bus_spi0_clk.common,
 	&spi1_clk.common,
+	&bus_spi1_clk.common,
 	&spi2_clk.common,
+	&bus_spi2_clk.common,
 	&spif_clk.common,
+	&bus_spif_clk.common,
 	&spi3_clk.common,
+	&bus_spi3_clk.common,
 	&spi4_clk.common,
+	&bus_spi4_clk.common,
 	&gpadc0_24m_clk.common,
+	&bus_gpadc0_clk.common,
+	&bus_ths0_clk.common,
 	&irrx_clk.common,
+	&bus_irrx_clk.common,
 	&irtx_clk.common,
+	&bus_irtx_clk.common,
+	&bus_lradc_clk.common,
 	&sgpio_clk.common,
+	&bus_sgpio_clk.common,
 	&lpc_clk.common,
+	&bus_lpc_clk.common,
 	&i2spcm0_clk.common,
+	&bus_i2spcm0_clk.common,
 	&i2spcm1_clk.common,
+	&bus_i2spcm1_clk.common,
 	&i2spcm2_clk.common,
 	&i2spcm2_asrc_clk.common,
+	&bus_i2spcm2_clk.common,
 	&i2spcm3_clk.common,
+	&bus_i2spcm3_clk.common,
 	&i2spcm4_clk.common,
+	&bus_i2spcm4_clk.common,
 	&spdif_tx_clk.common,
 	&spdif_rx_clk.common,
+	&bus_spdif_clk.common,
 	&dmic_clk.common,
+	&bus_dmic_clk.common,
 	&usb_ohci0_clk.common,
+	&bus_ohci0_clk.common,
+	&bus_ehci0_clk.common,
+	&bus_otg_clk.common,
 	&usb_ohci1_clk.common,
+	&bus_ohci1_clk.common,
+	&bus_ehci1_clk.common,
 	&usb01_ref_clk.common,
 	&usb2_u2_ref_clk.common,
 	&usb2_suspend_clk.common,
@@ -1521,25 +1863,41 @@  static struct ccu_common *sun60i_a733_ccu_clks[] = {
 	&serdes_phy_clk.common,
 	&gmac_ptp_clk.common,
 	&gmac0_phy_clk.common,
+	&bus_gmac0_clk.common,
 	&gmac1_phy_clk.common,
+	&bus_gmac1_clk.common,
 	&tcon_lcd0_clk.common,
+	&bus_tcon_lcd0_clk.common,
 	&tcon_lcd1_clk.common,
+	&bus_tcon_lcd1_clk.common,
 	&tcon_lcd2_clk.common,
+	&bus_tcon_lcd2_clk.common,
 	&dsi0_clk.common,
+	&bus_dsi0_clk.common,
 	&dsi1_clk.common,
+	&bus_dsi1_clk.common,
 	&combphy0_clk.common,
 	&combphy1_clk.common,
+	&bus_tcon_tv0_clk.common,
+	&bus_tcon_tv1_clk.common,
 	&edp_tv_clk.common,
+	&bus_edp_tv_clk.common,
 	&hdmi_cec_32k_clk.common,
 	&hdmi_cec_clk.common,
 	&hdmi_tv_clk.common,
+	&bus_hdmi_tv_clk.common,
 	&hdmi_sfr_clk.common,
 	&hdcp_esm_clk.common,
+	&bus_dpss_top0_clk.common,
+	&bus_dpss_top1_clk.common,
 	&ledc_clk.common,
+	&bus_ledc_clk.common,
+	&bus_dsc_clk.common,
 	&csi_master0_clk.common,
 	&csi_master1_clk.common,
 	&csi_master2_clk.common,
 	&csi_clk.common,
+	&bus_csi_clk.common,
 	&isp_clk.common,
 	&res_dcap_24m_clk.common,
 	&apb2jtag_clk.common,
@@ -1606,7 +1964,60 @@  static struct clk_hw_onecell_data sun60i_a733_hw_clks = {
 		[CLK_APB_UART]		= &apb_uart_clk.common.hw,
 		[CLK_TRACE]		= &trace_clk.common.hw,
 		[CLK_GIC]		= &gic_clk.common.hw,
+		[CLK_BUS_ITS_PCIE0_ACLK] = &bus_its_pcie0_aclk_clk.common.hw,
 		[CLK_MBUS]		= &mbus_clk.common.hw,
+		[CLK_MBUS_IOMMU0_SYS]	= &mbus_iommu0_sys_clk.common.hw,
+		[CLK_APB_IOMMU0_SYS]	= &apb_iommu0_sys_clk.common.hw,
+		[CLK_AHB_IOMMU0_SYS]	= &ahb_iommu0_sys_clk.common.hw,
+		[CLK_BUS_MSI_LITE0]	= &bus_msi_lite0_clk.common.hw,
+		[CLK_BUS_MSI_LITE1]	= &bus_msi_lite1_clk.common.hw,
+		[CLK_BUS_MSI_LITE2]	= &bus_msi_lite2_clk.common.hw,
+		[CLK_MBUS_IOMMU1_SYS]	= &mbus_iommu1_sys_clk.common.hw,
+		[CLK_APB_IOMMU1_SYS]	= &apb_iommu1_sys_clk.common.hw,
+		[CLK_AHB_IOMMU1_SYS]	= &ahb_iommu1_sys_clk.common.hw,
+		[CLK_AHB_VE_DEC]	= &ahb_ve_dec_clk.common.hw,
+		[CLK_AHB_VE_ENC]	= &ahb_ve_enc_clk.common.hw,
+		[CLK_AHB_VID_IN]	= &ahb_vid_in_clk.common.hw,
+		[CLK_AHB_VID_COUT0]	= &ahb_vid_cout0_clk.common.hw,
+		[CLK_AHB_VID_COUT1]	= &ahb_vid_cout1_clk.common.hw,
+		[CLK_AHB_DE]		= &ahb_de_clk.common.hw,
+		[CLK_AHB_NPU]		= &ahb_npu_clk.common.hw,
+		[CLK_AHB_GPU0]		= &ahb_gpu0_clk.common.hw,
+		[CLK_AHB_SERDES]	= &ahb_serdes_clk.common.hw,
+		[CLK_AHB_USB_SYS]	= &ahb_usb_sys_clk.common.hw,
+		[CLK_AHB_MSI_LITE0]	= &ahb_msi_lite0_clk.common.hw,
+		[CLK_AHB_STORE]		= &ahb_store_clk.common.hw,
+		[CLK_AHB_CPUS]		= &ahb_cpus_clk.common.hw,
+		[CLK_MBUS_IOMMU0]	= &mbus_iommu0_clk.common.hw,
+		[CLK_MBUS_IOMMU1]	= &mbus_iommu1_clk.common.hw,
+		[CLK_MBUS_DESYS]	= &mbus_desys_clk.common.hw,
+		[CLK_MBUS_VE_ENC0_GATE]	= &mbus_ve_enc0_gate_clk.common.hw,
+		[CLK_MBUS_VE_DEC0_GATE]	= &mbus_ve_dec0_gate_clk.common.hw,
+		[CLK_MBUS_GPU0]		= &mbus_gpu0_clk.common.hw,
+		[CLK_MBUS_NPU]		= &mbus_npu_clk.common.hw,
+		[CLK_MBUS_VID_IN]	= &mbus_vid_in_clk.common.hw,
+		[CLK_MBUS_SERDES]	= &mbus_serdes_clk.common.hw,
+		[CLK_MBUS_MSI_LITE0]	= &mbus_msi_lite0_clk.common.hw,
+		[CLK_MBUS_STORE]	= &mbus_store_clk.common.hw,
+		[CLK_MBUS_MSI_LITE2]	= &mbus_msi_lite2_clk.common.hw,
+		[CLK_MBUS_DMA0]		= &mbus_dma0_clk.common.hw,
+		[CLK_MBUS_VE_ENC0]	= &mbus_ve_enc0_clk.common.hw,
+		[CLK_MBUS_CE]		= &mbus_ce_clk.common.hw,
+		[CLK_MBUS_DMA1]		= &mbus_dma1_clk.common.hw,
+		[CLK_MBUS_NAND]		= &mbus_nand_clk.common.hw,
+		[CLK_MBUS_CSI]		= &mbus_csi_clk.common.hw,
+		[CLK_MBUS_ISP]		= &mbus_isp_clk.common.hw,
+		[CLK_MBUS_GMAC0]	= &mbus_gmac0_clk.common.hw,
+		[CLK_MBUS_GMAC1]	= &mbus_gmac1_clk.common.hw,
+		[CLK_MBUS_VE_DEC0]	= &mbus_ve_dec0_clk.common.hw,
+		[CLK_BUS_DMA0]		= &bus_dma0_clk.common.hw,
+		[CLK_BUS_DMA1]		= &bus_dma1_clk.common.hw,
+		[CLK_BUS_SPINLOCK]	= &bus_spinlock_clk.common.hw,
+		[CLK_BUS_MSGBOX0]	= &bus_msgbox0_clk.common.hw,
+		[CLK_BUS_PWM0]		= &bus_pwm0_clk.common.hw,
+		[CLK_BUS_PWM1]		= &bus_pwm1_clk.common.hw,
+		[CLK_BUS_DBG]		= &bus_dbg_clk.common.hw,
+		[CLK_BUS_SYSDAP]	= &bus_sysdap_clk.common.hw,
 		[CLK_TIMER0]		= &timer0_clk.common.hw,
 		[CLK_TIMER1]		= &timer1_clk.common.hw,
 		[CLK_TIMER2]		= &timer2_clk.common.hw,
@@ -1617,48 +2028,111 @@  static struct clk_hw_onecell_data sun60i_a733_hw_clks = {
 		[CLK_TIMER7]		= &timer7_clk.common.hw,
 		[CLK_TIMER8]		= &timer8_clk.common.hw,
 		[CLK_TIMER9]		= &timer9_clk.common.hw,
+		[CLK_BUS_TIMER]		= &bus_timer_clk.common.hw,
 		[CLK_AVS]		= &avs_clk.common.hw,
 		[CLK_DE0]		= &de0_clk.common.hw,
+		[CLK_BUS_DE0]		= &bus_de0_clk.common.hw,
 		[CLK_DI]		= &di_clk.common.hw,
+		[CLK_BUS_DI]		= &bus_di_clk.common.hw,
 		[CLK_G2D]		= &g2d_clk.common.hw,
+		[CLK_BUS_G2D]		= &bus_g2d_clk.common.hw,
 		[CLK_EINK]		= &eink_clk.common.hw,
 		[CLK_EINK_PANEL]	= &eink_panel_clk.common.hw,
+		[CLK_BUS_EINK]		= &bus_eink_clk.common.hw,
 		[CLK_VE_ENC0]		= &ve_enc0_clk.common.hw,
 		[CLK_VE_DEC0]		= &ve_dec0_clk.common.hw,
+		[CLK_BUS_VE_ENC0]	= &bus_ve_enc0_clk.common.hw,
+		[CLK_BUS_VE_DEC0]	= &bus_ve_dec0_clk.common.hw,
 		[CLK_CE]		= &ce_clk.common.hw,
+		[CLK_BUS_CE]		= &bus_ce_clk.common.hw,
+		[CLK_BUS_CE_SYS]	= &bus_ce_sys_clk.common.hw,
 		[CLK_NPU]		= &npu_clk.common.hw,
+		[CLK_BUS_NPU]		= &bus_npu_clk.common.hw,
 		[CLK_GPU0]		= &gpu0_clk.common.hw,
+		[CLK_BUS_GPU0]		= &bus_gpu0_clk.common.hw,
 		[CLK_DRAM0]		= &dram0_clk.common.hw,
+		[CLK_BUS_DRAM0]		= &bus_dram0_clk.common.hw,
 		[CLK_NAND0_CLK0]	= &nand0_clk0_clk.common.hw,
 		[CLK_NAND0_CLK1]	= &nand0_clk1_clk.common.hw,
+		[CLK_BUS_NAND0]		= &bus_nand0_clk.common.hw,
 		[CLK_MMC0]		= &mmc0_clk.common.hw,
+		[CLK_BUS_MMC0]		= &bus_mmc0_clk.common.hw,
 		[CLK_MMC1]		= &mmc1_clk.common.hw,
+		[CLK_BUS_MMC1]		= &bus_mmc1_clk.common.hw,
 		[CLK_MMC2]		= &mmc2_clk.common.hw,
+		[CLK_BUS_MMC2]		= &bus_mmc2_clk.common.hw,
 		[CLK_MMC3]		= &mmc3_clk.common.hw,
+		[CLK_BUS_MMC3]		= &bus_mmc3_clk.common.hw,
 		[CLK_UFS_AXI]		= &ufs_axi_clk.common.hw,
 		[CLK_UFS_CFG]		= &ufs_cfg_clk.common.hw,
+		[CLK_BUS_UFS]		= &bus_ufs_clk.common.hw,
+		[CLK_BUS_UART0]		= &bus_uart0_clk.common.hw,
+		[CLK_BUS_UART1]		= &bus_uart1_clk.common.hw,
+		[CLK_BUS_UART2]		= &bus_uart2_clk.common.hw,
+		[CLK_BUS_UART3]		= &bus_uart3_clk.common.hw,
+		[CLK_BUS_UART4]		= &bus_uart4_clk.common.hw,
+		[CLK_BUS_UART5]		= &bus_uart5_clk.common.hw,
+		[CLK_BUS_UART6]		= &bus_uart6_clk.common.hw,
+		[CLK_BUS_I2C0]		= &bus_i2c0_clk.common.hw,
+		[CLK_BUS_I2C1]		= &bus_i2c1_clk.common.hw,
+		[CLK_BUS_I2C2]		= &bus_i2c2_clk.common.hw,
+		[CLK_BUS_I2C3]		= &bus_i2c3_clk.common.hw,
+		[CLK_BUS_I2C4]		= &bus_i2c4_clk.common.hw,
+		[CLK_BUS_I2C5]		= &bus_i2c5_clk.common.hw,
+		[CLK_BUS_I2C6]		= &bus_i2c6_clk.common.hw,
+		[CLK_BUS_I2C7]		= &bus_i2c7_clk.common.hw,
+		[CLK_BUS_I2C8]		= &bus_i2c8_clk.common.hw,
+		[CLK_BUS_I2C9]		= &bus_i2c9_clk.common.hw,
+		[CLK_BUS_I2C10]		= &bus_i2c10_clk.common.hw,
+		[CLK_BUS_I2C11]		= &bus_i2c11_clk.common.hw,
+		[CLK_BUS_I2C12]		= &bus_i2c12_clk.common.hw,
 		[CLK_SPI0]		= &spi0_clk.common.hw,
+		[CLK_BUS_SPI0]		= &bus_spi0_clk.common.hw,
 		[CLK_SPI1]		= &spi1_clk.common.hw,
+		[CLK_BUS_SPI1]		= &bus_spi1_clk.common.hw,
 		[CLK_SPI2]		= &spi2_clk.common.hw,
+		[CLK_BUS_SPI2]		= &bus_spi2_clk.common.hw,
 		[CLK_SPIF]		= &spif_clk.common.hw,
+		[CLK_BUS_SPIF]		= &bus_spif_clk.common.hw,
 		[CLK_SPI3]		= &spi3_clk.common.hw,
+		[CLK_BUS_SPI3]		= &bus_spi3_clk.common.hw,
 		[CLK_SPI4]		= &spi4_clk.common.hw,
+		[CLK_BUS_SPI4]		= &bus_spi4_clk.common.hw,
 		[CLK_GPADC0_24M]	= &gpadc0_24m_clk.common.hw,
+		[CLK_BUS_GPADC0]	= &bus_gpadc0_clk.common.hw,
+		[CLK_BUS_THS0]		= &bus_ths0_clk.common.hw,
 		[CLK_IRRX]		= &irrx_clk.common.hw,
+		[CLK_BUS_IRRX]		= &bus_irrx_clk.common.hw,
 		[CLK_IRTX]		= &irtx_clk.common.hw,
+		[CLK_BUS_IRTX]		= &bus_irtx_clk.common.hw,
+		[CLK_BUS_LRADC]		= &bus_lradc_clk.common.hw,
 		[CLK_SGPIO]		= &sgpio_clk.common.hw,
+		[CLK_BUS_SGPIO]		= &bus_sgpio_clk.common.hw,
 		[CLK_LPC]		= &lpc_clk.common.hw,
+		[CLK_BUS_LPC]		= &bus_lpc_clk.common.hw,
 		[CLK_I2SPCM0]		= &i2spcm0_clk.common.hw,
+		[CLK_BUS_I2SPCM0]	= &bus_i2spcm0_clk.common.hw,
 		[CLK_I2SPCM1]		= &i2spcm1_clk.common.hw,
+		[CLK_BUS_I2SPCM1]	= &bus_i2spcm1_clk.common.hw,
 		[CLK_I2SPCM2]		= &i2spcm2_clk.common.hw,
 		[CLK_I2SPCM2_ASRC]	= &i2spcm2_asrc_clk.common.hw,
+		[CLK_BUS_I2SPCM2]	= &bus_i2spcm2_clk.common.hw,
 		[CLK_I2SPCM3]		= &i2spcm3_clk.common.hw,
+		[CLK_BUS_I2SPCM3]	= &bus_i2spcm3_clk.common.hw,
 		[CLK_I2SPCM4]		= &i2spcm4_clk.common.hw,
+		[CLK_BUS_I2SPCM4]	= &bus_i2spcm4_clk.common.hw,
 		[CLK_SPDIF_TX]		= &spdif_tx_clk.common.hw,
 		[CLK_SPDIF_RX]		= &spdif_rx_clk.common.hw,
+		[CLK_BUS_SPDIF]		= &bus_spdif_clk.common.hw,
 		[CLK_DMIC]		= &dmic_clk.common.hw,
+		[CLK_BUS_DMIC]		= &bus_dmic_clk.common.hw,
 		[CLK_USB_OHCI0]		= &usb_ohci0_clk.common.hw,
+		[CLK_BUS_OHCI0]		= &bus_ohci0_clk.common.hw,
+		[CLK_BUS_EHCI0]		= &bus_ehci0_clk.common.hw,
+		[CLK_BUS_OTG]		= &bus_otg_clk.common.hw,
 		[CLK_USB_OHCI1]		= &usb_ohci1_clk.common.hw,
+		[CLK_BUS_OHCI1]		= &bus_ohci1_clk.common.hw,
+		[CLK_BUS_EHCI1]		= &bus_ehci1_clk.common.hw,
 		[CLK_USB01_REF]		= &usb01_ref_clk.common.hw,
 		[CLK_USB2_U2_REF]	= &usb2_u2_ref_clk.common.hw,
 		[CLK_USB2_SUSPEND]	= &usb2_suspend_clk.common.hw,
@@ -1670,25 +2144,41 @@  static struct clk_hw_onecell_data sun60i_a733_hw_clks = {
 		[CLK_SERDES_PHY]	= &serdes_phy_clk.common.hw,
 		[CLK_GMAC_PTP]		= &gmac_ptp_clk.common.hw,
 		[CLK_GMAC0_PHY]		= &gmac0_phy_clk.common.hw,
+		[CLK_BUS_GMAC0]		= &bus_gmac0_clk.common.hw,
 		[CLK_GMAC1_PHY]		= &gmac1_phy_clk.common.hw,
+		[CLK_BUS_GMAC1]		= &bus_gmac1_clk.common.hw,
 		[CLK_TCON_LCD0]		= &tcon_lcd0_clk.common.hw,
+		[CLK_BUS_TCON_LCD0]	= &bus_tcon_lcd0_clk.common.hw,
 		[CLK_TCON_LCD1]		= &tcon_lcd1_clk.common.hw,
+		[CLK_BUS_TCON_LCD1]	= &bus_tcon_lcd1_clk.common.hw,
 		[CLK_TCON_LCD2]		= &tcon_lcd2_clk.common.hw,
+		[CLK_BUS_TCON_LCD2]	= &bus_tcon_lcd2_clk.common.hw,
 		[CLK_DSI0]		= &dsi0_clk.common.hw,
+		[CLK_BUS_DSI0]		= &bus_dsi0_clk.common.hw,
 		[CLK_DSI1]		= &dsi1_clk.common.hw,
+		[CLK_BUS_DSI1]		= &bus_dsi1_clk.common.hw,
 		[CLK_COMBPHY0]		= &combphy0_clk.common.hw,
 		[CLK_COMBPHY1]		= &combphy1_clk.common.hw,
+		[CLK_BUS_TCON_TV0]	= &bus_tcon_tv0_clk.common.hw,
+		[CLK_BUS_TCON_TV1]	= &bus_tcon_tv1_clk.common.hw,
 		[CLK_EDP_TV]		= &edp_tv_clk.common.hw,
+		[CLK_BUS_EDP_TV]	= &bus_edp_tv_clk.common.hw,
 		[CLK_HDMI_CEC_32K]	= &hdmi_cec_32k_clk.common.hw,
 		[CLK_HDMI_CEC]		= &hdmi_cec_clk.common.hw,
 		[CLK_HDMI_TV]		= &hdmi_tv_clk.common.hw,
+		[CLK_BUS_HDMI_TV]	= &bus_hdmi_tv_clk.common.hw,
 		[CLK_HDMI_SFR]		= &hdmi_sfr_clk.common.hw,
 		[CLK_HDCP_ESM]		= &hdcp_esm_clk.common.hw,
+		[CLK_BUS_DPSS_TOP0]	= &bus_dpss_top0_clk.common.hw,
+		[CLK_BUS_DPSS_TOP1]	= &bus_dpss_top1_clk.common.hw,
 		[CLK_LEDC]		= &ledc_clk.common.hw,
+		[CLK_BUS_LEDC]		= &bus_ledc_clk.common.hw,
+		[CLK_BUS_DSC]		= &bus_dsc_clk.common.hw,
 		[CLK_CSI_MASTER0]	= &csi_master0_clk.common.hw,
 		[CLK_CSI_MASTER1]	= &csi_master1_clk.common.hw,
 		[CLK_CSI_MASTER2]	= &csi_master2_clk.common.hw,
 		[CLK_CSI]		= &csi_clk.common.hw,
+		[CLK_BUS_CSI]		= &bus_csi_clk.common.hw,
 		[CLK_ISP]		= &isp_clk.common.hw,
 		[CLK_RES_DCAP_24M]	= &res_dcap_24m_clk.common.hw,
 		[CLK_APB2JTAG]		= &apb2jtag_clk.common.hw,